Finished correcting bugs on editing annotations

This commit is contained in:
Andrea Alberti 2024-08-18 04:30:13 +02:00
parent 38c8665f77
commit 8d460d8ecf
4 changed files with 100 additions and 72 deletions

View file

@ -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 <p> element)
const firstChild = tmp_div.firstElementChild;
if (firstChild && firstChild.tagName === 'P') {
// Move the content of the <p> element to label_div
label_div.innerHTML = firstChild.innerHTML;
// Optionally, you can remove the <p> 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();

View file

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

View file

@ -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:\
<ul>\
<li>markdown:</li>\
<li>html:</li>\
<li>text:</li>\
</ul>\
If the first line of annotation text contains none of the options above, \
the default <em>markdown:</em> 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 <em>${label}</em> to \
display the <em>annotation label</em> 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) => {

View file

@ -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 */
}