import {sizeToPixels} from "../../../utils/dom";
import {SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode";
+import {elem} from "../../../../services/dom";
export type CommonBlockAlignment = 'left' | 'right' | 'center' | 'justify' | '';
const validAlignments: CommonBlockAlignment[] = ['left', 'right', 'center', 'justify'];
nodeA.__dir !== nodeB.__dir;
}
+export function applyCommonPropertyChanges(prevNode: CommonBlockInterface, currentNode: CommonBlockInterface, element: HTMLElement): void {
+ if (prevNode.__id !== currentNode.__id) {
+ element.setAttribute('id', currentNode.__id);
+ }
+
+ if (prevNode.__alignment !== currentNode.__alignment) {
+ for (const alignment of validAlignments) {
+ element.classList.remove('align-' + alignment);
+ }
+
+ if (currentNode.__alignment) {
+ element.classList.add('align-' + currentNode.__alignment);
+ }
+ }
+
+ if (prevNode.__inset !== currentNode.__inset) {
+ if (currentNode.__inset) {
+ element.style.paddingLeft = `${currentNode.__inset}px`;
+ } else {
+ element.style.removeProperty('paddingLeft');
+ }
+ }
+
+ if (prevNode.__dir !== currentNode.__dir) {
+ if (currentNode.__dir) {
+ element.dir = currentNode.__dir;
+ } else {
+ element.removeAttribute('dir');
+ }
+ }
+}
+
export function updateElementWithCommonBlockProps(element: HTMLElement, node: CommonBlockInterface): void {
if (node.__id) {
element.setAttribute('id', node.__id);
import {getTable} from './LexicalTableSelectionHelpers';
import {CommonBlockNode, copyCommonBlockProperties, SerializedCommonBlockNode} from "lexical/nodes/CommonBlockNode";
import {
+ applyCommonPropertyChanges,
commonPropertiesDifferent, deserializeCommonBlockNode,
setCommonBlockPropsFromElement,
updateElementWithCommonBlockProps
} 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[];
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 {
domRows.length = 0;
while (currentNode != null) {
- const nodeMame = currentNode.nodeName;
+ const nodeName = currentNode.nodeName;
- if (nodeMame === 'COLGROUP') {
+ if (nodeName === 'COLGROUP' || nodeName === 'CAPTION') {
currentNode = currentNode.nextSibling;
continue;
}
- if (nodeMame === 'TD' || nodeMame === 'TH') {
+ if (nodeName === 'TD' || nodeName === 'TH') {
const elem = currentNode as HTMLElement;
const cell = {
elem,
TableRowNode,
} from './LexicalTableRowNode';
import {$isTableSelection} from './LexicalTableSelection';
+import {$isCaptionNode} from "@lexical/table/LexicalCaptionNode";
export function $createTableNodeWithDimensions(
rowCount: number,
return tableMap[row] === undefined || tableMap[row][column] === undefined;
}
- const gridChildren = grid.getChildren();
+ const gridChildren = grid.getChildren().filter(node => !$isCaptionNode(node));
for (let i = 0; i < gridChildren.length; i++) {
const row = gridChildren[i];
invariant(
tableNode,
tableElement,
this.editor,
- false,
+ true,
);
this.tableSelections.set(nodeKey, tableSelection);
}
} from "@lexical/table";
import {$getParentOfType} from "./nodes";
import {$getNodeFromSelection} from "./selection";
-import {formatSizeValue} from "./dom";
+import {el, formatSizeValue} from "./dom";
import {TableMap} from "./table-map";
function $getTableFromCell(cell: TableCellNode): TableNode|null {
return (widths.length > index) ? widths[index] : '';
}
+export function buildColgroupFromTableWidths(colWidths: string[]): HTMLElement|null {
+ if (colWidths.length === 0) {
+ return null
+ }
+
+ const colgroup = el('colgroup');
+ for (const width of colWidths) {
+ const col = el('col');
+ if (width) {
+ col.style.width = width;
+ }
+ colgroup.append(col);
+ }
+
+ return colgroup;
+}
+
export function $getTableCellsFromSelection(selection: BaseSelection|null): TableCellNode[] {
if ($isTableSelection(selection)) {
const nodes = selection.getNodes();