From fbb06457b1ae178ac4d2db49d4c67aca3f2ff6bc Mon Sep 17 00:00:00 2001 From: shunby <25155092+shunby@users.noreply.github.com> Date: Wed, 25 Sep 2024 00:50:31 +0900 Subject: [PATCH] Suppress re-rendering of callout widgets --- main.ts | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/main.ts b/main.ts index c43c461..fca4a2e 100644 --- a/main.ts +++ b/main.ts @@ -3,10 +3,20 @@ import { Plugin } from "obsidian"; import { around } from "monkey-around"; type CalloutWidgetType = WidgetType & { - clazz?: string; - text?: string; + clazz: string; + text: string; }; +function isCallout( + widget: (WidgetType & { clazz?: unknown; text?: unknown }) | undefined +): widget is CalloutWidgetType { + return ( + widget !== undefined && + widget.clazz === "cm-callout" && + typeof widget.text === "string" + ); +} + function makeFootrefHTML(tag: string) { const span1 = document.createElement("span"); span1.className = @@ -27,17 +37,19 @@ function makeFootrefHTML(tag: string) { // If `spec.widget` is a callout widget, replace its inner "[^tag]"s with HTML generated by `makeFootrefHTML`. function modifyCallout(spec: Parameters[0]) { - const widget: CalloutWidgetType | undefined = spec.widget; - if ( - widget && - widget.clazz === "cm-callout" && - widget.text && - typeof widget.text === "string" - ) { + const widget = spec.widget; + if (isCallout(widget)) { const footrefRegex = /\[\^([^\]]+)\]/g; widget.text = widget.text.replace(footrefRegex, (_, tag) => makeFootrefHTML(tag) ); + + // Modifying `widget.text` causes an inconsistency between `widget.text` and the document, + // leading Obsidian to recreate the widget. The eq method tells that the recreated widget + // is equivallent to the original one, preventeing unnecessary re-rendering. + widget.eq = function (other) { + return isCallout(other) && this.text === other.text; + }; } }