LexicalEditor,
LexicalNode,
NodeKey,
- SerializedElementNode, Spread,
+ Spread,
} from 'lexical';
import {addClassNamesToElement, isHTMLElement} from '@lexical/utils';
import {
$applyNodeReplacement,
$getNearestNodeFromDOMNode,
- ElementNode,
+
} from 'lexical';
import {$isTableCellNode} from './LexicalTableCellNode';
import {TableDOMCell, TableDOMTable} from './LexicalTableObserver';
import {getTable} from './LexicalTableSelectionHelpers';
-import {CommonBlockNode, copyCommonBlockProperties} from "lexical/nodes/CommonBlockNode";
+import {CommonBlockNode, copyCommonBlockProperties, SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode";
import {
+ applyCommonPropertyChanges,
commonPropertiesDifferent, deserializeCommonBlockNode,
- SerializedCommonBlockNode, setCommonBlockPropsFromElement,
+ setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps
-} from "../../nodes/_common";
+} from "lexical/nodes/common";
import {el, extractStyleMapFromElement, StyleMap} from "../../utils/dom";
-import {getTableColumnWidths} from "../../utils/tables";
+import {buildColgroupFromTableWidths, getTableColumnWidths} from "../../utils/tables";
export type SerializedTableNode = Spread<{
colWidths: string[];
static clone(node: TableNode): TableNode {
const newNode = new TableNode(node.__key);
copyCommonBlockProperties(node, newNode);
- newNode.__colWidths = node.__colWidths;
+ newNode.__colWidths = [...node.__colWidths];
newNode.__styles = new Map(node.__styles);
return newNode;
}
updateElementWithCommonBlockProps(tableElement, this);
const colWidths = this.getColWidths();
- if (colWidths.length > 0) {
- const colgroup = el('colgroup');
- for (const width of colWidths) {
- const col = el('col');
- if (width) {
- col.style.width = width;
- }
- colgroup.append(col);
- }
+ const colgroup = buildColgroupFromTableWidths(colWidths);
+ if (colgroup) {
tableElement.append(colgroup);
}
return tableElement;
}
- updateDOM(_prevNode: TableNode): boolean {
- return commonPropertiesDifferent(_prevNode, this)
- || this.__colWidths.join(':') !== _prevNode.__colWidths.join(':')
- || this.__styles.size !== _prevNode.__styles.size
- || (Array.from(this.__styles.values()).join(':') !== (Array.from(_prevNode.__styles.values()).join(':')));
+ updateDOM(_prevNode: TableNode, dom: HTMLElement): boolean {
+ applyCommonPropertyChanges(_prevNode, this, dom);
+
+ if (this.__colWidths.join(':') !== _prevNode.__colWidths.join(':')) {
+ const existingColGroup = Array.from(dom.children).find(child => child.nodeName === 'COLGROUP');
+ const newColGroup = buildColgroupFromTableWidths(this.__colWidths);
+ if (existingColGroup) {
+ existingColGroup.remove();
+ }
+
+ if (newColGroup) {
+ dom.prepend(newColGroup);
+ }
+ }
+
+ if (Array.from(this.__styles.values()).join(':') !== Array.from(_prevNode.__styles.values()).join(':')) {
+ dom.style.cssText = '';
+ for (const [name, value] of this.__styles.entries()) {
+ dom.style.setProperty(name, value);
+ }
+ }
+
+ return false;
}
exportDOM(editor: LexicalEditor): DOMExportOutput {
for (const child of Array.from(tableElement.children)) {
if (child.nodeName === 'TR') {
tBody.append(child);
+ } else if (child.nodeName === 'CAPTION') {
+ newElement.insertBefore(child, newElement.firstChild);
} else {
newElement.append(child);
}
getColWidths(): string[] {
const self = this.getLatest();
- return self.__colWidths;
+ return [...self.__colWidths];
}
getStyles(): StyleMap {