diff --git a/src/annotation_control.ts b/src/annotation_control.ts index 0a3e7ca..907edff 100644 --- a/src/annotation_control.ts +++ b/src/annotation_control.ts @@ -7,11 +7,38 @@ import { isPluginAnnotation } from "types"; export class annotationControl { private clickedLink: boolean; private isPlaceholder: boolean; + private annotationDesc:string; + private placeholder:string; + private label:string; - constructor(private plugin: PluginsAnnotations, private annotation_container:HTMLDivElement, private annotation_div:HTMLDivElement,pluginId:string,pluginName:string) { + constructor(private plugin: PluginsAnnotations, annotation_container:HTMLDivElement, pluginId:string,private pluginName:string) { this.clickedLink = false; this.isPlaceholder = this.plugin.settings.annotations[pluginId] ? false : true; + this.label = Platform.isMobile ? this.plugin.settings.label_mobile : this.plugin.settings.label_desktop + + /*const label_div = document.createElement('div'); + label_div.addEventListener('click', (event:MouseEvent) => { + event.stopPropagation(); + }); + label_div.classList.add('plugin-comment-label') + const label = Platform.isMobile ? this.plugin.settings.label_mobile : this.plugin.settings.label_desktop + const tmp_div = document.createElement('div'); + this.renderAnnotation(tmp_div,label); + + // Get the first child of tmp_div (assumed to be a

element) + const firstChild = tmp_div.firstElementChild; + + if (firstChild && firstChild.tagName === 'P') { + // Move the content of the

element to label_div + label_div.innerHTML = firstChild.innerHTML; + + // Optionally, you can remove the

from tmp_div if needed + tmp_div.removeChild(firstChild); + }*/ + + const annotation_div = document.createElement('div'); + annotation_div.className = 'plugin-comment-annotation'; if(this.plugin.settings.editable) { annotation_div.contentEditable = 'true'; @@ -21,15 +48,13 @@ export class annotationControl { annotation_div.classList.remove('plugin-comment-annotation-editable'); } - const placeholder = (this.plugin.settings.label_placeholder).replace(/\$\{plugin_name\}/g, pluginName); + this.placeholder = (this.plugin.settings.label_placeholder).replace(/\$\{plugin_name\}/g, pluginName); - let annotationDesc:string; - if(!this.isPlaceholder && isPluginAnnotation(this.plugin.settings.annotations[pluginId])) { const annotation = this.plugin.settings.annotations[pluginId]; - annotationDesc = annotation.desc; + this.annotationDesc = annotation.desc; } else { - annotationDesc = placeholder.trim(); + this.annotationDesc = this.placeholder.trim(); annotation_div.classList.add('plugin-comment-placeholder'); if (this.plugin.settings.hide_placeholders) { // if it is a placeholder @@ -42,7 +67,15 @@ export class annotationControl { } // Initial render - this.renderAnnotation(annotation_div,annotationDesc); + this.renderAnnotation(annotation_div); + + annotation_div.addEventListener('mousedown', (event:MouseEvent) => { + if (event.target && (event.target as HTMLElement).tagName === 'A') { + this.clickedLink = true; + } else { + this.clickedLink = false; + } + }); // Prevent click event propagation to parent annotation_div.addEventListener('click', (event:MouseEvent) => { @@ -51,6 +84,11 @@ export class annotationControl { } else { event.stopPropagation(); } + }); + + annotation_div.addEventListener('focus', (event:FocusEvent) => { + if(this.clickedLink) return; + if (this.isPlaceholder) { if (this.plugin.settings.delete_placeholder_string_on_insertion) { annotation_div.innerText = ''; @@ -75,6 +113,8 @@ export class annotationControl { selection.removeAllRanges(); selection.addRange(range); } + } else { + annotation_div.innerText = this.annotationDesc; // this removes all html markup for editing } }); @@ -87,53 +127,44 @@ export class annotationControl { // Add placeholder class back if no changes are made annotation_div.addEventListener('blur', (event:FocusEvent) => { if(!this.plugin.settings.editable) { return; } + if(this.clickedLink) return; const content = annotation_div.innerText.trim(); if (this.isPlaceholder || content === '') { // placeholder - annotation_div.innerHTML = placeholder; + annotation_div.innerHTML = this.placeholder; delete this.plugin.settings.annotations[pluginId]; annotation_div.classList.add('plugin-comment-placeholder'); if (this.plugin.settings.hide_placeholders) { annotation_container.classList.add('plugin-comment-placeholder'); } this.isPlaceholder = true; - annotationDesc = ''; + this.annotationDesc = ''; } else { this.isPlaceholder = false; - annotationDesc = content.trim(); + this.annotationDesc = content.trim(); this.plugin.settings.annotations[pluginId] = { - desc: annotationDesc, + desc: this.annotationDesc, name: pluginName, }; annotation_div.classList.remove('plugin-comment-placeholder'); - this.renderAnnotation(annotation_div,content); + this.renderAnnotation(annotation_div); } this.plugin.debouncedSaveAnnotations(); }); + + // annotation_container.appendChild(label_div); + annotation_container.appendChild(annotation_div); } - async renderAnnotation(annotation_div: HTMLElement, desc:string) { - annotation_div.innerText = ''; - const label = Platform.isMobile ? this.plugin.settings.label_mobile : this.plugin.settings.label_desktop; - const desc_with_label = label + desc; - await MarkdownRenderer.renderMarkdown(desc_with_label, annotation_div, '', this.plugin); - this.handleAnnotationLinks(annotation_div); - } - - create_label(): HTMLSpanElement | null { - const label = Platform.isMobile ? this.plugin.settings.label_mobile : this.plugin.settings.label_desktop; - if(label.trim() === "") { - return null; - } else { - const span = document.createElement('span'); - span.innerHTML = label; - span.classList.add('plugin-comment-label'); - return span; - } + async renderAnnotation(div: HTMLElement) { + div.innerText = ''; + const text = (this.label + this.annotationDesc).replace(/\$\{plugin_name\}/g, this.pluginName); + await MarkdownRenderer.renderMarkdown(text, div, '', this.plugin); + this.handleAnnotationLinks(div); } // Helper function to parse links and add click listeners @@ -141,6 +172,8 @@ export class annotationControl { const links = element.querySelectorAll('a'); links.forEach(link => { link.addEventListener('click', (event) => { + this.clickedLink = true; + event.preventDefault(); event.stopPropagation(); diff --git a/src/main.ts b/src/main.ts index 43a035e..13e2e6a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -495,12 +495,8 @@ export default class PluginsAnnotations extends Plugin { const annotation_container = document.createElement('div'); annotation_container.className = 'plugin-comment'; - const annotation_div = document.createElement('div'); - annotation_div.className = 'plugin-comment-annotation'; - - new annotationControl(this,annotation_container,annotation_div,pluginId,pluginName); - - annotation_container.appendChild(annotation_div); + new annotationControl(this,annotation_container,pluginId,pluginName); + descriptionDiv.appendChild(annotation_container); } } diff --git a/src/settings_tab.ts b/src/settings_tab.ts index 3aca0a2..b837f68 100644 --- a/src/settings_tab.ts +++ b/src/settings_tab.ts @@ -105,17 +105,8 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab { div.appendChild(p1); const p2 = document.createElement('p2'); - p2.innerHTML = "You can enter rich text notes using Markdown (recommended) and HTML. \ - Markdown annotations will be displayed as Obsidian renders Markdown text. \ - The annotation type can be selected by starting the annotation text with a line containing one \ - of the following options:\ -

\ - If the first line of annotation text contains none of the options above, \ - the default markdown: is assumed."; + p2.innerHTML = "You can enter rich text annotations using Markdown. \ + Once you are finished editing, the Markdown annotation will be rendered correctly."; div.appendChild(p2); const p3 = document.createElement('p'); @@ -123,11 +114,6 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab { vault by adding links such as [[My notes/Review of plugin XYZ|my plugin note]]."; div.appendChild(p3); - const p4 = document.createElement('p'); - p4.innerHTML = "When editing HTML annotations, use the placeholder ${label} to \ - display the annotation label at the chosen location." - div.appendChild(p4); - frag.appendChild(div); }); @@ -254,34 +240,42 @@ export class PluginsAnnotationsSettingTab extends PluginSettingTab { new Setting(containerEl).setName('Display').setHeading(); + let label; + let label_version; + let label_cb; + if (Platform.isMobile) { - new Setting(containerEl) - .setName('Annotation label:') - .setDesc('Choose the annotation label for the mobile version of Obsidian. \ - Use HTML code if you want to format it. Enter an empty string if \ - you want to hide the label.') - .addText(text => { - text.setPlaceholder('Annotation label'); - text.setValue(this.plugin.settings.label_mobile); - text.onChange(async (value: string) => { + label = this.plugin.settings.label_mobile; + label_version = 'mobile'; + label_cb = (value: string) => { this.plugin.settings.label_mobile = value; this.plugin.debouncedSaveAnnotations(); - })}); + }; } else { - new Setting(containerEl) - .setName('Annotation label:') - .setDesc('Choose the annotation label for the desktop version of Obsidian. \ - Use HTML code if you want to format it. Enter an empty string if you want \ - to hide the label.') - .addText(text => { - text.setPlaceholder('Annotation label'); - text.setValue(this.plugin.settings.label_desktop); - text.onChange(async (value: string) => { + label = this.plugin.settings.label_desktop; + label_version = 'desktop'; + label_cb = (value: string) => { this.plugin.settings.label_desktop = value; this.plugin.debouncedSaveAnnotations(); - })}); + }; } + new Setting(containerEl) + .setName('Annotation label:') + .setDesc(createFragment((frag) => { + frag.appendText(`Choose the annotation label for the ${label_version} version of Obsidian. \ + Use HTML code if you want to format it. Enter an empty string if you want \ + to hide the label. Use `); + frag.createEl('em').appendText('${plugin_name}'); + frag.appendText(' to refer to the plugin name; for example, you can generate automatic links to your notes with label of the kind '); + frag.createEl('em').appendText('[[00 Meta/Installed plugins/${plugin_name} | ${plugin_name}]]'); + frag.appendText('.'); + })) + .addText(text => { + text.setPlaceholder('Annotation label'); + text.setValue(label); + text.onChange(label_cb)}); + new Setting(containerEl) .setName('Placeholder label:') .setDesc(createFragment((frag) => { diff --git a/styles/styles.css b/styles/styles.css index 93f6903..97ebfbe 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -7,6 +7,11 @@ box-sizing: border-box; /* Ensure padding is included in the element's total width and height */ } +.plugin-comment-label { + float: left; + cursor: default; +} + .plugin-comment-annotation.plugin-comment-placeholder { color: #CCCCCC; /* Standard placeholder color */ }