From b14c4aa1edab5bf5e6fc092308914f951400aa9e Mon Sep 17 00:00:00 2001 From: logonoff Date: Sun, 20 Oct 2024 14:00:52 -0400 Subject: [PATCH] Hide delimiters when in live preview mode --- main.ts | 113 ++++++++++++++++++++++++++++------------------------- styles.css | 13 ++++++ 2 files changed, 73 insertions(+), 53 deletions(-) diff --git a/main.ts b/main.ts index faab57c..21b0034 100644 --- a/main.ts +++ b/main.ts @@ -85,59 +85,66 @@ const spoilerDecoration = Decoration.mark({ tagName: "span", }); +const spoilerDelimiterDecoration = Decoration.mark({ + class: "inline_spoilers-editor-spoiler-delimiter", + tagName: "span", +}); + class SpoilerEditorPlugin implements PluginValue { - decorations: DecorationSet; - - constructor(view: EditorView) { - this.decorations = this.buildDecorations(view); - } - - update(update: ViewUpdate) { - if (update.docChanged || update.viewportChanged) { - this.decorations = this.buildDecorations(update.view); - } - } - - destroy() { } - - buildDecorations(view: EditorView): DecorationSet { - const builder = new RangeSetBuilder(); - const ranges: { from: number, to: number }[] = []; - - for (const { from, to } of view.visibleRanges) { - syntaxTree(view.state).iterate({ - from, - to, - enter(node) { - const text = view.state.sliceDoc(node.from, node.to); - let match: RegExpExecArray | null; - - while ((match = SPOILER_REGEX.exec(text)) !== null) { - const from = match.index; - const to = from + match[0].length; - - const text = view.state.sliceDoc(from, to); - - if (!text.startsWith("||") && !text.endsWith("||")) { - continue; // sanity check - } - - ranges.push({ from, to }); - } - }, - }); - } - - // Sort ranges by `from` position to prevent Codemirror error - ranges.sort((a, b) => a.from - b.from); - - // Add sorted ranges to the builder - for (const range of ranges) { - builder.add(range.from, range.to, spoilerDecoration); - } - - return builder.finish(); - } + decorations: DecorationSet; + + constructor(view: EditorView) { + this.decorations = this.buildDecorations(view); + } + + update(update: ViewUpdate) { + if (update.docChanged || update.viewportChanged) { + this.decorations = this.buildDecorations(update.view); + } + } + + destroy() { } + + buildDecorations(view: EditorView): DecorationSet { + const builder = new RangeSetBuilder(); + const ranges: { from: number, to: number, isDelimiter: boolean }[] = []; + + for (const { from, to } of view.visibleRanges) { + syntaxTree(view.state).iterate({ + from, + to, + enter(node) { + const text = view.state.sliceDoc(node.from, node.to); + let match: RegExpExecArray | null; + + while ((match = SPOILER_REGEX.exec(text)) !== null) { + const from = match.index; + const to = from + match[0].length; + + const text = view.state.sliceDoc(from, to); + + if (!text.startsWith("||") && !text.endsWith("||")) { + continue; // sanity check + } + + ranges.push({ from, to: from + 2, isDelimiter: true }); + ranges.push({ from: to - 2, to, isDelimiter: true }); + ranges.push({ from: from + 2, to: to - 2, isDelimiter: false }); + } + }, + }); + } + + // Sort ranges by `from` position to prevent Codemirror error + ranges.sort((a, b) => a.from - b.from); + + // Add sorted ranges to the builder + for (const range of ranges) { + builder.add(range.from, range.to, range.isDelimiter ? spoilerDelimiterDecoration : spoilerDecoration); + } + + return builder.finish(); + } } const pluginSpec: PluginSpec = { @@ -196,7 +203,7 @@ class InlineSpoilerPluginSettingsTab extends PluginSettingTab { new Setting(containerEl) .setName('Reveal all spoilers') - .setDesc('Always show all spoilers, regardless of whether they are clicked or not.') + .setDesc('Always show all inline spoilers, regardless of whether they are clicked or not.') .addToggle(toggle => toggle .setValue(this.plugin.settings.showAllSpoilers) .onChange(async (value) => { diff --git a/styles.css b/styles.css index bd042b1..c75bece 100644 --- a/styles.css +++ b/styles.css @@ -27,3 +27,16 @@ available in the app when your plugin is enabled. background-color: var(--code-background); color: var(--code-normal); } + +.inline_spoilers-editor-spoiler-delimiter { + background-color: var(--code-background); + color: var(--text-normal); +} + +.is-live-preview .inline_spoilers-editor-spoiler-delimiter { + display: none; +} + +.is-live-preview .cm-active .inline_spoilers-editor-spoiler-delimiter { + display: unset; +}