import {fetchPost} from "../../../util/fetch";
import {getColIconByType} from "./col";
import {Constants} from "../../../constants";
import {renderCell} from "./cell";
import {unicode2Emoji} from "../../../emoji";
import {focusBlock} from "../../util/selection";
import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest";
import {stickyRow} from "./row";
import {getCalcValue} from "./calc";
import {openMenuPanel} from "./openMenuPanel";
export const avRender = (element: Element, protyle: IProtyle, cb?: () => void, viewID?: string) => {
let avElements: Element[] = [];
if (element.getAttribute("data-type") === "NodeAttributeView") {
// 编辑器内代码块编辑渲染
avElements = [element];
} else {
avElements = Array.from(element.querySelectorAll('[data-type="NodeAttributeView"]'));
}
if (avElements.length === 0) {
return;
}
if (avElements.length > 0) {
avElements.forEach((e: HTMLElement) => {
if (e.getAttribute("data-render") === "true") {
return;
}
if (e.firstElementChild.innerHTML === "") {
e.style.alignSelf = "";
let html = "";
[1, 2, 3].forEach(() => {
html += `
`;
});
e.firstElementChild.innerHTML = html;
}
const left = e.querySelector(".av__scroll")?.scrollLeft || 0;
const headerTransform = (e.querySelector(".av__row--header") as HTMLElement)?.style.transform;
const footerTransform = (e.querySelector(".av__row--footer") as HTMLElement)?.style.transform;
let selectCellId = "";
const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
if (selectCellElement) {
selectCellId = (hasClosestByClassName(selectCellElement, "av__row") as HTMLElement).dataset.id + Constants.ZWSP + selectCellElement.getAttribute("data-col-id");
}
const created = protyle.options.history?.created;
const snapshot = protyle.options.history?.snapshot;
let newViewID = "";
if (typeof viewID === "string") {
newViewID = viewID;
} else if (typeof viewID === "undefined") {
newViewID = e.querySelector(".av__header .item--focus")?.getAttribute("data-id");
}
fetchPost(created ? "/api/av/renderHistoryAttributeView" : (snapshot ? "/api/av/renderSnapshotAttributeView" : "/api/av/renderAttributeView"), {
id: e.getAttribute("data-av-id"),
created,
snapshot,
pageSize: parseInt(e.dataset.pageSize) || undefined,
viewID: newViewID
}, (response) => {
const data = response.data.view as IAVTable;
if (!e.dataset.pageSize) {
e.dataset.pageSize = data.pageSize.toString();
}
// header
let tableHTML = '";
}
calcHTML += `${getCalcValue(column) || '' + window.siyuan.languages.calc}
`;
if (pinIndex === index) {
calcHTML += "";
}
});
tableHTML += `
`;
// body
data.rows.forEach((row: IAVRow) => {
tableHTML += `
`;
if (pinIndex < 0) {
tableHTML += '
';
}
row.cells.forEach((cell, index) => {
if (data.columns[index].hidden) {
return;
}
tableHTML += `
${renderCell(cell.value, data.columns[index].wrap)}
`;
if (pinIndex === index) {
tableHTML += "
";
}
});
tableHTML += "";
});
let tabHTML = "";
response.data.views.forEach((item: IAVView) => {
tabHTML += `
${item.icon ? unicode2Emoji(item.icon, "item__graphic", true) : ''}
${item.name}
`;
});
e.firstElementChild.outerHTML = ``;
e.setAttribute("data-render", "true");
// 历史兼容
e.style.margin = "";
if (left) {
e.querySelector(".av__scroll").scrollLeft = left;
}
const editRect = protyle.contentElement.getBoundingClientRect();
if (headerTransform) {
(e.querySelector(".av__row--header") as HTMLElement).style.transform = headerTransform;
} else {
stickyRow(e, editRect, "top");
}
if (footerTransform) {
(e.querySelector(".av__row--footer") as HTMLElement).style.transform = footerTransform;
} else {
stickyRow(e, editRect, "bottom");
}
if (selectCellId) {
const newCellElement = e.querySelector(`.av__row[data-id="${selectCellId.split(Constants.ZWSP)[0]}"] .av__cell[data-col-id="${selectCellId.split(Constants.ZWSP)[1]}"]`);
if (newCellElement) {
newCellElement.classList.add("av__cell--select");
}
const avMaskElement = document.querySelector(".av__mask");
if (avMaskElement) {
(avMaskElement.querySelector("textarea, input") as HTMLTextAreaElement)?.focus();
} else if (!document.querySelector(".av__panel")) {
focusBlock(e);
}
}
if (getSelection().rangeCount > 0) {
// 修改表头后光标重新定位
const range = getSelection().getRangeAt(0);
if (!hasClosestByClassName(range.startContainer, "av__title")) {
const blockElement = hasClosestBlock(range.startContainer);
if (blockElement && e.isSameNode(blockElement)) {
focusBlock(e);
}
}
}
e.querySelector(".layout-tab-bar").scrollLeft = (e.querySelector(".layout-tab-bar .item--focus") as HTMLElement).offsetLeft;
if (cb) {
cb();
}
});
});
}
};
const refreshTimeouts: {
[key: string]: number;
} = {};
export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
if (operation.action === "setAttrViewName") {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.id}"]`)).forEach((item: HTMLElement) => {
const titleElement = item.querySelector(".av__title") as HTMLElement;
if (!titleElement) {
return;
}
titleElement.textContent = operation.data;
titleElement.dataset.title = operation.data;
});
}
// 只能 setTimeout,以前方案快速输入后最后一次修改会被忽略;必须为每一个 protyle 单独设置,否则有多个 protyle 时,其余无法被执行
clearTimeout(refreshTimeouts[protyle.id]);
refreshTimeouts[protyle.id] = window.setTimeout(() => {
if (operation.action === "setAttrViewColWidth") {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.avID}"]`)).forEach((item: HTMLElement) => {
const cellElement = item.querySelector(`.av__cell[data-col-id="${operation.id}"]`) as HTMLElement;
if (!cellElement || cellElement.style.width === operation.data) {
return;
}
item.querySelectorAll(".av__row").forEach(rowItem => {
(rowItem.querySelector(`[data-col-id="${operation.id}"]`) as HTMLElement).style.width = operation.data;
});
});
} else {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.avID}"]`)).forEach((item: HTMLElement) => {
item.removeAttribute("data-render");
avRender(item, protyle, () => {
if (operation.action === "addAttrViewCol" && item.querySelector(".av__pulse")) {
openMenuPanel({protyle, blockElement: item, type: "edit", colId: operation.id});
}
}, ["addAttrViewView", "duplicateAttrViewView"].includes(operation.action) ? operation.id :
(operation.action === "removeAttrViewView" ? null : undefined));
});
}
}, ["insertAttrViewBlock", "addAttrViewCol"].includes(operation.action) ? 2 : 100);
};