Merge pull request #10 from alaric1995/main

Add hover functionality
This commit is contained in:
Ondřej Závodný 2023-12-02 18:40:44 +01:00 committed by GitHub
commit 4a25827761
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 22 deletions

4
package-lock.json generated
View file

@ -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",

View file

@ -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

View file

@ -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<Decoration>();
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<CopyInlineCodeViewPlugin> = {
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
);

View file

@ -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<CopyInlineCodePluginSettings> = {
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)
})
})
}
}
}

34
src/settings.ts Normal file
View file

@ -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();
})
});
}
}

View file

@ -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;
}