This commit is contained in:
Vanessa 2023-07-19 13:55:42 +08:00
parent 4b873f2091
commit 0cac246415
16 changed files with 70 additions and 15 deletions

View File

@ -1,5 +1,6 @@
import {App} from "../index";
import {Constants} from "../constants";
import {genIconHTML} from "../protyle/render/util";
export const customBlockRender = (app: App, element: Element) => {
// TODO
@ -19,7 +20,7 @@ export const customBlockRender = (app: App, element: Element) => {
return;
}
if (!e.firstElementChild.classList.contains("protyle-icons")) {
e.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
e.insertAdjacentHTML("afterbegin", genIconHTML());
}
if (e.childElementCount < 4) {
e.lastElementChild.insertAdjacentHTML("beforebegin", `<span style="position: absolute">${Constants.ZWSP}</span>`);

View File

@ -356,6 +356,7 @@ const renderPDF = (id: string) => {
Protyle.chartRender(previewElement, "${servePath}/stage/protyle");
Protyle.mindmapRender(previewElement, "${servePath}/stage/protyle");
Protyle.abcRender(previewElement, "${servePath}/stage/protyle");
Protyle.htmlRender(previewElement);
Protyle.plantumlRender(previewElement, "${servePath}/stage/protyle");
}
fetchPost("/api/export/exportPreviewHTML", {
@ -643,6 +644,7 @@ const onExport = (data: IWebSocketData, filePath: string, type: string, removeAs
Protyle.chartRender(previewElement, "stage/protyle");
Protyle.mindmapRender(previewElement, "stage/protyle");
Protyle.abcRender(previewElement, "stage/protyle");
Protyle.htmlRender(previewElement);
Protyle.plantumlRender(previewElement, "stage/protyle");
document.querySelectorAll(".protyle-action__copy").forEach((item) => {
item.addEventListener("click", (event) => {

View File

@ -33,6 +33,7 @@ import {AIChat} from "../../ai/chat";
import {isMobile} from "../../util/functions";
import {isCtrl} from "../util/compatibility";
import {avRender} from "../render/av/render";
import {genIconHTML} from "../render/util";
export class Hint {
public timeId: number;
@ -675,7 +676,7 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
} else if (editableElement.textContent === "" && nodeElement.getAttribute("data-type") === "NodeParagraph") {
let newHTML = "";
if (value === "<div>") {
newHTML = `<div data-node-id="${id}" data-type="NodeHTMLBlock" class="render-node" data-subtype="block"><div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div><div><protyle-html data-content=""></protyle-html><span style="position: absolute">${Constants.ZWSP}</span></div><div class="protyle-attr" contenteditable="false"></div></div>`;
newHTML = `<div data-node-id="${id}" data-type="NodeHTMLBlock" class="render-node" data-subtype="block">${genIconHTML()}<div><protyle-html data-content=""></protyle-html><span style="position: absolute">${Constants.ZWSP}</span></div><div class="protyle-attr" contenteditable="false"></div></div>`;
} else {
editableElement.textContent = textContent;
newHTML = protyle.lute.SpinBlockDOM(nodeElement.outerHTML);
@ -693,7 +694,7 @@ ${unicode2Emoji(emoji.unicode)}</button>`;
} else {
let newHTML = protyle.lute.SpinBlockDOM(textContent);
if (value === "<div>") {
newHTML = `<div data-node-id="${Lute.NewNodeID()}" data-type="NodeHTMLBlock" class="render-node" data-subtype="block"><div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div><div><protyle-html data-content=""></protyle-html><span style="position: absolute">${Constants.ZWSP}</span></div><div class="protyle-attr" contenteditable="false"></div></div>`;
newHTML = `<div data-node-id="${Lute.NewNodeID()}" data-type="NodeHTMLBlock" class="render-node" data-subtype="block">${genIconHTML()}<div><protyle-html data-content=""></protyle-html><span style="position: absolute">${Constants.ZWSP}</span></div><div class="protyle-attr" contenteditable="false"></div></div>`;
}
nodeElement.insertAdjacentHTML("afterend", newHTML);
const oldHTML = nodeElement.outerHTML;

View File

@ -5,6 +5,7 @@ import { mermaidRender } from "./render/mermaidRender";
import { flowchartRender } from "./render/flowchartRender";
import { chartRender } from "./render/chartRender";
import { abcRender } from "./render/abcRender";
import { htmlRender } from "./render/htmlRender";
import { mindmapRender } from "./render/mindmapRender";
import { plantumlRender } from "./render/plantumlRender";
import { avRender } from "./render/av/render";
@ -31,6 +32,7 @@ class Protyle {
/** UML 渲染 */
public static plantumlRender = plantumlRender;
public static avRender = avRender;
public static htmlRender = htmlRender;
}
// 由于 https://github.com/siyuan-note/siyuan/issues/7800先临时解决一下

View File

@ -1,5 +1,6 @@
import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {genIconHTML} from "./util";
declare const ABCJS: {
renderAbc(element: Element, text: string, options: { responsive: string }): void;
@ -23,7 +24,7 @@ export const abcRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
return;
}
if(!e.firstElementChild.classList.contains("protyle-icons")) {
e.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
e.insertAdjacentHTML("afterbegin", genIconHTML());
}
if (e.childElementCount < 4) {
e.lastElementChild.insertAdjacentHTML("beforebegin", `<span style="position: absolute">${Constants.ZWSP}</span>`);

View File

@ -25,9 +25,9 @@ export const blockRender = (protyle: IProtyle, element: Element, top?: number) =
item.setAttribute("data-render", "true");
item.style.height = (item.clientHeight - 8) + "px"; // 减少抖动 https://ld246.com/article/1668669380171
item.innerHTML = `<div class="protyle-icons${hasClosestByAttribute(item.parentElement, "data-type", "NodeBlockQueryEmbed") ? " fn__none" : ""}">
<span aria-label="${window.siyuan.languages.refresh}" class="b3-tooltips__n b3-tooltips protyle-icon protyle-action__reload protyle-icon--first"><svg class="fn__rotate"><use xlink:href="#iconRefresh"></use></svg></span>
<span aria-label="${window.siyuan.languages.update} SQL" class="b3-tooltips__n b3-tooltips protyle-icon protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span>
<span aria-label="${window.siyuan.languages.more}" class="b3-tooltips__n b3-tooltips protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span>
<span aria-label="${window.siyuan.languages.refresh}" class="b3-tooltips__nw b3-tooltips protyle-icon protyle-action__reload protyle-icon--first"><svg class="fn__rotate"><use xlink:href="#iconRefresh"></use></svg></span>
<span aria-label="${window.siyuan.languages.update} SQL" class="b3-tooltips__nw b3-tooltips protyle-icon protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span>
<span aria-label="${window.siyuan.languages.more}" class="b3-tooltips__nw b3-tooltips protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span>
</div>${item.lastElementChild.outerHTML}`;
const content = Lute.UnEscapeHTMLStr(item.getAttribute("data-content"));
let breadcrumb: boolean | string = item.getAttribute("breadcrumb");

View File

@ -2,6 +2,7 @@ import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {hasClosestByClassName} from "../util/hasClosest";
import {looseJsonParse} from "../../util/functions";
import {genIconHTML} from "./util";
export const chartRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
let echartsElements: Element[] = [];
@ -34,7 +35,7 @@ export const chartRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
return;
}
if (!e.firstElementChild.classList.contains("protyle-icons")) {
e.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
e.insertAdjacentHTML("afterbegin", genIconHTML());
}
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
try {

View File

@ -1,6 +1,7 @@
import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {hasClosestByAttribute} from "../util/hasClosest";
import {genIconHTML} from "./util";
declare const flowchart: {
parse(text: string): { drawSVG: (type: Element) => void };
@ -42,7 +43,7 @@ const initFlowchart = (flowchartElements: Element[]) => {
// preview 不需要进行设置
if (item.getAttribute("data-node-id")) {
if (!item.firstElementChild.classList.contains("protyle-icons")) {
item.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
item.insertAdjacentHTML("afterbegin", genIconHTML());
}
if (item.childElementCount < 4) {
item.lastElementChild.insertAdjacentHTML("beforebegin", `<span style="position: absolute">${Constants.ZWSP}</span>`);

View File

@ -1,5 +1,6 @@
import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {genIconHTML} from "./util";
declare class Viz {
public renderSVGElement: (code: string) => Promise<any>;
@ -24,7 +25,7 @@ export const graphvizRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
return;
}
if (!e.firstElementChild.classList.contains("protyle-icons")) {
e.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
e.insertAdjacentHTML("afterbegin", genIconHTML());
}
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
try {

View File

@ -34,6 +34,9 @@ export const highlightRender = (element: Element, cdn = Constants.PROTYLE_CDN) =
addScript(`${cdn}/js/highlight.js/highlight.min.js?v=11.7.0`, "protyleHljsScript").then(() => {
addScript(`${cdn}/js/highlight.js/third-languages.js?v=1.0.1`, "protyleHljsThirdScript").then(() => {
codeElements.forEach((block: HTMLElement) => {
const iconElements = block.parentElement.querySelectorAll(".protyle-icon");
iconElements[0].setAttribute("aria-label", window.siyuan.languages.copy);
iconElements[1].setAttribute("aria-label", window.siyuan.languages.more);
if (block.getAttribute("data-render") === "true") {
return;
}

View File

@ -0,0 +1,18 @@
export const htmlRender = (element: Element) => {
let htmlElements: Element[] = [];
if (element.getAttribute("data-type") === "NodeHTMLBlock") {
// 编辑器内代码块编辑渲染
htmlElements = [element];
} else {
htmlElements = Array.from(element.querySelectorAll('[data-type="NodeHTMLBlock"]'));
}
if (htmlElements.length === 0) {
return;
}
if (htmlElements.length > 0) {
htmlElements.forEach((e: HTMLDivElement) => {
e.firstElementChild.firstElementChild.setAttribute("aria-label", window.siyuan.languages.edit);
e.firstElementChild.lastElementChild.setAttribute("aria-label", window.siyuan.languages.more);
});
}
};

View File

@ -66,7 +66,10 @@ const initMermaid = (mermaidElements: Element[]) => {
return;
}
if (!item.firstElementChild.classList.contains("protyle-icons")) {
item.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
item.insertAdjacentHTML("afterbegin", `<div class="protyle-icons">
<span aria-label="${window.siyuan.languages.edit}" class="b3-tooltips__sw b3-tooltips protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span>
<span aria-label="${window.siyuan.languages.more}" class="b3-tooltips__sw b3-tooltips protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span>
</div>`);
}
const renderElement = item.firstElementChild.nextElementSibling as HTMLElement;
renderElement.removeAttribute("data-processed");

View File

@ -1,6 +1,7 @@
import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {hasClosestByClassName} from "../util/hasClosest";
import {genIconHTML} from "./util";
export const mindmapRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
let mindmapElements: Element[] = [];
@ -31,7 +32,7 @@ export const mindmapRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
return;
}
if (!e.firstElementChild.classList.contains("protyle-icons")) {
e.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
e.insertAdjacentHTML("afterbegin", genIconHTML());
}
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
try {

View File

@ -1,5 +1,6 @@
import {addScript} from "../util/addScript";
import {Constants} from "../../constants";
import {genIconHTML} from "./util";
declare const plantumlEncoder: {
encode(options: string): string,
@ -22,7 +23,7 @@ export const plantumlRender = (element: Element, cdn = Constants.PROTYLE_CDN) =>
return;
}
if (!e.firstElementChild.classList.contains("protyle-icons")) {
e.insertAdjacentHTML("afterbegin", '<div class="protyle-icons"><span class="protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span><span class="protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span></div>');
e.insertAdjacentHTML("afterbegin", genIconHTML());
}
const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
try {

View File

@ -0,0 +1,6 @@
export const genIconHTML = () => {
return `<div class="protyle-icons">
<span aria-label="${window.siyuan.languages.edit}" class="b3-tooltips__nw b3-tooltips protyle-icon protyle-icon--first protyle-action__edit"><svg><use xlink:href="#iconEdit"></use></svg></span>
<span aria-label="${window.siyuan.languages.more}" class="b3-tooltips__nw b3-tooltips protyle-icon protyle-action__menu protyle-icon--last"><svg><use xlink:href="#iconMore"></use></svg></span>
</div>`
}

View File

@ -7,6 +7,7 @@ import {mindmapRender} from "../render/mindmapRender";
import {flowchartRender} from "../render/flowchartRender";
import {plantumlRender} from "../render/plantumlRender";
import {Constants} from "../../constants";
import {htmlRender} from "../render/htmlRender";
export const processPasteCode = (html: string, text: string) => {
const tempElement = document.createElement("div");
@ -31,7 +32,16 @@ export const processPasteCode = (html: string, text: string) => {
if (isCode) {
let code = text || html;
if (/\n/.test(code)) {
return `<div data-type="NodeCodeBlock" class="code-block" data-node-id="${Lute.NewNodeID()}"><div class="protyle-action"><span class="protyle-action--first protyle-action__language" contenteditable="false">${window.siyuan.storage[Constants.LOCAL_CODELANG]}</span><span class="fn__flex-1"></span><span class="protyle-icon protyle-icon--first protyle-action__copy"><svg><use xlink:href="#iconCopy"></use></svg></span><span class="protyle-icon protyle-icon--last protyle-action__menu"><svg><use xlink:href="#iconMore"></use></svg></span></div><div contenteditable="true" spellcheck="${window.siyuan.config.editor.spellcheck}">${code.replace(/&/g, "&amp;").replace(/</g, "&lt;")}<wbr></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
return `<div data-type="NodeCodeBlock" class="code-block" data-node-id="${Lute.NewNodeID()}">
<div class="protyle-action">
<span class="protyle-action--first protyle-action__language" contenteditable="false">${window.siyuan.storage[Constants.LOCAL_CODELANG]}</span>
<span class="fn__flex-1"></span>
<span aria-label="${window.siyuan.languages.copy}" class="b3-tooltips__nw b3-tooltips protyle-icon protyle-icon--first protyle-action__copy"><svg><use xlink:href="#iconCopy"></use></svg></span>
<span aria-label="${window.siyuan.languages.more}" class="b3-tooltips__nw b3-tooltips protyle-icon protyle-icon--last protyle-action__menu"><svg><use xlink:href="#iconMore"></use></svg></span>
</div>
<div contenteditable="true" spellcheck="${window.siyuan.config.editor.spellcheck}">${code.replace(/&/g, "&amp;").replace(/</g, "&lt;")}<wbr></div>
<div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div>
</div>`;
} else {
// Paste code from IDE no longer escape `<` and `>` https://github.com/siyuan-note/siyuan/issues/8340
code = code.replace("<", "&lt;").replace(">", "&gt;");
@ -43,8 +53,9 @@ export const processPasteCode = (html: string, text: string) => {
export const processRender = (previewPanel: Element) => {
const language = previewPanel.getAttribute("data-subtype");
if (!["abc", "plantuml", "mermaid", "flowchart", "echarts", "mindmap", "graphviz", "math"].includes(language)) {
if (!["abc", "plantuml", "mermaid", "flowchart", "echarts", "mindmap", "graphviz", "math"].includes(language) || previewPanel.getAttribute("data-type") !== "NodeHTMLBlock") {
abcRender(previewPanel);
htmlRender(previewPanel);
plantumlRender(previewPanel);
mermaidRender(previewPanel);
flowchartRender(previewPanel);
@ -70,5 +81,7 @@ export const processRender = (previewPanel: Element) => {
graphvizRender(previewPanel);
} else if (language === "math") {
mathRender(previewPanel);
} else if (previewPanel.getAttribute("data-type") === "NodeHTMLBlock") {
htmlRender(previewPanel);
}
};