diff --git a/app/src/config/appearance.ts b/app/src/config/appearance.ts
index 80daf9422..89e271908 100644
--- a/app/src/config/appearance.ts
+++ b/app/src/config/appearance.ts
@@ -9,6 +9,7 @@ import {isBrowser} from "../util/functions";
import {fetchPost} from "../util/fetch";
import {loadAssets, renderSnippet} from "../util/assets";
import {genOptions} from "../util/genOptions";
+import {hasClosestByClassName} from "../protyle/util/hasClosest";
export const appearance = {
element: undefined as Element,
@@ -263,7 +264,39 @@ export const appearance = {
}
});
},
- _snippet: [] as ISnippet[],
+ _bindSnippet: (element: HTMLElement) => {
+ const itemContentElement = hasClosestByClassName(element, "b3-label");
+ if (!itemContentElement) {
+ return
+ }
+ fetchPost("/api/snippet/setSnippet", {
+ id: itemContentElement.getAttribute("data-id"),
+ name: itemContentElement.querySelector("input").value,
+ type: itemContentElement.querySelector(".b3-chip").textContent,
+ content: itemContentElement.querySelector("textarea").value,
+ enabled: (itemContentElement.querySelector(".b3-switch") as HTMLInputElement).checked
+ }, (response) => {
+ itemContentElement.setAttribute("data-id", response.data.id)
+ renderSnippet();
+ })
+ },
+ _genSnippet: (options: ISnippet) => {
+ return `
+
+
${options.type}
+
+
+
+
+
+
+
+
+
+
+
+
`
+ },
bindEvent: () => {
if (window.siyuan.config.appearance.customCSS) {
fetchPost("/api/setting/getCustomCSS", {
@@ -280,7 +313,6 @@ export const appearance = {
return;
}
fetchPost("/api/snippet/getSnippet", {type: "all", enabled: 2}, (response) => {
- appearance._snippet = response.data._snippet;
let html = `
@@ -293,35 +325,61 @@ export const appearance = {
`;
response.data.snippets.forEach((item: ISnippet) => {
- html += `
-
-
${item.type}
-
-
${item.name}
-
-
-
-
-
-
`
+ html += appearance._genSnippet(item);
});
codeSnippetPanelElement.innerHTML = html;
+ response.data.snippets.forEach((item: ISnippet) => {
+ const nameElement = (codeSnippetPanelElement.querySelector(`[data-id="${item.id}"] input`) as HTMLInputElement)
+ nameElement.value = item.name;
+ const contentElement = codeSnippetPanelElement.querySelector(`[data-id="${item.id}"] textarea`) as HTMLTextAreaElement;
+ contentElement.textContent = item.content;
+ nameElement.addEventListener("blur", (event) => {
+ appearance._bindSnippet(nameElement);
+ })
+ contentElement.addEventListener("blur", (event) => {
+ appearance._bindSnippet(contentElement);
+ })
+ codeSnippetPanelElement.querySelector(`[data-id="${item.id}"] .b3-switch`).addEventListener("change", (event) => {
+ appearance._bindSnippet(contentElement);
+ })
+ });
});
});
codeSnippetPanelElement.addEventListener("click", (event) => {
const target = event.target as HTMLElement;
if (target.id === "addCodeSnippetCSS" || target.id === "addCodeSnippetJS") {
- target.parentElement.insertAdjacentHTML("afterend", `
-
-
${target.id === "addCodeSnippetCSS" ? "css" : "js"}
-
-
-
-
-
-
-
-
`)
+ target.parentElement.insertAdjacentHTML("afterend", appearance._genSnippet({
+ type: target.id === "addCodeSnippetCSS" ? "css" : "js",
+ name: "",
+ content: "",
+ enabled: false
+ }))
+ codeSnippetPanelElement.querySelector(".b3-text-field").addEventListener("blur", (event) => {
+ appearance._bindSnippet(event.target as HTMLElement);
+ })
+ codeSnippetPanelElement.querySelector("textarea.b3-text-field").addEventListener("blur", (event) => {
+ appearance._bindSnippet(event.target as HTMLElement);
+ })
+ codeSnippetPanelElement.querySelector('.b3-switch').addEventListener("change", (event) => {
+ appearance._bindSnippet(event.target as HTMLElement);
+ })
+ return;
+ }
+ const removeElement = hasClosestByClassName(target, "b3-tooltips")
+ if (removeElement) {
+ const id = removeElement.parentElement.parentElement.getAttribute("data-id");
+ removeElement.parentElement.parentElement.remove();
+ if (!id) {
+ return;
+ }
+ fetchPost("/api/snippet/removeSnippet", {
+ id
+ }, (response) => {
+ const exitElement = document.getElementById(`snippet${response.data.type === "css" ? "CSS" : "JS"}${response.data.id}`) as HTMLScriptElement;
+ if (exitElement) {
+ exitElement.remove();
+ }
+ })
}
})
const appearanceCustomElement = appearance.element.querySelector("#appearanceCustom");
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts
index cad630145..8c365c28f 100644
--- a/app/src/types/index.d.ts
+++ b/app/src/types/index.d.ts
@@ -53,6 +53,7 @@ interface ITextOption {
}
interface ISnippet {
+ id?: string
name: string
type: string
enabled: boolean
diff --git a/app/src/util/assets.ts b/app/src/util/assets.ts
index bfad33f50..c16cffb72 100644
--- a/app/src/util/assets.ts
+++ b/app/src/util/assets.ts
@@ -87,9 +87,9 @@ export const loadAssets = (data: IAppearance) => {
};
export const renderSnippet = () => {
- fetchPost("/api/snippet/getSnippet", {type: "all"}, (response) => {
+ fetchPost("/api/snippet/getSnippet", {type: "all", enabled: 2}, (response) => {
response.data.snippets.forEach((item: ISnippet) => {
- const id = `snippet${item.type === "css" ? "CSS" : "JS"}${item.name}`;
+ const id = `snippet${item.type === "css" ? "CSS" : "JS"}${item.id}`;
let exitElement = document.getElementById(id) as HTMLScriptElement;
if (!item.enabled) {
if (exitElement) {