Ver Fonte

:art: https://github.com/siyuan-note/siyuan/issues/13343

Vanessa há 7 meses atrás
pai
commit
c546e0fd94

+ 5 - 0
app/appearance/themes/daylight/theme.css

@@ -109,6 +109,11 @@
     --b3-color-transition: color .2s cubic-bezier(0, 0, .2, 1) 0ms;
     --b3-background-transition: background 20ms ease-in 0s;
 
+    /* 高亮 */
+    --b3-highlight-color: #222;
+    --b3-highlight-background: #ffff00;
+    --b3-highlight-current-background: #ff9632;
+
     /* 下拉菜单 */
     --b3-select-background: url("data:image/svg+xml;utf8,<svg fill='rgba(95, 99, 104, .68)' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>") no-repeat right 2px center var(--b3-theme-background);
 

+ 5 - 0
app/appearance/themes/midnight/theme.css

@@ -108,6 +108,11 @@
     --b3-color-transition: color .2s cubic-bezier(0, 0, .2, 1) 0ms;
     --b3-background-transition: background 20ms ease-in 0s;
 
+    /* 高亮 */
+    --b3-highlight-color: #222;
+    --b3-highlight-background: #ffff00;
+    --b3-highlight-current-background: #ff9632;
+
     /* 下拉菜单 */
     --b3-select-background: url("data:image/svg+xml;utf8,<svg fill='rgba(154, 160, 166, .68)' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>") no-repeat right 2px center var(--b3-theme-background);
 

+ 2 - 2
app/src/history/history.ts

@@ -694,7 +694,7 @@ const bindEvent = (app: App, element: Element, dialog?: Dialog) => {
                     assetElement.classList.remove("fn__none");
                     assetElement.innerHTML = renderAssetsPreview(dataPath);
                 } else if (type === "doc") {
-                    const k  = (firstPanelElement.querySelector(".b3-text-field") as HTMLInputElement).value;
+                    const k = (firstPanelElement.querySelector(".b3-text-field") as HTMLInputElement).value;
                     fetchPost("/api/history/getDocHistoryContent", {
                         historyPath: dataPath,
                         highlight: !isSupportCSSHL(),
@@ -713,7 +713,7 @@ const bindEvent = (app: App, element: Element, dialog?: Dialog) => {
                                 protyle: historyEditor.protyle,
                                 action: [Constants.CB_GET_HISTORY, Constants.CB_GET_HTML],
                             });
-                            searchMarkRender(historyEditor.protyle, k.split(" "), false);
+                            searchMarkRender(historyEditor.protyle, k.split(" "));
                         }
                     });
                 }

+ 2 - 2
app/src/layout/dock/Backlink.ts

@@ -136,7 +136,7 @@ export class Backlink extends Model {
             item.addEventListener("blur", (event: KeyboardEvent) => {
                 const inputElement = event.target as HTMLInputElement;
                 inputElement.classList.add("fn__none");
-                const filterIconElement =  inputElement.nextElementSibling;
+                const filterIconElement = inputElement.nextElementSibling;
                 if (inputElement.value) {
                     filterIconElement.classList.add("block__icon--active");
                     filterIconElement.setAttribute("aria-label", window.siyuan.languages.filter + " " + inputElement.value);
@@ -467,7 +467,7 @@ export class Backlink extends Model {
                     }
                 });
                 editor.protyle.notebookId = liElement.getAttribute("data-notebook-id");
-                searchMarkRender(editor.protyle, keyword.split(" "), false);
+                searchMarkRender(editor.protyle, keyword.split(" "));
                 this.editors.push(editor);
             });
         }

+ 2 - 2
app/src/protyle/index.ts

