diff --git a/db/demo.zip b/db/demo.zip index 237d80c94..3f35a4545 100644 Binary files a/db/demo.zip and b/db/demo.zip differ diff --git a/package-lock.json b/package-lock.json index 4563e5d8b..7adb9abb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "async-mutex": "0.5.0", "autocomplete.js": "0.38.1", "axios": "1.7.7", - "better-sqlite3": "11.3.0", + "better-sqlite3": "11.6.0", "bootstrap": "5.3.3", "boxicons": "2.1.4", "chokidar": "3.6.0", @@ -5076,10 +5076,11 @@ } }, "node_modules/better-sqlite3": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.3.0.tgz", - "integrity": "sha512-iHt9j8NPYF3oKCNOO5ZI4JwThjt3Z6J6XrcwG85VNMVzv1ByqrHWv5VILEbCMFWDsoHhXvQ7oC8vgRXFAKgl9w==", + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.6.0.tgz", + "integrity": "sha512-2J6k/eVxcFYY2SsTxsXrj6XylzHWPxveCn4fKPKZFv/Vqn/Cd7lOuX4d7rGQXT5zL+97MkNL3nSbCrIoe3LkgA==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" diff --git a/package.json b/package.json index df0468fe5..d87df4f95 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "async-mutex": "0.5.0", "autocomplete.js": "0.38.1", "axios": "1.7.7", - "better-sqlite3": "11.3.0", + "better-sqlite3": "11.6.0", "bootstrap": "5.3.3", "boxicons": "2.1.4", "chokidar": "3.6.0", diff --git a/src/public/app/widgets/dialogs/export.js b/src/public/app/widgets/dialogs/export.js index 92357afa0..7854acc91 100644 --- a/src/public/app/widgets/dialogs/export.js +++ b/src/public/app/widgets/dialogs/export.js @@ -49,7 +49,7 @@ const TPL = `
diff --git a/src/public/app/widgets/note_wrapper.js b/src/public/app/widgets/note_wrapper.js index 91e9ff3cf..424cb6da7 100644 --- a/src/public/app/widgets/note_wrapper.js +++ b/src/public/app/widgets/note_wrapper.js @@ -43,7 +43,7 @@ export default class NoteWrapperWidget extends FlexContainer { } this.$widget.toggleClass("full-content-width", - ['image', 'mermaid', 'book', 'render', 'canvas', 'webView'].includes(note.type) + ['image', 'mermaid', 'book', 'render', 'canvas', 'webView', 'mindMap'].includes(note.type) || !!note?.isLabelTruthy('fullContentWidth') ); diff --git a/src/public/app/widgets/ribbon_widgets/promoted_attributes.js b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js index 7a5f68838..b4f7084a3 100644 --- a/src/public/app/widgets/ribbon_widgets/promoted_attributes.js +++ b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js @@ -146,7 +146,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget { async createPromotedAttributeCell(definitionAttr, valueAttr, valueName) { const definition = definitionAttr.getDefinition(); - const id = `value-${this.noteId}-${definitionAttr.position}`; + const id = `value-${valueAttr.attributeId}`; const $input = $("") .prop("tabindex", 200 + definitionAttr.position) diff --git a/src/public/app/widgets/type_widgets/editable_text.js b/src/public/app/widgets/type_widgets/editable_text.js index 13f21882c..2a191c3d0 100644 --- a/src/public/app/widgets/type_widgets/editable_text.js +++ b/src/public/app/widgets/type_widgets/editable_text.js @@ -54,7 +54,7 @@ const TPL = ` cursor: text !important; } - .note-detail-editable-text *:not(figure,.include-note):first-child { + .note-detail-editable-text *:not(figure, .include-note, hr):first-child { margin-top: 0 !important; } diff --git a/src/public/app/widgets/type_widgets/options/code_notes/code_mime_types.js b/src/public/app/widgets/type_widgets/options/code_notes/code_mime_types.js index 40244f69d..300dee9b7 100644 --- a/src/public/app/widgets/type_widgets/options/code_notes/code_mime_types.js +++ b/src/public/app/widgets/type_widgets/options/code_notes/code_mime_types.js @@ -62,14 +62,14 @@ export default class CodeMimeTypesOptions extends OptionsWidget { const groupedMimeTypes = groupMimeTypesAlphabetically(ungroupedMimeTypes); // Plain text is displayed at the top intentionally. - this.$mimeTypes.append(buildSelectionForMimeType(plainTextMimeType)); + this.$mimeTypes.append(buildSelectionForMimeType.call(this, plainTextMimeType)); for (const [ initial, mimeTypes ] of Object.entries(groupedMimeTypes)) { const $section = $("
"); $section.append($("
").text(initial)); for (const mimeType of mimeTypes) { - $section.append(buildSelectionForMimeType(mimeType)); + $section.append(buildSelectionForMimeType.call(this, mimeType)); } this.$mimeTypes.append($section); diff --git a/src/public/stylesheets/theme-next.css b/src/public/stylesheets/theme-next.css index ff824c870..1e225dd15 100644 --- a/src/public/stylesheets/theme-next.css +++ b/src/public/stylesheets/theme-next.css @@ -40,7 +40,7 @@ --launcher-pane-size: 58px; --launcher-pane-horizontal-size: 54px; - --launcher-pane-horizontal-icon-size: 20px; + --launcher-pane-horizontal-icon-size: 20px; --launcher-pane-button-margin: 6px; --launcher-pane-button-gap: 3px; @@ -54,7 +54,7 @@ --menu-padding-size: 8px; --menu-item-icon-vert-offset: 0; - --more-accented-background-color: var(--card-background-hover-color); + --more-accented-background-color: var(--card-background-hover-color); } /* @@ -135,6 +135,7 @@ --launcher-pane-background-color: #e8e8e8; --launcher-pane-horizontal-background-color: #fafafa; + --launcher-pane-horizontal-border-color: rgba(0, 0, 0, 0.1); --launcher-pane-text-color: #000000bd; --launcher-pane-button-hover-color: black; --launcher-pane-button-hover-background: white; @@ -169,7 +170,6 @@ --scrollbar-border-color: #ddd; --scrollbar-background-color: #ddd; - --tooltip-background-color: #f8f8f8; --link-color: blue; --mermaid-theme: default; @@ -182,6 +182,16 @@ --card-border-color: #eaeaea; --card-shadow-color: rgba(0, 0, 0, 0.1); --card-box-shadow: 0 0 12px var(--card-shadow-color); + + --calendar-color: var(--menu-text-color); + --calendar-weekday-labels-color: var(--muted-text-color); + --calendar-day-hover-color: var(--hover-item-text-color); + --calendar-day-hover-background: var(--active-item-background-color); + --calendar-day-highlight-background: #80808024; + + --tooltip-border-color: transparent; + --tooltip-background-color: rgba(0, 0, 0, 0.8); + --tooltip-foreground-color: #fff; } /* @@ -195,7 +205,8 @@ --main-background-color: #333; --main-text-color: #ccc; --main-border-color: #454545; - --dropdown-border-color: #555; + --subtle-border-color: #313131; + --dropdown-border-color: #292929; --dropdown-shadow-opacity: .6; --dropdown-item-icon-destructive-color: #de6e5b; --disabled-tooltip-icon-color: #7fd2ef; @@ -266,6 +277,8 @@ --left-pane-item-selected-action-button-hover-shadow: 2px 2px 10px rgba(0, 0, 0, .25); --launcher-pane-background-color: #1a1a1a; + --launcher-pane-horizontal-background-color: #282828; + --launcher-pane-horizontal-border-color: rgb(22, 22, 22); --launcher-pane-text-color: #909090; --launcher-pane-button-hover-color: #ffffff; --launcher-pane-button-hover-background: #ffffff1c; @@ -294,7 +307,6 @@ --scrollbar-border-color: #666; --scrollbar-background-color: #333; - --tooltip-background-color: #333; --link-color: lightskyblue; --mermaid-theme: dark; @@ -306,6 +318,15 @@ --card-background-press-color: #464646; --card-border-color: #222222; --card-box-shadow: 0 0 12px rgba(0, 0, 0, 0.15); + + --calendar-color: var(--menu-text-color); + --calendar-weekday-labels-color: var(--muted-text-color); + --calendar-day-hover-color: var(--hover-item-text-color); + --calendar-day-hover-background: var(--active-item-background-color); + --calendar-day-highlight-background: #8080805a; + + --tooltip-background: rgba(0, 0, 0, 0.9); + --tooltip-foreground: #fff; } body ::-webkit-calendar-picker-indicator { @@ -378,7 +399,7 @@ #launcher-pane.horizontal { height: var(--launcher-pane-size) !important; - border-bottom: 1px solid var(--subtle-border-color); + border-bottom: 1px solid var(--launcher-pane-horizontal-border-color); } #launcher-pane .launcher-button, @@ -425,13 +446,24 @@ --hover-item-background-color: transparent; } -/* - * Left pane - */ +.tooltip .tooltip-arrow { + display: none; +} - /* Search Box */ +.tooltip-inner { + padding: 5px 10px !important; + border-radius: 8px; + border: 1px solid var(--tooltip-border-color) !important; + color: var(--tooltip-foreground-color) !important; + line-height: 1.25; + box-shadow: none !important; +} -#left-pane .quick-search { + /* + * Search Box + */ + +div.quick-search { --padding-top: 8px; --padding-left: 8px; --padding-right: 8px; @@ -445,7 +477,7 @@ padding: var(--padding-top) var(--padding-right) var(--padding-bottom) var(--padding-left); } -#left-pane .quick-search::before { +div.quick-search::before { /* The background rectangle of the search box */ position: absolute; content: ""; @@ -460,34 +492,34 @@ transition: background-color 200ms ease-in; } -#left-pane .quick-search:hover:before { +div.quick-search:hover:before { /* Hovered search box background rectangle */ background: var(--quick-search-hover-background); transition: background-color 75ms ease-out; } -#left-pane .quick-search:focus-within:before { +div.quick-search:focus-within:before { /* Focused search box background rectangle */ border-color: var(--quick-search-focus-border); background: var(--quick-search-focus-background); transition: background-color 100ms ease-out; } -#left-pane .quick-search input { - padding-left: 15px; - box-shadow: unset; - background: transparent; +div.quick-search input { + padding-left: 15px !important; + box-shadow: unset !important; + background: transparent !important; } -#left-pane .quick-search input::placeholder { +div.quick-search input::placeholder { color: var(--quick-search-color); } -#left-pane .quick-search:focus-within input { +div.quick-search:focus-within input { color: var(--quick-search-focus-color) !important; } -#left-pane .quick-search .search-button { +div.quick-search .search-button { display: flex; align-items: center; justify-content: center; @@ -500,27 +532,30 @@ transition: background-color 200ms ease-in !important; } -#left-pane .quick-search .search-button:active { +div.quick-search .search-button:active { transform: scale(.85); } -#left-pane .quick-search:focus-within:has(input:not(:placeholder-shown)) .search-button { +div.quick-search:focus-within:has(input:not(:placeholder-shown)) .search-button { /* Matches when the input has a value and the focus is inside the search box */ background: var(--left-pane-item-action-button-background) !important; color: var(--left-pane-item-action-button-color) !important; transition: background-color 500ms ease-out !important; } -html body #left-pane .quick-search:focus-within .search-button:hover, -#left-pane .quick-search .search-button.show { +html body .quick-search:focus-within .search-button:hover, +div.quick-search .search-button.show { /* Hover state */ background: var(--left-pane-item-action-button-hover-background) !important; color: var(--left-pane-item-action-button-color) !important; transition: background-color 100ms ease-out !important; } -/* Tree */ +/* + * Left pane + */ +/* Tree */ #left-pane .tree-actions { /* TODO: relocate instead of hiding */ @@ -539,14 +574,12 @@ html body #left-pane .quick-search:focus-within .search-button:hover, } #left-pane .ui-fancytree ul { - padding-left: 1px; - margin-left: 14px; - border-left: 1px solid var(--subtle-border-color); + padding-left: 10px; } /* The root element of the tree */ #left-pane .fancytree-container > li:first-child > span { - padding-left: 6px; + padding-left: 12px; } #left-pane span.fancytree-node.fancytree-active { @@ -694,7 +727,7 @@ html body #left-pane .quick-search:focus-within .search-button:hover, left: 0; right: 0; height: 1px; - background: var(--subtle-border-color); + border-bottom: 1px solid var(--launcher-pane-horizontal-border-color); } .tab-row-widget-container { @@ -712,6 +745,17 @@ html body #left-pane .quick-search:focus-within .search-button:hover, overflow: hidden; } +#root-widget.horizontal-layout .tab-row-widget .note-tab[active] .note-tab-wrapper { + border: 1px solid transparent; + border-bottom: 0; +} + +#root-widget.horizontal-layout .tab-row-widget .note-tab[active] .note-tab-wrapper { + box-shadow: unset; + border: 1px solid var(--launcher-pane-horizontal-border-color); + border-bottom: 0; +} + .tab-row-widget .note-tab .note-tab-wrapper { height: var(--tab-height) !important; transition: background 75ms ease-in, @@ -834,11 +878,14 @@ html body #left-pane .quick-search:focus-within .search-button:hover, */ #center-pane { - border-radius: var(--center-pane-border-radius) 0 0 0; padding-top: 2px; background: var(--main-background-color); } +.vertical-layout #center-pane { + border-radius: var(--center-pane-border-radius) 0 0 0; +} + /* * Ribbon & note header */ @@ -963,6 +1010,78 @@ html body .dropdown-item.disabled { color: var(--menu-item-arrow-color) !important; } +/* + * Calendar + */ + +.calendar-dropdown-widget { + padding: 12px; + color: var(--calendar-color); +} + +.calendar-dropdown-widget .calendar-header { + padding: 8px 0 20px 0; +} + +.calendar-dropdown-widget .calendar-header input[type="number"] { + appearance: textfield !important; +} + +.calendar-dropdown-widget .calendar-header input[type="number"]::-webkit-outer-spin-button, +.calendar-dropdown-widget .calendar-header input[type="number"]::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +.calendar-dropdown-widget .calendar-header input, +.calendar-dropdown-widget .calendar-header select { + /* TODO: Provide styling for background and states */ + border: unset; + text-align: center; + font-size: 1.4em; + font-weight: 300; +} + +.calendar-dropdown-widget .calendar-week span { + font-size: .85em; + font-weight: 500; + color: var(--calendar-weekday-labels-color); +} + +.calendar-dropdown-widget .calendar-body { + font-size: .9em; +} + +.calendar-dropdown-widget .calendar-body a { + background: transparent; + color: var(--calendar-color); +} + +.calendar-dropdown-widget .calendar-body a.calendar-date-exists { + position: relative; + text-decoration: none !important; +} + +.calendar-dropdown-widget .calendar-body a.calendar-date-exists:not(:hover)::before { + --vertical-margin: 13%; + --horiz-margin: 18%; + content: ""; + position: absolute; + top: var(--vertical-margin); + right: var(--horiz-margin); + bottom: var(--vertical-margin); + left: var(--horiz-margin); + border-radius: 6px; + background: var(--calendar-day-highlight-background); + z-index: -1; +} + +body .calendar-dropdown-widget .calendar-body a:hover { + border-radius: 6px; + background: var(--calendar-day-hover-background); + color: var(--calendar-day-hover-color) !important; +} + /* * TEXT NOTES */ @@ -980,7 +1099,7 @@ html body .dropdown-item.disabled { overflow: unset; } -html .note-detail-editable-text :not(figure, .include-note):first-child { +html .note-detail-editable-text :not(figure, .include-note, hr):first-child { /* Create some space for the top-side shadow */ margin-top: 1px !important; } @@ -1013,6 +1132,52 @@ html .note-detail-editable-text :not(figure, .include-note):first-child { cursor: default; } +.ck-content blockquote { + background: var(--card-background-color); + border: 1px solid var(--card-border-color) !important; + box-shadow: var(--card-box-shadow); + border-radius: 10px; + padding: 1em 2.5em; + position: relative; + font-style: unset !important; +} + +.ck-content blockquote p:last-of-type { + margin-bottom: 0 !important; +} + +.ck-content blockquote:before, +.ck-content blockquote:after { + position: absolute; + top: 0; + font-size: 48px; + opacity: 0.1; +} + +.ck-content blockquote:before { + content: "“"; + left: 0.2em; +} + +.ck-content blockquote:after { + content: "”"; + right: 0.35em; +} + +.ck-content hr { + margin: 5px 0; + height: 1px; + background-color: var(--main-border-color); + opacity: 1; +} + +.ck-content p code { + border: 1px solid var(--card-border-color); + box-shadow: var(--card-box-shadow); + border-radius: 6px; + background-color: var(--card-background-color); +} + .note-detail-printable:not(.word-wrap) pre code { white-space: pre; margin-right: 1em; @@ -1086,12 +1251,14 @@ html .note-detail-editable-text :not(figure, .include-note):first-child { * Note list */ .note-list .note-book-card { + --note-list-horizontal-padding: 22px; + --note-list-vertical-padding: 15px; background-color: var(--card-background-color); border: 1px solid var(--card-border-color) !important; box-shadow: 2px 3px 4px var(--card-shadow-color); border-radius: 12px; user-select: none; - padding: 15px 22px; + padding: 0; margin: 5px 10px 5px 0; } @@ -1112,9 +1279,10 @@ html .note-detail-editable-text :not(figure, .include-note):first-child { } .note-list-wrapper .note-book-card .note-book-header { - font-size: 1.1em; + font-size: 1em; font-weight: bold; - margin-bottom: 0.25em; + padding: 0.5em 1rem; + border-bottom-color: var(--card-border-color); } .note-list-wrapper .note-book-card .note-book-header .note-icon { @@ -1128,28 +1296,76 @@ html .note-detail-editable-text :not(figure, .include-note):first-child { vertical-align: middle; } -.note-list-wrapper .note-book-card .note-book-header:last-child { - border-bottom: 0; +.note-list-wrapper .note-book-card .note-book-header .rendered-note-attributes { + font-size: 0.7em; + font-weight: normal; margin-bottom: 0; - padding-bottom: 0; } -.note-list-wrapper .note-book-card .note-book-header .note-book-content { +.note-list-wrapper .note-book-card .note-book-header:last-child { + border-bottom: 0; +} + +.note-list-wrapper .note-book-card .note-book-content { padding: 0 !important; font-size: 0.8rem; } -.note-list-wrapper .note-book-card .note-book-header .note-book-content h1, -.note-list-wrapper .note-book-card .note-book-header .note-book-content h2, -.note-list-wrapper .note-book-card .note-book-header .note-book-content h3, -.note-list-wrapper .note-book-card .note-book-header .note-book-content h4, -.note-list-wrapper .note-book-card .note-book-header .note-book-content h5, -.note-list-wrapper .note-book-card .note-book-header .note-book-content h6 { +.note-list-wrapper .note-book-card .note-book-content .rendered-content { + padding: 1rem; +} + +.note-list-wrapper .note-book-card .note-book-content .rendered-content.text-with-ellipsis { + padding: 1rem !important; +} + +.note-list-wrapper .note-book-card .note-book-content h1, +.note-list-wrapper .note-book-card .note-book-content h2, +.note-list-wrapper .note-book-card .note-book-content h3, +.note-list-wrapper .note-book-card .note-book-content h4, +.note-list-wrapper .note-book-card .note-book-content h5, +.note-list-wrapper .note-book-card .note-book-content h6 { font-size: 1rem; color: var(--active-item-text-color); } -.note-list-wrapper .note-book-card .bx { - color: var(--left-pane-icon-color); - font-weight: bold; +.note-list-wrapper .note-book-card .note-book-content p:last-child { + margin-bottom: 0; } + +.note-list-wrapper .note-book-card .note-book-content.type-canvas .rendered-content, +.note-list-wrapper .note-book-card .note-book-content.type-mindMap .rendered-content, +.note-list-wrapper .note-book-card .note-book-content.type-code .rendered-content { + padding: 0; +} + +.note-list-wrapper .note-book-card .note-book-content.type-code pre { + height: 100%; + padding: 1em; +} + +.note-list-wrapper .note-book-card .bx { + color: var(--left-pane-icon-color) !important; +} + +.note-list.grid-view .note-book-card:hover { + background: var(--card-background-color) !important; + filter: contrast(105%); +} + +.note-list.grid-view .note-book-card img { + object-fit: cover !important; + width: 100%; +} + +.note-list.grid-view .ck-content { + line-height: 1.3; +} + +.note-list.grid-view .ck-content p { + margin-bottom: 0.5em; +} + +.note-list.grid-view .ck-content figure.image { + width: 25%; +} \ No newline at end of file diff --git a/src/public/stylesheets/tree.css b/src/public/stylesheets/tree.css index 0d748d6a0..f6139a99e 100644 --- a/src/public/stylesheets/tree.css +++ b/src/public/stylesheets/tree.css @@ -138,7 +138,7 @@ span.fancytree-node.protected > span.fancytree-custom-icon { span.fancytree-node.multiple-parents.shared .fancytree-title::after { font-family: 'boxicons' !important; font-size: smaller; - content: " \eb3d \ec03"; + content: " \eb3d \ec03"; } span.fancytree-node.multiple-parents .fancytree-title::after { diff --git a/src/public/translations/cn/translation.json b/src/public/translations/cn/translation.json index de5f96277..785eb9679 100644 --- a/src/public/translations/cn/translation.json +++ b/src/public/translations/cn/translation.json @@ -93,7 +93,7 @@ "export_note_title": "导出笔记", "close": "关闭", "export_type_subtree": "此笔记及其所有子笔记", - "format_html": "HTML ZIP 归档 - 建议使用此选项,因为它保留了所有格式。", + "format_html_zip": "HTML ZIP 归档 - 建议使用此选项,因为它保留了所有格式。", "format_markdown": "Markdown - 保留大部分格式。", "format_opml": "OPML - 大纲交换格式,仅限文本。不包括格式、图像和文件。", "opml_version_1": "OPML v1.0 - 仅限纯文本", diff --git a/src/public/translations/de/translation.json b/src/public/translations/de/translation.json index 55df50b2d..6563dde95 100644 --- a/src/public/translations/de/translation.json +++ b/src/public/translations/de/translation.json @@ -88,7 +88,7 @@ "export_note_title": "Notiz exportieren", "close": "Schließen", "export_type_subtree": "diese Notiz und alle ihre Unternotizen", - "format_html": "HTML im ZIP-Archiv – dies wird empfohlen, da dadurch die gesamte Formatierung erhalten bleibt.", + "format_html_zip": "HTML im ZIP-Archiv – dies wird empfohlen, da dadurch die gesamte Formatierung erhalten bleibt.", "format_markdown": "Markdown – dadurch bleiben die meisten Formatierungen erhalten.", "format_opml": "OPML – Outliner-Austauschformat nur für Text. Formatierungen, Bilder und Dateien sind nicht enthalten.", "opml_version_1": "OPML v1.0 – nur Klartext", diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json index d53061027..43c975c2e 100644 --- a/src/public/translations/en/translation.json +++ b/src/public/translations/en/translation.json @@ -93,7 +93,8 @@ "export_note_title": "Export note", "close": "Close", "export_type_subtree": "this note and all of its descendants", - "format_html": "HTML in ZIP archive - this is recommended since this preserves all the formatting.", + "format_html": "HTML - recomandat deoarece păstrează toată formatarea", + "format_html_zip": "HTML in ZIP archive - this is recommended since this preserves all the formatting.", "format_markdown": "Markdown - this preserves most of the formatting.", "format_opml": "OPML - outliner interchange format for text only. Formatting, images and files are not included.", "opml_version_1": "OPML v1.0 - plain text only", diff --git a/src/public/translations/es/translation.json b/src/public/translations/es/translation.json index 00a0be60a..cd6dec361 100644 --- a/src/public/translations/es/translation.json +++ b/src/public/translations/es/translation.json @@ -93,7 +93,7 @@ "export_note_title": "Exportar nota", "close": "Cerrar", "export_type_subtree": "esta nota y todos sus descendientes", - "format_html": "HTML en un archivo ZIP: se recomienda ya que conserva todo el formato.", + "format_html_zip": "HTML en un archivo ZIP: se recomienda ya que conserva todo el formato.", "format_markdown": "Markdown: esto conserva la mayor parte del formato.", "format_opml": "OPML: formato de intercambio de esquemas solo para texto. El formato, las imágenes y los archivos no están incluidos.", "opml_version_1": "OPML v1.0: solo texto sin formato", diff --git a/src/public/translations/fr/translation.json b/src/public/translations/fr/translation.json index 276c6147b..2a85f610e 100644 --- a/src/public/translations/fr/translation.json +++ b/src/public/translations/fr/translation.json @@ -89,7 +89,7 @@ "export_note_title": "Exporter la note", "close": "Fermer", "export_type_subtree": "cette note et tous ses descendants", - "format_html": "HTML dans l'archive ZIP - recommandé car cela préserve tout le formatage.", + "format_html_zip": "HTML dans l'archive ZIP - recommandé car cela préserve tout le formatage.", "format_markdown": "Markdown - préserve la majeure partie du formatage.", "format_opml": "OPML - format d'échange pour les outlineurs, uniquement pour le texte. Les mises en forme, images et fichiers ne sont pas inclus.", "opml_version_1": "OPML v1.0 - texte brut uniquement", diff --git a/src/public/translations/ro/translation.json b/src/public/translations/ro/translation.json index 9a10bf154..9e2f198da 100644 --- a/src/public/translations/ro/translation.json +++ b/src/public/translations/ro/translation.json @@ -509,7 +509,7 @@ "export_status": "Starea exportului", "export_type_single": "doar această notiță fără descendenții ei", "export_type_subtree": "această notiță și toți descendenții ei", - "format_html": "HTML în arhivă ZIP - recomandat deoarece păstrează toată formatarea", + "format_html_zip": "HTML în arhivă ZIP - recomandat deoarece păstrează toată formatarea", "format_markdown": "Markdown - păstrează majoritatea formatării", "format_opml": "OPML - format de interschimbare pentru editoare cu structură ierarhică (outline). Formatarea, imaginile și fișierele nu vor fi incluse.", "opml_version_1": "OPML v1.0 - text simplu", diff --git a/src/public/translations/tw/translation.json b/src/public/translations/tw/translation.json index 39c382f65..20409e686 100644 --- a/src/public/translations/tw/translation.json +++ b/src/public/translations/tw/translation.json @@ -93,7 +93,7 @@ "export_note_title": "匯出筆記", "close": "關閉", "export_type_subtree": "此筆記及其所有子筆記", - "format_html": "HTML ZIP 歸檔 - 建議使用此選項,因為它保留了所有格式。", + "format_html_zip": "HTML ZIP 歸檔 - 建議使用此選項,因為它保留了所有格式。", "format_markdown": "Markdown - 保留大部分格式。", "format_opml": "OPML - 大綱交換格式,僅限文字。不包括格式、圖片和文件。", "opml_version_1": "OPML v1.0 - 僅限純文字", diff --git a/src/services/hidden_subtree.ts b/src/services/hidden_subtree.ts index 584803a2f..3f0c01bdb 100644 --- a/src/services/hidden_subtree.ts +++ b/src/services/hidden_subtree.ts @@ -54,7 +54,7 @@ enum Command { * duplicate subtrees. This way, all instances will generate the same structure with the same IDs. */ -let HIDDEN_SUBTREE_DEFINITION = buildHiddenSubtreeDefinition(); +let hiddenSubtreeDefinition: Item; function buildHiddenSubtreeDefinition(): Item { return { @@ -288,11 +288,11 @@ function checkHiddenSubtree(force = false, extraOpts: CheckHiddenExtraOpts = {}) return; } - if (force) { - HIDDEN_SUBTREE_DEFINITION = buildHiddenSubtreeDefinition(); + if (!hiddenSubtreeDefinition || force) { + hiddenSubtreeDefinition = buildHiddenSubtreeDefinition(); } - checkHiddenSubtreeRecursively('root', HIDDEN_SUBTREE_DEFINITION, extraOpts); + checkHiddenSubtreeRecursively('root', hiddenSubtreeDefinition, extraOpts); } function checkHiddenSubtreeRecursively(parentNoteId: string, item: Item, extraOpts: CheckHiddenExtraOpts = {}) { diff --git a/src/services/html_sanitizer.ts b/src/services/html_sanitizer.ts index f6f889049..d3d48eea1 100644 --- a/src/services/html_sanitizer.ts +++ b/src/services/html_sanitizer.ts @@ -52,7 +52,8 @@ function sanitize(dirtyHtml: string) { return sanitizeHtml(dirtyHtml, { allowedTags, allowedAttributes: { - '*': [ 'class', 'style', 'title', 'src', 'href', 'hash', 'disabled', 'align', 'alt', 'center', 'data-*' ] + "*": [ 'class', 'style', 'title', 'src', 'href', 'hash', 'disabled', 'align', 'alt', 'center', 'data-*' ], + "input": [ "type", "checked" ] }, allowedSchemes: [ 'http', 'https', 'ftp', 'ftps', 'mailto', 'data', 'evernote', 'file', 'facetime', 'irc', 'gemini', 'git',