From 86861f6ec36b6015c20dd0b4529b627fc8f92667 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Wed, 31 May 2023 18:32:33 +0800 Subject: [PATCH 01/10] Show highlighted text in the left pane --- src/public/app/layouts/desktop_layout.js | 2 + src/public/app/widgets/highlighted_text.js | 267 ++++++++++++++++++ .../widgets/type_widgets/content_widget.js | 2 + .../options/text_notes/highlighted_text.js | 90 ++++++ src/routes/api/options.js | 2 + src/services/options_init.js | 2 + 6 files changed, 365 insertions(+) create mode 100644 src/public/app/widgets/highlighted_text.js create mode 100644 src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 17dcc99a7..3a9ec2930 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -44,6 +44,7 @@ import BacklinksWidget from "../widgets/floating_buttons/zpetne_odkazy.js"; import SharedInfoWidget from "../widgets/shared_info.js"; import FindWidget from "../widgets/find.js"; import TocWidget from "../widgets/toc.js"; +import HltWidget from "../widgets/highlighted_text.js"; import BulkActionsDialog from "../widgets/dialogs/bulk_actions.js"; import AboutDialog from "../widgets/dialogs/about.js"; import HelpDialog from "../widgets/dialogs/help.js"; @@ -181,6 +182,7 @@ export default class DesktopLayout { ) .child(new RightPaneContainer() .child(new TocWidget()) + .child(new HltWidget()) .child(...this.customWidgets.get('right-pane')) ) ) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js new file mode 100644 index 000000000..3dbfc9b5c --- /dev/null +++ b/src/public/app/widgets/highlighted_text.js @@ -0,0 +1,267 @@ +/** + * Widget: Show highlighted text in the right pane + * + * By design there's no support for nonsensical or malformed constructs: + * - For example, if there is a formula in the middle of the highlighted text, the two ends of the formula will be regarded as two entries + */ + +import attributeService from "../services/attributes.js"; +import RightPanelWidget from "./right_panel_widget.js"; +import options from "../services/options.js"; +import OnClickButtonWidget from "./buttons/onclick_button.js"; + +const TPL = `
+ + + +
`; + +export default class HltWidget extends RightPanelWidget { + constructor() { + super(); + + this.closeHltButton = new CloseHltButton(); + this.child(this.closeHltButton); + } + + get widgetTitle() { + return "Highlighted Text"; + } + + isEnabled() { + return super.isEnabled() + && this.note.type === 'text' + && !this.noteContext.viewScope.hltTemporarilyHidden + && this.noteContext.viewScope.viewMode === 'default'; + } + + async doRenderBody() { + this.$body.empty().append($(TPL)); + this.$hlt = this.$body.find('.hlt'); + this.$body.find('.hlt-widget').append(this.closeHltButton.render()); + } + + async refreshWithNote(note) { + const hltLabel = note.getLabel('hlt'); + + if (hltLabel?.value === 'hide') { + this.toggleInt(false); + this.triggerCommand("reEvaluateRightPaneVisibility"); + return; + } + + let $hlt = "", hltColors = [], hltBgColors = []; + + let optionsHltColors = JSON.parse(options.get('highlightedTextColors')); + let optionsHltBgColors = JSON.parse(options.get('highlightedTextBgColors')); + // Check for type text unconditionally in case alwaysShowWidget is set + if (this.note.type === 'text') { + const { content } = await note.getNoteComplement(); + //hltColors/hltBgColors are the colors/background-color that appear in notes and in options + ({ $hlt, hltColors, hltBgColors } = await this.getHlt(content, optionsHltColors, optionsHltBgColors)); + } + this.$hlt.html($hlt); + this.toggleInt( + ["", "show"].includes(hltLabel?.value) + || hltColors!="" + || hltBgColors!="" + ); + + this.triggerCommand("reEvaluateRightPaneVisibility"); + } + //Converts color values in RGB, RGBA, or HSL format to hexadecimal format, removing transparency + colorToHex(color) { + function rgbToHex(rgb) { + // Converts color values in RGB or RGBA format to hexadecimal format + var rgba = rgb.match(/\d+/g); + var r = parseInt(rgba[0]); + var g = parseInt(rgba[1]); + var b = parseInt(rgba[2]); + var hex = "#"; + hex += (r < 16 ? "0" : "") + r.toString(16); + hex += (g < 16 ? "0" : "") + g.toString(16); + hex += (b < 16 ? "0" : "") + b.toString(16); + return hex; + } + + function hslToHex(hsl) { + // Convert color values in HSL format to RGB format and then to hexadecimal format + var hslValues = hsl.match(/\d+(\.\d+)?/g); + var h = parseFloat(hslValues[0]) / 360; + var s = parseFloat(hslValues[1]) / 100; + var l = parseFloat(hslValues[2]) / 100; + var r, g, b; + + if (s === 0) { + r = g = b = l; // achromatic + } else { + function hueToRgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hueToRgb(p, q, h + 1 / 3); + g = hueToRgb(p, q, h); + b = hueToRgb(p, q, h - 1 / 3); + } + + var hex = "#"; + hex += (Math.round(r * 255) < 16 ? "0" : "") + Math.round(r * 255).toString(16); + hex += (Math.round(g * 255) < 16 ? "0" : "") + Math.round(g * 255).toString(16); + hex += (Math.round(b * 255) < 16 ? "0" : "") + Math.round(b * 255).toString(16); + return hex; + } + if (color.indexOf("rgb") !== -1) { + return rgbToHex(color); + } else if (color.indexOf("hsl") !== -1) { + return hslToHex(color); + } else { + return ""; + } + } + // Determine whether the highlighted color is in the options, avoid errors caused by errors in color conversion, + // and the error of each value is acceptable within 2 + hexIsInOptionHexs(targetColor, optionColors){ + for (let i = 0; i < optionColors.length; i++) { + if (Math.abs(parseInt(optionColors[i].slice(1, 3), 16) - parseInt(targetColor.slice(1, 3), 16)) > 2) { continue; } + if (Math.abs(parseInt(optionColors[i].slice(3, 5), 16) - parseInt(targetColor.slice(3, 5), 16)) > 2) { continue; } + if (Math.abs(parseInt(optionColors[i].slice(5, 7), 16) - parseInt(targetColor.slice(5, 7), 16)) > 2) { continue; } + return true; + } + return false; + } + /** + * Builds a jquery table of helight text. + */ + getHlt(html, optionsHltColors, optionsHltBgColors) { + const hltBCs = $(html).find(`span[style*="background-color"],span[style*="color"]`) + const $hlt = $("
    "); + let hltColors = []; + let hltBgColors = []; + for (let hltIndex = 0; hltIndex'); + + if (color != "") { + var hexColor = this.colorToHex(color); + if (this.hexIsInOptionHexs(hexColor,optionsHltColors)) { + $li.html(hltText) + hltColors.push(hexColor); + liDisplay=true; + } + } + if (bgColor != "") { + var hexBgColor = this.colorToHex(bgColor); + if (this.hexIsInOptionHexs(hexBgColor,optionsHltBgColors)) { + //When you need to add a background color, in order to make the display more comfortable, change the background color to transparent + $li.html(hltText.css("background-color", hexBgColor+"80")) + hltBgColors.push(hexBgColor); + liDisplay=true; + } + } + if(!liDisplay){ + $li.css("display","none"); + } + //The font color and background color may be nested or adjacent to each other. At this time, connect the front and back li to avoid interruption + if(hltIndex!=0 && hltBCs[hltIndex-1].nextSibling ===hltBCs[hltIndex] && $hlt.children().last().css("display")!="none"){ + $hlt.children().last().append($li.html()); + }else{ + $li.on("click", () => this.jumpToHlt(hltIndex)); + $hlt.append($li); + } + + }; + return { + $hlt, + hltColors, + hltBgColors + }; + } + + async jumpToHlt(hltIndex) { + const isReadOnly = await this.noteContext.isReadOnly(); + if (isReadOnly) { + const $container = await this.noteContext.getContentElement(); + const hltElement = $container.find(`span[style*="background-color"],span[style*="color"]`)[hltIndex]; + + if (hltElement != null) { + hltElement.scrollIntoView({ behavior: "smooth", block: "center" }); + } + } else { + const textEditor = await this.noteContext.getTextEditor(); + $(textEditor.editing.view.domRoots.values().next().value).find(`span[style*="background-color"],span[style*="color"]`)[hltIndex].scrollIntoView({ + behavior: "smooth", block: "center" + }); + } + } + + async closeHltCommand() { + this.noteContext.viewScope.hltTemporarilyHidden = true; + await this.refresh(); + this.triggerCommand('reEvaluateRightPaneVisibility'); + } + + async entitiesReloadedEvent({ loadResults }) { + if (loadResults.isNoteContentReloaded(this.noteId)) { + await this.refresh(); + } else if (loadResults.getAttributes().find(attr => attr.type === 'label' + && (attr.name.toLowerCase().includes('readonly') || attr.name === 'hlt') + && attributeService.isAffecting(attr, this.note))) { + await this.refresh(); + } + } +} + + +class CloseHltButton extends OnClickButtonWidget { + constructor() { + super(); + + this.icon("bx-x") + .title("Close HLT") + .titlePlacement("bottom") + .onClick((widget, e) => { + e.stopPropagation(); + + widget.triggerCommand("closeHlt"); + }) + .class("icon-action close-hlt"); + } +} diff --git a/src/public/app/widgets/type_widgets/content_widget.js b/src/public/app/widgets/type_widgets/content_widget.js index 967c996e5..f7a4846bd 100644 --- a/src/public/app/widgets/type_widgets/content_widget.js +++ b/src/public/app/widgets/type_widgets/content_widget.js @@ -7,6 +7,7 @@ import MaxContentWidthOptions from "./options/appearance/max_content_width.js"; import KeyboardShortcutsOptions from "./options/shortcuts.js"; import HeadingStyleOptions from "./options/text_notes/heading_style.js"; import TableOfContentsOptions from "./options/text_notes/table_of_contents.js"; +import HighlightedTextOptions from "./options/text_notes/highlighted_text.js"; import TextAutoReadOnlySizeOptions from "./options/text_notes/text_auto_read_only_size.js"; import VimKeyBindingsOptions from "./options/code_notes/vim_key_bindings.js"; import WrapLinesOptions from "./options/code_notes/wrap_lines.js"; @@ -61,6 +62,7 @@ const CONTENT_WIDGETS = { _optionsTextNotes: [ HeadingStyleOptions, TableOfContentsOptions, + HighlightedTextOptions, TextAutoReadOnlySizeOptions ], _optionsCodeNotes: [ diff --git a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js new file mode 100644 index 000000000..7fc2ce825 --- /dev/null +++ b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js @@ -0,0 +1,90 @@ +import OptionsWidget from "../options_widget.js"; + +const TPL = ` +
    + +

    Highlighted Text

    + + Displays highlighted text in the left pane. You can customize the highlighted text displayed in the left pane: +
    Text color:
    + + + + + + + + + + + + + + + +
    Background color:
    + + + + + + + + + + + + + + + +
    `; + +export default class HighlightedTextOptions extends OptionsWidget { + doRender() { + this.$widget = $(TPL); + this.$hltColors = this.$widget.find(".hlt-color"); + this.$hltColors.on('change', () => { + const hltColorVals=this.$widget.find('input.hlt-color[type="checkbox"]:checked').map(function() { + return this.value; + }).get(); + this.updateOption('highlightedTextColors', JSON.stringify(hltColorVals)); + + }); + this.$hltBgColors = this.$widget.find(".hlt-background-color"); + this.$hltBgColors.on('change', () =>{ + const hltBgColorVals=this.$widget.find('input.hlt-background-color[type="checkbox"]:checked').map(function() { + return this.value; + }).get(); + this.updateOption('highlightedTextBgColors', JSON.stringify(hltBgColorVals)); + }); + + } + + async optionsLoaded(options) { + const hltColorVals=JSON.parse(options.highlightedTextColors); + const hltBgColorVals=JSON.parse(options.highlightedTextBgColors); + this.$widget.find('input.hlt-color[type="checkbox"]').each(function () { + if ($.inArray($(this).val(), hltColorVals) !== -1) { + $(this).prop("checked", true); + } else { + $(this).prop("checked", false); + } + }); + this.$widget.find('input.hlt-background-color[type="checkbox"]').each(function () { + if ($.inArray($(this).val(), hltBgColorVals) !== -1) { + $(this).prop("checked", true); + } else { + $(this).prop("checked", false); + } + }); + } +} diff --git a/src/routes/api/options.js b/src/routes/api/options.js index e98b1795f..48f2590b9 100644 --- a/src/routes/api/options.js +++ b/src/routes/api/options.js @@ -60,6 +60,8 @@ const ALLOWED_OPTIONS = new Set([ 'compressImages', 'downloadImagesAutomatically', 'minTocHeadings', + 'highlightedTextColors', + 'highlightedTextBgColors', 'checkForUpdates', 'disableTray', 'customSearchEngineName', diff --git a/src/services/options_init.js b/src/services/options_init.js index 1ce5bbd5d..ba34fba03 100644 --- a/src/services/options_init.js +++ b/src/services/options_init.js @@ -87,6 +87,8 @@ const defaultOptions = [ { name: 'compressImages', value: 'true', isSynced: true }, { name: 'downloadImagesAutomatically', value: 'true', isSynced: true }, { name: 'minTocHeadings', value: '5', isSynced: true }, + { name: 'highlightedTextColors', value: '["#e64c4c","#e6994c","#e6e64c","#99e64c","#4ce64c","#4ce699","#4ce6e6","#4c99e6","#4c4ce6","#994ce6"]', isSynced: true }, + { name: 'highlightedTextBgColors', value: '["#e64c4c","#e6994c","#e6e64c","#99e64c","#4ce64c","#4ce699","#4ce6e6","#4c99e6","#4c4ce6","#994ce6"]', isSynced: true }, { name: 'checkForUpdates', value: 'true', isSynced: true }, { name: 'disableTray', value: 'false', isSynced: false }, { name: 'customSearchEngineName', value: 'Duckduckgo', isSynced: false }, From d2d286a4ff708bfe9e6bf2c04935379b9fd0db68 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Wed, 31 May 2023 21:47:43 +0800 Subject: [PATCH 02/10] Show highlighted text in the left pane --- src/public/app/layouts/desktop_layout.js | 4 +- src/public/app/widgets/highlighted_text.js | 36 ++++----- .../options/text_notes/highlighted_text.js | 81 +++++++++---------- 3 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 3a9ec2930..0125e4ed1 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -44,7 +44,7 @@ import BacklinksWidget from "../widgets/floating_buttons/zpetne_odkazy.js"; import SharedInfoWidget from "../widgets/shared_info.js"; import FindWidget from "../widgets/find.js"; import TocWidget from "../widgets/toc.js"; -import HltWidget from "../widgets/highlighted_text.js"; +import HighlightTextWidget from "../widgets/highlighted_text.js"; import BulkActionsDialog from "../widgets/dialogs/bulk_actions.js"; import AboutDialog from "../widgets/dialogs/about.js"; import HelpDialog from "../widgets/dialogs/help.js"; @@ -182,7 +182,7 @@ export default class DesktopLayout { ) .child(new RightPaneContainer() .child(new TocWidget()) - .child(new HltWidget()) + .child(new HighlightTextWidget()) .child(...this.customWidgets.get('right-pane')) ) ) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index 3dbfc9b5c..43bc377ce 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -10,41 +10,41 @@ import RightPanelWidget from "./right_panel_widget.js"; import options from "../services/options.js"; import OnClickButtonWidget from "./buttons/onclick_button.js"; -const TPL = `
    +const TPL = `
    - +
    `; -export default class HltWidget extends RightPanelWidget { +export default class HighlightTextWidget extends RightPanelWidget { constructor() { super(); @@ -59,20 +59,20 @@ export default class HltWidget extends RightPanelWidget { isEnabled() { return super.isEnabled() && this.note.type === 'text' - && !this.noteContext.viewScope.hltTemporarilyHidden + && !this.noteContext.viewScope.highlightedTextTemporarilyHidden && this.noteContext.viewScope.viewMode === 'default'; } async doRenderBody() { this.$body.empty().append($(TPL)); - this.$hlt = this.$body.find('.hlt'); - this.$body.find('.hlt-widget').append(this.closeHltButton.render()); + this.$hlt = this.$body.find('.highlighted-text'); + this.$body.find('.highlighted-text-widget').append(this.closeHltButton.render()); } async refreshWithNote(note) { - const hltLabel = note.getLabel('hlt'); + const hltLabel = note.getLabel('hideHighlightWidget'); - if (hltLabel?.value === 'hide') { + if (hltLabel?.value=="" || hltLabel?.value=== "true") { this.toggleInt(false); this.triggerCommand("reEvaluateRightPaneVisibility"); return; @@ -90,7 +90,7 @@ export default class HltWidget extends RightPanelWidget { } this.$hlt.html($hlt); this.toggleInt( - ["", "show"].includes(hltLabel?.value) + [undefined, "false"].includes(hltLabel?.value) || hltColors!="" || hltBgColors!="" ); @@ -200,7 +200,7 @@ export default class HltWidget extends RightPanelWidget { $li.css("display","none"); } //The font color and background color may be nested or adjacent to each other. At this time, connect the front and back li to avoid interruption - if(hltIndex!=0 && hltBCs[hltIndex-1].nextSibling ===hltBCs[hltIndex] && $hlt.children().last().css("display")!="none"){ + if(hltIndex!=0 && hltBCs[hltIndex-1].nextSibling === hltBCs[hltIndex] && $hlt.children().last().css("display")!="none"){ $hlt.children().last().append($li.html()); }else{ $li.on("click", () => this.jumpToHlt(hltIndex)); @@ -233,7 +233,7 @@ export default class HltWidget extends RightPanelWidget { } async closeHltCommand() { - this.noteContext.viewScope.hltTemporarilyHidden = true; + this.noteContext.viewScope.highlightedTextTemporarilyHidden = true; await this.refresh(); this.triggerCommand('reEvaluateRightPaneVisibility'); } @@ -255,13 +255,13 @@ class CloseHltButton extends OnClickButtonWidget { super(); this.icon("bx-x") - .title("Close HLT") + .title("Close HighlightTextWidget") .titlePlacement("bottom") .onClick((widget, e) => { e.stopPropagation(); widget.triggerCommand("closeHlt"); }) - .class("icon-action close-hlt"); + .class("icon-action close-highlighted-text"); } } diff --git a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js index 7fc2ce825..ec884959a 100644 --- a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js +++ b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js @@ -1,67 +1,64 @@ import OptionsWidget from "../options_widget.js"; const TPL = ` -
    +

    Highlighted Text

    - Displays highlighted text in the left pane. You can customize the highlighted text displayed in the left pane: + Displays highlighted text in the right panel. You can customize the highlighted text displayed in the right panel:
    Text color:
    - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
    Background color:
    - - - - - - - - - - - - - - - + + + + + + + + + + + + + + +
    `; export default class HighlightedTextOptions extends OptionsWidget { doRender() { this.$widget = $(TPL); - this.$hltColors = this.$widget.find(".hlt-color"); + this.$hltColors = this.$widget.find(".highlighted-text-color"); this.$hltColors.on('change', () => { - const hltColorVals=this.$widget.find('input.hlt-color[type="checkbox"]:checked').map(function() { + const hltColorVals=this.$widget.find('input.highlighted-text-color[type="checkbox"]:checked').map(function() { return this.value; }).get(); this.updateOption('highlightedTextColors', JSON.stringify(hltColorVals)); }); - this.$hltBgColors = this.$widget.find(".hlt-background-color"); + this.$hltBgColors = this.$widget.find(".highlighted-text-background-color"); this.$hltBgColors.on('change', () =>{ - const hltBgColorVals=this.$widget.find('input.hlt-background-color[type="checkbox"]:checked').map(function() { + const hltBgColorVals=this.$widget.find('input.highlighted-text-background-color[type="checkbox"]:checked').map(function() { return this.value; }).get(); this.updateOption('highlightedTextBgColors', JSON.stringify(hltBgColorVals)); @@ -72,14 +69,14 @@ export default class HighlightedTextOptions extends OptionsWidget { async optionsLoaded(options) { const hltColorVals=JSON.parse(options.highlightedTextColors); const hltBgColorVals=JSON.parse(options.highlightedTextBgColors); - this.$widget.find('input.hlt-color[type="checkbox"]').each(function () { + this.$widget.find('input.highlighted-text-color[type="checkbox"]').each(function () { if ($.inArray($(this).val(), hltColorVals) !== -1) { $(this).prop("checked", true); } else { $(this).prop("checked", false); } }); - this.$widget.find('input.hlt-background-color[type="checkbox"]').each(function () { + this.$widget.find('input.highlighted-text-background-color[type="checkbox"]').each(function () { if ($.inArray($(this).val(), hltBgColorVals) !== -1) { $(this).prop("checked", true); } else { From 92d5aeae41ea384c1b0249bd70721481bf7b4dfc Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Wed, 31 May 2023 22:34:24 +0800 Subject: [PATCH 03/10] Show highlighted text in the right panel --- src/public/app/widgets/highlighted_text.js | 11 ++-- .../options/text_notes/highlighted_text.js | 62 +++++++++---------- src/services/options_init.js | 4 +- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index 43bc377ce..c9f3ef08c 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -82,11 +82,14 @@ export default class HighlightTextWidget extends RightPanelWidget { let optionsHltColors = JSON.parse(options.get('highlightedTextColors')); let optionsHltBgColors = JSON.parse(options.get('highlightedTextBgColors')); + const colorToValDic={"Dark": "#000000", "Dim grey": "#4d4d4d", "Grey": "#999999", "Light grey": "#e6e6e6", "White": "#ffffff", "Red": "#e64c4c", "Orange": "#e6994c", "Yellow": "#e6e64c", "Light green": "#99e64c", "Green": "#4ce64c", "Aquamarine": "#4ce699", "Turquoise": "#4ce6e6", "Light blue": "#4c99e6", "Blue": "#4c4ce6", "Purple": "#994ce6"} + const optionsHltColorsVal = optionsHltColors.map(color => colorToValDic[color]); + const optionsHltBgColorsVal = optionsHltBgColors.map(color => colorToValDic[color]); // Check for type text unconditionally in case alwaysShowWidget is set if (this.note.type === 'text') { const { content } = await note.getNoteComplement(); //hltColors/hltBgColors are the colors/background-color that appear in notes and in options - ({ $hlt, hltColors, hltBgColors } = await this.getHlt(content, optionsHltColors, optionsHltBgColors)); + ({ $hlt, hltColors, hltBgColors } = await this.getHlt(content, optionsHltColorsVal, optionsHltBgColorsVal)); } this.$hlt.html($hlt); this.toggleInt( @@ -167,7 +170,7 @@ export default class HighlightTextWidget extends RightPanelWidget { /** * Builds a jquery table of helight text. */ - getHlt(html, optionsHltColors, optionsHltBgColors) { + getHlt(html, optionsHltColorsVal, optionsHltBgColorsVal) { const hltBCs = $(html).find(`span[style*="background-color"],span[style*="color"]`) const $hlt = $("
      "); let hltColors = []; @@ -181,7 +184,7 @@ export default class HighlightTextWidget extends RightPanelWidget { if (color != "") { var hexColor = this.colorToHex(color); - if (this.hexIsInOptionHexs(hexColor,optionsHltColors)) { + if (this.hexIsInOptionHexs(hexColor,optionsHltColorsVal)) { $li.html(hltText) hltColors.push(hexColor); liDisplay=true; @@ -189,7 +192,7 @@ export default class HighlightTextWidget extends RightPanelWidget { } if (bgColor != "") { var hexBgColor = this.colorToHex(bgColor); - if (this.hexIsInOptionHexs(hexBgColor,optionsHltBgColors)) { + if (this.hexIsInOptionHexs(hexBgColor,optionsHltBgColorsVal)) { //When you need to add a background color, in order to make the display more comfortable, change the background color to transparent $li.html(hltText.css("background-color", hexBgColor+"80")) hltBgColors.push(hexBgColor); diff --git a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js index ec884959a..d5c284d94 100644 --- a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js +++ b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js @@ -3,7 +3,7 @@ import OptionsWidget from "../options_widget.js"; const TPL = `

      Highlighted Text

      - Displays highlighted text in the right panel. You can customize the highlighted text displayed in the right panel: + You can customize the highlighted text displayed in the right panel:
      Text color:
      - + @@ -28,7 +28,7 @@ const TPL = `
      Background color:
      - + From 0a66809bf0ca8aabe4af5426b1bc6eaa68098dd9 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Thu, 1 Jun 2023 20:38:55 +0800 Subject: [PATCH 05/10] Not show when nothing is checked in the options --- src/public/app/widgets/highlighted_text.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index 1182c6fc2..b6ced3124 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -81,16 +81,16 @@ export default class HighlightTextWidget extends RightPanelWidget { } const hltLabel = note.getLabel('hideHighlightWidget'); - if (hltLabel?.value == "" || hltLabel?.value === "true") { + let optionsHltColors = JSON.parse(options.get('highlightedTextColors')); + let optionsHltBgColors = JSON.parse(options.get('highlightedTextBgColors')); + + if (hltLabel?.value == "" || hltLabel?.value === "true" || (optionsHltColors=="" && optionsHltBgColors=="")) { this.toggleInt(false); this.triggerCommand("reEvaluateRightPaneVisibility"); return; } let $hlt = "", hltLiCount = -1; - - let optionsHltColors = JSON.parse(options.get('highlightedTextColors')); - let optionsHltBgColors = JSON.parse(options.get('highlightedTextBgColors')); //Obtained by `textEditor.config.get('fontColor.colors'), but this command can only be used in edit mode, so it is directly saved here const colorToValDic = { "Black": "hsl(0,0%,0%)", "Dim grey": "hsl(0,0%,30%)", "Grey": "hsl(0,0%,60%)", "Light grey": "hsl(0,0%,90%)", "White": "hsl(0,0%,100%)", "Red": "hsl(0,75%,60%)", "Orange": "hsl(30,75%,60%)", "Yellow": "hsl(60,75%,60%)", "Light green": "hsl(90,75%,60%)", "Green": "hsl(120,75%,60%)", "Aquamarine": "hsl(150,75%,60%)", "Turquoise": "hsl(180,75%,60%)", "Light blue": "hsl(210,75%,60%)", "Blue": "hsl(240,75%,60%)", "Purple": "hsl(270,75%,60%)" } const optionsHltColorsVal = optionsHltColors.map(color => colorToValDic[color]); From 1413756d0095d6b8384f297d78e1b35a9590de44 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Sat, 3 Jun 2023 11:55:50 +0800 Subject: [PATCH 06/10] Show highlighted text in right panel --- src/public/app/widgets/highlighted_text.js | 168 ++++++++++-------- .../options/text_notes/highlighted_text.js | 83 ++------- src/routes/api/options.js | 3 +- src/services/options_init.js | 3 +- 4 files changed, 113 insertions(+), 144 deletions(-) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index b6ced3124..f13bdc6b8 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -81,25 +81,20 @@ export default class HighlightTextWidget extends RightPanelWidget { } const hltLabel = note.getLabel('hideHighlightWidget'); - let optionsHltColors = JSON.parse(options.get('highlightedTextColors')); - let optionsHltBgColors = JSON.parse(options.get('highlightedTextBgColors')); + const optionsHlt = JSON.parse(options.get('highlightedText')); - if (hltLabel?.value == "" || hltLabel?.value === "true" || (optionsHltColors=="" && optionsHltBgColors=="")) { + if (hltLabel?.value == "" || hltLabel?.value === "true" || optionsHlt == "") { this.toggleInt(false); this.triggerCommand("reEvaluateRightPaneVisibility"); return; } let $hlt = "", hltLiCount = -1; - //Obtained by `textEditor.config.get('fontColor.colors'), but this command can only be used in edit mode, so it is directly saved here - const colorToValDic = { "Black": "hsl(0,0%,0%)", "Dim grey": "hsl(0,0%,30%)", "Grey": "hsl(0,0%,60%)", "Light grey": "hsl(0,0%,90%)", "White": "hsl(0,0%,100%)", "Red": "hsl(0,75%,60%)", "Orange": "hsl(30,75%,60%)", "Yellow": "hsl(60,75%,60%)", "Light green": "hsl(90,75%,60%)", "Green": "hsl(120,75%,60%)", "Aquamarine": "hsl(150,75%,60%)", "Turquoise": "hsl(180,75%,60%)", "Light blue": "hsl(210,75%,60%)", "Blue": "hsl(240,75%,60%)", "Purple": "hsl(270,75%,60%)" } - const optionsHltColorsVal = optionsHltColors.map(color => colorToValDic[color]); - const optionsHltBgColorsVal = optionsHltBgColors.map(color => colorToValDic[color]); // Check for type text unconditionally in case alwaysShowWidget is set if (this.note.type === 'text') { const { content } = await note.getNoteComplement(); //hltColors/hltBgColors are the colors/background-color that appear in notes and in options - ({ $hlt, hltLiCount } = await this.getHlt(content, optionsHltColorsVal, optionsHltBgColorsVal)); + ({ $hlt, hltLiCount } = await this.getHlt(content, optionsHlt)); } this.$hlt.html($hlt); if ([undefined, "false"].includes(hltLabel?.value) && hltLiCount > 0) { @@ -110,90 +105,115 @@ export default class HighlightTextWidget extends RightPanelWidget { this.noteContext.viewScope.highlightedTextTemporarilyHiddenPrevious = false; } - this.triggerCommand("reEvaluateRightPaneVisibility"); } /** * Builds a jquery table of helight text. */ - getHlt(html, optionsHltColorsVal, optionsHltBgColorsVal) { - const hltTagsRegex = /]*(?:background-color|color):[^;>]+;[^>]*>(.*?)<\/span>/gi; - let prevEndIndex = -1; - let prevLiDisplay = false; - const $hlt = $("
        "); - let hltLiCount = 0; - for (let match = null, hltIndex = 0; ((match = hltTagsRegex.exec(html)) !== null); hltIndex++) { - var spanHtml = match[0]; - const styleString = match[0].match(/style="(.*?)"/)[1]; - const text = match[1]; - const startIndex = match.index; - const endIndex = hltTagsRegex.lastIndex - 1; - var $li = $('
      1. '); - - const styles = styleString - .split(';') - .filter(item => item.includes('background-color') || item.includes('color')) - .map(item => item.trim()); - - for (let stylesIndex = 0; stylesIndex < styles.length; stylesIndex++) { - var [color, colorVal] = styles[stylesIndex].split(':'); - colorVal = colorVal.replace(/\s+/g, ''); - if (color == "color" && optionsHltColorsVal.indexOf(colorVal) >= 0) { - $li.html(spanHtml) - hltLiCount++; - - } - else if (color == "background-color" && optionsHltBgColorsVal.indexOf(colorVal) >= 0) { - - //When you need to add a background color, in order to make the display more comfortable, change the background color to Translucent - const spanHtmlRegex = /background-color:\s*(hsl|rgb)\((\d{1,3}),(\d{1,3}%?),(\d{1,3}%?)\)/i; - let spanHtmlMatch = spanHtml.match(spanHtmlRegex); - if (spanHtmlMatch && spanHtmlMatch.length > 4) { - let newColorValue = `${spanHtmlMatch[1]}a(${spanHtmlMatch[2]},${spanHtmlMatch[3]},${spanHtmlMatch[4]},0.5)`; - spanHtml = spanHtml.replace(spanHtmlRegex, `background-color: ${newColorValue}`); - } - $li.html(spanHtml) - hltLiCount++; - - } else { - $li.css("display", "none"); - } - } - if ($li.css("display")!="none"){ - if (prevEndIndex != -1 && startIndex === prevEndIndex + 1 && prevLiDisplay == true) { - $hlt.children().last().append($li.html()); - } else { - if ($li.text().trim() == "") { $li.css("display", "none"); } - $li.on("click", () => this.jumpToHlt(hltIndex)); - $hlt.append($li); - } - } - - prevEndIndex = endIndex; - prevLiDisplay = $li.css("display")!="none"; + getHlt(html, optionsHlt) { + // element priority: span>i>strong>u + // matches a span containing background-color + const regex1 = /]*style\s*=\s*[^>]*background-color:[^>]*?>[\s\S]*?<\/span>/gi; + // matches a span containing color + const regex2 = /]*style\s*=\s*[^>]*[^-]color:[^>]*?>[\s\S]*?<\/span>/gi; + // match italics + const regex3 = /[\s\S]*?<\/i>/gi; + // match bold + const regex4 = /[\s\S]*?<\/strong>/gi; + // match underline + const regex5 = /[\s\S]*?<\/u>/g; + // Possible values in optionsHlt: '["bold","italic","underline","color","bgColor"]' + let findSubStr="", combinedRegexStr = ""; + if (optionsHlt.indexOf("bgColor") >= 0){ + findSubStr+=`,span[style*="background-color"]`; + combinedRegexStr+=`|${regex1.source}`; } + if (optionsHlt.indexOf("color") >= 0){ + findSubStr+=`,span[style*="color"]`; + combinedRegexStr+=`|${regex2.source}`; + } + if (optionsHlt.indexOf("italic") >= 0){ + findSubStr+=`,i`; + combinedRegexStr+=`|${regex3.source}`; + } + if (optionsHlt.indexOf("bold") >= 0){ + findSubStr+=`,strong`; + combinedRegexStr+=`|${regex4.source}`; + } + if (optionsHlt.indexOf("underline") >= 0){ + findSubStr+=`,u`; + combinedRegexStr+=`|${regex5.source}`; + } + + findSubStr = findSubStr.substring(1) + combinedRegexStr = `(` + combinedRegexStr.substring(1) + `)`; + const combinedRegex = new RegExp(combinedRegexStr, 'gi'); + var $hlt = $("
          "); + var hltLiCount = 0; + let prevEndIndex = -1; + for (let match = null, hltIndex = 0; ((match = combinedRegex.exec(html)) !== null); hltIndex++) { + var subHtml = match[0]; + const startIndex = match.index; + const endIndex = combinedRegex.lastIndex; + hltLiCount++; + if (prevEndIndex != -1 && startIndex === prevEndIndex) { + $hlt.children().last().append(subHtml); + } else { + var $li = $('
        1. '); + $li.html(subHtml); + if ($li.text().trim() == "") { $li.css("display", "none"); } + $li.on("click", () => this.jumpToHlt(findSubStr,hltIndex)); + $hlt.append($li); + } + prevEndIndex = endIndex; + } + return { $hlt, hltLiCount }; } - - async jumpToHlt(hltIndex) { + async jumpToHlt(findSubStr,hltIndex) { const isReadOnly = await this.noteContext.isReadOnly(); + let targetElement; if (isReadOnly) { const $container = await this.noteContext.getContentElement(); - const hltElement = $container.find(`span[style*="background-color"],span[style*="color"]`)[hltIndex]; - - if (hltElement != null) { - hltElement.scrollIntoView({ behavior: "smooth", block: "center" }); - } + targetElement=$container.find(findSubStr).filter(function() { + if (findSubStr.indexOf("color")>=0 && findSubStr.indexOf("background-color")<0){ + let color = this.style.color; + return $(this).prop('tagName')=="SPAN" && color==""?false:true; + }else{ + return true; + } + }).filter(function() { + return $(this).parent(findSubStr).length === 0 + && $(this).parent().parent(findSubStr).length === 0 + && $(this).parent().parent().parent(findSubStr).length === 0 + && $(this).parent().parent().parent().parent(findSubStr).length === 0; + }) } else { const textEditor = await this.noteContext.getTextEditor(); - $(textEditor.editing.view.domRoots.values().next().value).find(`span[style*="background-color"],span[style*="color"]`)[hltIndex].scrollIntoView({ - behavior: "smooth", block: "center" - }); + targetElement=$(textEditor.editing.view.domRoots.values().next().value).find(findSubStr).filter(function() { + // When finding span[style*="color"] but not looking for span[style*="background-color"], + // the background-color error will be regarded as color, so it needs to be filtered + if (findSubStr.indexOf("color")>=0 && findSubStr.indexOf("background-color")<0){ + let color = this.style.color; + return $(this).prop('tagName')=="SPAN" && color==""?false:true; + }else{ + return true; + } + }).filter(function() { + //Need to filter out the child elements of the element that has been found + return $(this).parent(findSubStr).length === 0 + && $(this).parent().parent(findSubStr).length === 0 + && $(this).parent().parent().parent(findSubStr).length === 0 + && $(this).parent().parent().parent().parent(findSubStr).length === 0; + }) } + targetElement[hltIndex].scrollIntoView({ + behavior: "smooth", block: "center" + }); } async closeHltCommand() { diff --git a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js index 8af3503f8..90a47b616 100644 --- a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js +++ b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js @@ -1,83 +1,34 @@ import OptionsWidget from "../options_widget.js"; const TPL = ` -
          - +

          Highlighted Text

          - - You can customize the highlighted text displayed in the right panel: -
          Text color:
          - - - - - - - - - - - - - - - -
          Background color:
          - - - - - - - - - - - - - - - + + You can customize the highlighted text displayed in the right panel:
          + + + + + +
          `; export default class HighlightedTextOptions extends OptionsWidget { doRender() { this.$widget = $(TPL); - this.$hltColors = this.$widget.find(".highlighted-text-color"); - this.$hltColors.on('change', () => { - const hltColorVals=this.$widget.find('input.highlighted-text-color[type="checkbox"]:checked').map(function() { + this.$hlt = this.$widget.find(".highlighted-text-check"); + this.$hlt.on('change', () => { + const hltVals=this.$widget.find('input.highlighted-text-check[type="checkbox"]:checked').map(function() { return this.value; }).get(); - this.updateOption('highlightedTextColors', JSON.stringify(hltColorVals)); - - }); - this.$hltBgColors = this.$widget.find(".highlighted-text-background-color"); - this.$hltBgColors.on('change', () =>{ - const hltBgColorVals=this.$widget.find('input.highlighted-text-background-color[type="checkbox"]:checked').map(function() { - return this.value; - }).get(); - this.updateOption('highlightedTextBgColors', JSON.stringify(hltBgColorVals)); - }); - + this.updateOption('highlightedText', JSON.stringify(hltVals)); + }); } async optionsLoaded(options) { - const hltColorVals=JSON.parse(options.highlightedTextColors); - const hltBgColorVals=JSON.parse(options.highlightedTextBgColors); - this.$widget.find('input.highlighted-text-color[type="checkbox"]').each(function () { - if ($.inArray($(this).val(), hltColorVals) !== -1) { - $(this).prop("checked", true); - } else { - $(this).prop("checked", false); - } - }); - this.$widget.find('input.highlighted-text-background-color[type="checkbox"]').each(function () { - if ($.inArray($(this).val(), hltBgColorVals) !== -1) { + const hltVals=JSON.parse(options.highlightedText); + this.$widget.find('input.highlighted-text-check[type="checkbox"]').each(function () { + if ($.inArray($(this).val(), hltVals) !== -1) { $(this).prop("checked", true); } else { $(this).prop("checked", false); diff --git a/src/routes/api/options.js b/src/routes/api/options.js index 48f2590b9..4d9ee77a2 100644 --- a/src/routes/api/options.js +++ b/src/routes/api/options.js @@ -60,8 +60,7 @@ const ALLOWED_OPTIONS = new Set([ 'compressImages', 'downloadImagesAutomatically', 'minTocHeadings', - 'highlightedTextColors', - 'highlightedTextBgColors', + 'highlightedText', 'checkForUpdates', 'disableTray', 'customSearchEngineName', diff --git a/src/services/options_init.js b/src/services/options_init.js index 53ca56932..358403214 100644 --- a/src/services/options_init.js +++ b/src/services/options_init.js @@ -87,8 +87,7 @@ const defaultOptions = [ { name: 'compressImages', value: 'true', isSynced: true }, { name: 'downloadImagesAutomatically', value: 'true', isSynced: true }, { name: 'minTocHeadings', value: '5', isSynced: true }, - { name: 'highlightedTextColors', value: '["Red","Orange","Yellow","Light green","Green","Aquamarine","Turquoise","Light blue","Blue","Purple"]', isSynced: true }, - { name: 'highlightedTextBgColors', value: '["Red","Orange","Yellow","Light green","Green","Aquamarine","Turquoise","Light blue","Blue","Purple"]', isSynced: true }, + { name: 'highlightedText', value: '["bold","italic","underline","color","bgColor"]', isSynced: true }, { name: 'checkForUpdates', value: 'true', isSynced: true }, { name: 'disableTray', value: 'false', isSynced: false }, { name: 'customSearchEngineName', value: 'Duckduckgo', isSynced: false }, From 33fdad51593dd616f28521f7fb293ad41ebb3c15 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Sat, 3 Jun 2023 14:43:20 +0800 Subject: [PATCH 07/10] Show highlighted text in right panel --- src/public/app/widgets/highlighted_text.js | 25 ++++++++++++---------- src/public/app/widgets/toc.js | 4 ++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index f13bdc6b8..f39e7c696 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -28,6 +28,8 @@ const TPL = `
          margin-bottom: 3px; text-align: justify; text-justify: distribute; + word-wrap: break-word; + hyphens: auto; } .highlighted-text li:hover { @@ -149,26 +151,27 @@ export default class HighlightTextWidget extends RightPanelWidget { findSubStr = findSubStr.substring(1) combinedRegexStr = `(` + combinedRegexStr.substring(1) + `)`; const combinedRegex = new RegExp(combinedRegexStr, 'gi'); - var $hlt = $("
            "); - var hltLiCount = 0; - let prevEndIndex = -1; - for (let match = null, hltIndex = 0; ((match = combinedRegex.exec(html)) !== null); hltIndex++) { + let $hlt = $("
              "); + let prevEndIndex = -1, hltLiCount = 0; + for (let match = null, hltIndex=0; ((match = combinedRegex.exec(html)) !== null); hltIndex++) { var subHtml = match[0]; const startIndex = match.index; const endIndex = combinedRegex.lastIndex; - hltLiCount++; if (prevEndIndex != -1 && startIndex === prevEndIndex) { $hlt.children().last().append(subHtml); } else { - var $li = $('
            1. '); - $li.html(subHtml); - if ($li.text().trim() == "") { $li.css("display", "none"); } - $li.on("click", () => this.jumpToHlt(findSubStr,hltIndex)); - $hlt.append($li); + if ([...subHtml.matchAll(/(?<=^|>)[^><]+?(?=<|$)/g)].map(matchTmp => matchTmp[0]).join('').trim() != ""){ + var $li = $('
            2. '); + $li.html(subHtml); + $li.on("click", () => this.jumpToHlt(findSubStr,hltIndex)); + $hlt.append($li); + hltLiCount++; + }else{ + continue + } } prevEndIndex = endIndex; } - return { $hlt, hltLiCount diff --git a/src/public/app/widgets/toc.js b/src/public/app/widgets/toc.js index f17c3e65b..43ecb8f2d 100644 --- a/src/public/app/widgets/toc.js +++ b/src/public/app/widgets/toc.js @@ -38,6 +38,10 @@ const TPL = `
              .toc li { cursor: pointer; + text-align: justify; + text-justify: distribute; + word-wrap: break-word; + hyphens: auto; } .toc li:hover { From 446c41d020f0df9647af491c5b24e3e20e87631e Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Sat, 3 Jun 2023 17:00:15 +0800 Subject: [PATCH 08/10] Show highlighted text in right panel --- src/public/app/layouts/desktop_layout.js | 4 ++-- src/public/app/widgets/highlighted_text.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 0125e4ed1..17d569c4c 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -44,7 +44,7 @@ import BacklinksWidget from "../widgets/floating_buttons/zpetne_odkazy.js"; import SharedInfoWidget from "../widgets/shared_info.js"; import FindWidget from "../widgets/find.js"; import TocWidget from "../widgets/toc.js"; -import HighlightTextWidget from "../widgets/highlighted_text.js"; +import HighlightedTextWidget from "../widgets/highlighted_text.js"; import BulkActionsDialog from "../widgets/dialogs/bulk_actions.js"; import AboutDialog from "../widgets/dialogs/about.js"; import HelpDialog from "../widgets/dialogs/help.js"; @@ -182,7 +182,7 @@ export default class DesktopLayout { ) .child(new RightPaneContainer() .child(new TocWidget()) - .child(new HighlightTextWidget()) + .child(new HighlightedTextWidget()) .child(...this.customWidgets.get('right-pane')) ) ) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index f39e7c696..2ddecce88 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -46,7 +46,7 @@ const TPL = `
              `; -export default class HighlightTextWidget extends RightPanelWidget { +export default class HighlightedTextWidget extends RightPanelWidget { constructor() { super(); @@ -242,7 +242,7 @@ class CloseHltButton extends OnClickButtonWidget { super(); this.icon("bx-x") - .title("Close HighlightTextWidget") + .title("Close HighlightedTextWidget") .titlePlacement("bottom") .onClick((widget, e) => { e.stopPropagation(); From 3e3d7aa4d7e6cebadf7ec7083c11715e50c89992 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Sat, 3 Jun 2023 17:12:06 +0800 Subject: [PATCH 09/10] Show highlighted text in right panel --- src/public/app/widgets/highlighted_text.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index 2ddecce88..b22697994 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -95,7 +95,6 @@ export default class HighlightedTextWidget extends RightPanelWidget { // Check for type text unconditionally in case alwaysShowWidget is set if (this.note.type === 'text') { const { content } = await note.getNoteComplement(); - //hltColors/hltBgColors are the colors/background-color that appear in notes and in options ({ $hlt, hltLiCount } = await this.getHlt(content, optionsHlt)); } this.$hlt.html($hlt); From 8852e8e531062dcf92f30cb1ea8da57e3ac2502e Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Sun, 4 Jun 2023 16:02:30 +0800 Subject: [PATCH 10/10] Show highlighted text in right panel --- src/public/app/widgets/highlighted_text.js | 14 ++++++++------ src/public/app/widgets/toc.js | 8 ++++---- .../options/text_notes/highlighted_text.js | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/public/app/widgets/highlighted_text.js b/src/public/app/widgets/highlighted_text.js index b22697994..daced39d4 100644 --- a/src/public/app/widgets/highlighted_text.js +++ b/src/public/app/widgets/highlighted_text.js @@ -72,11 +72,11 @@ export default class HighlightedTextWidget extends RightPanelWidget { } async refreshWithNote(note) { - /*The reason for adding highlightedTextTemporarilyHiddenPrevious is to record whether the previous state of the highlightedText is hidden or displayed, + /*The reason for adding highlightedTextPreviousVisible is to record whether the previous state of the highlightedText is hidden or displayed, * and then let it be displayed/hidden at the initial time. * If there is no such value, when the right panel needs to display toc but not highlighttext, every time the note content is changed, * highlighttext Widget will appear and then close immediately, because getHlt function will consume time*/ - if (this.noteContext.viewScope.highlightedTextTemporarilyHiddenPrevious == true) { + if (this.noteContext.viewScope.highlightedTextPreviousVisible == true) { this.toggleInt(true); } else { this.toggleInt(false); @@ -100,20 +100,19 @@ export default class HighlightedTextWidget extends RightPanelWidget { this.$hlt.html($hlt); if ([undefined, "false"].includes(hltLabel?.value) && hltLiCount > 0) { this.toggleInt(true); - this.noteContext.viewScope.highlightedTextTemporarilyHiddenPrevious = true; + this.noteContext.viewScope.highlightedTextPreviousVisible = true; } else { this.toggleInt(false); - this.noteContext.viewScope.highlightedTextTemporarilyHiddenPrevious = false; + this.noteContext.viewScope.highlightedTextPreviousVisible = false; } this.triggerCommand("reEvaluateRightPaneVisibility"); } /** - * Builds a jquery table of helight text. + * Builds a table of helight text. */ getHlt(html, optionsHlt) { - // element priority: span>i>strong>u // matches a span containing background-color const regex1 = /]*style\s*=\s*[^>]*background-color:[^>]*?>[\s\S]*?<\/span>/gi; // matches a span containing color @@ -125,6 +124,7 @@ export default class HighlightedTextWidget extends RightPanelWidget { // match underline const regex5 = /[\s\S]*?<\/u>/g; // Possible values in optionsHlt: '["bold","italic","underline","color","bgColor"]' + // element priority: span>i>strong>u let findSubStr="", combinedRegexStr = ""; if (optionsHlt.indexOf("bgColor") >= 0){ findSubStr+=`,span[style*="background-color"]`; @@ -157,8 +157,10 @@ export default class HighlightedTextWidget extends RightPanelWidget { const startIndex = match.index; const endIndex = combinedRegex.lastIndex; if (prevEndIndex != -1 && startIndex === prevEndIndex) { + //If the previous element is connected to this element in HTML, then concatenate them into one. $hlt.children().last().append(subHtml); } else { + //hide li if its text content is empty if ([...subHtml.matchAll(/(?<=^|>)[^><]+?(?=<|$)/g)].map(matchTmp => matchTmp[0]).join('').trim() != ""){ var $li = $('
            3. '); $li.html(subHtml); diff --git a/src/public/app/widgets/toc.js b/src/public/app/widgets/toc.js index 43ecb8f2d..8d66b3294 100644 --- a/src/public/app/widgets/toc.js +++ b/src/public/app/widgets/toc.js @@ -84,11 +84,11 @@ export default class TocWidget extends RightPanelWidget { } async refreshWithNote(note) { - /*The reason for adding tocTemporarilyHiddenPrevious is to record whether the previous state of the toc is hidden or displayed, + /*The reason for adding tocPreviousVisible is to record whether the previous state of the toc is hidden or displayed, * and then let it be displayed/hidden at the initial time. If there is no such value, * when the right panel needs to display highlighttext but not toc, every time the note content is changed, * toc will appear and then close immediately, because getToc(html) function will consume time*/ - if (this.noteContext.viewScope.tocTemporarilyHiddenPrevious ==true){ + if (this.noteContext.viewScope.tocPreviousVisible ==true){ this.toggleInt(true); }else{ this.toggleInt(false); @@ -112,10 +112,10 @@ export default class TocWidget extends RightPanelWidget { this.$toc.html($toc); if (["", "show"].includes(tocLabel?.value) || headingCount >= options.getInt('minTocHeadings')){ this.toggleInt(true); - this.noteContext.viewScope.tocTemporarilyHiddenPrevious=true; + this.noteContext.viewScope.tocPreviousVisible=true; }else{ this.toggleInt(false); - this.noteContext.viewScope.tocTemporarilyHiddenPrevious=false; + this.noteContext.viewScope.tocPreviousVisible=false; } this.triggerCommand("reEvaluateRightPaneVisibility"); diff --git a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js index 90a47b616..4f96999cc 100644 --- a/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js +++ b/src/public/app/widgets/type_widgets/options/text_notes/highlighted_text.js @@ -16,7 +16,7 @@ const TPL = ` export default class HighlightedTextOptions extends OptionsWidget { doRender() { this.$widget = $(TPL); - this.$hlt = this.$widget.find(".highlighted-text-check"); + this.$hlt = this.$widget.find("input.highlighted-text-check"); this.$hlt.on('change', () => { const hltVals=this.$widget.find('input.highlighted-text-check[type="checkbox"]:checked').map(function() { return this.value;