diff --git a/manifest.json b/manifest.json index 55a0a42..01c47cf 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { "id": "obsidian42-strange-new-worlds", "name": "Obsidian42 - Strange New Worlds", - "version": "1.1.0", - "minAppVersion": "1.0.0", + "version": "1.1.1", + "minAppVersion": "1.1.0", "description": "Revealing networked thought and the strange new worlds created by your vault", "author": "TfTHacker", "authorUrl": "https://twitter.com/TfTHacker", diff --git a/package.json b/package.json index 65506c1..53734d9 100644 --- a/package.json +++ b/package.json @@ -11,18 +11,18 @@ "license": "MIT", "devDependencies": { "@codemirror/commands": "^6.1.2", - "@codemirror/language": "^6.3.1", + "@codemirror/language": "^6.3.2", "@codemirror/search": "^6.2.3", - "@codemirror/state": "^6.1.3", - "@codemirror/view": "^6.5.0", - "@types/node": "^18.11.9", - "@typescript-eslint/eslint-plugin": "^5.43.0", - "@typescript-eslint/parser": "^5.43.0", + "@codemirror/state": "^6.1.4", + "@codemirror/view": "^6.7.1", + "@types/node": "^18.11.15", + "@typescript-eslint/eslint-plugin": "^5.46.1", + "@typescript-eslint/parser": "^5.46.1", "builtin-modules": "^3.2.0", - "esbuild": "0.15.14", + "esbuild": "0.16.7", "obsidian": "^0.16.3", "tslib": "2.4.1", - "typescript": "4.8.4" + "typescript": "4.9.4" }, "dependencies": { "tippy.js": "^6.3.7" diff --git a/src/indexer.ts b/src/indexer.ts index 3d079e5..a5e372c 100644 --- a/src/indexer.ts +++ b/src/indexer.ts @@ -1,6 +1,6 @@ // This module builds on Obsidians cache to provide more specific link information -import { CachedMetadata, HeadingCache, stripHeading, TFile, Pos} from "obsidian"; +import { CachedMetadata, HeadingCache, stripHeading, TFile, Pos, parseLinktext} from "obsidian"; import SNWPlugin from "./main"; import {Link, TransformedCache} from "./types"; @@ -30,7 +30,28 @@ export function getSnwAllLinksResolutions(){ export function buildLinksAndReferences(): void { if(thePlugin.showCountsActive!=true) return; - allLinkResolutions = thePlugin.app.fileManager.getAllLinkResolutions(); //cache this for use in other pages + allLinkResolutions = []; + thePlugin.app.metadataCache.iterateReferences((src,refs)=>{ + const resolvedFilePath = parseLinktext(refs.link); + if(resolvedFilePath?.path) { + const resolvedTFile = thePlugin.app.metadataCache.getFirstLinkpathDest(resolvedFilePath.path, "/"); + const ghlink = !resolvedTFile ? resolvedFilePath.path : ""; // file doesnt exist, its a ghost link + + allLinkResolutions.push( + { + reference: { + displayText: refs.displayText, + link: refs.link, + position: refs.position + }, + resolvedFile: resolvedTFile, + ghostLink: ghlink, + sourceFile: thePlugin.app.metadataCache.getFirstLinkpathDest(src, "/"), + excludedFile: false + } + ) + } + }) // START: Remove file exclusions for frontmatter snw-index-exclude const snwIndexExceptionsList = Object.entries(app.metadataCache.metadataCache).filter((e)=>{ @@ -40,24 +61,32 @@ export function buildLinksAndReferences(): void { return snwIndexExceptionsList.find(f=>f[0]===e[1].hash); }); + + for (let i = 0; i < allLinkResolutions.length; i++) { allLinkResolutions[i].excludedFile = false; - const fileName = allLinkResolutions[i].resolvedFile.path; - for (let e = 0; e < snwIndexExceptions.length; e++) { - if(fileName==snwIndexExceptions[e][0]) { - allLinkResolutions[i].excludedFile = true; - break; + if(allLinkResolutions[i]?.resolvedFile?.path){ + const fileName = allLinkResolutions[i].resolvedFile.path; + for (let e = 0; e < snwIndexExceptions.length; e++) { + if(fileName==snwIndexExceptions[e][0]) { + allLinkResolutions[i].excludedFile = true; + break; + } } - } + } } // END: Exclusions + const refs = allLinkResolutions.reduce((acc: {[x:string]: Link[]}, link : Link): { [x:string]: Link[] } => { let keyBasedOnLink = ""; let keyBasedOnFullPath = "" keyBasedOnLink = link.reference.link; - keyBasedOnFullPath = link.resolvedFile.path.replace(link.resolvedFile.name,"") + link.reference.link; + if(link?.resolvedFile) + keyBasedOnFullPath = link.resolvedFile.path.replace(link.resolvedFile.name,"") + link.reference.link; + else + keyBasedOnFullPath = link.ghostLink; if(keyBasedOnLink===keyBasedOnFullPath) { keyBasedOnFullPath=null; @@ -203,6 +232,6 @@ export function getSNWCacheByFile(file: TFile): TransformedCache { transformedCache.cacheMetaData = cachedMetaData; transformedCache.createDate = Date.now(); cacheCurrentPages.set(file.path, transformedCache); - + return transformedCache; } diff --git a/src/types.ts b/src/types.ts index b6d8f33..3f80745 100644 --- a/src/types.ts +++ b/src/types.ts @@ -25,6 +25,7 @@ declare module "obsidian" { position: Pos } } + iterateReferences:( cb: (sourcePath: string, reference: ReferenceCache) => void ) => void } interface Vault { @@ -50,7 +51,8 @@ export interface Link { position: Pos } resolvedFile: TFile - resolvedPaths: string[] + // resolvedPaths: string[] + ghostLink: string sourceFile: TFile excludedFile: boolean; } diff --git a/src/ui/components/uic-ref-area.ts b/src/ui/components/uic-ref-area.ts index e477b7c..6627929 100644 --- a/src/ui/components/uic-ref-area.ts +++ b/src/ui/components/uic-ref-area.ts @@ -54,7 +54,10 @@ const getRefAreaItems = async (refType: string, key: string, filePath: string): if(refType==="File") { const allLinks: Link[] = getSnwAllLinksResolutions(); - const incomingLinks = allLinks.filter(f=>f?.resolvedFile.path===filePath); + const incomingLinks = allLinks.filter(f=>{ + if(!f?.resolvedFile) return false; + return f?.resolvedFile?.path===filePath; + }); countOfRefs = incomingLinks.length; linksToLoop = incomingLinks; } else { diff --git a/src/ui/headerRefCount.ts b/src/ui/headerRefCount.ts index 3261b92..12f669f 100644 --- a/src/ui/headerRefCount.ts +++ b/src/ui/headerRefCount.ts @@ -44,7 +44,10 @@ function processHeader(mdView: MarkdownView) { const allLinks: Link[] = getSnwAllLinksResolutions(); if(allLinks==undefined) return; - const incomingLinks = allLinks.filter(f=>f?.resolvedFile.path===mdView.file.path); + const incomingLinks = allLinks.filter(f=>{ + if(!f?.resolvedFile) return false; + return f?.resolvedFile?.path===mdView.file.path; + }); let incomingLinksCount = incomingLinks.length; diff --git a/src/view-extensions/gutters-cm6.ts b/src/view-extensions/gutters-cm6.ts index fcfccd4..24caf84 100644 --- a/src/view-extensions/gutters-cm6.ts +++ b/src/view-extensions/gutters-cm6.ts @@ -59,11 +59,7 @@ const ReferenceGutterExtension = gutter({ if(embed.position.start.line +1 === lineNumberInFile) { for (const ref of transformedCache.embeds) { if(ref?.references[0]?.excludedFile!=true && ref?.references.length>0 && ref?.pos.start.line+1 === lineNumberInFile) { - // @ts-ignore - let refOriginalLink = ref.references[0].reference.original; - if(refOriginalLink.substring(0,1)!="!") - refOriginalLink = "!" + refOriginalLink; - if( editorView.state.doc.lineAt(line.from).text.trim() === refOriginalLink) { + if( editorView.state.doc.lineAt(line.from).text.trim() === `![[${ref.key}]]`) { if(thePlugin.snwAPI.enableDebugging.GutterEmbedCounter) thePlugin.snwAPI.console("ReferenceGutterExtension New gutter", ref.references.length, "embed", ref.key, ref.key, "snw-embed-special" ); return new referenceGutterMarker(ref.references.length, "embed", ref.key, ref.references[0].resolvedFile.path.replace(".md",""), "snw-embed-special"); diff --git a/src/view-extensions/references-cm6.ts b/src/view-extensions/references-cm6.ts index 8e19161..25c0ac3 100644 --- a/src/view-extensions/references-cm6.ts +++ b/src/view-extensions/references-cm6.ts @@ -147,7 +147,9 @@ const constructWidgetForInlineReference = (refType: string, key: string, referen } if(matchKey===key) { - if(ref?.references[0]?.excludedFile!=true && ref?.references.length>=thePlugin.settings.minimumRefCountThreshold) + if( ref?.references[0]?.excludedFile!=true && + ref?.references[0]?.resolvedFile && + ref?.references.length>=thePlugin.settings.minimumRefCountThreshold) return new InlineReferenceWidget(ref.references.length, ref.type, ref.key, ref.references[0].resolvedFile.path.replace(".md",""), null, ref.pos.start.line); else return null; diff --git a/src/view-extensions/references-preview.ts b/src/view-extensions/references-preview.ts index d668af1..44bb7c0 100644 --- a/src/view-extensions/references-preview.ts +++ b/src/view-extensions/references-preview.ts @@ -88,7 +88,7 @@ class snwChildComponent extends MarkdownRenderChild { if ( value.references[0]?.excludedFile!=true && value.references.length >= minRefCountThreshold && (value.pos.start.line >= this.sectionInfo?.lineStart && value.pos.end.line <= this.sectionInfo?.lineEnd) && !isThisAnEmbed ) { - const referenceElement = htmlDecorationForReferencesElement(value.references.length, "block", value.key, value.references[0].resolvedFile.path.replace(".md",""), "", value.pos.start.line); + const referenceElement = htmlDecorationForReferencesElement(value.references.length, "block", value.key, value.references[0]?.resolvedFile?.path.replace(".md",""), "", value.pos.start.line); let blockElement: HTMLElement = this.containerEl.querySelector('p') if (!blockElement) { blockElement = this.containerEl.querySelector("li"); @@ -109,7 +109,7 @@ class snwChildComponent extends MarkdownRenderChild { const embedKey = element.getAttribute('src'); for (const value of transformedCache.embeds) { if (value.references[0]?.excludedFile!=true && value.references.length >= minRefCountThreshold && embedKey.endsWith(value.key)) { - const referenceElement = htmlDecorationForReferencesElement(value.references.length, "embed", value.key, value.references[0].resolvedFile.path.replace(".md",""), "", value.pos.start.line); + const referenceElement = htmlDecorationForReferencesElement(value.references.length, "embed", value.key, value.references[0]?.resolvedFile?.path.replace(".md",""), "", value.pos.start.line); referenceElement.addClass('snw-embed-preview'); element.after(referenceElement); break; @@ -124,7 +124,7 @@ class snwChildComponent extends MarkdownRenderChild { const textContext = headerKey.getAttribute("data-heading") for (const value of transformedCache.headings) { if (value.references[0]?.excludedFile!=true && value.references.length >= minRefCountThreshold && value.headerMatch === textContext) { - const referenceElement = htmlDecorationForReferencesElement(value.references.length, "heading", value.key, value.references[0].resolvedFile.path.replace(".md",""), "", value.pos.start.line); + const referenceElement = htmlDecorationForReferencesElement(value.references.length, "heading", value.key, value.references[0]?.resolvedFile?.path.replace(".md",""), "", value.pos.start.line); referenceElement.addClass("snw-heading-preview"); this.containerEl.querySelector("h1,h2,h3,h4,h5,h6").insertAdjacentElement("beforeend", referenceElement); break; @@ -138,7 +138,7 @@ class snwChildComponent extends MarkdownRenderChild { const link = element.getAttribute('data-href'); for (const value of transformedCache.links) { if (value.references[0]?.excludedFile!=true && value.references.length >= minRefCountThreshold && (value.key === link || (value?.original!=undefined && value?.original.contains(link)))) { - const referenceElement = htmlDecorationForReferencesElement(value.references.length, "link", value.key, value.references[0].resolvedFile.path.replace(".md",""), "", value.pos.start.line); + const referenceElement = htmlDecorationForReferencesElement(value.references.length, "link", value.key, value.references[0]?.resolvedFile?.path.replace(".md",""), "", value.pos.start.line); referenceElement.addClass('snw-link-preview'); element.after(referenceElement); break; diff --git a/versions.json b/versions.json index bce515c..9441b9f 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,5 @@ { - "0.0.01": "0.13.8", - "0.0.06": "0.16.2" + "1.1.1" : "1.1.5", + "0.0.06": "0.16.2", + "0.0.01": "0.13.8" } \ No newline at end of file