Vanessa 2022-10-11 23:38:14 +08:00
parent 41a7c5d63f
commit c56c69e0e0
18 changed files with 121 additions and 39 deletions

View file

@ -1,4 +1,5 @@
{
"editMode": "Edit Mode",
"editReadonly": "Read-only mode",
"editReadonlyTip": "After enabling, the editor will load the document in read-only mode. When you need to edit, you can click the edit button on the top bar to switch to edit mode",
"generateConflictDoc": "Generate conflict documentation when syncing conflicts",

View file

@ -1,4 +1,5 @@
{
"editMode": "Modo de edición",
"editReadonly": "Modo de solo lectura",
"editReadonlyTip": "Cuando está habilitado, el editor cargará el documento en modo de solo lectura. Cuando necesite editar, puede hacer clic en el botón editar en la barra superior para cambiar al modo de edición",
"generateConflictDoc": "Generar documentación de conflicto al sincronizar conflictos",

View file

@ -1,4 +1,5 @@
{
"editMode": "Mode d'édition",
"editReadonly": "Mode lecture seule",
"editReadonlyTip": "Lorsqu'il est activé, l'éditeur charge le document en mode lecture seule. Lorsque vous avez besoin d'éditer, vous pouvez cliquer sur le bouton d'édition de la barre supérieure pour passer en mode d'édition",
"generateConflictDoc": "Générer une documentation sur les conflits lors de la synchronisation des conflits",

View file

@ -1,4 +1,5 @@
{
"editMode": "編輯模式",
"editReadonly": "只讀模式",
"editReadonlyTip": "啟用後編輯器將以只讀模式載入文檔,需要編輯時可點擊頂欄編輯按鈕切換到編輯模式",
"generateConflictDoc": "同步衝突時生成衝突文檔",

View file

@ -1,4 +1,5 @@
{
"editMode": "编辑模式",
"editReadonly": "只读模式",
"editReadonlyTip": "启用后编辑器将以只读模式载入文档,需要编辑时可点击顶栏编辑按钮切换到编辑模式",
"generateConflictDoc": "同步冲突时生成冲突文档",

View file

@ -198,7 +198,7 @@ export class BlockPanel {
},
typewriterMode: false,
after: (editor) => {
if (window.siyuan.config.readonly) {
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) {
disabledProtyle(editor.protyle);
}
editorElement.addEventListener("mouseleave", () => {

View file

@ -4,9 +4,51 @@ import {fetchPost} from "../util/fetch";
import {confirmDialog} from "../dialog/confirmDialog";
import {setPadding} from "../protyle/ui/initUI";
import {reloadProtyle} from "../protyle/util/reload";
import {disabledProtyle, enableProtyle} from "../protyle/util/onGet";
export const editor = {
element: undefined as Element,
setMode: (readOnly?: boolean) => {
const target = document.querySelector("#barReadonly");
if (typeof readOnly === "undefined") {
readOnly = target.getAttribute("aria-label") === `${window.siyuan.languages.use} ${window.siyuan.languages.editReadonly}`
}
window.siyuan.config.editor.readOnly = readOnly;
if (readOnly) {
target.setAttribute("aria-label", `${window.siyuan.languages.use} ${window.siyuan.languages.editMode}`);
target.querySelector('use').setAttribute("xlink:href", "#iconPreview");
} else {
target.setAttribute("aria-label", `${window.siyuan.languages.use} ${window.siyuan.languages.editReadonly}`);
target.querySelector('use').setAttribute("xlink:href", "#iconEdit");
}
fetchPost("/api/setting/setEditor", window.siyuan.config.editor, () => {
const allModels = getAllModels()
allModels.editor.forEach(editor => {
if (readOnly) { disabledProtyle(editor.editor.protyle);
} else {
enableProtyle(editor.editor.protyle);
}
});
allModels.backlink.forEach(backlink => {
backlink.editors.forEach(editor => {
if (readOnly) {
disabledProtyle(editor.protyle);
} else {
enableProtyle(editor.protyle);
}
})
});
window.siyuan.blockPanels.forEach(item => {
item.editors.forEach(editor => {
if (readOnly) {
disabledProtyle(editor.protyle);
} else {
enableProtyle(editor.protyle);
}
})
})
});
},
genHTML: () => {
let fontFamilyHTML = "";
fontFamilyHTML = '<select id="fontFamily" class="b3-select fn__flex-center fn__size200"></select>';
@ -208,8 +250,11 @@ export const editor = {
});
});
},
onSetEditor: (editor: IEditor) => {
window.siyuan.config.editor = editor;
onSetEditor: (editorData: IEditor) => {
if (editorData.readOnly !== window.siyuan.config.editor.readOnly) {
editor.setMode(editorData.readOnly);
}
window.siyuan.config.editor = editorData;
getAllModels().editor.forEach((item) => {
reloadProtyle(item.editor.protyle);
setPadding(item.editor.protyle);

View file

@ -47,7 +47,7 @@ export class Editor extends Model {
scrollAttr: options.scrollAttr,
typewriterMode: true,
after: (editor) => {
if (window.siyuan.config.readonly) {
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) {
disabledProtyle(editor.protyle);
}

View file

@ -33,6 +33,9 @@ export const rename = (options: {
type: "notebook" | "file"
range?: Range,
}) => {
if (window.siyuan.config.editor.readOnly) {
return;
}
const dialog = new Dialog({
title: window.siyuan.languages.rename,
content: `<div class="b3-dialog__content"><input class="b3-text-field fn__block" value=""></div>

View file

@ -68,7 +68,7 @@ export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL]) =
},
after: (editor) => {
// protyle 仅初始化一次,后续更新时会对 url 等再次复制
if (window.siyuan.config.readonly || document.querySelector("#toolbarEdit use").getAttribute("xlink:href") === "#iconEdit") {
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly || document.querySelector("#toolbarEdit use").getAttribute("xlink:href") === "#iconEdit") {
disabledProtyle(editor.protyle);
} else {
enableProtyle(editor.protyle);

View file

@ -135,14 +135,14 @@ export class Gutter {
return;
}
if (protyle.disabled) {
confirmDialog(window.siyuan.languages["_kernel"]["34"], window.siyuan.languages.foldTip, () => {
if (isMobile()) {
if (isMobile()) {
confirmDialog(window.siyuan.languages["_kernel"]["34"], window.siyuan.languages.foldTip, () => {
(document.getElementById("toolbarName") as HTMLInputElement).readOnly = false;
document.querySelector("#toolbarEdit use").setAttribute("xlink:href", "#iconPreview");
}
enableProtyle(protyle);
gutterFold();
});
enableProtyle(protyle);
gutterFold();
})
}
} else {
gutterFold();
}
@ -420,7 +420,7 @@ export class Gutter {
return true;
}
});
if (!isList && !window.siyuan.config.readonly) {
if (!isList && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
const turnIntoSubmenu: IMenu[] = [];
if (isContinue) {
turnIntoSubmenu.push(this.turnsIntoOne({
@ -599,7 +599,7 @@ export class Gutter {
writeText(protyle.lute.BlockDOM2HTML(html));
}
}).element);
if (window.siyuan.config.readonly) {
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) {
return;
}
window.siyuan.menus.menu.append(new MenuItem({
@ -689,7 +689,7 @@ export class Gutter {
nodeElement.classList.add("protyle-wysiwyg--select");
countBlockWord([id], protyle.block.rootID);
// "heading1-6", "list", "ordered-list", "check", "quote", "code", "table", "line", "math", "paragraph"
if (type === "NodeParagraph" && !window.siyuan.config.readonly) {
if (type === "NodeParagraph" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
turnIntoSubmenu.push(this.turnsIntoOne({
icon: "iconList",
label: window.siyuan.languages.list,
@ -772,7 +772,7 @@ export class Gutter {
level: 6,
type: "Blocks2Hs",
}));
} else if (type === "NodeHeading" && !window.siyuan.config.readonly) {
} else if (type === "NodeHeading" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
turnIntoSubmenu.push(this.turnsInto({
icon: "iconParagraph",
label: window.siyuan.languages.paragraph,
@ -848,7 +848,7 @@ export class Gutter {
type: "Blocks2Hs",
}));
}
} else if (type === "NodeList" && !window.siyuan.config.readonly) {
} else if (type === "NodeList" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconParagraph",
label: window.siyuan.languages.paragraph,
@ -909,7 +909,7 @@ export class Gutter {
type: "OL2TL"
}));
}
} else if (type === "NodeBlockquote" && !window.siyuan.config.readonly) {
} else if (type === "NodeBlockquote" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
turnIntoSubmenu.push(this.turnsOneInto({
icon: "iconParagraph",
label: window.siyuan.languages.paragraph,
@ -919,7 +919,7 @@ export class Gutter {
type: "CancelBlockquote"
}));
}
if (turnIntoSubmenu.length > 0 && !window.siyuan.config.readonly) {
if (turnIntoSubmenu.length > 0 && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({
icon: "iconRefresh",
label: window.siyuan.languages.turnInto,
@ -963,7 +963,7 @@ export class Gutter {
}
}, {
label: window.siyuan.languages.duplicate,
disabled: window.siyuan.config.readonly,
disabled: window.siyuan.config.readonly || window.siyuan.config.editor.readOnly,
click() {
const tempElement = nodeElement.cloneNode(true) as HTMLElement;
const newId = Lute.NewNodeID();
@ -986,7 +986,7 @@ export class Gutter {
}
}])
}).element);
if (!window.siyuan.config.readonly) {
if (!window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({
label: window.siyuan.languages.cut,
accelerator: "⌘X",
@ -1020,7 +1020,7 @@ export class Gutter {
}
}).element);
}
if (type === "NodeSuperBlock" && !window.siyuan.config.readonly) {
if (type === "NodeSuperBlock" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
window.siyuan.menus.menu.append(new MenuItem({
label: window.siyuan.languages.cancel + " " + window.siyuan.languages.superBlock,
@ -1031,7 +1031,7 @@ export class Gutter {
hideElements(["gutter"], protyle);
}
}).element);
} else if (type === "NodeCodeBlock" && !window.siyuan.config.readonly && !nodeElement.getAttribute("data-subtype")) {
} else if (type === "NodeCodeBlock" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly && !nodeElement.getAttribute("data-subtype")) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
const linewrap = nodeElement.getAttribute("linewrap");
const ligatures = nodeElement.getAttribute("ligatures");
@ -1100,7 +1100,7 @@ export class Gutter {
}
}]
}).element);
} else if (type === "NodeCodeBlock" && !window.siyuan.config.readonly && ["echarts", "mindmap"].includes(nodeElement.getAttribute("data-subtype"))) {
} else if (type === "NodeCodeBlock" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly && ["echarts", "mindmap"].includes(nodeElement.getAttribute("data-subtype"))) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
const height = (nodeElement as HTMLElement).style.height;
let html = nodeElement.outerHTML;
@ -1132,7 +1132,7 @@ export class Gutter {
}
}]
}).element);
} else if (type === "NodeTable" && !window.siyuan.config.readonly) {
} else if (type === "NodeTable" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
let range = getEditorRange(nodeElement);
const tableElement = nodeElement.querySelector("table");
if (!tableElement.contains(range.startContainer)) {
@ -1148,7 +1148,7 @@ export class Gutter {
submenu: tableMenu(protyle, nodeElement, cellElement as HTMLTableCellElement, range) as IMenu[]
}).element);
}
} else if ((type === "NodeVideo" || type === "NodeAudio") && !window.siyuan.config.readonly) {
} else if ((type === "NodeVideo" || type === "NodeAudio") && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "assetSubMenu",
@ -1157,7 +1157,7 @@ export class Gutter {
label: window.siyuan.languages.assets,
submenu: videoMenu(protyle, nodeElement, type)
}).element);
} else if (type === "NodeIFrame" && !window.siyuan.config.readonly) {
} else if (type === "NodeIFrame" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "assetSubMenu",
@ -1166,7 +1166,7 @@ export class Gutter {
label: window.siyuan.languages.assets,
submenu: iframeMenu(protyle, nodeElement)
}).element);
} else if (type === "NodeHTMLBlock" && !window.siyuan.config.readonly) {
} else if (type === "NodeHTMLBlock" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
window.siyuan.menus.menu.append(new MenuItem({
icon: "iconHTML5",
@ -1175,7 +1175,7 @@ export class Gutter {
protyle.toolbar.showRender(protyle, nodeElement);
}
}).element);
} else if (type === "NodeBlockQueryEmbed" && !window.siyuan.config.readonly) {
} else if (type === "NodeBlockQueryEmbed" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
window.siyuan.menus.menu.append(new MenuItem({
id: "assetSubMenu",
@ -1197,7 +1197,7 @@ export class Gutter {
}
}]
}).element);
} else if (type === "NodeHeading" && !window.siyuan.config.readonly) {
} else if (type === "NodeHeading" && !window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
const headingSubMenu = [];
if (subType !== "h1") {
@ -1298,7 +1298,7 @@ export class Gutter {
}
}
}).element);
if (!window.siyuan.config.readonly) {
if (!window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({
icon: "iconBefore",
label: window.siyuan.languages["insert-before"],
@ -1675,7 +1675,7 @@ export class Gutter {
}
index += 1;
if (isShow) {
html = `<button ${window.siyuan.config.readonly ? "" : 'draggable="true"'} data-type="${type}" data-subtype="${nodeElement.getAttribute("data-subtype")}" data-node-id="${nodeElement.getAttribute("data-node-id")}"><svg><use xlink:href="#${getIconByType(type, nodeElement.getAttribute("data-subtype"))}"></use></svg></button>` + html;
html = `<button ${(window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) ? "" : 'draggable="true"'} data-type="${type}" data-subtype="${nodeElement.getAttribute("data-subtype")}" data-node-id="${nodeElement.getAttribute("data-node-id")}"><svg><use xlink:href="#${getIconByType(type, nodeElement.getAttribute("data-subtype"))}"></use></svg></button>` + html;
}
let foldHTML = "";
if (type === "NodeListItem" && nodeElement.childElementCount > 3 || type === "NodeHeading") {
@ -1685,7 +1685,7 @@ export class Gutter {
if (type === "NodeListItem" || type === "NodeList") {
listItem = nodeElement;
if (type === "NodeListItem" && nodeElement.childElementCount > 3) {
html = `<button ${window.siyuan.config.readonly ? "" : 'draggable="true"'} data-type="${type}" data-subtype="${nodeElement.getAttribute("data-subtype")}" data-node-id="${nodeElement.getAttribute("data-node-id")}"><svg><use xlink:href="#${getIconByType(type, nodeElement.getAttribute("data-subtype"))}"></use></svg></button>${foldHTML}`;
html = `<button ${(window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) ? "" : 'draggable="true"'} data-type="${type}" data-subtype="${nodeElement.getAttribute("data-subtype")}" data-node-id="${nodeElement.getAttribute("data-node-id")}"><svg><use xlink:href="#${getIconByType(type, nodeElement.getAttribute("data-subtype"))}"></use></svg></button>${foldHTML}`;
}
}
if (type === "NodeHeading") {

View file

@ -286,7 +286,7 @@ export class Title {
}
}).element);
}
if (!window.siyuan.config.readonly) {
if (!window.siyuan.config.readonly && !window.siyuan.config.editor.readOnly) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
window.siyuan.menus.menu.append(new MenuItem({
label: window.siyuan.languages.attr,

View file

@ -174,7 +174,6 @@ const setHTML = (options: { content: string, action?: string[], unScroll?: boole
highlightRender(protyle.wysiwyg.element);
blockRender(protyle, protyle.wysiwyg.element);
if (options.action.includes(Constants.CB_GET_HISTORY)) {
disabledProtyle(protyle);
return;
}
if (protyle.options.render.scroll) {
@ -279,6 +278,9 @@ const setHTML = (options: { content: string, action?: string[], unScroll?: boole
export const disabledProtyle = (protyle: IProtyle) => {
hideElements(["gutter", "toolbar", "select", "hint", "util"], protyle);
protyle.disabled = true;
if (protyle.title) {
protyle.title.element.querySelector(".protyle-title__input").setAttribute("contenteditable", "false");
}
protyle.wysiwyg.element.setAttribute("contenteditable", "false");
protyle.wysiwyg.element.querySelectorAll('[contenteditable="true"][spellcheck="false"]').forEach(item => {
item.setAttribute("contenteditable", "false");
@ -291,6 +293,9 @@ export const enableProtyle = (protyle: IProtyle) => {
if (navigator && navigator.maxTouchPoints > 1 && ["MacIntel", "iPhone"].includes(navigator.platform)) {
// iPhoneiPad 端输入 contenteditable 为 true 时会在块中间插入 span
} else {
if (protyle.title) {
protyle.title.element.querySelector(".protyle-title__input").setAttribute("contenteditable", "true");
}
protyle.wysiwyg.element.setAttribute("contenteditable", "true");
}
protyle.wysiwyg.element.querySelectorAll('[contenteditable="false"][spellcheck="false"]').forEach(item => {

View file

@ -5,6 +5,7 @@ import {Constants} from "../../constants";
import {processRender} from "../util/processCode";
import {highlightRender} from "../markdown/highlightRender";
import {blockRender} from "../markdown/blockRender";
import {disabledProtyle} from "../util/onGet";
export const renderBacklink = (protyle: IProtyle, backlinkData: {
blockPaths: IBreadcrumb[],
@ -21,6 +22,9 @@ export const renderBacklink = (protyle: IProtyle, backlinkData: {
highlightRender(protyle.wysiwyg.element);
blockRender(protyle, protyle.wysiwyg.element);
removeLoading(protyle);
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) {
disabledProtyle(protyle);
}
};
const setBacklinkFold = (html: string, expand: boolean) => {
@ -65,6 +69,9 @@ export const loadBreadcrumb = (protyle: IProtyle, element: HTMLElement) => {
processRender(protyle.wysiwyg.element);
highlightRender(protyle.wysiwyg.element);
blockRender(protyle, protyle.wysiwyg.element);
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) {
disabledProtyle(protyle);
}
});
};

View file

@ -7,7 +7,7 @@ import {getDisplayName, getNotebookName} from "../util/pathName";
import {setPanelFocus} from "../layout/util";
import {escapeHtml} from "../util/escape";
import {fetchPost} from "../util/fetch";
import {onGet} from "../protyle/util/onGet";
import {disabledProtyle, onGet} from "../protyle/util/onGet";
import {openFileById} from "../editor/util";
import {addLoading} from "../protyle/ui/initUI";
import {unicode2Emoji} from "../emoji";
@ -203,7 +203,10 @@ export class Search extends Model {
gutter: true,
breadcrumbDocName: true,
},
after: () => {
after: (editor) => {
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) {
disabledProtyle(editor.protyle);
}
setTimeout(() => {
const matchElement = this.protyle.protyle.wysiwyg.element.querySelector(`div[data-node-id="${id}"] span[data-type="search-mark"]`);
if (matchElement) {

View file

@ -5,7 +5,7 @@ import {Constants} from "../constants";
import {Protyle} from "../protyle";
import {Dialog} from "../dialog";
import {fetchPost, fetchSyncPost} from "../util/fetch";
import {onGet} from "../protyle/util/onGet";
import {disabledProtyle, onGet} from "../protyle/util/onGet";
import {openFileById} from "../editor/util";
import {addLoading} from "../protyle/ui/initUI";
import {getAllModels} from "../layout/getAll";
@ -649,7 +649,10 @@ const getArticle = (options: {
gutter: true,
breadcrumbDocName: true
},
after: () => {
after: (editor) => {
if (window.siyuan.config.readonly || window.siyuan.config.editor.readOnly) {
disabledProtyle(editor.protyle);
}
setTimeout(() => {
const matchElement = protyle.protyle.wysiwyg.element.querySelector(`div[data-node-id="${options.id}"] span[data-type="search-mark"]`);
if (matchElement) {

View file

@ -7,7 +7,7 @@ import {isMobile} from "./functions";
import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {renderAssetsPreview} from "../asset/renderAssets";
import {Protyle} from "../protyle";
import {onGet} from "../protyle/util/onGet";
import {disabledProtyle, onGet} from "../protyle/util/onGet";
let historyEditor: Protyle;
const renderDoc = (element: HTMLElement, currentPage: number) => {
@ -328,6 +328,9 @@ export const openHistory = () => {
breadcrumbContext: false,
},
typewriterMode: false,
after(editor) {
disabledProtyle(editor.protyle);
}
});
const repoElement = dialog.element.querySelector('#historyContainer [data-type="repo"]');
const selectElement = repoElement.querySelector(".b3-select") as HTMLSelectElement;

View file

@ -28,6 +28,7 @@ import {initStatus} from "../layout/status";
import {syncGuide} from "../sync/syncGuide";
import {showMessage} from "../dialog/message";
import {replaceLocalPath} from "../editor/rename";
import {editor} from "../config/editor";
const matchKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => {
if (key1 === "general") {
@ -184,6 +185,9 @@ const initBar = () => {
<div id="barSync" class="toolbar__item b3-tooltips b3-tooltips__se" aria-label="${window.siyuan.config.sync.stat || (window.siyuan.languages.syncNow + " " + updateHotkeyTip(window.siyuan.config.keymap.general.syncNow.custom))}">
<svg><use xlink:href="#iconCloud"></use></svg>
</div>
<div id="barReadonly" class="toolbar__item b3-tooltips b3-tooltips__se" aria-label="${window.siyuan.languages.use} ${window.siyuan.config.editor.readOnly ? window.siyuan.languages.editMode : window.siyuan.languages.editReadonly}">
<svg><use xlink:href="#icon${window.siyuan.config.editor.readOnly ? "Preview" : "Edit"}"></use></svg>
</div>
<button id="barBack" data-menu="true" class="toolbar__item toolbar__item--disabled b3-tooltips b3-tooltips__se" aria-label="${window.siyuan.languages.goBack} ${updateHotkeyTip(window.siyuan.config.keymap.general.goBack.custom)}">
<svg>
<use xlink:href="#iconLeft"></use>
@ -207,6 +211,10 @@ const initBar = () => {
syncGuide(target);
event.stopPropagation();
break;
} else if (target.id === "barReadonly") {
editor.setMode();
event.stopPropagation();
break;
} else if (target.id === "barForward") {
goForward();
event.stopPropagation();