From 62eb25841cfcb73780c482f2ed3aaf3e856b377c Mon Sep 17 00:00:00 2001 From: TfT Hacker Date: Fri, 7 Oct 2022 21:09:48 +0200 Subject: [PATCH] 0.0.24 Switch to MarkdownRenderChild --- src/cm-extensions/references-preview.ts | 170 ++++++++++++++---------- src/main.ts | 8 +- 2 files changed, 105 insertions(+), 73 deletions(-) diff --git a/src/cm-extensions/references-preview.ts b/src/cm-extensions/references-preview.ts index 8510783..3d33720 100644 --- a/src/cm-extensions/references-preview.ts +++ b/src/cm-extensions/references-preview.ts @@ -1,4 +1,4 @@ -import {MarkdownPostProcessorContext} from "obsidian"; +import {MarkdownPostProcessorContext, MarkdownRenderChild, MarkdownSectionInformation, TFile} from "obsidian"; import {htmlDecorationForReferencesElement} from "./htmlDecorations"; import {getSNWCacheByFile} from "../indexer"; import ThePlugin from "../main"; @@ -10,6 +10,7 @@ export function setPluginVariableForMarkdownPreviewProcessor(plugin: ThePlugin) thePlugin = plugin; } + /** * Function called by main.registerMarkdownPostProcessor - this function renders the html when in preview mode * @@ -23,93 +24,122 @@ export function setPluginVariableForMarkdownPreviewProcessor(plugin: ThePlugin) */ export default function markdownPreviewProcessor(el : HTMLElement, ctx : MarkdownPostProcessorContext) { + if(thePlugin.snwAPI.enableDebugging.PreviewRendering) + thePlugin.snwAPI.console("markdownPreviewProcessor(HTMLElement, MarkdownPostProcessorContext,ctx.getSectionInfo", el, ctx, ctx.getSectionInfo(el)) + // @ts-ignore if(ctx.remainingNestLevel===4) return; // This is an attempt to prevent processing of embed files if(el.hasAttribute("uic")) return; // this is a custom component, don't render SNW inside it. - if(thePlugin.snwAPI.enableDebugging.PreviewRendering) - thePlugin.snwAPI.console("markdownPreviewProcessor(HTMLElement, MarkdownPostProcessorContext,ctx.getSectionInfo", el, ctx, ctx.getSectionInfo(el)) - const currentFile = thePlugin.app.vault.fileMap[ctx.sourcePath]; // check for incompatibility with other plugins - if(app.metadataCache.getFileCache(currentFile)?.frontmatter?.["kanban-plugin"] ) return; //no support for kanban board + if(thePlugin.app.metadataCache.getFileCache(currentFile)?.frontmatter?.["kanban-plugin"] ) return; //no support for kanban board - const transformedCache = getSNWCacheByFile(currentFile); - - const minRefCountThreshold = thePlugin.settings.minimumRefCountThreshold; - - if (transformedCache?.blocks || transformedCache.embeds || transformedCache.headings || transformedCache.links) { - const sectionInfo = ctx.getSectionInfo(el); - - if (thePlugin.settings.enableRenderingBlockIdInMarkdown && transformedCache?.blocks) { - let isThisAnEmbed = false; - try { // we don't want to proccess embeds - // @ts-ignore - isThisAnEmbed = ctx.containerEl.closest(".snw-embed-preview").nextSibling.classList.contains("snw-reference"); - } catch (error) { /* nothing to do here */ } - - for (const value of transformedCache.blocks) { - if ( value.references.length >= minRefCountThreshold && - (value.pos.start.line >= sectionInfo?.lineStart && value.pos.end.line <= sectionInfo?.lineEnd) && - !isThisAnEmbed ) { - const referenceElement = htmlDecorationForReferencesElement(value.references.length, "block", value.key, value.references[0].resolvedFile.path.replace(".md",""), "", value.pos.start.line); - let blockElement: HTMLElement = el.querySelector('p') - if (!blockElement) { - blockElement = el.querySelector("li"); + ctx.addChild(new snwChildComponent(el, ctx.getSectionInfo(el), currentFile )); + +} + + +class snwChildComponent extends MarkdownRenderChild { + containerEl: HTMLElement; + sectionInfo: MarkdownSectionInformation; + currentFile: TFile + + constructor(containerEl: HTMLElement, sectionInfo: MarkdownSectionInformation, currentFile: TFile) { + super(containerEl); + this.containerEl = containerEl; + this.sectionInfo = sectionInfo; + this.currentFile = currentFile; + } + + onload(): void { + this.processMarkdown() + if(thePlugin.environmentInitialized===false) { + // @ts-ignore + thePlugin.registerEvent(thePlugin.app.metadataCache.on("snw:onlayoutready", () => { + // after layout at startupis finished, if any documents are open they need to be refreshed + this.processMarkdown(); + })); + } + } + + processMarkdown(): void { + const minRefCountThreshold = thePlugin.settings.minimumRefCountThreshold; + const transformedCache = getSNWCacheByFile(this.currentFile); + + if (transformedCache?.blocks || transformedCache.embeds || transformedCache.headings || transformedCache.links) { + + if (thePlugin.settings.enableRenderingBlockIdInMarkdown && transformedCache?.blocks) { + let isThisAnEmbed = false; + try { // we don't want to proccess embeds + // @ts-ignore + isThisAnEmbed = ctx.containerEl.closest(".snw-embed-preview").nextSibling.classList.contains("snw-reference"); + } catch (error) { /* nothing to do here */ } + + for (const value of transformedCache.blocks) { + if ( 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); + let blockElement: HTMLElement = this.containerEl.querySelector('p') + if (!blockElement) { + blockElement = this.containerEl.querySelector("li"); + } + try { + if (!blockElement.hasClass("snw-block-preview")) { + referenceElement.addClass("snw-block-preview"); + blockElement.append(referenceElement); + break; + } + } catch (error) { /* nothing to do here */ } } - try { - if (!blockElement.hasClass("snw-block-preview")) { - referenceElement.addClass("snw-block-preview"); - blockElement.append(referenceElement); - break; - } - } catch (error) { /* nothing to do here */ } } } - } - if (thePlugin.settings.enableRenderingEmbedsInMarkdown && transformedCache?.embeds) { - el.querySelectorAll(".internal-embed:not(.snw-embed-preview)").forEach(element => { - const embedKey = element.getAttribute('src'); - for (const value of transformedCache.embeds) { - if (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); - referenceElement.addClass('snw-embed-preview'); - element.after(referenceElement); - break; + if (thePlugin.settings.enableRenderingEmbedsInMarkdown && transformedCache?.embeds) { + this.containerEl.querySelectorAll(".internal-embed:not(.snw-embed-preview)").forEach(element => { + const embedKey = element.getAttribute('src'); + for (const value of transformedCache.embeds) { + if (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); + referenceElement.addClass('snw-embed-preview'); + element.after(referenceElement); + break; + } } - } - }); - } + }); + } - if(thePlugin.settings.enableRenderingHeadersInMarkdown) { - const headerKey = el.querySelector("[data-heading]"); - if (transformedCache?.headings && headerKey) { - const textContext = headerKey.getAttribute("data-heading") - for (const value of transformedCache.headings) { - if (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); - referenceElement.addClass("snw-heading-preview"); - el.querySelector("h1,h2,h3,h4,h5,h6").insertAdjacentElement("beforeend", referenceElement); - break; + if(thePlugin.settings.enableRenderingHeadersInMarkdown) { + const headerKey = this.containerEl.querySelector("[data-heading]"); + if (transformedCache?.headings && headerKey) { + const textContext = headerKey.getAttribute("data-heading") + for (const value of transformedCache.headings) { + if (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); + referenceElement.addClass("snw-heading-preview"); + this.containerEl.querySelector("h1,h2,h3,h4,h5,h6").insertAdjacentElement("beforeend", referenceElement); + break; + } } } } - } - if(thePlugin.settings.enableRenderingLinksInMarkdown && transformedCache?.links) { - el.querySelectorAll("a.internal-link:not(.snw-link-preview)").forEach(element => { - const link = element.getAttribute('data-href'); - for (const value of transformedCache.links) { - if (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); - referenceElement.addClass('snw-link-preview'); - element.after(referenceElement); - break; + if(thePlugin.settings.enableRenderingLinksInMarkdown && transformedCache?.links) { + this.containerEl.querySelectorAll("a.internal-link:not(.snw-link-preview)").forEach(element => { + const link = element.getAttribute('data-href'); + for (const value of transformedCache.links) { + if (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); + referenceElement.addClass('snw-link-preview'); + element.after(referenceElement); + break; + } } - } - }); - } + }); + } + } } + } diff --git a/src/main.ts b/src/main.ts index 17b274b..b11b63a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,6 +24,7 @@ export default class ThePlugin extends Plugin { markdownPostProcessorSNW: MarkdownPostProcessor = null; editorExtensions: Extension[] = []; sidebarPaneSNW: SideBarPaneView; + environmentInitialized = false; async onload(): Promise < void > { console.log("loading " + this.appName); @@ -40,8 +41,8 @@ export default class ThePlugin extends Plugin { // @ts-ignore globalThis.snwAPI = this.snwAPI; // API access to SNW for Templater, Dataviewjs and the console debugger - // initial build of references - buildLinksAndReferences(); + // // initial build of references + // buildLinksAndReferences(); await this.loadSettings(); this.addSettingTab(new SettingsTab(this.app, this)); @@ -69,7 +70,6 @@ export default class ThePlugin extends Plugin { this.registerEditorExtension(this.editorExtensions); - this.toggleStateHeaderCount(); this.toggleStateSNWMarkdownPreview(); this.toggleStateSNWLivePreview(); @@ -82,6 +82,8 @@ export default class ThePlugin extends Plugin { if( !this.app.workspace.getLeavesOfType(VIEW_TYPE_SNW)?.length ) { await this.app.workspace.getRightLeaf(false).setViewState({type: VIEW_TYPE_SNW, active: false}); } + this.app.metadataCache.trigger("snw:onlayoutready"); + setTimeout(()=>this.environmentInitialized=true, 5000); // Used to make everything is initialized. }); }); }