mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-01 06:18:49 +01:00
This commit is contained in:
parent
bb1314c66f
commit
bd264d7104
6 changed files with 179 additions and 123 deletions
|
|
@ -730,7 +730,7 @@
|
|||
"insertImgURL": "插入图片链接",
|
||||
"insertIframeURL": "插入 IFrame 链接",
|
||||
"context": "上下文",
|
||||
"dockTip": "\n单击 展开/最小化\n右键 调整位置",
|
||||
"dockTip": "\n单击 <span class='ft__on-surface ft__nowrap'>展开/最小化</span>\n右键/拖拽 <span class='ft__on-surface ft__nowrap'>调整位置</span>",
|
||||
"shadow": "投影",
|
||||
"hollow": "镂空",
|
||||
"attrValue1": "属性值留空则会自动删除该属性",
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ export const globalClick = (event: MouseEvent & { target: HTMLElement }) => {
|
|||
if (ghostElement.dataset.ghostType === "dock") {
|
||||
ghostElement.parentElement.querySelectorAll(".dock__item").forEach((item: HTMLElement) => {
|
||||
item.style.opacity = "";
|
||||
item.classList.add("b3-tooltips");
|
||||
});
|
||||
document.querySelector("#dockMoveItem")?.remove();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ export class Dock {
|
|||
}
|
||||
}
|
||||
if (!showDock) {
|
||||
this.element.firstElementChild.innerHTML = `<span class="dock__item dock__item--pin b3-tooltips b3-tooltips__${this.getClassDirect(0)}" aria-label="${this.pin ? window.siyuan.languages.unpin : window.siyuan.languages.pin}">
|
||||
this.element.firstElementChild.innerHTML = `<span class="dock__item dock__item--pin ariaLabel" aria-label="${this.pin ? window.siyuan.languages.unpin : window.siyuan.languages.pin}">
|
||||
<svg><use xlink:href="#icon${this.pin ? "Unpin" : "Pin"}"></use></svg>
|
||||
</span>`;
|
||||
this.element.classList.add("fn__none");
|
||||
|
|
@ -157,7 +157,6 @@ export class Dock {
|
|||
moveEvent.stopPropagation();
|
||||
if (!ghostElement) {
|
||||
item.style.opacity = "0.38";
|
||||
item.classList.remove("b3-tooltips");
|
||||
ghostElement = item.cloneNode(true) as HTMLElement;
|
||||
ghostElement.setAttribute("data-ghost-type", "dock");
|
||||
this.element.append(ghostElement);
|
||||
|
|
@ -281,11 +280,10 @@ export class Dock {
|
|||
documentSelf.onselectstart = null;
|
||||
documentSelf.onselect = null;
|
||||
ghostElement?.remove();
|
||||
if (item.classList.contains("b3-tooltips")) {
|
||||
if (item.style.opacity !== "0.38") {
|
||||
return;
|
||||
}
|
||||
item.style.opacity = "";
|
||||
item.classList.add("b3-tooltips");
|
||||
if (!moveItem.classList.contains("fn__none")) {
|
||||
let dock;
|
||||
if (moveItem.parentElement.parentElement.id === "dockBottom") {
|
||||
|
|
@ -773,8 +771,6 @@ export class Dock {
|
|||
delete sourceDock.data[type];
|
||||
|
||||
// 目标处理
|
||||
sourceElement.classList.remove("b3-tooltips__n", "b3-tooltips__ne", "b3-tooltips__nw", "b3-tooltips__s", "b3-tooltips__se", "b3-tooltips__sw", "b3-tooltips__e", "b3-tooltips__w");
|
||||
sourceElement.classList.add(`b3-tooltips__${this.getClassDirect(index)}`);
|
||||
sourceElement.setAttribute("data-index", index.toString());
|
||||
if (previousType) {
|
||||
this.element.querySelector(`[data-type="${previousType}"]`).after(sourceElement);
|
||||
|
|
@ -804,23 +800,6 @@ export class Dock {
|
|||
delete this.data[key];
|
||||
}
|
||||
|
||||
private getClassDirect(index: number) {
|
||||
let direct = "e";
|
||||
switch (this.position) {
|
||||
case "Right":
|
||||
direct = "w";
|
||||
break;
|
||||
case "Bottom":
|
||||
if (index === 0) {
|
||||
direct = "ne";
|
||||
} else {
|
||||
direct = "nw";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return direct;
|
||||
}
|
||||
|
||||
public setSize() {
|
||||
const activesElement = this.element.querySelectorAll(".dock__item--active");
|
||||
activesElement.forEach((item) => {
|
||||
|
|
@ -860,7 +839,7 @@ export class Dock {
|
|||
if (typeof tabIndex === "undefined" && !TYPES.includes(item.type)) {
|
||||
return;
|
||||
}
|
||||
html += `<span data-height="${item.size.height}" data-width="${item.size.width}" data-type="${item.type}" data-index="${index}" data-hotkey="${item.hotkey || ""}" data-hotkeyLangId="${item.hotkeyLangId || ""}" data-title="${item.title}" class="dock__item${item.show ? " dock__item--active" : ""} b3-tooltips b3-tooltips__${this.getClassDirect(index)}" aria-label="${item.title} ${item.hotkey ? updateHotkeyTip(item.hotkey) : ""}${window.siyuan.languages.dockTip}">
|
||||
html += `<span data-height="${item.size.height}" data-width="${item.size.width}" data-type="${item.type}" data-index="${index}" data-hotkey="${item.hotkey || ""}" data-hotkeyLangId="${item.hotkeyLangId || ""}" data-title="${item.title}" class="dock__item${item.show ? " dock__item--active" : ""} ariaLabel" aria-label="<span style='white-space:pre'>${item.title} ${item.hotkey ? updateHotkeyTip(item.hotkey) : ""}${window.siyuan.languages.dockTip}</span>">
|
||||
<svg><use xlink:href="#${item.icon}"></use></svg>
|
||||
</span>`;
|
||||
this.data[item.type] = true;
|
||||
|
|
@ -873,7 +852,7 @@ export class Dock {
|
|||
this.element.firstElementChild.lastElementChild.insertAdjacentHTML("beforebegin", html);
|
||||
}
|
||||
} else {
|
||||
this.element.firstElementChild.innerHTML = `${html}<span class="dock__item dock__item--pin b3-tooltips b3-tooltips__${this.getClassDirect(index)}" aria-label="${this.pin ? window.siyuan.languages.unpin : window.siyuan.languages.pin}">
|
||||
this.element.firstElementChild.innerHTML = `${html}<span class="dock__item dock__item--pin ariaLabel" aria-label="${this.pin ? window.siyuan.languages.unpin : window.siyuan.languages.pin}">
|
||||
<svg><use xlink:href="#icon${this.pin ? "Unpin" : "Pin"}"></use></svg>
|
||||
</span>`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,20 +14,19 @@ import {copyPlainText, isMac, isOnlyMeta, openByMobile, updateHotkeyTip, writeTe
|
|||
import {
|
||||
transaction,
|
||||
turnsIntoOneTransaction,
|
||||
turnsIntoTransaction,
|
||||
turnsIntoTransaction, turnsOneInto,
|
||||
updateBatchTransaction,
|
||||
updateTransaction
|
||||
} from "../wysiwyg/transaction";
|
||||
import {removeBlock} from "../wysiwyg/remove";
|
||||
import {focusBlock, focusByRange, focusByWbr, getEditorRange} from "../util/selection";
|
||||
import {focusBlock, focusByRange, getEditorRange} from "../util/selection";
|
||||
import {hideElements} from "../ui/hideElements";
|
||||
import {processRender} from "../util/processCode";
|
||||
import {highlightRender} from "../render/highlightRender";
|
||||
import {blockRender} from "../render/blockRender";
|
||||
import {removeEmbed} from "../wysiwyg/removeEmbed";
|
||||
import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../wysiwyg/getBlock";
|
||||
import * as dayjs from "dayjs";
|
||||
import {fetchPost, fetchSyncPost} from "../../util/fetch";
|
||||
import {fetchPost} from "../../util/fetch";
|
||||
import {
|
||||
cancelSB,
|
||||
genEmptyElement,
|
||||
|
|
@ -449,91 +448,8 @@ export class Gutter {
|
|||
icon: options.icon,
|
||||
label: options.label,
|
||||
accelerator: options.accelerator,
|
||||
async click() {
|
||||
if (!options.nodeElement.querySelector("wbr")) {
|
||||
getContenteditableElement(options.nodeElement)?.insertAdjacentHTML("afterbegin", "<wbr>");
|
||||
}
|
||||
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
|
||||
for await(const item of options.nodeElement.querySelectorAll('[data-type="NodeHeading"][fold="1"]')) {
|
||||
const itemId = item.getAttribute("data-node-id");
|
||||
item.removeAttribute("fold");
|
||||
const response = await fetchSyncPost("/api/transactions", {
|
||||
session: options.protyle.id,
|
||||
app: Constants.SIYUAN_APPID,
|
||||
transactions: [{
|
||||
doOperations: [{
|
||||
action: "unfoldHeading",
|
||||
id: itemId,
|
||||
}],
|
||||
undoOperations: [{
|
||||
action: "foldHeading",
|
||||
id: itemId
|
||||
}],
|
||||
}]
|
||||
});
|
||||
options.protyle.undo.add([{
|
||||
action: "unfoldHeading",
|
||||
id: itemId,
|
||||
}], [{
|
||||
action: "foldHeading",
|
||||
id: itemId
|
||||
}], options.protyle);
|
||||
item.insertAdjacentHTML("afterend", response.data[0].doOperations[0].retData);
|
||||
}
|
||||
}
|
||||
const oldHTML = options.nodeElement.outerHTML;
|
||||
const previousId = options.nodeElement.previousElementSibling?.getAttribute("data-node-id");
|
||||
const parentId = options.nodeElement.parentElement.getAttribute("data-node-id") || options.protyle.block.parentID;
|
||||
// @ts-ignore
|
||||
const newHTML = options.protyle.lute[options.type](options.nodeElement.outerHTML, options.level);
|
||||
options.nodeElement.outerHTML = newHTML;
|
||||
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
|
||||
const tempElement = document.createElement("template");
|
||||
tempElement.innerHTML = newHTML;
|
||||
const doOperations: IOperation[] = [{
|
||||
action: "delete",
|
||||
id: options.id
|
||||
}];
|
||||
const undoOperations: IOperation[] = [];
|
||||
let tempPreviousId = previousId;
|
||||
Array.from(tempElement.content.children).forEach((item) => {
|
||||
const tempId = item.getAttribute("data-node-id");
|
||||
doOperations.push({
|
||||
action: "insert",
|
||||
data: item.outerHTML,
|
||||
id: tempId,
|
||||
previousID: tempPreviousId,
|
||||
parentID: parentId
|
||||
});
|
||||
undoOperations.push({
|
||||
action: "delete",
|
||||
id: tempId
|
||||
});
|
||||
tempPreviousId = tempId;
|
||||
});
|
||||
undoOperations.push({
|
||||
action: "insert",
|
||||
data: oldHTML,
|
||||
id: options.id,
|
||||
previousID: previousId,
|
||||
parentID: parentId
|
||||
});
|
||||
transaction(options.protyle, doOperations, undoOperations);
|
||||
} else {
|
||||
updateTransaction(options.protyle, options.id, newHTML, oldHTML);
|
||||
}
|
||||
focusByWbr(options.protyle.wysiwyg.element, getEditorRange(options.protyle.wysiwyg.element));
|
||||
options.protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => {
|
||||
if (item.textContent === "") {
|
||||
fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => {
|
||||
item.innerHTML = response.data;
|
||||
});
|
||||
}
|
||||
});
|
||||
blockRender(options.protyle, options.protyle.wysiwyg.element);
|
||||
processRender(options.protyle.wysiwyg.element);
|
||||
highlightRender(options.protyle.wysiwyg.element);
|
||||
avRender(options.protyle.wysiwyg.element, options.protyle);
|
||||
click() {
|
||||
turnsOneInto(options);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,13 @@ import {
|
|||
import {matchHotKey} from "../util/hotKey";
|
||||
import {enter, softEnter} from "./enter";
|
||||
import {fixTable} from "../util/table";
|
||||
import {turnsIntoOneTransaction, turnsIntoTransaction, updateBatchTransaction, updateTransaction} from "./transaction";
|
||||
import {
|
||||
turnsIntoOneTransaction,
|
||||
turnsIntoTransaction,
|
||||
turnsOneInto,
|
||||
updateBatchTransaction,
|
||||
updateTransaction
|
||||
} from "./transaction";
|
||||
import {fontEvent} from "../toolbar/Font";
|
||||
import {addSubList, listIndent, listOutdent} from "./list";
|
||||
import {newFileContentBySelect, rename, replaceFileName} from "../../editor/rename";
|
||||
|
|
@ -1330,10 +1336,73 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (matchHotKey(window.siyuan.config.keymap.editor.insert.check.custom, event)) {
|
||||
protyle.hint.splitChar = "/";
|
||||
protyle.hint.lastIndex = -1;
|
||||
protyle.hint.fill("* [ ] " + Lute.Caret, protyle);
|
||||
const isMatchList = matchHotKey(window.siyuan.config.keymap.editor.insert.list.custom, event)
|
||||
const isMatchCheck = matchHotKey(window.siyuan.config.keymap.editor.insert.check.custom, event)
|
||||
const isMatchOList = matchHotKey(window.siyuan.config.keymap.editor.insert["ordered-list"].custom, event)
|
||||
if (isMatchList || isMatchOList || isMatchCheck) {
|
||||
const selectsElement: HTMLElement[] = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
|
||||
if (selectsElement.length === 0) {
|
||||
protyle.hint.splitChar = "/";
|
||||
protyle.hint.lastIndex = -1;
|
||||
protyle.hint.fill((isMatchCheck ? "* [ ] " : (isMatchList ? "* " : "1. ")) + Lute.Caret, protyle);
|
||||
} else if (selectsElement.length === 1) {
|
||||
const subType = selectsElement[0].dataset.subtype
|
||||
const type = selectsElement[0].dataset.type
|
||||
if (type === "NodeParagraph") {
|
||||
turnsIntoOneTransaction({
|
||||
protyle,
|
||||
selectsElement,
|
||||
type: isMatchCheck ? "Blocks2TLs" : (isMatchList ? "Blocks2ULs" : "Blocks2OLs")
|
||||
});
|
||||
} else if (type === "NodeList") {
|
||||
const id = selectsElement[0].dataset.nodeId
|
||||
if (subType === "o" && (isMatchList || isMatchCheck)) {
|
||||
turnsOneInto({
|
||||
protyle,
|
||||
nodeElement: selectsElement[0],
|
||||
id,
|
||||
type: isMatchCheck ? "UL2TL" : "OL2UL",
|
||||
});
|
||||
} else if (subType === "t" && (isMatchList || isMatchOList)) {
|
||||
turnsOneInto({
|
||||
protyle,
|
||||
nodeElement: selectsElement[0],
|
||||
id,
|
||||
type: isMatchList ? "TL2UL" : "TL2OL",
|
||||
});
|
||||
} else if (isMatchCheck || isMatchOList) {
|
||||
turnsOneInto({
|
||||
protyle,
|
||||
nodeElement: selectsElement[0],
|
||||
id,
|
||||
type: isMatchCheck ? "OL2TL" : "UL2OL",
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let isList = false;
|
||||
let isContinue = false;
|
||||
selectsElement.find((item, index) => {
|
||||
if (item.classList.contains("li")) {
|
||||
isList = true;
|
||||
return true;
|
||||
}
|
||||
if (item.nextElementSibling && selectsElement[index + 1] &&
|
||||
item.nextElementSibling.isSameNode(selectsElement[index + 1])) {
|
||||
isContinue = true;
|
||||
} else if (index !== selectsElement.length - 1) {
|
||||
isContinue = false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (!isList && isContinue) {
|
||||
turnsIntoOneTransaction({
|
||||
protyle,
|
||||
selectsElement,
|
||||
type: isMatchCheck ? "Blocks2TLs" : (isMatchList ? "Blocks2ULs" : "Blocks2OLs")
|
||||
});
|
||||
}
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import {fetchPost} from "../../util/fetch";
|
||||
import {fetchPost, fetchSyncPost} from "../../util/fetch";
|
||||
import {focusBlock, focusByWbr, focusSideBlock, getEditorRange} from "../util/selection";
|
||||
import {getTopAloneElement} from "./getBlock";
|
||||
import {getContenteditableElement, getTopAloneElement} from "./getBlock";
|
||||
import {Constants} from "../../constants";
|
||||
import {blockRender} from "../render/blockRender";
|
||||
import {processRender} from "../util/processCode";
|
||||
|
|
@ -1025,6 +1025,99 @@ export const turnsIntoTransaction = (options: {
|
|||
hideElements(["gutter"], options.protyle);
|
||||
};
|
||||
|
||||
export const turnsOneInto = async (options: {
|
||||
protyle: IProtyle,
|
||||
nodeElement: Element,
|
||||
id: string,
|
||||
type: string,
|
||||
level?: number
|
||||
}) => {
|
||||
if (!options.nodeElement.querySelector("wbr")) {
|
||||
getContenteditableElement(options.nodeElement)?.insertAdjacentHTML("afterbegin", "<wbr>");
|
||||
}
|
||||
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
|
||||
for await(const item of options.nodeElement.querySelectorAll('[data-type="NodeHeading"][fold="1"]')) {
|
||||
const itemId = item.getAttribute("data-node-id");
|
||||
item.removeAttribute("fold");
|
||||
const response = await fetchSyncPost("/api/transactions", {
|
||||
session: options.protyle.id,
|
||||
app: Constants.SIYUAN_APPID,
|
||||
transactions: [{
|
||||
doOperations: [{
|
||||
action: "unfoldHeading",
|
||||
id: itemId,
|
||||
}],
|
||||
undoOperations: [{
|
||||
action: "foldHeading",
|
||||
id: itemId
|
||||
}],
|
||||
}]
|
||||
});
|
||||
options.protyle.undo.add([{
|
||||
action: "unfoldHeading",
|
||||
id: itemId,
|
||||
}], [{
|
||||
action: "foldHeading",
|
||||
id: itemId
|
||||
}], options.protyle);
|
||||
item.insertAdjacentHTML("afterend", response.data[0].doOperations[0].retData);
|
||||
}
|
||||
}
|
||||
const oldHTML = options.nodeElement.outerHTML;
|
||||
const previousId = options.nodeElement.previousElementSibling?.getAttribute("data-node-id");
|
||||
const parentId = options.nodeElement.parentElement.getAttribute("data-node-id") || options.protyle.block.parentID;
|
||||
// @ts-ignore
|
||||
const newHTML = options.protyle.lute[options.type](options.nodeElement.outerHTML, options.level);
|
||||
options.nodeElement.outerHTML = newHTML;
|
||||
if (options.type === "CancelList" || options.type === "CancelBlockquote") {
|
||||
const tempElement = document.createElement("template");
|
||||
tempElement.innerHTML = newHTML;
|
||||
const doOperations: IOperation[] = [{
|
||||
action: "delete",
|
||||
id: options.id
|
||||
}];
|
||||
const undoOperations: IOperation[] = [];
|
||||
let tempPreviousId = previousId;
|
||||
Array.from(tempElement.content.children).forEach((item) => {
|
||||
const tempId = item.getAttribute("data-node-id");
|
||||
doOperations.push({
|
||||
action: "insert",
|
||||
data: item.outerHTML,
|
||||
id: tempId,
|
||||
previousID: tempPreviousId,
|
||||
parentID: parentId
|
||||
});
|
||||
undoOperations.push({
|
||||
action: "delete",
|
||||
id: tempId
|
||||
});
|
||||
tempPreviousId = tempId;
|
||||
});
|
||||
undoOperations.push({
|
||||
action: "insert",
|
||||
data: oldHTML,
|
||||
id: options.id,
|
||||
previousID: previousId,
|
||||
parentID: parentId
|
||||
});
|
||||
transaction(options.protyle, doOperations, undoOperations);
|
||||
} else {
|
||||
updateTransaction(options.protyle, options.id, newHTML, oldHTML);
|
||||
}
|
||||
focusByWbr(options.protyle.wysiwyg.element, getEditorRange(options.protyle.wysiwyg.element));
|
||||
options.protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => {
|
||||
if (item.textContent === "") {
|
||||
fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => {
|
||||
item.innerHTML = response.data;
|
||||
});
|
||||
}
|
||||
});
|
||||
blockRender(options.protyle, options.protyle.wysiwyg.element);
|
||||
processRender(options.protyle.wysiwyg.element);
|
||||
highlightRender(options.protyle.wysiwyg.element);
|
||||
avRender(options.protyle.wysiwyg.element, options.protyle);
|
||||
}
|
||||
|
||||
const updateRef = (protyle: IProtyle, id: string, index = 0) => {
|
||||
if (index > 6) {
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue