diff --git a/src/public/app/widgets/type_widgets/content_widget.js b/src/public/app/widgets/type_widgets/content_widget.js index 7f4a4e3ee..f749d5cbd 100644 --- a/src/public/app/widgets/type_widgets/content_widget.js +++ b/src/public/app/widgets/type_widgets/content_widget.js @@ -25,6 +25,7 @@ import NoteErasureTimeoutOptions from "./options/other/note_erasure_timeout.js"; import RevisionsSnapshotIntervalOptions from "./options/other/revisions_snapshot_interval.js"; import RevisionSnapshotsLimitOptions from "./options/other/revision_snapshots_limit.js"; import NetworkConnectionsOptions from "./options/other/network_connections.js"; +import HtmlImportTagsOptions from "./options/other/html_import_tags.js"; import AdvancedSyncOptions from "./options/advanced/sync.js"; import DatabaseIntegrityCheckOptions from "./options/advanced/database_integrity_check.js"; import ConsistencyChecksOptions from "./options/advanced/consistency_checks.js"; @@ -94,7 +95,8 @@ const CONTENT_WIDGETS = { AttachmentErasureTimeoutOptions, RevisionsSnapshotIntervalOptions, RevisionSnapshotsLimitOptions, - NetworkConnectionsOptions + NetworkConnectionsOptions, + HtmlImportTagsOptions ], _optionsAdvanced: [ DatabaseIntegrityCheckOptions, diff --git a/src/public/app/widgets/type_widgets/options/other/html_import_tags.js b/src/public/app/widgets/type_widgets/options/other/html_import_tags.js index 0cc719c56..66c1cbb88 100644 --- a/src/public/app/widgets/type_widgets/options/other/html_import_tags.js +++ b/src/public/app/widgets/type_widgets/options/other/html_import_tags.js @@ -3,26 +3,39 @@ import { t } from "../../../../services/i18n.js"; const TPL = `
-

${t("options.html_import_tags.title")}

+

${t("import.html_import_tags.title")}

-

${t("options.html_import_tags.description")}

+

${t("import.html_import_tags.description")}

+ placeholder="${t("import.html_import_tags.placeholder")}">
- ${t("options.html_import_tags.help")} + ${t("import.html_import_tags.help")}
`; +const defaultTags = [ + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', + 'li', 'b', 'i', 'strong', 'em', 'strike', 's', 'del', 'abbr', 'code', 'hr', 'br', 'div', + 'table', 'thead', 'caption', 'tbody', 'tfoot', 'tr', 'th', 'td', 'pre', 'section', 'img', + 'figure', 'figcaption', 'span', 'label', 'input', 'details', 'summary', 'address', 'aside', 'footer', + 'header', 'hgroup', 'main', 'nav', 'dl', 'dt', 'menu', 'bdi', 'bdo', 'dfn', 'kbd', 'mark', 'q', 'time', + 'var', 'wbr', 'area', 'map', 'track', 'video', 'audio', 'picture', 'del', 'ins', + 'en-media', + 'acronym', 'article', 'big', 'button', 'cite', 'col', 'colgroup', 'data', 'dd', + 'fieldset', 'form', 'legend', 'meter', 'noscript', 'option', 'progress', 'rp', + 'samp', 'small', 'sub', 'sup', 'template', 'textarea', 'tt' +]; + export default class HtmlImportTagsOptions extends OptionsWidget { doRender() { this.$widget = $(TPL); @@ -31,46 +44,41 @@ export default class HtmlImportTagsOptions extends OptionsWidget { this.$allowedTags = this.$widget.find('.allowed-html-tags'); this.$resetButton = this.$widget.find('.reset-to-default'); - this.loadTags(); - this.$allowedTags.on('change', () => this.saveTags()); this.$resetButton.on('click', () => this.resetToDefault()); + + // Load initial tags + this.refresh(); } - loadTags() { + async optionsLoaded(options) { try { - const tags = JSON.parse(this.getOption('allowedHtmlTags')); - this.$allowedTags.val(tags.join('\\n')); + if (options.allowedHtmlTags) { + const tags = JSON.parse(options.allowedHtmlTags); + this.$allowedTags.val(tags.join('\\n')); + } else { + // If no tags are set, show the defaults + this.$allowedTags.val(defaultTags.join('\\n')); + } } catch (e) { console.error('Could not load HTML tags:', e); + // On error, show the defaults + this.$allowedTags.val(defaultTags.join('\\n')); } } async saveTags() { const tagsText = this.$allowedTags.val(); - const tags = tagsText.split('\\n') + const tags = tagsText.split(/[,\\s]+/) // Split on commas, spaces, or newlines .map(tag => tag.trim()) .filter(tag => tag.length > 0); await this.updateOption('allowedHtmlTags', JSON.stringify(tags)); } - resetToDefault() { - const defaultTags = [ - 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', - 'li', 'b', 'i', 'strong', 'em', 'strike', 's', 'del', 'abbr', 'code', 'hr', 'br', 'div', - 'table', 'thead', 'caption', 'tbody', 'tfoot', 'tr', 'th', 'td', 'pre', 'section', 'img', - 'figure', 'figcaption', 'span', 'label', 'input', 'details', 'summary', 'address', 'aside', 'footer', - 'header', 'hgroup', 'main', 'nav', 'dl', 'dt', 'menu', 'bdi', 'bdo', 'dfn', 'kbd', 'mark', 'q', 'time', - 'var', 'wbr', 'area', 'map', 'track', 'video', 'audio', 'picture', 'del', 'ins', - 'en-media', - 'acronym', 'article', 'big', 'button', 'cite', 'col', 'colgroup', 'data', 'dd', - 'fieldset', 'form', 'legend', 'meter', 'noscript', 'option', 'progress', 'rp', - 'samp', 'small', 'sub', 'sup', 'template', 'textarea', 'tt' - ]; - - this.$allowedTags.val(defaultTags.join('\\n')); - this.saveTags(); + async resetToDefault() { + this.$allowedTags.val(defaultTags.join('\\n')); // Use actual newlines + await this.saveTags(); } } diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index 15f215f08..7d53998ec 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -174,10 +174,10 @@ "failed": "Import failed: {{message}}.", "html_import_tags": { "title": "HTML Import Tags", - "description": "Configure which HTML tags are preserved when importing notes.", + "description": "Configure which HTML tags should be preserved when importing notes. Tags not in this list will be removed during import.", "placeholder": "Enter HTML tags, one per line", "help": "Enter HTML tags to preserve during import. Some tags (like 'script') are always removed for security.", - "reset_button": "Reset to Default" + "reset_button": "Reset to Default List" } }, "include_note": { diff --git a/src/services/options_init.ts b/src/services/options_init.ts index f83608213..4ba325c4a 100644 --- a/src/services/options_init.ts +++ b/src/services/options_init.ts @@ -136,7 +136,7 @@ const defaultOptions: DefaultOption[] = [ // Text note configuration { name: "textNoteEditorType", value: "ckeditor-balloon", isSynced: true }, - // HTML sanitization configuration + // HTML import configuration { name: "allowedHtmlTags", value: JSON.stringify([ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', 'li', 'b', 'i', 'strong', 'em', 'strike', 's', 'del', 'abbr', 'code', 'hr', 'br', 'div', @@ -148,7 +148,7 @@ const defaultOptions: DefaultOption[] = [ 'acronym', 'article', 'big', 'button', 'cite', 'col', 'colgroup', 'data', 'dd', 'fieldset', 'form', 'legend', 'meter', 'noscript', 'option', 'progress', 'rp', 'samp', 'small', 'sub', 'sup', 'template', 'textarea', 'tt' - ]), isSynced: true } + ]), isSynced: true }, ]; /**