mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-21 17:10:12 +01:00
✨ https://github.com/siyuan-note/siyuan/issues/8895 block attr
This commit is contained in:
parent
17055347db
commit
435ad45cb5
14 changed files with 258 additions and 186 deletions
|
|
@ -149,7 +149,7 @@ export const openFileWechatNotify = (protyle: IProtyle) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const openFileAttr = (attrs: IObject, focusName = "bookmark") => {
|
export const openFileAttr = (attrs: IObject, focusName = "bookmark", protyle?: IProtyle) => {
|
||||||
let customHTML = "";
|
let customHTML = "";
|
||||||
let notifyHTML = "";
|
let notifyHTML = "";
|
||||||
let hasAV = false;
|
let hasAV = false;
|
||||||
|
|
@ -187,7 +187,7 @@ export const openFileAttr = (attrs: IObject, focusName = "bookmark") => {
|
||||||
<span class="item__text">${window.siyuan.languages.builtIn}</span>
|
<span class="item__text">${window.siyuan.languages.builtIn}</span>
|
||||||
<span class="fn__flex-1"></span>
|
<span class="fn__flex-1"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item item--full${hasAV ? "" : " fn__none"}" data-type="av">
|
<div class="item item--full${hasAV ? "" : " fn__none"}" data-type="NodeAttributeView">
|
||||||
<span class="fn__flex-1"></span>
|
<span class="fn__flex-1"></span>
|
||||||
<span class="item__text">${window.siyuan.languages.database}</span>
|
<span class="item__text">${window.siyuan.languages.database}</span>
|
||||||
<span class="fn__flex-1"></span>
|
<span class="fn__flex-1"></span>
|
||||||
|
|
@ -225,7 +225,7 @@ export const openFileAttr = (attrs: IObject, focusName = "bookmark") => {
|
||||||
</label>
|
</label>
|
||||||
${notifyHTML}
|
${notifyHTML}
|
||||||
</div>
|
</div>
|
||||||
<div data-type="av" class="fn__none custom-attr"></div>
|
<div data-type="NodeAttributeView" class="fn__none custom-attr" data-av-id="${attrs["custom-avs"]}" data-node-id="${attrs.id}"></div>
|
||||||
<div data-type="custom" class="fn__none custom-attr">
|
<div data-type="custom" class="fn__none custom-attr">
|
||||||
${customHTML}
|
${customHTML}
|
||||||
<div class="b3-label">
|
<div class="b3-label">
|
||||||
|
|
@ -252,8 +252,8 @@ export const openFileAttr = (attrs: IObject, focusName = "bookmark") => {
|
||||||
target.classList.add("item--focus");
|
target.classList.add("item--focus");
|
||||||
dialog.element.querySelectorAll(".custom-attr").forEach((item: HTMLElement) => {
|
dialog.element.querySelectorAll(".custom-attr").forEach((item: HTMLElement) => {
|
||||||
if (item.dataset.type === target.dataset.type) {
|
if (item.dataset.type === target.dataset.type) {
|
||||||
if (item.dataset.type === "av" && item.innerHTML === "") {
|
if (item.dataset.type === "NodeAttributeView" && item.innerHTML === "") {
|
||||||
renderAVAttribute(item, attrs.id);
|
renderAVAttribute(item, attrs.id, protyle);
|
||||||
}
|
}
|
||||||
item.classList.remove("fn__none");
|
item.classList.remove("fn__none");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -349,13 +349,13 @@ export const openFileAttr = (attrs: IObject, focusName = "bookmark") => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const openAttr = (nodeElement: Element, focusName = "bookmark") => {
|
export const openAttr = (nodeElement: Element, focusName = "bookmark", protyle?: IProtyle) => {
|
||||||
if (nodeElement.getAttribute("data-type") === "NodeThematicBreak") {
|
if (nodeElement.getAttribute("data-type") === "NodeThematicBreak") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const id = nodeElement.getAttribute("data-node-id");
|
const id = nodeElement.getAttribute("data-node-id");
|
||||||
fetchPost("/api/attr/getBlockAttrs", {id}, (response) => {
|
fetchPost("/api/attr/getBlockAttrs", {id}, (response) => {
|
||||||
openFileAttr(response.data, focusName);
|
openFileAttr(response.data, focusName, protyle);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export class Breadcrumb {
|
||||||
fetchPost("/api/block/getDocInfo", {
|
fetchPost("/api/block/getDocInfo", {
|
||||||
id: protyle.block.rootID
|
id: protyle.block.rootID
|
||||||
}, (response) => {
|
}, (response) => {
|
||||||
openFileAttr(response.data.ial);
|
openFileAttr(response.data.ial, "bookmark", protyle);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const targetRect = target.getBoundingClientRect();
|
const targetRect = target.getBoundingClientRect();
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ export class Gutter {
|
||||||
}
|
}
|
||||||
foldElement.classList.remove("protyle-wysiwyg--hl");
|
foldElement.classList.remove("protyle-wysiwyg--hl");
|
||||||
} else if (window.siyuan.shiftIsPressed && !protyle.disabled) {
|
} else if (window.siyuan.shiftIsPressed && !protyle.disabled) {
|
||||||
openAttr(protyle.wysiwyg.element.querySelector(`[data-node-id="${id}"]`));
|
openAttr(protyle.wysiwyg.element.querySelector(`[data-node-id="${id}"]`), "bookmark", protyle);
|
||||||
} else {
|
} else {
|
||||||
this.renderMenu(protyle, buttonElement);
|
this.renderMenu(protyle, buttonElement);
|
||||||
// https://ld246.com/article/1648433751993
|
// https://ld246.com/article/1648433751993
|
||||||
|
|
@ -1478,7 +1478,7 @@ export class Gutter {
|
||||||
icon: "iconAttr",
|
icon: "iconAttr",
|
||||||
accelerator: window.siyuan.config.keymap.editor.general.attr.custom + "/" + updateHotkeyTip("⇧Click"),
|
accelerator: window.siyuan.config.keymap.editor.general.attr.custom + "/" + updateHotkeyTip("⇧Click"),
|
||||||
click() {
|
click() {
|
||||||
openAttr(nodeElement);
|
openAttr(nodeElement, "bookmark", protyle);
|
||||||
}
|
}
|
||||||
}).element);
|
}).element);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ export class Title {
|
||||||
fetchPost("/api/block/getDocInfo", {
|
fetchPost("/api/block/getDocInfo", {
|
||||||
id: protyle.block.rootID
|
id: protyle.block.rootID
|
||||||
}, (response) => {
|
}, (response) => {
|
||||||
openFileAttr(response.data.ial);
|
openFileAttr(response.data.ial, "bookmark", protyle);
|
||||||
});
|
});
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
@ -179,7 +179,7 @@ export class Title {
|
||||||
fetchPost("/api/block/getDocInfo", {
|
fetchPost("/api/block/getDocInfo", {
|
||||||
id: protyle.block.rootID
|
id: protyle.block.rootID
|
||||||
}, (response) => {
|
}, (response) => {
|
||||||
openFileAttr(response.data.ial);
|
openFileAttr(response.data.ial, "bookmark", protyle);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const iconRect = iconElement.getBoundingClientRect();
|
const iconRect = iconElement.getBoundingClientRect();
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ export const openTitleMenu = (protyle: IProtyle, position: {
|
||||||
icon: "iconAttr",
|
icon: "iconAttr",
|
||||||
accelerator: window.siyuan.config.keymap.editor.general.attr.custom + "/" + updateHotkeyTip("⇧Click"),
|
accelerator: window.siyuan.config.keymap.editor.general.attr.custom + "/" + updateHotkeyTip("⇧Click"),
|
||||||
click() {
|
click() {
|
||||||
openFileAttr(response.data.ial);
|
openFileAttr(response.data.ial, "bookmark", protyle);
|
||||||
}
|
}
|
||||||
}).element);
|
}).element);
|
||||||
window.siyuan.menus.menu.append(new MenuItem({
|
window.siyuan.menus.menu.append(new MenuItem({
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import {MenuItem} from "../../../menus/Menu";
|
||||||
import {exportAsset} from "../../../menus/util";
|
import {exportAsset} from "../../../menus/util";
|
||||||
import {setPosition} from "../../../util/setPosition";
|
import {setPosition} from "../../../util/setPosition";
|
||||||
import {previewImage} from "../../preview/image";
|
import {previewImage} from "../../preview/image";
|
||||||
|
import {genAVValueHTML} from "./blockAttr";
|
||||||
|
|
||||||
export const bindAssetEvent = (options: {
|
export const bindAssetEvent = (options: {
|
||||||
protyle: IProtyle,
|
protyle: IProtyle,
|
||||||
|
|
@ -104,14 +105,13 @@ export const updateAssetCell = (options: {
|
||||||
addUpdateValue?: IAVCellAssetValue[],
|
addUpdateValue?: IAVCellAssetValue[],
|
||||||
removeContent?: string
|
removeContent?: string
|
||||||
}) => {
|
}) => {
|
||||||
let cellIndex = 0;
|
let cellIndex: number;
|
||||||
Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||||
if (item.dataset.id === options.cellElements[0].dataset.id) {
|
if (item.dataset.id === options.cellElements[0].dataset.id) {
|
||||||
cellIndex = index;
|
cellIndex = index;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const colId = options.cellElements[0].dataset.colId;
|
const colId = options.cellElements[0].dataset.colId;
|
||||||
const cellDoOperations: IOperation[] = [];
|
const cellDoOperations: IOperation[] = [];
|
||||||
const cellUndoOperations: IOperation[] = [];
|
const cellUndoOperations: IOperation[] = [];
|
||||||
|
|
@ -121,11 +121,19 @@ export const updateAssetCell = (options: {
|
||||||
const rowID = item.parentElement.dataset.id;
|
const rowID = item.parentElement.dataset.id;
|
||||||
options.data.view.rows.find(row => {
|
options.data.view.rows.find(row => {
|
||||||
if (row.id === rowID) {
|
if (row.id === rowID) {
|
||||||
cellData = row.cells[cellIndex];
|
if (typeof cellIndex === "number") {
|
||||||
// 为空时 cellId 每次请求都不一致
|
cellData = row.cells[cellIndex];
|
||||||
cellData.id = item.dataset.id;
|
// 为空时 cellId 每次请求都不一致
|
||||||
if (!cellData.value || !cellData.value.mAsset) {
|
cellData.id = item.dataset.id;
|
||||||
cellData.value = {mAsset: []} as IAVCellValue;
|
if (!cellData.value || !cellData.value.mAsset) {
|
||||||
|
cellData.value = {mAsset: []} as IAVCellValue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cellData = row.cells.find(cellItem => {
|
||||||
|
if (cellItem.id === item.dataset.id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -188,14 +196,18 @@ export const updateAssetCell = (options: {
|
||||||
mAsset: oldValue
|
mAsset: oldValue
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
updateAttrViewCellAnimation(item);
|
if (item.classList.contains("custom-attr__avvalue")) {
|
||||||
|
item.innerHTML = genAVValueHTML(cellData.value)
|
||||||
|
} else {
|
||||||
|
updateAttrViewCellAnimation(item);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
transaction(options.protyle, cellDoOperations, cellUndoOperations);
|
transaction(options.protyle, cellDoOperations, cellUndoOperations);
|
||||||
const menuElement = document.querySelector(".av__panel > .b3-menu") as HTMLElement;
|
const menuElement = document.querySelector(".av__panel > .b3-menu") as HTMLElement;
|
||||||
if (menuElement) {
|
if (menuElement) {
|
||||||
menuElement.innerHTML = getAssetHTML(options.data.view, options.cellElements);
|
menuElement.innerHTML = getAssetHTML(options.data.view, options.cellElements);
|
||||||
bindAssetEvent({protyle: options.protyle, data: options.data, menuElement, cellElements: options.cellElements});
|
bindAssetEvent({protyle: options.protyle, data: options.data, menuElement, cellElements: options.cellElements});
|
||||||
const cellRect = options.protyle.wysiwyg.element.querySelector(`.av__cell[data-id="${options.cellElements[0].dataset.id}"]`).getBoundingClientRect();
|
const cellRect = (options.cellElements[0].classList.contains("custom-attr__avvalue") ? options.cellElements[0] : options.protyle.wysiwyg.element.querySelector(`.av__cell[data-id="${options.cellElements[0].dataset.id}"]`)).getBoundingClientRect();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
||||||
}, Constants.TIMEOUT_LOAD); // 等待图片加载
|
}, Constants.TIMEOUT_LOAD); // 等待图片加载
|
||||||
|
|
@ -251,7 +263,7 @@ export const editAssetItem = (protyle: IProtyle, data: IAV, cellElements: HTMLEl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
openMenu(protyle.app, linkAddress, false, true);
|
openMenu(protyle ? protyle.app : window.siyuan.ws.app, linkAddress, false, true);
|
||||||
/// #if !BROWSER
|
/// #if !BROWSER
|
||||||
if (linkAddress?.startsWith("assets/")) {
|
if (linkAddress?.startsWith("assets/")) {
|
||||||
window.siyuan.menus.menu.append(new MenuItem(exportAsset(linkAddress)).element);
|
window.siyuan.menus.menu.append(new MenuItem(exportAsset(linkAddress)).element);
|
||||||
|
|
@ -302,7 +314,7 @@ export const addAssetLink = (protyle: IProtyle, data: IAV, cellElements: HTMLEle
|
||||||
const rect = target.getBoundingClientRect();
|
const rect = target.getBoundingClientRect();
|
||||||
menu.open({
|
menu.open({
|
||||||
x: rect.right,
|
x: rect.right,
|
||||||
y: rect.bottom,
|
y: rect.top,
|
||||||
w: rect.width,
|
w: rect.width,
|
||||||
h: rect.height,
|
h: rect.height,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ import {hasClosestByAttribute} from "../../util/hasClosest";
|
||||||
import {Menu} from "../../../plugin/Menu";
|
import {Menu} from "../../../plugin/Menu";
|
||||||
import {Constants} from "../../../constants";
|
import {Constants} from "../../../constants";
|
||||||
import * as dayjs from "dayjs";
|
import * as dayjs from "dayjs";
|
||||||
|
import {popTextCell} from "./cell";
|
||||||
|
|
||||||
const genAVValueHTML = (value: IAVCellValue) => {
|
export const genAVValueHTML = (value: IAVCellValue) => {
|
||||||
let html = "";
|
let html = "";
|
||||||
switch (value.type) {
|
switch (value.type) {
|
||||||
case "text":
|
case "text":
|
||||||
|
|
@ -57,7 +58,156 @@ const genAVValueHTML = (value: IAVCellValue) => {
|
||||||
return html;
|
return html;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const renderAVAttribute = (element: HTMLElement, id: string) => {
|
const popDateMenu = (dateElement: HTMLElement) => {
|
||||||
|
const dateMenu = new Menu("custom-attr-av-date", () => {
|
||||||
|
const textElements = window.siyuan.menus.menu.element.querySelectorAll(".b3-text-field") as NodeListOf<HTMLInputElement>;
|
||||||
|
const hasEndDate = (window.siyuan.menus.menu.element.querySelector(".b3-switch") as HTMLInputElement).checked;
|
||||||
|
fetchPost("/api/av/setAttributeViewBlockAttr", {
|
||||||
|
avID: dateElement.dataset.avId,
|
||||||
|
keyID: dateElement.dataset.colId,
|
||||||
|
rowID: dateElement.dataset.blockId,
|
||||||
|
cellID: dateElement.dataset.id,
|
||||||
|
value: {
|
||||||
|
date: {
|
||||||
|
isNotEmpty: textElements[0].value !== "",
|
||||||
|
isNotEmpty2: textElements[1].value !== "",
|
||||||
|
content: new Date(textElements[0].value).getTime(),
|
||||||
|
content2: new Date(textElements[1].value).getTime(),
|
||||||
|
hasEndDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let dataHTML = "";
|
||||||
|
if (textElements[0].value !== "") {
|
||||||
|
dataHTML = `<span data-content="${new Date(textElements[0].value).getTime()}">${dayjs(textElements[0].value).format("YYYY-MM-DD HH:mm")}</span>`;
|
||||||
|
}
|
||||||
|
if (hasEndDate && textElements[0].value !== "" && textElements[1].value !== "") {
|
||||||
|
dataHTML += `<svg class="custom-attr__avarrow"><use xlink:href="#iconForward"></use></svg><span data-content="${new Date(textElements[1].value).getTime()}">${dayjs(textElements[1].value).format("YYYY-MM-DD HH:mm")}</span>`;
|
||||||
|
}
|
||||||
|
dateElement.innerHTML = dataHTML;
|
||||||
|
});
|
||||||
|
if (dateMenu.isOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const hasEndDate = dateElement.querySelector("svg");
|
||||||
|
const timeElements = dateElement.querySelectorAll("span");
|
||||||
|
dateMenu.addItem({
|
||||||
|
iconHTML: "",
|
||||||
|
label: `<input value="${timeElements[0] ? dayjs(parseInt(timeElements[0].dataset.content)).format("YYYY-MM-DDTHH:mm") : ""}" type="datetime-local" class="b3-text-field fn__size200" style="margin: 4px 0">`
|
||||||
|
});
|
||||||
|
dateMenu.addItem({
|
||||||
|
iconHTML: "",
|
||||||
|
label: `<input value="${timeElements[1] ? dayjs(parseInt(timeElements[1].dataset.content)).format("YYYY-MM-DDTHH:mm") : ""}" type="datetime-local" class="b3-text-field fn__size200${hasEndDate ? "" : " fn__none"}" style="margin: 4px 0">`
|
||||||
|
});
|
||||||
|
dateMenu.addSeparator();
|
||||||
|
dateMenu.addItem({
|
||||||
|
iconHTML: "",
|
||||||
|
label: `<label class="fn__flex">
|
||||||
|
<span>${window.siyuan.languages.endDate}</span>
|
||||||
|
<span class="fn__space fn__flex-1"></span>
|
||||||
|
<input type="checkbox" class="b3-switch fn__flex-center"${hasEndDate ? " checked" : ""}>
|
||||||
|
</label>`,
|
||||||
|
click(element, event) {
|
||||||
|
const switchElement = element.querySelector(".b3-switch") as HTMLInputElement;
|
||||||
|
if ((event.target as HTMLElement).tagName !== "INPUT") {
|
||||||
|
switchElement.checked = !switchElement.checked;
|
||||||
|
} else {
|
||||||
|
switchElement.outerHTML = `<input type="checkbox" class="b3-switch fn__flex-center"${switchElement.checked ? " checked" : ""}>`;
|
||||||
|
}
|
||||||
|
window.siyuan.menus.menu.element.querySelectorAll('[type="datetime-local"]')[1].classList.toggle("fn__none");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dateMenu.addSeparator();
|
||||||
|
dateMenu.addItem({
|
||||||
|
icon: "iconTrashcan",
|
||||||
|
label: window.siyuan.languages.clear,
|
||||||
|
click() {
|
||||||
|
const textElements = window.siyuan.menus.menu.element.querySelectorAll(".b3-text-field") as NodeListOf<HTMLInputElement>;
|
||||||
|
textElements[0].value = "";
|
||||||
|
textElements[1].value = "";
|
||||||
|
(window.siyuan.menus.menu.element.querySelector(".b3-switch") as HTMLInputElement).checked = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const datetRect = dateElement.getBoundingClientRect();
|
||||||
|
dateMenu.open({
|
||||||
|
x: datetRect.left,
|
||||||
|
y: datetRect.bottom
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const popSelectMenu = (mSelectElement: HTMLElement) => {
|
||||||
|
const mSelectMenu = new Menu("custom-attr-av-select", () => {
|
||||||
|
const mSelect: { content: string, color: string }[] = [];
|
||||||
|
let mSelectHTML = "";
|
||||||
|
window.siyuan.menus.menu.element.querySelectorAll(".svg").forEach(item => {
|
||||||
|
const chipElement = item.parentElement.previousElementSibling.firstElementChild as HTMLElement;
|
||||||
|
const content = chipElement.textContent.trim();
|
||||||
|
const color = chipElement.dataset.color;
|
||||||
|
mSelect.push({
|
||||||
|
content,
|
||||||
|
color
|
||||||
|
});
|
||||||
|
mSelectHTML += `<span class="b3-chip b3-chip--middle" style="background-color:var(--b3-font-background${color});color:var(--b3-font-color${color})">${content}</span>`;
|
||||||
|
});
|
||||||
|
fetchPost("/api/av/setAttributeViewBlockAttr", {
|
||||||
|
avID: mSelectElement.dataset.avId,
|
||||||
|
keyID: mSelectElement.dataset.colId,
|
||||||
|
rowID: mSelectElement.dataset.blockId,
|
||||||
|
cellID: mSelectElement.dataset.id,
|
||||||
|
value: {
|
||||||
|
mSelect
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mSelectElement.innerHTML = mSelectHTML;
|
||||||
|
});
|
||||||
|
if (mSelectMenu.isOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const names: string[] = [];
|
||||||
|
mSelectElement.querySelectorAll(".b3-chip").forEach(item => {
|
||||||
|
names.push(item.textContent.trim());
|
||||||
|
});
|
||||||
|
JSON.parse(mSelectElement.dataset.options || "").forEach((item: { name: string, color: string }) => {
|
||||||
|
mSelectMenu.addItem({
|
||||||
|
iconHTML: "",
|
||||||
|
label: `<span class="b3-chip" data-color="${item.color}" style="height:24px;background-color:var(--b3-font-background${item.color});color:var(--b3-font-color${item.color})">
|
||||||
|
<span class="fn__ellipsis">${item.name}</span>
|
||||||
|
</span>`,
|
||||||
|
accelerator: names.includes(item.name) ? '<svg class="svg" style="height: 30px; float: left;"><use xlink:href="#iconSelect"></use></svg>' : Constants.ZWSP,
|
||||||
|
click(element) {
|
||||||
|
const acceleratorElement = element.querySelector(".b3-menu__accelerator");
|
||||||
|
if (mSelectElement.dataset.type === "select") {
|
||||||
|
window.siyuan.menus.menu.element.querySelectorAll(".b3-menu__accelerator").forEach(itemElement => {
|
||||||
|
if (itemElement.isSameNode(acceleratorElement)) {
|
||||||
|
if (acceleratorElement.querySelector("svg")) {
|
||||||
|
acceleratorElement.innerHTML = "";
|
||||||
|
} else {
|
||||||
|
acceleratorElement.innerHTML = '<svg class="svg" style="height: 30px; float: left;"><use xlink:href="#iconSelect"></use></svg>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
itemElement.innerHTML = "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (acceleratorElement.querySelector("svg")) {
|
||||||
|
acceleratorElement.innerHTML = "";
|
||||||
|
} else {
|
||||||
|
acceleratorElement.innerHTML = '<svg class="svg" style="height: 30px; float: left;"><use xlink:href="#iconSelect"></use></svg>';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const mSelecttRect = mSelectElement.getBoundingClientRect();
|
||||||
|
mSelectMenu.open({
|
||||||
|
x: mSelecttRect.left,
|
||||||
|
y: mSelecttRect.bottom
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const renderAVAttribute = (element: HTMLElement, id: string, protyle?: IProtyle) => {
|
||||||
fetchPost("/api/av/getAttributeViewKeys", {id}, (response) => {
|
fetchPost("/api/av/getAttributeViewKeys", {id}, (response) => {
|
||||||
let html = "";
|
let html = "";
|
||||||
response.data.forEach((table: {
|
response.data.forEach((table: {
|
||||||
|
|
@ -77,12 +227,12 @@ export const renderAVAttribute = (element: HTMLElement, id: string) => {
|
||||||
<span>${table.avName || window.siyuan.languages.database}</span>
|
<span>${table.avName || window.siyuan.languages.database}</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
table.keyValues?.forEach(item => {
|
table.keyValues?.forEach(item => {
|
||||||
html += `<div class="block__icons">
|
html += `<div class="block__icons" data-id="${id}">
|
||||||
<div class="block__logo">
|
<div class="block__logo">
|
||||||
<svg><use xlink:href="#${getColIconByType(item.key.type)}"></use></svg>
|
<svg><use xlink:href="#${getColIconByType(item.key.type)}"></use></svg>
|
||||||
<span>${item.key.name}</span>
|
<span>${item.key.name}</span>
|
||||||
</div>
|
</div>
|
||||||
<div data-av-id="${table.avID}" data-key-id="${item.values[0].keyID}" data-block-id="${item.values[0].blockID}" data-id="${item.values[0].id}" data-type="${item.values[0].type}"
|
<div data-av-id="${table.avID}" data-col-id="${item.values[0].keyID}" data-block-id="${item.values[0].blockID}" data-id="${item.values[0].id}" data-type="${item.values[0].type}"
|
||||||
data-options="${item.key?.options ? escapeAttr(JSON.stringify(item.key.options)) : "[]"}"
|
data-options="${item.key?.options ? escapeAttr(JSON.stringify(item.key.options)) : "[]"}"
|
||||||
class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes(item.values[0].type) ? "" : " custom-attr__avvalue"}">
|
class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes(item.values[0].type) ? "" : " custom-attr__avvalue"}">
|
||||||
${genAVValueHTML(item.values[0])}
|
${genAVValueHTML(item.values[0])}
|
||||||
|
|
@ -95,155 +245,21 @@ class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes
|
||||||
const target = event.target as HTMLElement;
|
const target = event.target as HTMLElement;
|
||||||
const dateElement = hasClosestByAttribute(target, "data-type", "date");
|
const dateElement = hasClosestByAttribute(target, "data-type", "date");
|
||||||
if (dateElement) {
|
if (dateElement) {
|
||||||
const dateMenu = new Menu("custom-attr-av-date", () => {
|
popDateMenu(dateElement);
|
||||||
const textElements = window.siyuan.menus.menu.element.querySelectorAll(".b3-text-field") as NodeListOf<HTMLInputElement>;
|
|
||||||
const hasEndDate = (window.siyuan.menus.menu.element.querySelector(".b3-switch") as HTMLInputElement).checked;
|
|
||||||
fetchPost("/api/av/setAttributeViewBlockAttr", {
|
|
||||||
avID: dateElement.dataset.avId,
|
|
||||||
keyID: dateElement.dataset.keyId,
|
|
||||||
rowID: dateElement.dataset.blockId,
|
|
||||||
cellID: dateElement.dataset.id,
|
|
||||||
value: {
|
|
||||||
date: {
|
|
||||||
isNotEmpty: textElements[0].value !== "",
|
|
||||||
isNotEmpty2: textElements[1].value !== "",
|
|
||||||
content: new Date(textElements[0].value).getTime(),
|
|
||||||
content2: new Date(textElements[1].value).getTime(),
|
|
||||||
hasEndDate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let dataHTML = "";
|
|
||||||
if (textElements[0].value !== "") {
|
|
||||||
dataHTML = `<span data-content="${new Date(textElements[0].value).getTime()}">${dayjs(textElements[0].value).format("YYYY-MM-DD HH:mm")}</span>`;
|
|
||||||
}
|
|
||||||
if (hasEndDate && textElements[0].value !== "" && textElements[1].value !== "") {
|
|
||||||
dataHTML += `<svg class="custom-attr__avarrow"><use xlink:href="#iconForward"></use></svg><span data-content="${new Date(textElements[1].value).getTime()}">${dayjs(textElements[1].value).format("YYYY-MM-DD HH:mm")}</span>`;
|
|
||||||
}
|
|
||||||
dateElement.innerHTML = dataHTML;
|
|
||||||
});
|
|
||||||
if (dateMenu.isOpen) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const hasEndDate = dateElement.querySelector("svg");
|
|
||||||
const timeElements = dateElement.querySelectorAll("span");
|
|
||||||
dateMenu.addItem({
|
|
||||||
iconHTML: "",
|
|
||||||
label: `<input value="${timeElements[0] ? dayjs(parseInt(timeElements[0].dataset.content)).format("YYYY-MM-DDTHH:mm") : ""}" type="datetime-local" class="b3-text-field fn__size200" style="margin: 4px 0">`
|
|
||||||
});
|
|
||||||
dateMenu.addItem({
|
|
||||||
iconHTML: "",
|
|
||||||
label: `<input value="${timeElements[1] ? dayjs(parseInt(timeElements[1].dataset.content)).format("YYYY-MM-DDTHH:mm") : ""}" type="datetime-local" class="b3-text-field fn__size200${hasEndDate ? "" : " fn__none"}" style="margin: 4px 0">`
|
|
||||||
});
|
|
||||||
dateMenu.addSeparator();
|
|
||||||
dateMenu.addItem({
|
|
||||||
iconHTML: "",
|
|
||||||
label: `<label class="fn__flex">
|
|
||||||
<span>${window.siyuan.languages.endDate}</span>
|
|
||||||
<span class="fn__space fn__flex-1"></span>
|
|
||||||
<input type="checkbox" class="b3-switch fn__flex-center"${hasEndDate ? " checked" : ""}>
|
|
||||||
</label>`,
|
|
||||||
click(element, event) {
|
|
||||||
const switchElement = element.querySelector(".b3-switch") as HTMLInputElement;
|
|
||||||
if ((event.target as HTMLElement).tagName !== "INPUT") {
|
|
||||||
switchElement.checked = !switchElement.checked;
|
|
||||||
} else {
|
|
||||||
switchElement.outerHTML = `<input type="checkbox" class="b3-switch fn__flex-center"${switchElement.checked ? " checked" : ""}>`;
|
|
||||||
}
|
|
||||||
window.siyuan.menus.menu.element.querySelectorAll('[type="datetime-local"]')[1].classList.toggle("fn__none");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
dateMenu.addSeparator();
|
|
||||||
dateMenu.addItem({
|
|
||||||
icon: "iconTrashcan",
|
|
||||||
label: window.siyuan.languages.clear,
|
|
||||||
click() {
|
|
||||||
const textElements = window.siyuan.menus.menu.element.querySelectorAll(".b3-text-field") as NodeListOf<HTMLInputElement>;
|
|
||||||
textElements[0].value = "";
|
|
||||||
textElements[1].value = "";
|
|
||||||
(window.siyuan.menus.menu.element.querySelector(".b3-switch") as HTMLInputElement).checked = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const datetRect = dateElement.getBoundingClientRect();
|
|
||||||
dateMenu.open({
|
|
||||||
x: datetRect.left,
|
|
||||||
y: datetRect.bottom
|
|
||||||
});
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const mSelectElement = hasClosestByAttribute(target, "data-type", "select") || hasClosestByAttribute(target, "data-type", "mSelect");
|
const mSelectElement = hasClosestByAttribute(target, "data-type", "select") || hasClosestByAttribute(target, "data-type", "mSelect");
|
||||||
if (mSelectElement) {
|
if (mSelectElement) {
|
||||||
const mSelectMenu = new Menu("custom-attr-av-select", () => {
|
popSelectMenu(mSelectElement);
|
||||||
const mSelect: { content: string, color: string }[] = [];
|
event.stopPropagation();
|
||||||
let mSelectHTML = "";
|
event.preventDefault();
|
||||||
window.siyuan.menus.menu.element.querySelectorAll(".svg").forEach(item => {
|
return;
|
||||||
const chipElement = item.parentElement.previousElementSibling.firstElementChild as HTMLElement;
|
}
|
||||||
const content = chipElement.textContent.trim();
|
const mAssetElement = hasClosestByAttribute(target, "data-type", "mAsset");
|
||||||
const color = chipElement.dataset.color;
|
if (mAssetElement) {
|
||||||
mSelect.push({
|
popTextCell(protyle, [mAssetElement], "mAsset");
|
||||||
content,
|
|
||||||
color
|
|
||||||
});
|
|
||||||
mSelectHTML += `<span class="b3-chip b3-chip--middle" style="background-color:var(--b3-font-background${color});color:var(--b3-font-color${color})">${content}</span>`;
|
|
||||||
});
|
|
||||||
fetchPost("/api/av/setAttributeViewBlockAttr", {
|
|
||||||
avID: mSelectElement.dataset.avId,
|
|
||||||
keyID: mSelectElement.dataset.keyId,
|
|
||||||
rowID: mSelectElement.dataset.blockId,
|
|
||||||
cellID: mSelectElement.dataset.id,
|
|
||||||
value: {
|
|
||||||
mSelect
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mSelectElement.innerHTML = mSelectHTML;
|
|
||||||
});
|
|
||||||
if (mSelectMenu.isOpen) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const names: string[] = [];
|
|
||||||
mSelectElement.querySelectorAll(".b3-chip").forEach(item => {
|
|
||||||
names.push(item.textContent.trim());
|
|
||||||
});
|
|
||||||
JSON.parse(mSelectElement.dataset.options || "").forEach((item: { name: string, color: string }) => {
|
|
||||||
mSelectMenu.addItem({
|
|
||||||
iconHTML: "",
|
|
||||||
label: `<span class="b3-chip" data-color="${item.color}" style="height:24px;background-color:var(--b3-font-background${item.color});color:var(--b3-font-color${item.color})">
|
|
||||||
<span class="fn__ellipsis">${item.name}</span>
|
|
||||||
</span>`,
|
|
||||||
accelerator: names.includes(item.name) ? '<svg class="svg" style="height: 30px; float: left;"><use xlink:href="#iconSelect"></use></svg>' : Constants.ZWSP,
|
|
||||||
click(element) {
|
|
||||||
const acceleratorElement = element.querySelector(".b3-menu__accelerator");
|
|
||||||
if (mSelectElement.dataset.type === "select") {
|
|
||||||
window.siyuan.menus.menu.element.querySelectorAll(".b3-menu__accelerator").forEach(itemElement => {
|
|
||||||
if (itemElement.isSameNode(acceleratorElement)) {
|
|
||||||
if (acceleratorElement.querySelector("svg")) {
|
|
||||||
acceleratorElement.innerHTML = "";
|
|
||||||
} else {
|
|
||||||
acceleratorElement.innerHTML = '<svg class="svg" style="height: 30px; float: left;"><use xlink:href="#iconSelect"></use></svg>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
itemElement.innerHTML = "";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (acceleratorElement.querySelector("svg")) {
|
|
||||||
acceleratorElement.innerHTML = "";
|
|
||||||
} else {
|
|
||||||
acceleratorElement.innerHTML = '<svg class="svg" style="height: 30px; float: left;"><use xlink:href="#iconSelect"></use></svg>';
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
const mSelecttRect = mSelectElement.getBoundingClientRect();
|
|
||||||
mSelectMenu.open({
|
|
||||||
x: mSelecttRect.left,
|
|
||||||
y: mSelecttRect.bottom
|
|
||||||
});
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return;
|
return;
|
||||||
|
|
@ -267,7 +283,7 @@ class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes
|
||||||
}
|
}
|
||||||
fetchPost("/api/av/setAttributeViewBlockAttr", {
|
fetchPost("/api/av/setAttributeViewBlockAttr", {
|
||||||
avID: item.parentElement.dataset.avId,
|
avID: item.parentElement.dataset.avId,
|
||||||
keyID: item.parentElement.dataset.keyId,
|
keyID: item.parentElement.dataset.colId,
|
||||||
rowID: item.parentElement.dataset.blockId,
|
rowID: item.parentElement.dataset.blockId,
|
||||||
cellID: item.parentElement.dataset.id,
|
cellID: item.parentElement.dataset.id,
|
||||||
value
|
value
|
||||||
|
|
|
||||||
|
|
@ -339,8 +339,10 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
|
||||||
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
|
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[]) => {
|
export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type?: TAVCol) => {
|
||||||
const type = cellElements[0].parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElements[0].getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
if (!type) {
|
||||||
|
type = cellElements[0].parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElements[0].getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
||||||
|
}
|
||||||
if (type === "block") {
|
if (type === "block") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export const openMenuPanel = (options: {
|
||||||
</div>`);
|
</div>`);
|
||||||
avPanelElement = document.querySelector(".av__panel");
|
avPanelElement = document.querySelector(".av__panel");
|
||||||
const menuElement = avPanelElement.lastElementChild as HTMLElement;
|
const menuElement = avPanelElement.lastElementChild as HTMLElement;
|
||||||
const tabRect = options.blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
|
const tabRect = options.blockElement.querySelector(".layout-tab-bar")?.getBoundingClientRect();
|
||||||
if (["select", "date", "asset"].includes(options.type)) {
|
if (["select", "date", "asset"].includes(options.type)) {
|
||||||
const cellRect = options.cellElements[options.cellElements.length - 1].getBoundingClientRect();
|
const cellRect = options.cellElements[options.cellElements.length - 1].getBoundingClientRect();
|
||||||
if (options.type === "select") {
|
if (options.type === "select") {
|
||||||
|
|
@ -94,7 +94,12 @@ export const openMenuPanel = (options: {
|
||||||
window.siyuan.dragElement.style.opacity = "";
|
window.siyuan.dragElement.style.opacity = "";
|
||||||
const sourceElement = window.siyuan.dragElement;
|
const sourceElement = window.siyuan.dragElement;
|
||||||
window.siyuan.dragElement = undefined;
|
window.siyuan.dragElement = undefined;
|
||||||
if (options.protyle.disabled) {
|
if (options.protyle && options.protyle.disabled) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!options.protyle && window.siyuan.config.readonly) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,31 @@ export const uploadLocalFiles = (files: string[], protyle: IProtyle, isUpload: b
|
||||||
};
|
};
|
||||||
|
|
||||||
export const uploadFiles = (protyle: IProtyle, files: FileList | DataTransferItemList | File[], element?: HTMLInputElement, successCB?: (res: string) => void) => {
|
export const uploadFiles = (protyle: IProtyle, files: FileList | DataTransferItemList | File[], element?: HTMLInputElement, successCB?: (res: string) => void) => {
|
||||||
|
// 文档书中点开属性->数据库后的变更操作
|
||||||
|
if (!protyle) {
|
||||||
|
const formData = new FormData();
|
||||||
|
for (let i = 0, iMax = files.length; i < iMax; i++) {
|
||||||
|
formData.append("file[]", files[i] as File);
|
||||||
|
}
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", Constants.UPLOAD_ADDRESS);
|
||||||
|
xhr.onreadystatechange = () => {
|
||||||
|
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
successCB(xhr.responseText);
|
||||||
|
} else if (xhr.status === 0) {
|
||||||
|
showMessage(window.siyuan.languages.fileTypeError);
|
||||||
|
} else {
|
||||||
|
showMessage(xhr.responseText);
|
||||||
|
}
|
||||||
|
if (element) {
|
||||||
|
element.value = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(formData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// FileList | DataTransferItemList | File[] => File[]
|
// FileList | DataTransferItemList | File[] => File[]
|
||||||
let fileList = [];
|
let fileList = [];
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ export const commonClick = (event: MouseEvent & {
|
||||||
/// #endif
|
/// #endif
|
||||||
} else {
|
} else {
|
||||||
if (data) {
|
if (data) {
|
||||||
openFileAttr(data, "bookmark");
|
openFileAttr(data, "bookmark", protyle);
|
||||||
} else {
|
} else {
|
||||||
openAttr(attrBookmarkElement.parentElement.parentElement, "bookmark");
|
openAttr(attrBookmarkElement.parentElement.parentElement, "bookmark", protyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
@ -34,9 +34,9 @@ export const commonClick = (event: MouseEvent & {
|
||||||
/// #endif
|
/// #endif
|
||||||
} else {
|
} else {
|
||||||
if (data) {
|
if (data) {
|
||||||
openFileAttr(data, "name");
|
openFileAttr(data, "name", protyle);
|
||||||
} else {
|
} else {
|
||||||
openAttr(attrNameElement.parentElement.parentElement, "name");
|
openAttr(attrNameElement.parentElement.parentElement, "name", protyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
@ -51,9 +51,9 @@ export const commonClick = (event: MouseEvent & {
|
||||||
/// #endif
|
/// #endif
|
||||||
} else {
|
} else {
|
||||||
if (data) {
|
if (data) {
|
||||||
openFileAttr(data, "alias");
|
openFileAttr(data, "alias", protyle);
|
||||||
} else {
|
} else {
|
||||||
openAttr(attrAliasElement.parentElement.parentElement, "alias");
|
openAttr(attrAliasElement.parentElement.parentElement, "alias", protyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
@ -68,9 +68,9 @@ export const commonClick = (event: MouseEvent & {
|
||||||
/// #endif
|
/// #endif
|
||||||
} else {
|
} else {
|
||||||
if (data) {
|
if (data) {
|
||||||
openFileAttr(data, "memo");
|
openFileAttr(data, "memo", protyle);
|
||||||
} else {
|
} else {
|
||||||
openAttr(attrMemoElement.parentElement.parentElement, "memo");
|
openAttr(attrMemoElement.parentElement.parentElement, "memo", protyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
|
||||||
|
|
@ -1978,7 +1978,7 @@ export class WYSIWYG {
|
||||||
}
|
}
|
||||||
hideElements(["gutter"], protyle);
|
hideElements(["gutter"], protyle);
|
||||||
} else if (event.shiftKey && !protyle.disabled) {
|
} else if (event.shiftKey && !protyle.disabled) {
|
||||||
openAttr(actionElement.parentElement);
|
openAttr(actionElement.parentElement, "bookmark", protyle);
|
||||||
} else if (ctrlIsPressed) {
|
} else if (ctrlIsPressed) {
|
||||||
zoomOut({protyle, id: actionId});
|
zoomOut({protyle, id: actionId});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1056,7 +1056,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
|
||||||
} else {
|
} else {
|
||||||
actionElement = topElement;
|
actionElement = topElement;
|
||||||
}
|
}
|
||||||
openAttr(actionElement);
|
openAttr(actionElement, "bookmark", protyle);
|
||||||
} else {
|
} else {
|
||||||
const oldHTML = topElement.outerHTML;
|
const oldHTML = topElement.outerHTML;
|
||||||
const name = Lute.EscapeHTMLStr(selectText);
|
const name = Lute.EscapeHTMLStr(selectText);
|
||||||
|
|
|
||||||
|
|
@ -945,6 +945,18 @@ const updateRef = (protyle: IProtyle, id: string, index = 0) => {
|
||||||
|
|
||||||
let transactionsTimeout: number;
|
let transactionsTimeout: number;
|
||||||
export const transaction = (protyle: IProtyle, doOperations: IOperation[], undoOperations?: IOperation[]) => {
|
export const transaction = (protyle: IProtyle, doOperations: IOperation[], undoOperations?: IOperation[]) => {
|
||||||
|
if (!protyle) {
|
||||||
|
// 文档书中点开属性->数据库后的变更操作
|
||||||
|
fetchPost("/api/transactions", {
|
||||||
|
session: Constants.SIYUAN_APPID,
|
||||||
|
app: Constants.SIYUAN_APPID,
|
||||||
|
transactions: [{
|
||||||
|
doOperations
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const lastTransaction = window.siyuan.transactions[window.siyuan.transactions.length - 1];
|
const lastTransaction = window.siyuan.transactions[window.siyuan.transactions.length - 1];
|
||||||
let needDebounce = false;
|
let needDebounce = false;
|
||||||
const time = new Date().getTime();
|
const time = new Date().getTime();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue