${item.key.name}
diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts
index ef7903188..080fac51a 100644
--- a/app/src/protyle/render/av/cell.ts
+++ b/app/src/protyle/render/av/cell.ts
@@ -175,9 +175,13 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
if (!blockElement) {
return;
}
- calcElement.parentElement.classList.add("av__row--show");
+ const rowElement = hasClosestByClassName(calcElement, "av__row--footer");
+ if (!rowElement) {
+ return;
+ }
+ rowElement.classList.add("av__row--show");
const menu = new Menu("av-calc", () => {
- calcElement.parentElement.classList.remove("av__row--show");
+ rowElement.classList.remove("av__row--show");
});
if (menu.isOpen) {
return;
@@ -346,14 +350,28 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
};
-export const cellScrollIntoView = (blockElement: HTMLElement, cellRect: DOMRect, onlyHeight = true) => {
+export const cellScrollIntoView = (blockElement: HTMLElement, cellElement: Element, onlyHeight = true) => {
+ const cellRect = cellElement.getBoundingClientRect();
if (!onlyHeight) {
const avScrollElement = blockElement.querySelector(".av__scroll");
- const avScrollRect = avScrollElement.getBoundingClientRect();
- if (avScrollRect.left > cellRect.left) {
- avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - avScrollRect.left;
- } else if (avScrollRect.right < cellRect.right) {
- avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.right - avScrollRect.right;
+ if (avScrollElement) {
+ const avScrollRect = avScrollElement.getBoundingClientRect();
+ if (avScrollRect.right < cellRect.right) {
+ avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.right - avScrollRect.right;
+ } else {
+ const rowElement = hasClosestByClassName(cellElement, "av__row");
+ if (rowElement) {
+ const stickyElement = rowElement.querySelector(".av__colsticky");
+ if (stickyElement) {
+ const stickyRight = stickyElement.getBoundingClientRect().right
+ if (stickyRight > cellRect.left) {
+ avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - stickyRight;
+ }
+ } else if (avScrollRect.left > cellRect.left) {
+ avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - avScrollRect.left;
+ }
+ }
+ }
}
}
if (!blockElement.querySelector(".av__header")) {
@@ -377,9 +395,17 @@ export const cellScrollIntoView = (blockElement: HTMLElement, cellRect: DOMRect,
}
};
+export const getTypeByCellElement = (cellElement: Element) => {
+ const scrollElement = hasClosestByClassName(cellElement, "av__scroll")
+ if (!scrollElement) {
+ return;
+ }
+ return scrollElement.querySelector(".av__row--header").querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
+}
+
export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type?: TAVCol) => {
if (!type) {
- type = cellElements[0].parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElements[0].getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
+ type = getTypeByCellElement(cellElements[0])
}
if (type === "updated" || type === "created") {
return;
@@ -396,7 +422,7 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
contentElement.scrollTop = contentElement.scrollTop + cellRect.top - 110;
}
/// #else
- cellScrollIntoView(blockElement, cellRect);
+ cellScrollIntoView(blockElement, cellElements[0], false);
/// #endif
}
cellRect = cellElements[0].getBoundingClientRect();
@@ -406,14 +432,17 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
html = ``;
} else if (type === "number") {
html = ``;
- } else if (["select", "mSelect"].includes(type) && blockElement) {
- openMenuPanel({protyle, blockElement, type: "select", cellElements});
- return;
- } else if (type === "mAsset" && blockElement) {
- openMenuPanel({protyle, blockElement, type: "asset", cellElements});
- return;
- } else if (type === "date" && blockElement) {
- openMenuPanel({protyle, blockElement, type: "date", cellElements});
+ } else if (blockElement) {
+ if (["select", "mSelect"].includes(type)) {
+ openMenuPanel({protyle, blockElement, type: "select", cellElements});
+ } else if (type === "mAsset") {
+ openMenuPanel({protyle, blockElement, type: "asset", cellElements});
+ } else if (type === "date") {
+ openMenuPanel({protyle, blockElement, type: "date", cellElements});
+ }
+ if (!hasClosestByClassName(cellElements[0], "custom-attr")) {
+ cellElements[0].classList.add("av__cell--select");
+ }
return;
}
window.siyuan.menus.menu.remove();
@@ -459,12 +488,16 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
};
const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElement[]) => {
+ const rowElement = hasClosestByClassName(cellElements[0], "av__row");
+ if (!rowElement) {
+ return;
+ }
if (!document.contains(cellElements[0]) && cellElements.length === 1) {
// 原始 cell 已被更新
- const avid = cellElements[0].parentElement.dataset.avid;
+ const avid = rowElement.dataset.avid;
if (avid) {
// 新增行后弹出的输入框
- const previousId = cellElements[0].parentElement.dataset.previousId;
+ const previousId = rowElement.dataset.previousId;
cellElements[0] = protyle.wysiwyg.element.querySelector(previousId ? `[data-av-id="${avid}"] .av__row[data-id="${previousId}"]` : `[data-av-id="${avid}"] .av__row--header`).nextElementSibling.querySelector('[data-detached="true"]');
} else {
// 修改单元格后立即修改其他单元格
@@ -474,7 +507,7 @@ const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElem
}
}
}
- if (cellElements.length === 1 && cellElements[0].dataset.detached === "true" && !cellElements[0].parentElement.dataset.id) {
+ if (cellElements.length === 1 && cellElements[0].dataset.detached === "true" && !rowElement.dataset.id) {
return;
}
const blockElement = hasClosestBlock(cellElements[0]);
@@ -514,10 +547,16 @@ const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElem
const rowID = rowElement.getAttribute("data-id");
const cellId = item.getAttribute("data-id");
const colId = item.getAttribute("data-col-id");
- const inputValue: { content: string | number, isNotEmpty?: boolean } = {
+ const inputValue: {
+ content: string | number,
+ isNotEmpty?: boolean
+ } = {
content: (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value
};
- const oldValue: { content: string | number, isNotEmpty?: boolean } = {
+ const oldValue: {
+ content: string | number,
+ isNotEmpty?: boolean
+ } = {
content: type === "block" ? item.firstElementChild.textContent.trim() : item.textContent.trim()
};
if (type === "number") {
diff --git a/app/src/protyle/render/av/col.ts b/app/src/protyle/render/av/col.ts
index f9a73eb4f..125b8c1f8 100644
--- a/app/src/protyle/render/av/col.ts
+++ b/app/src/protyle/render/av/col.ts
@@ -577,6 +577,26 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
}]);
}
});
+ }
+ const isPin = cellElement.dataset.pin === "true"
+ menu.addItem({
+ icon: "iconPin",
+ label: isPin ? window.siyuan.languages.unfreezeCol : window.siyuan.languages.freezeCol,
+ click() {
+ transaction(protyle, [{
+ action: "setAttrViewColPin",
+ id: colId,
+ avID,
+ data: !isPin
+ }], [{
+ action: "setAttrViewColPin",
+ id: colId,
+ avID,
+ data: isPin
+ }]);
+ }
+ });
+ if (type !== "block") {
menu.addItem({
icon: "iconCopy",
label: window.siyuan.languages.duplicate,
diff --git a/app/src/protyle/render/av/date.ts b/app/src/protyle/render/av/date.ts
index 8ec841acb..85f77512d 100644
--- a/app/src/protyle/render/av/date.ts
+++ b/app/src/protyle/render/av/date.ts
@@ -2,13 +2,14 @@ import {transaction} from "../../wysiwyg/transaction";
import * as dayjs from "dayjs";
import {updateAttrViewCellAnimation} from "./action";
import {genAVValueHTML} from "./blockAttr";
+import {hasClosestByClassName} from "../../util/hasClosest";
export const getDateHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
let hasEndDate = true;
let cellValue: IAVCell;
cellElements.forEach((cellElement) => {
data.rows.find(row => {
- if (cellElement.parentElement.dataset.id === row.id) {
+ if ((hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id === row.id) {
row.cells.find(cell => {
if (cell.id === cellElement.dataset.id) {
if (!cell.value || !cell.value.date || !cell.value.date.hasEndDate) {
@@ -141,7 +142,7 @@ export const setDateValue = (options: {
value: IAVCellDateValue
}) => {
let cellIndex: number;
- Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
+ Array.from((hasClosestByClassName(options.cellElements[0], "av__row") as HTMLElement).querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
if (item.dataset.id === options.cellElements[0].dataset.id) {
cellIndex = index;
return true;
@@ -153,7 +154,7 @@ export const setDateValue = (options: {
options.cellElements.forEach(item => {
let cellData: IAVCell;
let oldValue;
- const rowID = item.parentElement.dataset.id;
+ const rowID = (hasClosestByClassName(item, "av__row") as HTMLElement).dataset.id;
options.data.view.rows.find(row => {
if (row.id === rowID) {
if (typeof cellIndex === "number") {
diff --git a/app/src/protyle/render/av/keydown.ts b/app/src/protyle/render/av/keydown.ts
index 2557737ff..c0d740bab 100644
--- a/app/src/protyle/render/av/keydown.ts
+++ b/app/src/protyle/render/av/keydown.ts
@@ -2,6 +2,7 @@ import {matchHotKey} from "../../util/hotKey";
import {selectRow} from "./row";
import {cellScrollIntoView, popTextCell} from "./cell";
import {avContextmenu} from "./action";
+import {hasClosestByClassName} from "../../util/hasClosest";
export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyle: IProtyle) => {
if (!nodeElement.classList.contains("av") || !window.siyuan.menus.menu.element.classList.contains("fn__none")) {
@@ -17,9 +18,13 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
}
const selectCellElement = nodeElement.querySelector(".av__cell--select") as HTMLElement;
if (selectCellElement) {
+ const rowElement = hasClosestByClassName(selectCellElement, "av__row");
+ if (!rowElement) {
+ return false;
+ }
if (event.key === "Escape") {
selectCellElement.classList.remove("av__cell--select");
- selectRow(selectCellElement.parentElement.querySelector(".av__firstcol"), "select");
+ selectRow(rowElement.querySelector(".av__firstcol"), "select");
event.preventDefault();
return true;
}
@@ -30,57 +35,64 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
}
let newCellElement;
if (event.key === "ArrowLeft") {
- const previousRowElement = selectCellElement.parentElement.previousElementSibling;
- if (selectCellElement.previousElementSibling && selectCellElement.previousElementSibling.classList.contains("av__cell")) {
- newCellElement = selectCellElement.previousElementSibling;
+ const previousRowElement = rowElement.previousElementSibling;
+ if (selectCellElement.previousElementSibling && !selectCellElement.previousElementSibling.classList.contains("av__firstcol")) {
+ if (selectCellElement.previousElementSibling.classList.contains("av__cell")) {
+ newCellElement = selectCellElement.previousElementSibling;
+ } else {
+ newCellElement = selectCellElement.previousElementSibling.lastElementChild;
+ }
} else if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) {
- newCellElement = previousRowElement.lastElementChild.previousElementSibling;
+ const previousCellElements = previousRowElement.querySelectorAll(".av__cell")
+ newCellElement = previousCellElements[previousCellElements.length - 1];
}
if (newCellElement) {
selectCellElement.classList.remove("av__cell--select");
newCellElement.classList.add("av__cell--select");
- cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
+ cellScrollIntoView(nodeElement, newCellElement, false);
}
event.preventDefault();
return true;
}
if (event.key === "ArrowRight") {
- const nextRowElement = selectCellElement.parentElement.nextElementSibling;
+ const nextRowElement = rowElement.nextElementSibling;
if (selectCellElement.nextElementSibling && selectCellElement.nextElementSibling.classList.contains("av__cell")) {
newCellElement = selectCellElement.nextElementSibling;
+ } else if (!selectCellElement.nextElementSibling && selectCellElement.parentElement.nextElementSibling) {
+ newCellElement = selectCellElement.parentElement.nextElementSibling;
} else if (nextRowElement && !nextRowElement.classList.contains("av__row--footer")) {
newCellElement = nextRowElement.querySelector(".av__cell");
}
if (newCellElement) {
selectCellElement.classList.remove("av__cell--select");
newCellElement.classList.add("av__cell--select");
- cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
+ cellScrollIntoView(nodeElement, newCellElement, false);
}
event.preventDefault();
return true;
}
if (event.key === "ArrowUp") {
- const previousRowElement = selectCellElement.parentElement.previousElementSibling;
+ const previousRowElement = rowElement.previousElementSibling;
if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) {
newCellElement = previousRowElement.querySelector(`.av__cell[data-col-id="${selectCellElement.dataset.colId}"]`);
}
if (newCellElement) {
selectCellElement.classList.remove("av__cell--select");
newCellElement.classList.add("av__cell--select");
- cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
+ cellScrollIntoView(nodeElement, newCellElement);
}
event.preventDefault();
return true;
}
if (event.key === "ArrowDown") {
- const nextRowElement = selectCellElement.parentElement.nextElementSibling;
+ const nextRowElement = rowElement.nextElementSibling;
if (nextRowElement && !nextRowElement.classList.contains("av__row--footer")) {
newCellElement = nextRowElement.querySelector(`.av__cell[data-col-id="${selectCellElement.dataset.colId}"]`);
}
if (newCellElement) {
selectCellElement.classList.remove("av__cell--select");
newCellElement.classList.add("av__cell--select");
- cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
+ cellScrollIntoView(nodeElement, newCellElement);
}
event.preventDefault();
return true;
@@ -115,7 +127,7 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll");
if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) {
selectRow(previousRowElement.querySelector(".av__firstcol"), "select");
- cellScrollIntoView(nodeElement, previousRowElement.getBoundingClientRect(), true);
+ cellScrollIntoView(nodeElement, previousRowElement);
} else {
nodeElement.classList.add("protyle-wysiwyg--select");
}
@@ -127,7 +139,7 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll");
if (nextRowElement && !nextRowElement.classList.contains("av__row--add")) {
selectRow(nextRowElement.querySelector(".av__firstcol"), "select");
- cellScrollIntoView(nodeElement, nextRowElement.getBoundingClientRect(), true);
+ cellScrollIntoView(nodeElement, nextRowElement);
} else {
nodeElement.classList.add("protyle-wysiwyg--select");
}
diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts
index 48cfad5b9..985e624d4 100644
--- a/app/src/protyle/render/av/render.ts
+++ b/app/src/protyle/render/av/render.ts
@@ -6,6 +6,7 @@ import * as dayjs from "dayjs";
import {unicode2Emoji} from "../../../emoji";
import {focusBlock} from "../../util/selection";
import {isMac} from "../../util/compatibility";
+import {hasClosestByClassName} from "../../util/hasClosest";
export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) => {
let avElements: Element[] = [];
@@ -45,20 +46,41 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) =
let selectCellId = "";
const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
if (selectCellElement) {
- selectCellId = selectCellElement.parentElement.dataset.id + Constants.ZWSP + selectCellElement.getAttribute("data-col-id");
+ selectCellId = (hasClosestByClassName(selectCellElement, "av__row") as HTMLElement).dataset.id + Constants.ZWSP + selectCellElement.getAttribute("data-col-id");
}
fetchPost("/api/av/renderAttributeView", {
id: e.getAttribute("data-av-id"),
}, (response) => {
const data = response.data.view as IAVTable;
// header
- let tableHTML = '`;
`;
});
setTimeout(() => {
- e.firstElementChild.outerHTML = `
+ e.firstElementChild.outerHTML = `
`;
@@ -223,7 +260,9 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}
`;
if (newCellElement) {
newCellElement.classList.add("av__cell--select");
}
- focusBlock(e);
+ if (!document.querySelector(".av__panel")) {
+ focusBlock(e);
+ }
}
if (cb) {
cb();
@@ -270,7 +309,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation, isUndo: bool
avRender(item, protyle, () => {
// https://github.com/siyuan-note/siyuan/issues/9599
if (!isUndo && operation.action === "insertAttrViewBlock" && operation.isDetached) {
- popTextCell(protyle, [item.querySelector(`.av__row[data-id="${operation.srcIDs[0]}"] > .av__cell[data-detached="true"]`)], "block");
+ popTextCell(protyle, [item.querySelector(`.av__row[data-id="${operation.srcIDs[0]}"] .av__cell[data-detached="true"]`)], "block");
}
});
});
diff --git a/app/src/protyle/render/av/row.ts b/app/src/protyle/render/av/row.ts
index 5a2646ba9..48d3e16b5 100644
--- a/app/src/protyle/render/av/row.ts
+++ b/app/src/protyle/render/av/row.ts
@@ -1,27 +1,36 @@
-import {hasClosestBlock} from "../../util/hasClosest";
+import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest";
import {focusBlock} from "../../util/selection";
export const selectRow = (checkElement: Element, type: "toggle" | "select" | "unselect" | "unselectAll") => {
- const rowElement = checkElement.parentElement;
+ const rowElement = hasClosestByClassName(checkElement, "av__row");
+ if (!rowElement) {
+ return
+ }
const useElement = checkElement.querySelector("use");
if (rowElement.classList.contains("av__row--header") || type === "unselectAll") {
if ("#iconCheck" === useElement.getAttribute("xlink:href")) {
rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => {
item.querySelector("use").setAttribute("xlink:href", "#iconUncheck");
- item.parentElement.classList.remove("av__row--select");
+ const rowItemElement = hasClosestByClassName(item, "av__row");
+ if (rowItemElement) {
+ rowItemElement.classList.remove("av__row--select");
+ }
});
} else {
rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => {
item.querySelector("use").setAttribute("xlink:href", "#iconCheck");
- item.parentElement.classList.add("av__row--select");
+ const rowItemElement = hasClosestByClassName(item, "av__row");
+ if (rowItemElement) {
+ rowItemElement.classList.add("av__row--select");
+ }
});
}
} else {
if (type === "select" || (useElement.getAttribute("xlink:href") === "#iconUncheck" && type === "toggle")) {
- checkElement.parentElement.classList.add("av__row--select");
+ rowElement.classList.add("av__row--select");
useElement.setAttribute("xlink:href", "#iconCheck");
} else if (type === "unselect" || (useElement.getAttribute("xlink:href") === "#iconCheck" && type === "toggle")) {
- checkElement.parentElement.classList.remove("av__row--select");
+ rowElement.classList.remove("av__row--select");
useElement.setAttribute("xlink:href", "#iconUncheck");
}
}
@@ -60,15 +69,21 @@ export const updateHeader = (rowElement: HTMLElement) => {
export const insertAttrViewBlockAnimation = (blockElement: Element, size: number, previousId: string, avId?: string) => {
const previousElement = blockElement.querySelector(`.av__row[data-id="${previousId}"]`) || blockElement.querySelector(".av__row--header");
- let colHTML = "";
- previousElement.querySelectorAll(".av__cell").forEach((item: HTMLElement) => {
+ let colHTML = '
';
+ const pinIndex = previousElement.querySelectorAll(".av__colsticky .av__cell").length - 1;
+ if (pinIndex > -1) {
+ colHTML = `
`;
+ }
+ previousElement.querySelectorAll(".av__cell").forEach((item: HTMLElement, index) => {
colHTML += `
`;
+ if (pinIndex === index) {
+ colHTML += `
`;
+ }
});
let html = "";
new Array(size).fill(1).forEach(() => {
html += `
`;
});
diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts
index f2eb5993f..845eda375 100644
--- a/app/src/protyle/render/av/select.ts
+++ b/app/src/protyle/render/av/select.ts
@@ -54,7 +54,7 @@ export const removeCellOption = (protyle: IProtyle, data: IAV, cellElements: HTM
const undoOperations: IOperation[] = [];
let newData: IAVCellSelectValue[];
cellElements.forEach((item, elementIndex) => {
- const rowID = item.parentElement.dataset.id;
+ const rowID = (hasClosestByClassName(item, "av__row") as HTMLElement).dataset.id;
const cellId = item.dataset.id;
let cellData: IAVCell;
data.view.rows.find(row => {
@@ -157,7 +157,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
} else {
cellElements.forEach((cellElement: HTMLMediaElement) => {
data.view.rows.find(row => {
- if (row.id === cellElement.parentElement.dataset.id) {
+ if (row.id === (hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id) {
row.cells.find(cell => {
if (cell.id === cellElement.dataset.id) {
cell.value.mSelect.find((item) => {
@@ -235,7 +235,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
} else {
cellElements.forEach((cellElement: HTMLElement) => {
data.view.rows.find(row => {
- if (row.id === cellElement.parentElement.dataset.id) {
+ if (row.id === (hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id) {
row.cells.find(cell => {
if (cell.id === cellElement.dataset.id) {
cell.value.mSelect.find((item, index) => {
@@ -314,7 +314,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
} else {
cellElements.forEach((cellElement: HTMLElement) => {
data.view.rows.find(row => {
- if (row.id === cellElement.parentElement.dataset.id) {
+ if (row.id === (hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id) {
row.cells.find(cell => {
if (cell.id === cellElement.dataset.id) {
cell.value.mSelect.find((item) => {
@@ -394,8 +394,6 @@ export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLE
addColOptionOrCell(protyle, data, cellElements, currentElement, menuElement);
} else if (event.key === "Backspace" && inputElement.value === "") {
removeCellOption(protyle, data, cellElements, inputElement.previousElementSibling as HTMLElement);
- } else if (event.key === "Escape") {
- menuElement.parentElement.remove();
}
});
};
@@ -413,14 +411,18 @@ export const addColOptionOrCell = (protyle: IProtyle, data: IAV, cellElements: H
return;
}
- const colId = cellElements[0].dataset.colId;
+ const rowElement = hasClosestByClassName(cellElements[0], "av__row");
+ if (!rowElement) {
+ return;
+ }
let cellIndex: number;
- Array.from(cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
+ Array.from(rowElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
if (item.dataset.id === cellElements[0].dataset.id) {
cellIndex = index;
return true;
}
});
+ const colId = cellElements[0].dataset.colId;
let colData: IAVColumn;
data.view.columns.find((item: IAVColumn) => {
if (item.id === colId) {
@@ -436,8 +438,12 @@ export const addColOptionOrCell = (protyle: IProtyle, data: IAV, cellElements: H
const cellUndoOperations: IOperation[] = [];
let newValue: IAVCellSelectValue[];
cellElements.forEach((item, index) => {
+ const itemRowElement = hasClosestByClassName(item, "av__row");
+ if (!itemRowElement) {
+ return;
+ }
let cellData: IAVCell;
- const rowID = item.parentElement.dataset.id;
+ const rowID = itemRowElement.dataset.id;
data.view.rows.find(row => {
if (row.id === rowID) {
if (typeof cellIndex === "number") {
@@ -553,7 +559,8 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
let allUniqueOptions: IAVCellSelectValue[] = [];
data.rows.find(row => {
- if (cellElements[0].parentElement.dataset.id === row.id) {
+ const rowElement = hasClosestByClassName(cellElements[0], "av__row");
+ if (rowElement && rowElement.dataset.id === row.id) {
row.cells.find(cell => {
if (cell.id === cellElements[0].dataset.id) {
if (cell.value && cell.value.mSelect) {
diff --git a/app/src/protyle/scroll/event.ts b/app/src/protyle/scroll/event.ts
index f83586fdb..24d1a1f8b 100644
--- a/app/src/protyle/scroll/event.ts
+++ b/app/src/protyle/scroll/event.ts
@@ -27,7 +27,7 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
const scrollRect = item.querySelector(".av__scroll").getBoundingClientRect()
const headerElement = item.querySelector(".av__row--header") as HTMLElement;
if (headerElement) {
- const distance = elementRect.top - scrollRect.top;
+ const distance = Math.floor(elementRect.top - scrollRect.top);
if (distance > 0 && distance < scrollRect.height) {
headerElement.style.transform = `translateY(${distance}px)`;
} else {
@@ -37,7 +37,7 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
const footerElement = item.querySelector(".av__row--footer") as HTMLElement;
if (footerElement) {
if (footerElement.querySelector(".av__calc--ashow")) {
- const distance = elementRect.bottom - scrollRect.bottom;
+ const distance = Math.floor(elementRect.bottom - footerElement.parentElement.getBoundingClientRect().bottom);
if (distance < 0 && -distance < scrollRect.height) {
footerElement.style.transform = `translateY(${distance}px)`;
} else {
diff --git a/app/src/protyle/toolbar/Font.ts b/app/src/protyle/toolbar/Font.ts
index 4bf8df442..f1ad62cf3 100644
--- a/app/src/protyle/toolbar/Font.ts
+++ b/app/src/protyle/toolbar/Font.ts
@@ -216,10 +216,16 @@ export const fontEvent = (protyle: IProtyle, nodeElements: Element[], type?: str
e.style.textShadow = "";
e.style.backgroundColor = "";
e.style.fontSize = "";
+ if (e.classList.contains("av")) {
+ e.querySelector(".av__container").setAttribute("style", "--av-background:--b3-theme-background");
+ }
} else if (type === "style1") {
const colorList = color.split(Constants.ZWSP);
e.style.backgroundColor = colorList[0];
e.style.color = colorList[1];
+ if (e.classList.contains("av")) {
+ e.querySelector(".av__container").setAttribute("style", `--av-background:${colorList[0]}`);
+ }
} else if (type === "style2") {
e.style.webkitTextStroke = "0.2px var(--b3-theme-on-background)";
e.style.webkitTextFillColor = "transparent";
@@ -229,6 +235,9 @@ export const fontEvent = (protyle: IProtyle, nodeElements: Element[], type?: str
e.style.color = color;
} else if (type === "backgroundColor") {
e.style.backgroundColor = color;
+ if (e.classList.contains("av")) {
+ e.querySelector(".av__container").setAttribute("style", `--av-background:${color}`);
+ }
} else if (type === "fontSize") {
e.style.fontSize = color;
}
diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts
index 32b3ca267..706890f87 100644
--- a/app/src/protyle/util/editorCommonEvent.ts
+++ b/app/src/protyle/util/editorCommonEvent.ts
@@ -852,15 +852,39 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => {
const blockElement = hasClosestBlock(targetElement);
if (blockElement) {
const avID = blockElement.getAttribute("data-av-id");
+ let previousID = "";
+ if (targetClass.includes("dragover__left")) {
+ if (targetElement.previousElementSibling) {
+ if (targetElement.previousElementSibling.classList.contains("av__colsticky")) {
+ previousID = targetElement.previousElementSibling.lastElementChild.getAttribute("data-col-id")
+ } else {
+ previousID = targetElement.previousElementSibling.getAttribute("data-col-id")
+ }
+ }
+ } else {
+ previousID = targetElement.getAttribute("data-col-id")
+ }
+ let oldPreviousID = "";
+ const rowElement = hasClosestByClassName(targetElement, "av__row");
+ if (rowElement) {
+ const oldPreviousElement = rowElement.querySelector(`[data-col-id="${gutterTypes[2]}"`)?.previousElementSibling
+ if (oldPreviousElement) {
+ if (oldPreviousElement.classList.contains("av__colsticky")) {
+ oldPreviousID = oldPreviousElement.lastElementChild.getAttribute("data-col-id")
+ } else {
+ oldPreviousID = oldPreviousElement.getAttribute("data-col-id")
+ }
+ }
+ }
transaction(protyle, [{
action: "sortAttrViewCol",
avID,
- previousID: (targetClass.includes("dragover__left") ? targetElement.previousElementSibling?.getAttribute("data-col-id") : targetElement.getAttribute("data-col-id")) || "",
+ previousID,
id: gutterTypes[2],
}], [{
action: "sortAttrViewCol",
avID,
- previousID: targetElement.parentElement.querySelector(`[data-col-id="${gutterTypes[2]}"`).previousElementSibling?.getAttribute("data-col-id") || "",
+ previousID: oldPreviousID,
id: gutterTypes[2],
}]);
}
@@ -1111,8 +1135,14 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => {
if (gutterType && gutterType.startsWith(`${Constants.SIYUAN_DROP_GUTTER}NodeAttributeView${Constants.ZWSP}Col${Constants.ZWSP}`.toLowerCase())) {
// 表头只能拖拽到当前 av 的表头中
targetElement = hasClosestByClassName(event.target, "av__cell");
- if (targetElement && !targetElement.parentElement.isSameNode(window.siyuan.dragElement.parentElement)) {
- targetElement = false;
+ if (targetElement) {
+ const targetRowElement = hasClosestByClassName(targetElement, "av__row--header")
+ const dragRowElement = hasClosestByClassName(window.siyuan.dragElement, "av__row--header")
+ if (!targetRowElement || !dragRowElement ||
+ (targetRowElement && dragRowElement && !targetRowElement.isSameNode(dragRowElement))
+ ) {
+ targetElement = false;
+ }
}
} else if (targetElement && gutterType && gutterType.startsWith(`${Constants.SIYUAN_DROP_GUTTER}NodeAttributeView${Constants.ZWSP}Row${Constants.ZWSP}`.toLowerCase())) {
// 行只能拖拽当前 av 中
diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts
index 8c5c41386..631d65acd 100644
--- a/app/src/protyle/wysiwyg/index.ts
+++ b/app/src/protyle/wysiwyg/index.ts
@@ -384,9 +384,12 @@ export class WYSIWYG {
let newWidth: string;
documentSelf.onmousemove = (moveEvent: MouseEvent) => {
newWidth = Math.max(oldWidth + (moveEvent.clientX - event.clientX), 58) + "px";
- dragElement.parentElement.parentElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
- (item.querySelector(`[data-col-id="${dragColId}"]`) as HTMLElement).style.width = newWidth;
- });
+ const scrollElement = hasClosestByClassName(dragElement, "av__scroll")
+ if (scrollElement) {
+ scrollElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
+ (item.querySelector(`[data-col-id="${dragColId}"]`) as HTMLElement).style.width = newWidth;
+ });
+ }
};
documentSelf.onmouseup = () => {
diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts
index dfdb1ffa1..bbdfd0304 100644
--- a/app/src/protyle/wysiwyg/transaction.ts
+++ b/app/src/protyle/wysiwyg/transaction.ts
@@ -711,7 +711,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo:
"updateAttrViewColOption", "updateAttrViewCell", "sortAttrViewRow", "sortAttrViewCol", "setAttrViewColHidden",
"setAttrViewColWrap", "setAttrViewColWidth", "removeAttrViewColOption", "setAttrViewName", "setAttrViewFilters",
"setAttrViewSorts", "setAttrViewColCalc", "removeAttrViewCol", "updateAttrViewColNumberFormat", "removeAttrViewBlock",
- "replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColIcon"].includes(operation.action)) {
+ "replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColIcon", "setAttrViewColPin"].includes(operation.action)) {
refreshAV(protyle, operation, isUndo);
} else if (operation.action === "doUpdateUpdated") {
updateElements.forEach(item => {
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts
index 62d8f31bf..7a8f16300 100644
--- a/app/src/types/index.d.ts
+++ b/app/src/types/index.d.ts
@@ -27,6 +27,7 @@ type TOperation =
| "updateAttrViewColTemplate"
| "sortAttrViewRow"
| "sortAttrViewCol"
+ | "setAttrViewColPin"
| "setAttrViewColHidden"
| "setAttrViewColWrap"
| "setAttrViewColWidth"
@@ -1029,11 +1030,12 @@ interface IAVSort {
}
interface IAVColumn {
- width: number,
+ width: string,
icon: string,
id: string,
name: string,
wrap: boolean,
+ pin: boolean,
hidden: boolean,
type: TAVCol,
numberFormat: string,