@@ -85,8 +85,8 @@ export class Protyle {
         if (isSupportCSSHL()) {
             const styleId = genUUID();
             this.protyle.highlight.styleElement.dataset.uuid = styleId;
-            this.protyle.highlight.styleElement.textContent = `.protyle-wysiwyg::highlight(search-mark-${styleId}) {background-color: var(--b3-protyle-inline-mark-background);color: var(--b3-protyle-inline-mark-color);}
-  .protyle-wysiwyg::highlight(search-mark-hl-${styleId}) {background-color: var(--b3-theme-primary-lighter);box-shadow: 0 0 0 .5px var(--b3-theme-on-background);}`;
+            this.protyle.highlight.styleElement.textContent = `.protyle-wysiwyg::highlight(search-mark-${styleId}) {background-color: var(--b3-highlight-background);color: var(--b3-highlight-color);}
+  .protyle-wysiwyg::highlight(search-mark-hl-${styleId}) {color: var(--b3-highlight-color);background-color: var(--b3-highlight-current-background)}`;
         }
 
         this.protyle.hint = new Hint(this.protyle);

+ 23 - 5
app/src/protyle/render/searchMarkRender.ts

@@ -1,6 +1,7 @@
 import {Constants} from "../../constants";
+import {isInEmbedBlock} from "../util/hasClosest";
 
-export const searchMarkRender = (protyle: IProtyle, keys: string[], isHL: boolean, cb?: () => void) => {
+export const searchMarkRender = (protyle: IProtyle, keys: string[], hlId?: string | number, cb?: () => void) => {
     if (!isSupportCSSHL()) {
         return;
     }
@@ -8,6 +9,16 @@ export const searchMarkRender = (protyle: IProtyle, keys: string[], isHL: boolea
         protyle.highlight.markHL.clear();
         protyle.highlight.mark.clear();
         protyle.highlight.ranges = [];
+        let isSetHL = false;
+        let hlBlockElement: Element;
+        if (typeof hlId === "string") {
+            Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-node-id='${hlId}']`)).find(item => {
+                if (!isInEmbedBlock(item)) {
+                    hlBlockElement = item
+                    return true
+                }
+            })
+        }
 
 
         // 准备一个数组来保存所有文本节点
@@ -25,7 +36,7 @@ export const searchMarkRender = (protyle: IProtyle, keys: string[], isHL: boolea
         }
 
         const text = protyle.wysiwyg.element.textContent;
-        const rangeIndexes: { range: Range, startIndex: number }[] = [];
+        const rangeIndexes: { range: Range, startIndex: number, isCurrent: boolean }[] = [];
 
         keys.forEach(key => {
             if (!key) {
@@ -50,7 +61,13 @@ export const searchMarkRender = (protyle: IProtyle, keys: string[], isHL: boolea
                     currentTextNode = textNodes[currentNodeIndex];
                     range.setEnd(currentTextNode, endIndex - (currentNodeIndex ? textNodesSize[currentNodeIndex - 1] : 0));
 
-                    rangeIndexes.push({range, startIndex});
+                    let isCurrent = false;
+                    if (!isSetHL && hlBlockElement && hlBlockElement.contains(currentTextNode)) {
+                        isSetHL = true;
+                        isCurrent = true;
+                    }
+
+                    rangeIndexes.push({range, startIndex, isCurrent});
                 } catch (e) {
                     console.error("searchMarkRender error:", e);
                 }
@@ -65,7 +82,8 @@ export const searchMarkRender = (protyle: IProtyle, keys: string[], isHL: boolea
                 return 0;
             }
         }).forEach((item, index) => {
-            if (index === protyle.highlight.rangeIndex && isHL) {
+            if ((typeof hlId === "string" && item.isCurrent) || (typeof hlId === "number" && hlId === index)) {
+                protyle.highlight.rangeIndex = index;
                 protyle.highlight.markHL.add(item.range);
             } else {
                 protyle.highlight.mark.add(item.range);
@@ -73,7 +91,7 @@ export const searchMarkRender = (protyle: IProtyle, keys: string[], isHL: boolea
             protyle.highlight.ranges.push(item.range);
         });
         CSS.highlights.set("search-mark-" + protyle.highlight.styleElement.dataset.uuid, protyle.highlight.mark);
-        if (isHL) {
+        if (typeof hlId !== "undefined") {
             CSS.highlights.set("search-mark-hl-" + protyle.highlight.styleElement.dataset.uuid, protyle.highlight.markHL);
         }
         if (cb) {

+ 2 - 2
app/src/protyle/util/reload.ts

@@ -46,7 +46,7 @@ export const reloadProtyle = (protyle: IProtyle, focus: boolean, updateReadonly?
             }, response => {
                 protyle.options.backlinkData = isMention ? response.data.backmentions : response.data.backlinks;
                 renderBacklink(protyle, protyle.options.backlinkData);
-                searchMarkRender(protyle, keyword.split(" "), false);
+                searchMarkRender(protyle, keyword.split(" "));
             });
         }
     } else {
@@ -58,7 +58,7 @@ export const reloadProtyle = (protyle: IProtyle, focus: boolean, updateReadonly?
             updateReadonly,
             cb(keys) {
                 if (protyle.query?.key) {
-                    searchMarkRender(protyle, keys, true);
+                    searchMarkRender(protyle, keys, protyle.highlight.rangeIndex);
                 }
             }
         });

+ 3 - 4
app/src/search/util.ts

@@ -1249,10 +1249,9 @@ export const getArticle = (options: {
 
                 const contentRect = options.edit.protyle.contentElement.getBoundingClientRect();
                 if (isSupportCSSHL()) {
-                    options.edit.protyle.highlight.rangeIndex = 0;
-                    searchMarkRender(options.edit.protyle, getResponse.data.keywords, true, () => {
-                        if (options.edit.protyle.highlight.ranges.length > 0) {
-                            options.edit.protyle.contentElement.scrollTop = options.edit.protyle.contentElement.scrollTop + options.edit.protyle.highlight.ranges[0].getBoundingClientRect().top - contentRect.top - contentRect.height / 2;
+                    searchMarkRender(options.edit.protyle, getResponse.data.keywords, options.id, () => {
+                        if (options.edit.protyle.highlight.ranges.length > 0 && options.edit.protyle.highlight.ranges[options.edit.protyle.highlight.rangeIndex]) {
+                            options.edit.protyle.contentElement.scrollTop = options.edit.protyle.contentElement.scrollTop + options.edit.protyle.highlight.ranges[options.edit.protyle.highlight.rangeIndex].getBoundingClientRect().top - contentRect.top - contentRect.height / 2;
                         }
                     });
                 } else {

+ 1 - 1
app/src/types/protyle.d.ts

@@ -484,7 +484,7 @@ interface IProtyle {
         mark: Highlight
         markHL: Highlight
         ranges: Range[]
-        rangeIndex: 0
+        rangeIndex: number
         styleElement: HTMLStyleElement
     }
     getInstance: () => import("../protyle").Protyle,