mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-20 19:10:49 +08:00
This commit is contained in:
parent
4b873f2091
commit
0cac246415
@ -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>`);
|
||||
|
@ -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) => {
|
||||
|
@ -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;
|
||||
|
@ -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,先临时解决一下
|
||||
|
@ -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>`);
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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>`);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
18
app/src/protyle/render/htmlRender.ts
Normal file
18
app/src/protyle/render/htmlRender.ts
Normal 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);
|
||||
});
|
||||
}
|
||||
};
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
6
app/src/protyle/render/util.ts
Normal file
6
app/src/protyle/render/util.ts
Normal 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>`
|
||||
}
|
@ -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, "&").replace(/</g, "<")}<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, "&").replace(/</g, "<")}<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("<", "<").replace(">", ">");
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user