import {getAllModels} from "../layout/getAll";
/// #if !BROWSER
import {ipcRenderer} from "electron";
/// #endif
import {setInlineStyle} from "../util/assets";
import {fetchPost} from "../util/fetch";
import {confirmDialog} from "../dialog/confirmDialog";
import {reloadProtyle} from "../protyle/util/reload";
import {updateHotkeyTip} from "../protyle/util/compatibility";
import {Constants} from "../constants";
import {resize} from "../protyle/util/resize";
import {setReadOnly} from "./util/setReadOnly";
import {Menu} from "../plugin/Menu";
export const editor = {
element: undefined as Element,
genHTML: () => {
let spellcheckTip = "";
/// #if !BROWSER
spellcheckTip = window.siyuan.languages.spellcheckTip2;
/// #else
spellcheckTip = window.siyuan.languages.spellcheckTip;
/// #endif
return `
${window.siyuan.languages.headingEmbedMode}
${window.siyuan.languages.headingEmbedModeTip}
${window.siyuan.languages.md9}
${window.siyuan.languages.md36}
${window.siyuan.languages.md35}
${window.siyuan.languages.md36}
${window.siyuan.languages.md41}
${window.siyuan.languages.historyRetentionDaysTip}
${window.siyuan.languages.clearHistory}
${window.siyuan.languages.floatWindowMode}
${window.siyuan.languages.floatWindowModeTip}
${window.siyuan.languages.fontSize}
${window.siyuan.languages.fontSizeTip}
${window.siyuan.languages.md29}
${window.siyuan.languages.md30}
${window.siyuan.languages.katexMacros}
${window.siyuan.languages.katexMacrosTip}
`;
},
bindEvent: async () => {
/// #if !BROWSER
const languages: string[] = await ipcRenderer.invoke(Constants.SIYUAN_GET, {
cmd: "availableSpellCheckerLanguages",
});
let spellcheckLanguagesHTML = "";
languages.forEach(item => {
spellcheckLanguagesHTML += `${item}
`;
});
const spellcheckLanguagesElement = editor.element.querySelector("#spellcheckLanguages");
spellcheckLanguagesElement.innerHTML = spellcheckLanguagesHTML;
spellcheckLanguagesElement.addEventListener("click", (event) => {
const target = event.target as Element;
if (target.classList.contains("b3-chip")) {
target.classList.toggle("b3-chip--current");
ipcRenderer.send(Constants.SIYUAN_CMD, {
cmd: "setSpellCheckerLanguages",
languages: Array.from(spellcheckLanguagesElement.querySelectorAll(".b3-chip--current")).map(item => item.textContent)
});
setEditor();
}
});
if (window.siyuan.config.editor.spellcheck) {
spellcheckLanguagesElement.classList.remove("fn__none");
}
/// #endif
const fontFamilyElement = editor.element.querySelector("#fontFamily") as HTMLSelectElement;
fontFamilyElement.addEventListener("click", () => {
fetchPost("/api/system/getSysFonts", {}, (response) => {
const fontMenu = new Menu();
fontMenu.addItem({
iconHTML: "",
checked: window.siyuan.config.editor.fontFamily === "",
label: `${window.siyuan.languages.default}
`,
click: () => {
if ("" === window.siyuan.config.editor.fontFamily) {
return;
}
fontFamilyElement.value = "";
fontFamilyElement.style.fontFamily = "";
setEditor();
}
});
response.data.forEach((item: string) => {
fontMenu.addItem({
iconHTML: "",
checked: window.siyuan.config.editor.fontFamily === item,
label: `${item}
`,
click: () => {
if (item === window.siyuan.config.editor.fontFamily) {
return;
}
fontFamilyElement.value = item;
fontFamilyElement.style.fontFamily = item + ",var(--b3-font-family)";
setEditor();
}
});
});
const rect = fontFamilyElement.getBoundingClientRect();
fontMenu.open({
x: rect.left,
y: rect.bottom
});
});
});
editor.element.querySelector("#clearHistory").addEventListener("click", () => {
confirmDialog(window.siyuan.languages.clearHistory, window.siyuan.languages.confirmClearHistory, () => {
fetchPost("/api/history/clearWorkspaceHistory", {});
});
});
const setEditor = () => {
let dynamicLoadBlocks = parseInt((editor.element.querySelector("#dynamicLoadBlocks") as HTMLInputElement).value);
if (48 > dynamicLoadBlocks) {
dynamicLoadBlocks = 48;
(editor.element.querySelector("#dynamicLoadBlocks") as HTMLInputElement).value = "48";
}
fetchPost("/api/setting/setEditor", {
fullWidth: (editor.element.querySelector("#fullWidth") as HTMLInputElement).checked,
markdown: {
inlineAsterisk: (editor.element.querySelector("#editorMarkdownInlineAsterisk") as HTMLInputElement).checked,
inlineUnderscore: (editor.element.querySelector("#editorMarkdownInlineUnderscore") as HTMLInputElement).checked,
inlineSup: (editor.element.querySelector("#editorMarkdownInlineSup") as HTMLInputElement).checked,
inlineSub: (editor.element.querySelector("#editorMarkdownInlineSub") as HTMLInputElement).checked,
inlineTag: (editor.element.querySelector("#editorMarkdownInlineTag") as HTMLInputElement).checked,
inlineMath: (editor.element.querySelector("#editorMarkdownInlineMath") as HTMLInputElement).checked,
inlineStrikethrough: (editor.element.querySelector("#editorMarkdownInlineStrikethrough") as HTMLInputElement).checked,
inlineMark: (editor.element.querySelector("#editorMarkdownInlineMark") as HTMLInputElement).checked
},
allowHTMLBLockScript: (editor.element.querySelector("#allowHTMLBLockScript") as HTMLInputElement).checked,
justify: (editor.element.querySelector("#justify") as HTMLInputElement).checked,
rtl: (editor.element.querySelector("#rtl") as HTMLInputElement).checked,
readOnly: (editor.element.querySelector("#readOnly") as HTMLInputElement).checked,
displayBookmarkIcon: (editor.element.querySelector("#displayBookmarkIcon") as HTMLInputElement).checked,
displayNetImgMark: (editor.element.querySelector("#displayNetImgMark") as HTMLInputElement).checked,
codeSyntaxHighlightLineNum: (editor.element.querySelector("#codeSyntaxHighlightLineNum") as HTMLInputElement).checked,
embedBlockBreadcrumb: (editor.element.querySelector("#embedBlockBreadcrumb") as HTMLInputElement).checked,
headingEmbedMode: parseInt((editor.element.querySelector("#headingEmbedMode") as HTMLSelectElement).value),
listLogicalOutdent: (editor.element.querySelector("#listLogicalOutdent") as HTMLInputElement).checked,
listItemDotNumberClickFocus: (editor.element.querySelector("#listItemDotNumberClickFocus") as HTMLInputElement).checked,
spellcheck: (editor.element.querySelector("#spellcheck") as HTMLInputElement).checked,
/// #if !BROWSER
spellcheckLanguages: Array.from(spellcheckLanguagesElement.querySelectorAll(".b3-chip--current")).map(item => item.textContent),
/// #else
// @ts-ignore
spellcheckLanguages: window.siyuan.config.editor.spellcheckLanguages,
/// #endif
onlySearchForDoc: (editor.element.querySelector("#onlySearchForDoc") as HTMLInputElement).checked,
floatWindowMode: parseInt((editor.element.querySelector("#floatWindowMode") as HTMLSelectElement).value),
plantUMLServePath: (editor.element.querySelector("#plantUMLServePath") as HTMLInputElement).value,
katexMacros: (editor.element.querySelector("#katexMacros") as HTMLTextAreaElement).value,
codeLineWrap: (editor.element.querySelector("#codeLineWrap") as HTMLInputElement).checked,
virtualBlockRef: (editor.element.querySelector("#virtualBlockRef") as HTMLInputElement).checked,
virtualBlockRefInclude: (editor.element.querySelector("#virtualBlockRefInclude") as HTMLTextAreaElement).value,
virtualBlockRefExclude: (editor.element.querySelector("#virtualBlockRefExclude") as HTMLTextAreaElement).value,
blockRefDynamicAnchorTextMaxLen: parseInt((editor.element.querySelector("#blockRefDynamicAnchorTextMaxLen") as HTMLInputElement).value),
backlinkExpandCount: parseInt((editor.element.querySelector("#backlinkExpandCount") as HTMLInputElement).value),
backmentionExpandCount: parseInt((editor.element.querySelector("#backmentionExpandCount") as HTMLInputElement).value),
backlinkContainChildren: (editor.element.querySelector("#backlinkContainChildren") as HTMLInputElement).checked,
dynamicLoadBlocks: dynamicLoadBlocks,
codeLigatures: (editor.element.querySelector("#codeLigatures") as HTMLInputElement).checked,
codeTabSpaces: parseInt((editor.element.querySelector("#codeTabSpaces") as HTMLInputElement).value),
fontSize: parseInt((editor.element.querySelector("#fontSize") as HTMLInputElement).value),
fontSizeScrollZoom: (editor.element.querySelector("#fontSizeScrollZoom") as HTMLInputElement).checked,
generateHistoryInterval: parseInt((editor.element.querySelector("#generateHistoryInterval") as HTMLInputElement).value),
historyRetentionDays: parseInt((editor.element.querySelector("#historyRetentionDays") as HTMLInputElement).value),
fontFamily: fontFamilyElement.value,
emoji: window.siyuan.config.editor.emoji
}, response => {
editor._onSetEditor(response.data);
});
};
editor.element.querySelectorAll("input.b3-switch, select.b3-select, input.b3-slider").forEach((item) => {
item.addEventListener("change", () => {
setEditor();
/// #if !BROWSER
if (item.id === "spellcheck") {
spellcheckLanguagesElement.classList.toggle("fn__none");
}
/// #endif
});
});
editor.element.querySelectorAll("textarea.b3-text-field, input.b3-text-field, input.b3-slider").forEach((item) => {
if (!item.getAttribute("readonly")) {
item.addEventListener("blur", () => {
setEditor();
});
}
});
editor.element.querySelectorAll("input.b3-slider").forEach((item) => {
item.addEventListener("input", (event) => {
const target = event.target as HTMLInputElement;
target.parentElement.setAttribute("aria-label", target.value);
});
});
},
_onSetEditor: (editorData: Config.IEditor) => {
const changeReadonly = editorData.readOnly !== window.siyuan.config.editor.readOnly;
if (changeReadonly) {
setReadOnly(editorData.readOnly);
}
window.siyuan.config.editor = editorData;
getAllModels().editor.forEach((item) => {
reloadProtyle(item.editor.protyle, false);
let isFullWidth = item.editor.protyle.wysiwyg.element.getAttribute(Constants.CUSTOM_SY_FULLWIDTH);
if (!isFullWidth) {
isFullWidth = window.siyuan.config.editor.fullWidth ? "true" : "false";
}
if (isFullWidth === "true" && item.editor.protyle.contentElement.getAttribute("data-fullwidth") === "true") {
return;
}
resize(item.editor.protyle);
if (isFullWidth === "true") {
item.editor.protyle.contentElement.setAttribute("data-fullwidth", "true");
} else {
item.editor.protyle.contentElement.removeAttribute("data-fullwidth");
}
});
setInlineStyle();
}
};