mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 14:40:12 +01:00
This commit is contained in:
parent
3f9e6d0eaa
commit
9dba5dbb4a
1 changed files with 208 additions and 205 deletions
|
|
@ -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 = `<div data-subtype="h${currentLevel}" data-node-id="${newId}" data-type="NodeHeading" class="h${currentLevel}"><div contenteditable="true" spellcheck="false"><wbr></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
|
||||
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 = `<div data-subtype="h${currentLevel}" data-node-id="${newId}" data-type="NodeHeading" class="h${currentLevel}"><div contenteditable="true" spellcheck="false"><wbr></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
|
||||
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 = `<div data-subtype="h${currentLevel + 1}" data-node-id="${newId}" data-type="NodeHeading" class="h${currentLevel + 1}"><div contenteditable="true" spellcheck="false"><wbr></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
|
||||
const html = `<div data-subtype="h${currentLevel}" data-node-id="${newId}" data-type="NodeHeading" class="h${currentLevel}"><div contenteditable="true" spellcheck="false"><wbr></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
|
||||
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 = `<div data-subtype="h${currentLevel + 1}" data-node-id="${newId}" data-type="NodeHeading" class="h${currentLevel + 1}"><div contenteditable="true" spellcheck="false"><wbr></div><div class="protyle-attr" contenteditable="false">${Constants.ZWSP}</div></div>`;
|
||||
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);
|
||||
|
||||
// 展开子标题
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue