mirror of https://github.com/halo-dev/halo
fix: resolve the issue of text editing not being effective before the table (#5365)
#### What type of PR is this? /kind bug /area editor /area console #### What this PR does / why we need it: 在 #5191 中对表格新增了如果可以左右滚动时,则显示阴影的特性。而根据 `prosemirror` 的数据流处理策略,在 `decorations` 中,state 是 new EditorState,但通过 `this.editor.view` 获取到的 view 为 old EditorView,进而导致使用了最新的坐标,并且使用其坐标通过旧版本的 view 中获取 DOM 而产生的错误。 本 PR 使用 `NodeView` 而不是 `decorations` 来重新处理表格阴影。 #### How to test it? 在默认富文本编辑器中新建一个表格。在表格前使用拼音输入文本,查看此文本能否被输入。 同时查看表格阴影是否存在 #### Which issue(s) this PR fixes: Fixes #5352 #### Does this PR introduce a user-facing change? ```release-note 解决默认富文本编辑器表格前字符无法被编辑的问题。 ```pull/5382/head v2.12.3
parent
50e954d297
commit
ca4f705f2d
|
@ -15,9 +15,6 @@ import {
|
|||
type NodeView,
|
||||
type EditorState,
|
||||
type DOMOutputSpec,
|
||||
Plugin,
|
||||
DecorationSet,
|
||||
Decoration,
|
||||
} from "@/tiptap/pm";
|
||||
import TableCell from "./table-cell";
|
||||
import TableRow from "./table-row";
|
||||
|
@ -129,14 +126,22 @@ class TableView implements NodeView {
|
|||
this.containerDOM.addEventListener("wheel", (e) => {
|
||||
return this.handleHorizontalWheel(this.containerDOM, e);
|
||||
});
|
||||
|
||||
let mouseX = 0;
|
||||
let mouseY = 0;
|
||||
document.addEventListener("mousemove", function (event) {
|
||||
mouseX = event.clientX;
|
||||
mouseY = event.clientY;
|
||||
});
|
||||
|
||||
this.containerDOM.addEventListener("scroll", () => {
|
||||
if (!editor) {
|
||||
return false;
|
||||
}
|
||||
const { state, view } = editor;
|
||||
const { tr } = state;
|
||||
view.dispatch(tr);
|
||||
return false;
|
||||
const { view } = editor;
|
||||
const coords = { left: mouseX, top: mouseY };
|
||||
const pos = view.posAtCoords(coords);
|
||||
editor.commands.setTextSelection(pos?.pos || 0);
|
||||
});
|
||||
|
||||
this.scrollDom = document.createElement("div");
|
||||
|
@ -147,6 +152,11 @@ class TableView implements NodeView {
|
|||
this.colgroup = this.table.appendChild(document.createElement("colgroup"));
|
||||
updateColumns(node, this.colgroup, this.table, cellMinWidth);
|
||||
this.contentDOM = this.table.appendChild(document.createElement("tbody"));
|
||||
// delay execution during initialization, otherwise
|
||||
// the correct scrollWidth cannot be obtained.
|
||||
setTimeout(() => {
|
||||
this.updateTableShadow();
|
||||
});
|
||||
}
|
||||
|
||||
update(node: ProseMirrorNode) {
|
||||
|
@ -156,15 +166,32 @@ class TableView implements NodeView {
|
|||
|
||||
this.node = node;
|
||||
updateColumns(node, this.colgroup, this.table, this.cellMinWidth);
|
||||
this.updateTableShadow();
|
||||
return true;
|
||||
}
|
||||
|
||||
updateTableShadow() {
|
||||
const { scrollWidth, clientWidth, scrollLeft } = this
|
||||
.containerDOM as HTMLElement;
|
||||
if (scrollWidth > clientWidth && scrollLeft < scrollWidth - clientWidth) {
|
||||
this.dom.classList.add("table-right-shadow");
|
||||
} else {
|
||||
this.dom.classList.remove("table-right-shadow");
|
||||
}
|
||||
if (scrollLeft > 0) {
|
||||
this.dom.classList.add("table-left-shadow");
|
||||
} else {
|
||||
this.dom.classList.remove("table-left-shadow");
|
||||
}
|
||||
}
|
||||
|
||||
ignoreMutation(
|
||||
mutation: MutationRecord | { type: "selection"; target: Element }
|
||||
) {
|
||||
return (
|
||||
mutation.type === "attributes" &&
|
||||
(mutation.target === this.table ||
|
||||
mutation.target === this.dom ||
|
||||
this.colgroup.contains(mutation.target))
|
||||
);
|
||||
}
|
||||
|
@ -487,48 +514,6 @@ const Table = TiptapTable.extend<ExtensionOptions & TableOptions>({
|
|||
onTransaction() {
|
||||
editor = this.editor;
|
||||
},
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
const plugins = this.parent?.() ?? [];
|
||||
return [
|
||||
...plugins,
|
||||
new Plugin({
|
||||
props: {
|
||||
decorations: (state) => {
|
||||
const { doc, tr } = state;
|
||||
const decorations: Decoration[] = [];
|
||||
doc.descendants((node, pos) => {
|
||||
if (node.type.name === Table.name) {
|
||||
const { view } = this.editor;
|
||||
const nodeDom = view.nodeDOM(pos) || view.domAtPos(pos)?.node;
|
||||
if (!nodeDom) {
|
||||
return true;
|
||||
}
|
||||
const { scrollWidth, clientWidth, scrollLeft } =
|
||||
nodeDom.firstChild as HTMLElement;
|
||||
let classNames = "";
|
||||
if (
|
||||
scrollWidth > clientWidth &&
|
||||
scrollLeft < scrollWidth - clientWidth
|
||||
) {
|
||||
classNames += "table-right-shadow ";
|
||||
}
|
||||
if (scrollLeft > 0) {
|
||||
classNames += "table-left-shadow ";
|
||||
}
|
||||
decorations.push(
|
||||
Decoration.node(pos, pos + node.nodeSize, {
|
||||
class: classNames,
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
return DecorationSet.create(tr.doc, decorations);
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
},
|
||||
}).configure({ resizable: true });
|
||||
|
||||
export default Table;
|
||||
|
|
Loading…
Reference in New Issue