From 5b3499101ec883241b798f4c84161ac5e15fc1de Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 25 Feb 2024 22:27:59 +0800 Subject: [PATCH] :art: https://github.com/siyuan-note/siyuan/issues/10432 --- .../assets/scss/component/_typography.scss | 6 ++++- app/src/assets/scss/protyle/_wysiwyg.scss | 24 +++++++++---------- app/src/boot/globalEvent/event.ts | 4 ++-- app/src/protyle/render/abcRender.ts | 6 +++-- app/src/protyle/render/av/rollup.ts | 1 - app/src/protyle/render/chartRender.ts | 3 ++- app/src/protyle/render/flowchartRender.ts | 5 ++-- app/src/protyle/render/graphvizRender.ts | 4 +++- app/src/protyle/render/mermaidRender.ts | 9 ++++--- app/src/protyle/render/mindmapRender.ts | 3 ++- app/src/protyle/render/plantumlRender.ts | 4 +++- app/src/protyle/render/util.ts | 15 +++++++++--- app/src/protyle/util/onGet.ts | 13 ++++++++++ 13 files changed, 65 insertions(+), 32 deletions(-) diff --git a/app/src/assets/scss/component/_typography.scss b/app/src/assets/scss/component/_typography.scss index e8ab2561b..592731d87 100644 --- a/app/src/assets/scss/component/_typography.scss +++ b/app/src/assets/scss/component/_typography.scss @@ -259,7 +259,7 @@ display: inline-block !important; position: absolute !important; width: 1px !important; - right: 0 !important; + right: 6px !important; outline: 0 !important; background: 0 0 !important; text-decoration: initial !important; @@ -487,6 +487,10 @@ right: 4px; top: 4px; display: flex; + + &--show { + opacity: .86; + } } &-icon { diff --git a/app/src/assets/scss/protyle/_wysiwyg.scss b/app/src/assets/scss/protyle/_wysiwyg.scss index 8855ef668..66c5f3fb7 100644 --- a/app/src/assets/scss/protyle/_wysiwyg.scss +++ b/app/src/assets/scss/protyle/_wysiwyg.scss @@ -243,6 +243,10 @@ &.render-node { min-height: 32px; + &:hover > .protyle-icons { + opacity: .86; + } + &[data-type="NodeBlockQueryEmbed"] { background-color: var(--b3-theme-surface); border-left: 1px dashed var(--b3-theme-surface-lighter); @@ -616,23 +620,19 @@ } } - .img:hover .protyle-icons, - .render-node:hover > .protyle-icons, - .protyle-icons--show { + .img:hover .protyle-icons { opacity: .86; } .render-node .img:hover .protyle-icons, .render-node .render-node:hover > .protyle-icons { - opacity: 0; - } -} - -// https://ld246.com/article/1708826665603 -.protyle-wysiwyg[contenteditable="false"] { - .img:hover .protyle-icons, - .render-node:hover > .protyle-icons, - .protyle-icons--show { + display: none; + } +} + +.protyle-wysiwyg:not([custom-sy-readonly]), +.protyle-wysiwyg[custom-sy-readonly="true"] { + .img:hover .protyle-icons { display: none; } } diff --git a/app/src/boot/globalEvent/event.ts b/app/src/boot/globalEvent/event.ts index 098a91f6b..a613b975d 100644 --- a/app/src/boot/globalEvent/event.ts +++ b/app/src/boot/globalEvent/event.ts @@ -8,7 +8,7 @@ import {Constants} from "../../constants"; import {isIPad} from "../../protyle/util/compatibility"; import {globalTouchEnd, globalTouchStart} from "./touch"; import {initDockMenu} from "../../menus/dock"; -import {hasClosestByAttribute, hasClosestByClassName} from "../../protyle/util/hasClosest"; +import {hasClosestByAttribute, hasClosestByClassName, hasTopClosestByAttribute} from "../../protyle/util/hasClosest"; import {initTabMenu} from "../../menus/tab"; import {getInstanceById} from "../../layout/util"; import {Tab} from "../../layout/Tab"; @@ -85,7 +85,7 @@ export const initWindowEvent = (app: App) => { } return; } - const embedBlockElement = hasClosestByAttribute(target, "data-type", "NodeBlockQueryEmbed"); + const embedBlockElement = hasTopClosestByAttribute(target, "data-type", "NodeBlockQueryEmbed"); if (embedBlockElement) { embedBlockElement.firstElementChild.classList.toggle("protyle-icons--show"); return; diff --git a/app/src/protyle/render/abcRender.ts b/app/src/protyle/render/abcRender.ts index c5540bbd1..b8abbe46a 100644 --- a/app/src/protyle/render/abcRender.ts +++ b/app/src/protyle/render/abcRender.ts @@ -1,6 +1,7 @@ import {addScript} from "../util/addScript"; import {Constants} from "../../constants"; import {genIconHTML} from "./util"; +import {hasClosestByClassName} from "../util/hasClosest"; export const abcRender = (element: Element, cdn = Constants.PROTYLE_CDN) => { let abcElements: Element[] = []; @@ -15,12 +16,13 @@ export const abcRender = (element: Element, cdn = Constants.PROTYLE_CDN) => { } if (abcElements.length > 0) { addScript(`${cdn}/js/abcjs/abcjs-basic-min.js?v=6.2.2`, "protyleAbcjsScript").then(() => { + const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true) abcElements.forEach((e: HTMLDivElement) => { if (e.getAttribute("data-render") === "true") { return; } - if(!e.firstElementChild.classList.contains("protyle-icons")) { - e.insertAdjacentHTML("afterbegin", genIconHTML()); + if (!e.firstElementChild.classList.contains("protyle-icons")) { + e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement)); } const renderElement = e.firstElementChild.nextElementSibling as HTMLElement; renderElement.innerHTML = `${Constants.ZWSP}
`; diff --git a/app/src/protyle/render/av/rollup.ts b/app/src/protyle/render/av/rollup.ts index 404ec0fbf..61fbb62c6 100644 --- a/app/src/protyle/render/av/rollup.ts +++ b/app/src/protyle/render/av/rollup.ts @@ -72,7 +72,6 @@ const genSearchList = (element: Element, keyword: string, avId: string, isRelati response.data.keys.forEach((item: IAVColumn, index: number) => { html += `
${item.icon ? unicode2Emoji(item.icon, "b3-list-item__graphic", true) : ``} - ${genIconHTML()} ${escapeHtml(item.name || window.siyuan.languages.title)}
`; }); diff --git a/app/src/protyle/render/chartRender.ts b/app/src/protyle/render/chartRender.ts index 2685e6fa2..413e62cb1 100644 --- a/app/src/protyle/render/chartRender.ts +++ b/app/src/protyle/render/chartRender.ts @@ -30,12 +30,13 @@ export const chartRender = (element: Element, cdn = Constants.PROTYLE_CDN) => { }); } } + const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true) echartsElements.forEach(async (e: HTMLDivElement) => { if (e.getAttribute("data-render") === "true") { return; } if (!e.firstElementChild.classList.contains("protyle-icons")) { - e.insertAdjacentHTML("afterbegin", genIconHTML()); + e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement)); } const renderElement = e.firstElementChild.nextElementSibling as HTMLElement; try { diff --git a/app/src/protyle/render/flowchartRender.ts b/app/src/protyle/render/flowchartRender.ts index 6de68fdb2..cd4060d5d 100644 --- a/app/src/protyle/render/flowchartRender.ts +++ b/app/src/protyle/render/flowchartRender.ts @@ -1,6 +1,6 @@ import {addScript} from "../util/addScript"; import {Constants} from "../../constants"; -import {hasClosestByAttribute} from "../util/hasClosest"; +import {hasClosestByAttribute, hasClosestByClassName} from "../util/hasClosest"; import {genIconHTML} from "./util"; declare const flowchart: { @@ -36,12 +36,13 @@ export const flowchartRender = (element: Element, cdn = Constants.PROTYLE_CDN) = }; const initFlowchart = (flowchartElements: Element[]) => { + const wysiswgElement = hasClosestByClassName(flowchartElements[0], "protyle-wysiwyg", true) flowchartElements.forEach((item: HTMLElement) => { if (item.getAttribute("data-render") === "true") { return; } if (!item.firstElementChild.classList.contains("protyle-icons")) { - item.insertAdjacentHTML("afterbegin", genIconHTML()); + item.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement)); } const renderElement = item.firstElementChild.nextElementSibling; renderElement.innerHTML = `${Constants.ZWSP}
`; diff --git a/app/src/protyle/render/graphvizRender.ts b/app/src/protyle/render/graphvizRender.ts index 145d6fd66..eaf3cb72e 100644 --- a/app/src/protyle/render/graphvizRender.ts +++ b/app/src/protyle/render/graphvizRender.ts @@ -1,6 +1,7 @@ import {addScript} from "../util/addScript"; import {Constants} from "../../constants"; import {genIconHTML} from "./util"; +import {hasClosestByClassName} from "../util/hasClosest"; export const graphvizRender = (element: Element, cdn = Constants.PROTYLE_CDN) => { let graphvizElements: Element[] = []; @@ -14,12 +15,13 @@ export const graphvizRender = (element: Element, cdn = Constants.PROTYLE_CDN) => return; } addScript(`${cdn}/js/graphviz/viz.js?v=0.0.0`, "protyleGraphVizScript").then(() => { + const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true) graphvizElements.forEach((e: HTMLDivElement) => { if (e.getAttribute("data-render") === "true") { return; } if (!e.firstElementChild.classList.contains("protyle-icons")) { - e.insertAdjacentHTML("afterbegin", genIconHTML()); + e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement)); } const renderElement = e.firstElementChild.nextElementSibling as HTMLElement; try { diff --git a/app/src/protyle/render/mermaidRender.ts b/app/src/protyle/render/mermaidRender.ts index 5ad177e77..625952232 100644 --- a/app/src/protyle/render/mermaidRender.ts +++ b/app/src/protyle/render/mermaidRender.ts @@ -1,6 +1,7 @@ import {addScript} from "../util/addScript"; import {Constants} from "../../constants"; -import {hasClosestByAttribute} from "../util/hasClosest"; +import {hasClosestByAttribute, hasClosestByClassName} from "../util/hasClosest"; +import {genIconHTML} from "./util"; export const mermaidRender = (element: Element, cdn = Constants.PROTYLE_CDN) => { let mermaidElements: Element[] = []; @@ -56,15 +57,13 @@ export const mermaidRender = (element: Element, cdn = Constants.PROTYLE_CDN) => }; const initMermaid = (mermaidElements: Element[]) => { + const wysiswgElement = hasClosestByClassName(mermaidElements[0], "protyle-wysiwyg", true) mermaidElements.forEach(async (item: HTMLElement) => { if (item.getAttribute("data-render") === "true") { return; } if (!item.firstElementChild.classList.contains("protyle-icons")) { - item.insertAdjacentHTML("afterbegin", `
- - -
`); + item.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement)); } const renderElement = item.firstElementChild.nextElementSibling as HTMLElement; const id = "mermaid" + Lute.NewNodeID(); diff --git a/app/src/protyle/render/mindmapRender.ts b/app/src/protyle/render/mindmapRender.ts index b16a10cce..2acb3348c 100644 --- a/app/src/protyle/render/mindmapRender.ts +++ b/app/src/protyle/render/mindmapRender.ts @@ -27,12 +27,13 @@ export const mindmapRender = (element: Element, cdn = Constants.PROTYLE_CDN) => }); } } + const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true) mindmapElements.forEach((e: HTMLDivElement) => { if (e.getAttribute("data-render") === "true") { return; } if (!e.firstElementChild.classList.contains("protyle-icons")) { - e.insertAdjacentHTML("afterbegin", genIconHTML()); + e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement)); } const renderElement = e.firstElementChild.nextElementSibling as HTMLElement; try { diff --git a/app/src/protyle/render/plantumlRender.ts b/app/src/protyle/render/plantumlRender.ts index 218c72a68..1d3a5cf67 100644 --- a/app/src/protyle/render/plantumlRender.ts +++ b/app/src/protyle/render/plantumlRender.ts @@ -1,6 +1,7 @@ import {addScript} from "../util/addScript"; import {Constants} from "../../constants"; import {genIconHTML} from "./util"; +import {hasClosestByClassName} from "../util/hasClosest"; export const plantumlRender = (element: Element, cdn = Constants.PROTYLE_CDN) => { let plantumlElements: Element[] = []; @@ -14,12 +15,13 @@ export const plantumlRender = (element: Element, cdn = Constants.PROTYLE_CDN) => return; } addScript(`${cdn}/js/plantuml/plantuml-encoder.min.js?v=0.0.0`, "protylePlantumlScript").then(() => { + const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true) plantumlElements.forEach((e: HTMLDivElement) => { if (e.getAttribute("data-render") === "true") { return; } if (!e.firstElementChild.classList.contains("protyle-icons")) { - e.insertAdjacentHTML("afterbegin", genIconHTML()); + e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement)); } const renderElement = e.firstElementChild.nextElementSibling as HTMLElement; try { diff --git a/app/src/protyle/render/util.ts b/app/src/protyle/render/util.ts index d1168ddf7..778d468d7 100644 --- a/app/src/protyle/render/util.ts +++ b/app/src/protyle/render/util.ts @@ -1,6 +1,15 @@ -export const genIconHTML = () => { +export const genIconHTML = (element?: false|HTMLElement) => { + let enable = true; + if (element) { + const readonly = element.getAttribute("custom-sy-readonly"); + if (typeof readonly === "string") { + enable = element.getAttribute("custom-sy-readonly") === "false"; + } else { + return '
'; + } + } return `
- - + +
`; }; diff --git a/app/src/protyle/util/onGet.ts b/app/src/protyle/util/onGet.ts index ecd66e159..45c96adb5 100644 --- a/app/src/protyle/util/onGet.ts +++ b/app/src/protyle/util/onGet.ts @@ -296,6 +296,12 @@ export const disabledProtyle = (protyle: IProtyle) => { protyle.wysiwyg.element.querySelectorAll(".protyle-icons--show").forEach(item => { item.classList.remove("protyle-icons--show"); }); + protyle.wysiwyg.element.querySelectorAll(".render-node .protyle-action__edit").forEach(item => { + item.classList.add("fn__none"); + if (item.classList.contains("protyle-icon--first")) { + item.nextElementSibling?.classList.add("protyle-icon--first") + } + }); protyle.wysiwyg.element.style.userSelect = "text"; protyle.wysiwyg.element.setAttribute("contenteditable", "false"); protyle.wysiwyg.element.querySelectorAll('[contenteditable="true"][spellcheck]').forEach(item => { @@ -347,6 +353,13 @@ export const enableProtyle = (protyle: IProtyle) => { if (protyle.background) { protyle.background.element.classList.add("protyle-background--enable"); } + + protyle.wysiwyg.element.querySelectorAll(".render-node .protyle-action__edit").forEach(item => { + item.classList.remove("fn__none"); + if (item.classList.contains("protyle-icon--first")) { + item.nextElementSibling?.classList.remove("protyle-icon--first") + } + }); protyle.wysiwyg.element.querySelectorAll('[contenteditable="false"][spellcheck]').forEach(item => { if (!hasClosestByClassName(item, "protyle-wysiwyg__embed")) { item.setAttribute("contenteditable", "true");