diff --git a/package-lock.json b/package-lock.json index aacefc6..8657d4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "obsidian-sample-plugin", - "version": "1.0.0", + "version": "1.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "obsidian-sample-plugin", - "version": "1.0.0", + "version": "1.1.2", "license": "MIT", "devDependencies": { "@codemirror/language": "^6.8.0", diff --git a/src/copy-code-widget.ts b/src/copy-code-widget.ts index 3d66d49..17f9c06 100644 --- a/src/copy-code-widget.ts +++ b/src/copy-code-widget.ts @@ -2,13 +2,15 @@ import { EditorView, WidgetType } from "@codemirror/view"; import { Notice } from "obsidian"; export class CopyWidget extends WidgetType { - constructor() { - super(); - } + showOnHover: boolean; + constructor(showOnHover: boolean) { + super(); + this.showOnHover = showOnHover; + } toDOM(view: EditorView): HTMLElement { - const icon = createSpan({cls: "copy-to-clipboard-icon", text: "\xa0📋"}) - + const icon = createSpan({cls: "copy-to-clipboard-icon", text: "\xa0📋"}) + icon.toggleClass("show-on-hover", this.showOnHover) icon.onclick = (event) => { const element = (event.target as HTMLElement) let previousElement = element.previousElementSibling diff --git a/src/copy-inline-code-view-plugin.ts b/src/copy-inline-code-view-plugin.ts index 6c8a281..819ff42 100644 --- a/src/copy-inline-code-view-plugin.ts +++ b/src/copy-inline-code-view-plugin.ts @@ -11,10 +11,13 @@ import { } from "@codemirror/view"; import { CopyWidget } from "./copy-code-widget"; + class CopyInlineCodeViewPlugin implements PluginValue { decorations: DecorationSet; + showOnHover: boolean; - constructor(view: EditorView) { + constructor(view:EditorView, showOnHover: boolean) { + this.showOnHover = showOnHover; this.decorations = this.buildDecorations(view); } @@ -28,7 +31,7 @@ class CopyInlineCodeViewPlugin implements PluginValue { buildDecorations(view: EditorView): DecorationSet { const builder = new RangeSetBuilder(); - + const showOnHover = this.showOnHover for (const { from, to } of view.visibleRanges) { syntaxTree(view.state).iterate({ from, @@ -39,7 +42,7 @@ class CopyInlineCodeViewPlugin implements PluginValue { node.to + 1, node.to + 1, Decoration.widget({ - widget: new CopyWidget(), + widget: new CopyWidget(showOnHover), }) ); } @@ -51,11 +54,11 @@ class CopyInlineCodeViewPlugin implements PluginValue { } } -const pluginSpec: PluginSpec = { - decorations: (value: CopyInlineCodeViewPlugin) => value.decorations, +export const createCopyPlugin = (showOnHover: boolean) => { + return ViewPlugin.define( + (view: EditorView) => new CopyInlineCodeViewPlugin(view, showOnHover), + { + decorations: (p) => p.decorations, + } + ); }; - -export const copyPlugin = ViewPlugin.fromClass( - CopyInlineCodeViewPlugin, - pluginSpec -); \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 7207006..bdccb70 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,36 @@ +import { CopyInlineCodePluginTab } from "./settings"; import { Notice, Plugin } from 'obsidian'; -import { copyPlugin as copyInlineCodePlugin } from './copy-inline-code-view-plugin'; +import { createCopyPlugin } from './copy-inline-code-view-plugin'; + + +interface CopyInlineCodePluginSettings { + showOnHover: boolean; +} + +const DEFAULT_SETTINGS: Partial = { + showOnHover: false, +}; export default class CopyInlineCodePlugin extends Plugin { + settings: CopyInlineCodePluginSettings; - async onload() { - this.registerEditorExtension([copyInlineCodePlugin]); + async onload() { + await this.loadSettings(); + this.addSettingTab(new CopyInlineCodePluginTab(this.app, this)); + this.copyInlineCodeLogic(); + + } + + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + } + + async saveSettings() { + await this.saveData(this.settings); + } + + async copyInlineCodeLogic() { + this.registerEditorExtension([createCopyPlugin(this.settings.showOnHover)]); this.registerMarkdownPostProcessor((element, context) => { const inlineCodes = element.querySelectorAll("*:not(pre) > code"); @@ -14,7 +40,8 @@ export default class CopyInlineCodePlugin extends Plugin { } const icon = createSpan({cls: "copy-to-clipboard-icon", text: "\xa0📋"}) - const textToCopy = code.textContent + icon.toggleClass("show-on-hover", this.settings.showOnHover) + const textToCopy = code.textContent icon.onclick = (event) => { if(textToCopy) { @@ -27,5 +54,6 @@ export default class CopyInlineCodePlugin extends Plugin { code.appendChild(icon) }) }) - } + } } + diff --git a/src/settings.ts b/src/settings.ts new file mode 100644 index 0000000..dae4036 --- /dev/null +++ b/src/settings.ts @@ -0,0 +1,34 @@ +import CopyInlineCodePlugin from "./main"; +import { App, PluginSettingTab, Setting } from "obsidian"; + +export class CopyInlineCodePluginTab extends PluginSettingTab { + plugin: CopyInlineCodePlugin; + + constructor(app: App, plugin: CopyInlineCodePlugin) { + super(app, plugin); + this.plugin = plugin; + } + + + display(): void { + const { containerEl } = this; + + containerEl.empty(); + containerEl.createEl('p', { + cls: 'tasks-setting-important', + text: 'Changing any settings requires a restart of obsidian.', + }); + + new Setting(containerEl) + .setName("Show on hover") + .setDesc("Copy icon only visible on hover (restart obsidian after change)") + .addToggle((component) => { + component + .setValue(this.plugin.settings.showOnHover) + .onChange(async (value) => { + this.plugin.settings.showOnHover = value; + await this.plugin.saveSettings(); + }) + }); + } +} diff --git a/styles.css b/styles.css index d238688..57b7ed1 100644 --- a/styles.css +++ b/styles.css @@ -1,3 +1,22 @@ .copy-to-clipboard-icon { cursor: pointer } + +.show-on-hover { + cursor: pointer; + opacity: 0; +} + +/* Source Mode */ +.cm-line:hover .show-on-hover { + opacity: 1.0; +} +/* Reading Mode */ +code:hover .show-on-hover { + opacity: 1.0; +} + +.tasks-setting-important { + color: red; + font-weight: bold; +}