]> BookStack Code Mirror - bookstack/commitdiff
WYSIWYG: Code & table fixes
authorDan Brown <redacted>
Sat, 5 Oct 2024 11:42:47 +0000 (12:42 +0100)
committerDan Brown <redacted>
Sat, 5 Oct 2024 11:42:47 +0000 (12:42 +0100)
- Fixed new code block insertion to remove selection area instead of
  just adding after.
- Added default table column widths to not be collapsed
- Updated table dom export to not duplicate colgroups.

resources/js/wysiwyg/lexical/table/LexicalTableNode.ts
resources/js/wysiwyg/ui/framework/blocks/table-creator.ts
resources/js/wysiwyg/utils/formats.ts
resources/js/wysiwyg/utils/nodes.ts
resources/js/wysiwyg/utils/selection.ts

index 3e695eaa47581ce04255473fe5c61e6593d19245..357ba3e738bd6771caea89989bc9825b94b53e8f 100644 (file)
@@ -83,30 +83,26 @@ export class TableNode extends ElementNode {
     return {
       ...super.exportDOM(editor),
       after: (tableElement) => {
-        if (tableElement) {
-          const newElement = tableElement.cloneNode() as ParentNode;
-          const colGroup = document.createElement('colgroup');
-          const tBody = document.createElement('tbody');
-          if (isHTMLElement(tableElement)) {
-            tBody.append(...tableElement.children);
-          }
-          const firstRow = this.getFirstChildOrThrow<TableRowNode>();
-
-          if (!$isTableRowNode(firstRow)) {
-            throw new Error('Expected to find row node.');
-          }
+        if (!tableElement) {
+          return;
+        }
 
-          const colCount = firstRow.getChildrenSize();
+        const newElement = tableElement.cloneNode() as ParentNode;
+        const tBody = document.createElement('tbody');
 
-          for (let i = 0; i < colCount; i++) {
-            const col = document.createElement('col');
-            colGroup.append(col);
+        if (isHTMLElement(tableElement)) {
+          for (const child of Array.from(tableElement.children)) {
+            if (child.nodeName === 'TR') {
+              tBody.append(child);
+            } else {
+              newElement.append(child);
+            }
           }
+        }
 
-          newElement.replaceChildren(colGroup, tBody);
+        newElement.append(tBody);
 
-          return newElement as HTMLElement;
-        }
+        return newElement as HTMLElement;
       },
     };
   }
index a8a142df5a14438f616c3848a7230164c8337e51..30ff3abc56caa1df99535934fdbcad0e341dbc25 100644 (file)
@@ -74,8 +74,12 @@ export class EditorTableCreator extends EditorUiElement {
             return;
         }
 
+        const targetColWidth = Math.min(Math.round(840 / columns), 240);
+        const colWidths = Array(columns).fill(targetColWidth + 'px');
+
         this.getContext().editor.update(() => {
             const table = $createTableNodeWithDimensions(rows, columns, false) as CustomTableNode;
+            table.setColWidths(colWidths);
             $insertNewBlockNodeAtSelection(table);
         });
     }
index 97038f07bad2db1e82b0b7077e0f680197f731c5..0ec9220dd2ea55a9f1e54cf0278e6f875190b5d7 100644 (file)
@@ -3,7 +3,7 @@ import {$createTextNode, $getSelection, $insertNodes, LexicalEditor, LexicalNode
 import {
     $getBlockElementNodesInSelection,
     $getNodeFromSelection,
-    $insertNewBlockNodeAtSelection, $selectionContainsNodeType,
+    $insertNewBlockNodeAtSelection, $selectionContainsNodeType, $selectSingleNode,
     $toggleSelectionBlockNodeType,
     getLastSelection
 } from "./selection";
@@ -65,9 +65,19 @@ export function formatCodeBlock(editor: LexicalEditor) {
             editor.update(() => {
                 const codeBlock = $createCodeBlockNode();
                 codeBlock.setCode(selection?.getTextContent() || '');
-                $insertNewBlockNodeAtSelection(codeBlock, true);
+
+                const selectionNodes = $getBlockElementNodesInSelection(selection);
+                const firstSelectionNode = selectionNodes[0];
+                const extraNodes = selectionNodes.slice(1);
+                if (firstSelectionNode) {
+                    firstSelectionNode.replace(codeBlock);
+                    extraNodes.forEach(n => n.remove());
+                } else {
+                    $insertNewBlockNodeAtSelection(codeBlock, true);
+                }
+
                 $openCodeEditorForNode(editor, codeBlock);
-                codeBlock.selectStart();
+                $selectSingleNode(codeBlock);
             });
         } else {
             $openCodeEditorForNode(editor, codeBlock);
index 48fbe043f390e7e08a259ae74090d1b0cb7623f8..2dd99d369c76e776bb406ef1f377834a37fe3fe5 100644 (file)
@@ -1,7 +1,7 @@
 import {
     $getRoot,
     $isDecoratorNode,
-    $isElementNode,
+    $isElementNode, $isRootNode,
     $isTextNode,
     ElementNode,
     LexicalEditor,
@@ -84,7 +84,7 @@ export function $getNearestBlockNodeForCoords(editor: LexicalEditor, x: number,
 
 export function $getNearestNodeBlockParent(node: LexicalNode): LexicalNode|null {
     const isBlockNode = (node: LexicalNode): boolean => {
-        return ($isElementNode(node) || $isDecoratorNode(node)) && !node.isInline();
+        return ($isElementNode(node) || $isDecoratorNode(node)) && !node.isInline() && !$isRootNode(node);
     };
 
     if (isBlockNode(node)) {
index f1055d98ac84113160d27c1cd6b67abc1df50264..67c2d91b26c0bc086a6c2bec747631c6c587a729 100644 (file)
@@ -82,8 +82,8 @@ export function $insertNewBlockNodeAtSelection(node: LexicalNode, insertAfter: b
 }
 
 export function $insertNewBlockNodesAtSelection(nodes: LexicalNode[], insertAfter: boolean = true) {
-    const selection = $getSelection();
-    const blockElement = selection ? $getNearestBlockElementAncestorOrThrow(selection.getNodes()[0]) : null;
+    const selectionNodes = $getSelection()?.getNodes() || [];
+    const blockElement = selectionNodes.length > 0 ? $getNearestNodeBlockParent(selectionNodes[0]) : null;
 
     if (blockElement) {
         if (insertAfter) {