diff --git a/app/src/layout/dock/Outline.ts b/app/src/layout/dock/Outline.ts
index 6499da919..c4fb9223b 100644
--- a/app/src/layout/dock/Outline.ts
+++ b/app/src/layout/dock/Outline.ts
@@ -875,169 +875,128 @@ export class Outline extends Model {
const currentLevel = this.getHeadingLevel(element);
window.siyuan.menus.menu.remove();
window.siyuan.menus.menu.element.setAttribute("data-name", Constants.MENU_OUTLINE_CONTEXT);
- // 升级
- if (currentLevel > 1) {
- window.siyuan.menus.menu.append(new MenuItem({
- id: "upgrade",
- icon: "iconUp",
- label: window.siyuan.languages.upgrade,
- click: () => {
- const data = this.getProtyleAndBlockElement(element);
- if (data) {
- turnsIntoTransaction({
- protyle: data.protyle,
- selectsElement: [data.blockElement],
- type: "Blocks2Hs",
- level: currentLevel - 1
- });
- }
- }
- }).element);
- }
-
- // 降级
- if (currentLevel < 6) {
- window.siyuan.menus.menu.append(new MenuItem({
- id: "downgrade",
- icon: "iconDown",
- label: window.siyuan.languages.downgrade,
- click: () => {
- const data = this.getProtyleAndBlockElement(element);
- if (data) {
- turnsIntoTransaction({
- protyle: data.protyle,
- selectsElement: [data.blockElement],
- type: "Blocks2Hs",
- level: currentLevel + 1
- });
- }
- }
- }).element);
- }
-
- // 带子标题转换
const id = element.getAttribute("data-node-id");
- checkFold(id, (zoomIn) => {
- openFileById({
- app: this.app,
- id,
- action: zoomIn ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML, Constants.CB_GET_OUTLINE] : [Constants.CB_GET_FOCUS, Constants.CB_GET_OUTLINE, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML],
- });
- });
- this.setCurrentById(id);
- const headingSubMenu = [];
- if (currentLevel !== 1) {
- headingSubMenu.push(this.genHeadingTransform(id, 1));
- }
- if (currentLevel !== 2) {
- headingSubMenu.push(this.genHeadingTransform(id, 2));
- }
- if (currentLevel !== 3) {
- headingSubMenu.push(this.genHeadingTransform(id, 3));
- }
- if (currentLevel !== 4) {
- headingSubMenu.push(this.genHeadingTransform(id, 4));
- }
- if (currentLevel !== 5) {
- headingSubMenu.push(this.genHeadingTransform(id, 5));
- }
- if (currentLevel !== 6) {
- headingSubMenu.push(this.genHeadingTransform(id, 6));
- }
-
- if (headingSubMenu.length > 0) {
- window.siyuan.menus.menu.append(new MenuItem({
- id: "tWithSubtitle",
- type: "submenu",
- icon: "iconRefresh",
- label: window.siyuan.languages.tWithSubtitle,
- submenu: headingSubMenu
- }).element);
- }
-
- window.siyuan.menus.menu.append(new MenuItem({id: "separator_1", type: "separator"}).element);
-
- // 在前面插入同级标题
- window.siyuan.menus.menu.append(new MenuItem({
- id: "insertSameLevelHeadingBefore",
- icon: "iconBefore",
- label: window.siyuan.languages.insertSameLevelHeadingBefore,
- click: () => {
- const data = this.getProtyleAndBlockElement(element);
- const newId = Lute.NewNodeID();
- const html = `
`;
- transaction(data.protyle, [{
- action: "insert",
- data: html,
- id: newId,
- previousID: data.blockElement.previousElementSibling?.getAttribute("data-node-id"),
- parentID: data.blockElement.parentElement.getAttribute("data-node-id") || data.protyle.block.parentID,
- }], [{
- action: "delete",
- id: newId
- }]);
- data.blockElement.insertAdjacentHTML("beforebegin", html);
- data.blockElement.previousElementSibling.scrollIntoView();
- focusByWbr(data.blockElement.previousElementSibling, document.createRange());
+ if (!window.siyuan.config.readonly) {
+ // 升级
+ if (currentLevel > 1) {
+ window.siyuan.menus.menu.append(new MenuItem({
+ id: "upgrade",
+ icon: "iconUp",
+ label: window.siyuan.languages.upgrade,
+ click: () => {
+ const data = this.getProtyleAndBlockElement(element);
+ if (data) {
+ turnsIntoTransaction({
+ protyle: data.protyle,
+ selectsElement: [data.blockElement],
+ type: "Blocks2Hs",
+ level: currentLevel - 1
+ });
+ }
+ }
+ }).element);
}
- }).element);
- // 在后面插入同级标题
- window.siyuan.menus.menu.append(new MenuItem({
- id: "insertSameLevelHeadingAfter",
- icon: "iconAfter",
- label: window.siyuan.languages.insertSameLevelHeadingAfter,
- click: () => {
- fetchPost("/api/block/getHeadingDeleteTransaction", {
+ // 降级
+ if (currentLevel < 6) {
+ window.siyuan.menus.menu.append(new MenuItem({
+ id: "downgrade",
+ icon: "iconDown",
+ label: window.siyuan.languages.downgrade,
+ click: () => {
+ const data = this.getProtyleAndBlockElement(element);
+ if (data) {
+ turnsIntoTransaction({
+ protyle: data.protyle,
+ selectsElement: [data.blockElement],
+ type: "Blocks2Hs",
+ level: currentLevel + 1
+ });
+ }
+ }
+ }).element);
+ }
+
+ // 带子标题转换
+ checkFold(id, (zoomIn) => {
+ openFileById({
+ app: this.app,
id,
- }, (deleteResponse) => {
- const data = this.getProtyleAndBlockElement(element);
- const previousID = deleteResponse.data.doOperations[deleteResponse.data.doOperations.length - 1].id;
+ action: zoomIn ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML, Constants.CB_GET_OUTLINE] : [Constants.CB_GET_FOCUS, Constants.CB_GET_OUTLINE, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML],
+ });
+ });
+ this.setCurrentById(id);
+ const headingSubMenu = [];
+ if (currentLevel !== 1) {
+ headingSubMenu.push(this.genHeadingTransform(id, 1));
+ }
+ if (currentLevel !== 2) {
+ headingSubMenu.push(this.genHeadingTransform(id, 2));
+ }
+ if (currentLevel !== 3) {
+ headingSubMenu.push(this.genHeadingTransform(id, 3));
+ }
+ if (currentLevel !== 4) {
+ headingSubMenu.push(this.genHeadingTransform(id, 4));
+ }
+ if (currentLevel !== 5) {
+ headingSubMenu.push(this.genHeadingTransform(id, 5));
+ }
+ if (currentLevel !== 6) {
+ headingSubMenu.push(this.genHeadingTransform(id, 6));
+ }
+ if (headingSubMenu.length > 0) {
+ window.siyuan.menus.menu.append(new MenuItem({
+ id: "tWithSubtitle",
+ type: "submenu",
+ icon: "iconRefresh",
+ label: window.siyuan.languages.tWithSubtitle,
+ submenu: headingSubMenu
+ }).element);
+ }
+
+ window.siyuan.menus.menu.append(new MenuItem({id: "separator_1", type: "separator"}).element);
+
+ // 在前面插入同级标题
+ window.siyuan.menus.menu.append(new MenuItem({
+ id: "insertSameLevelHeadingBefore",
+ icon: "iconBefore",
+ label: window.siyuan.languages.insertSameLevelHeadingBefore,
+ click: () => {
+ const data = this.getProtyleAndBlockElement(element);
const newId = Lute.NewNodeID();
const html = ``;
transaction(data.protyle, [{
action: "insert",
data: html,
id: newId,
- previousID,
+ previousID: data.blockElement.previousElementSibling?.getAttribute("data-node-id"),
+ parentID: data.blockElement.parentElement.getAttribute("data-node-id") || data.protyle.block.parentID,
}], [{
action: "delete",
id: newId
}]);
- const previousElement = data.protyle.wysiwyg.element.querySelector(`[data-node-id="${previousID}"]`);
- if (previousElement) {
- previousElement.insertAdjacentHTML("afterend", html);
- previousElement.nextElementSibling.scrollIntoView();
- focusByWbr(previousElement.nextElementSibling, document.createRange());
- }
- });
- }
- }).element);
+ data.blockElement.insertAdjacentHTML("beforebegin", html);
+ data.blockElement.previousElementSibling.scrollIntoView();
+ focusByWbr(data.blockElement.previousElementSibling, document.createRange());
+ }
+ }).element);
- // 添加子标题
- if (currentLevel < 6) { // 只有当前级别小于6时才能添加子标题
+ // 在后面插入同级标题
window.siyuan.menus.menu.append(new MenuItem({
- id: "addChildHeading",
- icon: "iconAdd",
- label: window.siyuan.languages.addChildHeading,
+ id: "insertSameLevelHeadingAfter",
+ icon: "iconAfter",
+ label: window.siyuan.languages.insertSameLevelHeadingAfter,
click: () => {
fetchPost("/api/block/getHeadingDeleteTransaction", {
id,
}, (deleteResponse) => {
- let previousID = deleteResponse.data.doOperations[deleteResponse.data.doOperations.length - 1].id;
- deleteResponse.data.undoOperations.find((operationsItem: IOperation, index: number) => {
- const startIndex = operationsItem.data.indexOf(' data-subtype="h');
- if (startIndex > -1 && startIndex < 260 && parseInt(operationsItem.data.substring(startIndex + 16, startIndex + 17)) === currentLevel + 1) {
- previousID = deleteResponse.data.undoOperations[index - 1].id;
- return true;
- }
- });
-
-
const data = this.getProtyleAndBlockElement(element);
+ const previousID = deleteResponse.data.doOperations[deleteResponse.data.doOperations.length - 1].id;
+
const newId = Lute.NewNodeID();
- const html = ``;
+ const html = ``;
transaction(data.protyle, [{
action: "insert",
data: html,
@@ -1056,9 +1015,52 @@ export class Outline extends Model {
});
}
}).element);
- }
- window.siyuan.menus.menu.append(new MenuItem({id: "separator_2", type: "separator"}).element);
+ // 添加子标题
+ if (currentLevel < 6) { // 只有当前级别小于6时才能添加子标题
+ window.siyuan.menus.menu.append(new MenuItem({
+ id: "addChildHeading",
+ icon: "iconAdd",
+ label: window.siyuan.languages.addChildHeading,
+ click: () => {
+ fetchPost("/api/block/getHeadingDeleteTransaction", {
+ id,
+ }, (deleteResponse) => {
+ let previousID = deleteResponse.data.doOperations[deleteResponse.data.doOperations.length - 1].id;
+ deleteResponse.data.undoOperations.find((operationsItem: IOperation, index: number) => {
+ const startIndex = operationsItem.data.indexOf(' data-subtype="h');
+ if (startIndex > -1 && startIndex < 260 && parseInt(operationsItem.data.substring(startIndex + 16, startIndex + 17)) === currentLevel + 1) {
+ previousID = deleteResponse.data.undoOperations[index - 1].id;
+ return true;
+ }
+ });
+
+
+ const data = this.getProtyleAndBlockElement(element);
+ const newId = Lute.NewNodeID();
+ const html = ``;
+ transaction(data.protyle, [{
+ action: "insert",
+ data: html,
+ id: newId,
+ previousID,
+ }], [{
+ action: "delete",
+ id: newId
+ }]);
+ const previousElement = data.protyle.wysiwyg.element.querySelector(`[data-node-id="${previousID}"]`);
+ if (previousElement) {
+ previousElement.insertAdjacentHTML("afterend", html);
+ previousElement.nextElementSibling.scrollIntoView();
+ focusByWbr(previousElement.nextElementSibling, document.createRange());
+ }
+ });
+ }
+ }).element);
+ }
+
+ window.siyuan.menus.menu.append(new MenuItem({id: "separator_2", type: "separator"}).element);
+ }
// 复制带子标题
window.siyuan.menus.menu.append(new MenuItem({
@@ -1082,28 +1084,66 @@ export class Outline extends Model {
}
}).element);
- // 剪切带子标题
- window.siyuan.menus.menu.append(new MenuItem({
- id: "cutHeadings1",
- icon: "iconCut",
- label: `${window.siyuan.languages.cut} ${window.siyuan.languages.headings1}`,
- click: () => {
- const data = this.getProtyleAndBlockElement(element);
- fetchPost("/api/block/getHeadingChildrenDOM", {
- id,
- removeFoldAttr: data.blockElement.getAttribute("fold") !== "1"
- }, (response) => {
- if (isInAndroid()) {
- window.JSAndroid.writeHTMLClipboard(data.protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
- } else if (isInHarmony()) {
- window.JSHarmony.writeHTMLClipboard(data.protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
- } else {
- writeText(response.data + Constants.ZWSP);
- }
+ if (!window.siyuan.config.readonly) {
+ // 剪切带子标题
+ window.siyuan.menus.menu.append(new MenuItem({
+ id: "cutHeadings1",
+ icon: "iconCut",
+ label: `${window.siyuan.languages.cut} ${window.siyuan.languages.headings1}`,
+ click: () => {
+ const data = this.getProtyleAndBlockElement(element);
+ fetchPost("/api/block/getHeadingChildrenDOM", {
+ id,
+ removeFoldAttr: data.blockElement.getAttribute("fold") !== "1"
+ }, (response) => {
+ if (isInAndroid()) {
+ window.JSAndroid.writeHTMLClipboard(data.protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
+ } else if (isInHarmony()) {
+ window.JSHarmony.writeHTMLClipboard(data.protyle.lute.BlockDOM2StdMd(response.data).trimEnd(), response.data + Constants.ZWSP);
+ } else {
+ writeText(response.data + Constants.ZWSP);
+ }
+ fetchPost("/api/block/getHeadingDeleteTransaction", {
+ id,
+ }, (deleteResponse) => {
+ deleteResponse.data.doOperations.forEach((operation: IOperation) => {
+ data.protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${operation.id}"]`).forEach((itemElement: HTMLElement) => {
+ itemElement.remove();
+ });
+ });
+ if (data.protyle.wysiwyg.element.childElementCount === 0) {
+ const newID = Lute.NewNodeID();
+ const emptyElement = genEmptyElement(false, false, newID);
+ data.protyle.wysiwyg.element.insertAdjacentElement("afterbegin", emptyElement);
+ deleteResponse.data.doOperations.push({
+ action: "insert",
+ data: emptyElement.outerHTML,
+ id: newID,
+ parentID: data.protyle.block.parentID
+ });
+ deleteResponse.data.undoOperations.push({
+ action: "delete",
+ id: newID,
+ });
+ focusBlock(emptyElement);
+ }
+ transaction(data.protyle, deleteResponse.data.doOperations, deleteResponse.data.undoOperations);
+ });
+ });
+ }
+ }).element);
+
+ // 删除
+ window.siyuan.menus.menu.append(new MenuItem({
+ id: "deleteHeadings1",
+ icon: "iconTrashcan",
+ label: `${window.siyuan.languages.delete} ${window.siyuan.languages.headings1}`,
+ click: () => {
+ const data = this.getProtyleAndBlockElement(element);
fetchPost("/api/block/getHeadingDeleteTransaction", {
id,
- }, (deleteResponse) => {
- deleteResponse.data.doOperations.forEach((operation: IOperation) => {
+ }, (response) => {
+ response.data.doOperations.forEach((operation: IOperation) => {
data.protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${operation.id}"]`).forEach((itemElement: HTMLElement) => {
itemElement.remove();
});
@@ -1112,60 +1152,23 @@ export class Outline extends Model {
const newID = Lute.NewNodeID();
const emptyElement = genEmptyElement(false, false, newID);
data.protyle.wysiwyg.element.insertAdjacentElement("afterbegin", emptyElement);
- deleteResponse.data.doOperations.push({
+ response.data.doOperations.push({
action: "insert",
data: emptyElement.outerHTML,
id: newID,
parentID: data.protyle.block.parentID
});
- deleteResponse.data.undoOperations.push({
+ response.data.undoOperations.push({
action: "delete",
id: newID,
});
focusBlock(emptyElement);
}
- transaction(data.protyle, deleteResponse.data.doOperations, deleteResponse.data.undoOperations);
+ transaction(data.protyle, response.data.doOperations, response.data.undoOperations);
});
- });
- }
- }).element);
-
- // 删除
- window.siyuan.menus.menu.append(new MenuItem({
- id: "deleteHeadings1",
- icon: "iconTrashcan",
- label: `${window.siyuan.languages.delete} ${window.siyuan.languages.headings1}`,
- click: () => {
- const data = this.getProtyleAndBlockElement(element);
- fetchPost("/api/block/getHeadingDeleteTransaction", {
- id,
- }, (response) => {
- response.data.doOperations.forEach((operation: IOperation) => {
- data.protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${operation.id}"]`).forEach((itemElement: HTMLElement) => {
- itemElement.remove();
- });
- });
- if (data.protyle.wysiwyg.element.childElementCount === 0) {
- const newID = Lute.NewNodeID();
- const emptyElement = genEmptyElement(false, false, newID);
- data.protyle.wysiwyg.element.insertAdjacentElement("afterbegin", emptyElement);
- response.data.doOperations.push({
- action: "insert",
- data: emptyElement.outerHTML,
- id: newID,
- parentID: data.protyle.block.parentID
- });
- response.data.undoOperations.push({
- action: "delete",
- id: newID,
- });
- focusBlock(emptyElement);
- }
- transaction(data.protyle, response.data.doOperations, response.data.undoOperations);
- });
- }
- }).element);
-
+ }
+ }).element);
+ }
window.siyuan.menus.menu.append(new MenuItem({id: "separator_3", type: "separator"}).element);
// 展开子标题