File tree Expand file tree Collapse file tree 5 files changed +101
-8
lines changed Expand file tree Collapse file tree 5 files changed +101
-8
lines changed Original file line number Diff line number Diff line change @@ -1165,6 +1165,16 @@ export class LexicalNode {
1165
1165
markDirty ( ) : void {
1166
1166
this . getWritable ( ) ;
1167
1167
}
1168
+
1169
+ /**
1170
+ * Insert the DOM of this node into that of the parent.
1171
+ * Allows this node to implement custom DOM attachment logic.
1172
+ * Boolean result indicates if the insertion was handled by the function.
1173
+ * A true return value prevents default insertion logic from taking place.
1174
+ */
1175
+ insertDOMIntoParent ( nodeDOM : HTMLElement , parentDOM : HTMLElement ) : boolean {
1176
+ return false ;
1177
+ }
1168
1178
}
1169
1179
1170
1180
function errorOnTypeKlassMismatch (
Original file line number Diff line number Diff line change @@ -171,16 +171,21 @@ function $createNode(
171
171
}
172
172
173
173
if ( parentDOM !== null ) {
174
- if ( insertDOM != null ) {
175
- parentDOM . insertBefore ( dom , insertDOM ) ;
176
- } else {
177
- // @ts -expect-error: internal field
178
- const possibleLineBreak = parentDOM . __lexicalLineBreak ;
179
174
180
- if ( possibleLineBreak != null ) {
181
- parentDOM . insertBefore ( dom , possibleLineBreak ) ;
175
+ const inserted = node ?. insertDOMIntoParent ( dom , parentDOM ) ;
176
+
177
+ if ( ! inserted ) {
178
+ if ( insertDOM != null ) {
179
+ parentDOM . insertBefore ( dom , insertDOM ) ;
182
180
} else {
183
- parentDOM . appendChild ( dom ) ;
181
+ // @ts -expect-error: internal field
182
+ const possibleLineBreak = parentDOM . __lexicalLineBreak ;
183
+
184
+ if ( possibleLineBreak != null ) {
185
+ parentDOM . insertBefore ( dom , possibleLineBreak ) ;
186
+ } else {
187
+ parentDOM . appendChild ( dom ) ;
188
+ }
184
189
}
185
190
}
186
191
}
Original file line number Diff line number Diff line change
1
+ import {
2
+ DOMConversionMap ,
3
+ DOMExportOutput ,
4
+ EditorConfig ,
5
+ ElementNode ,
6
+ LexicalEditor ,
7
+ LexicalNode ,
8
+ SerializedElementNode
9
+ } from "lexical" ;
10
+
11
+
12
+ export class CaptionNode extends ElementNode {
13
+ static getType ( ) : string {
14
+ return 'caption' ;
15
+ }
16
+
17
+ static clone ( node : CaptionNode ) : CaptionNode {
18
+ return new CaptionNode ( node . __key ) ;
19
+ }
20
+
21
+ createDOM ( _config : EditorConfig , _editor : LexicalEditor ) : HTMLElement {
22
+ return document . createElement ( 'caption' ) ;
23
+ }
24
+
25
+ updateDOM ( _prevNode : unknown , _dom : HTMLElement , _config : EditorConfig ) : boolean {
26
+ return false ;
27
+ }
28
+
29
+ isParentRequired ( ) : true {
30
+ return true ;
31
+ }
32
+
33
+ canBeEmpty ( ) : boolean {
34
+ return false ;
35
+ }
36
+
37
+ exportJSON ( ) : SerializedElementNode {
38
+ return {
39
+ ...super . exportJSON ( ) ,
40
+ type : 'caption' ,
41
+ version : 1 ,
42
+ } ;
43
+ }
44
+
45
+ insertDOMIntoParent ( nodeDOM : HTMLElement , parentDOM : HTMLElement ) : boolean {
46
+ parentDOM . insertBefore ( nodeDOM , parentDOM . firstChild ) ;
47
+ return true ;
48
+ }
49
+
50
+ static importJSON ( serializedNode : SerializedElementNode ) : CaptionNode {
51
+ return $createCaptionNode ( ) ;
52
+ }
53
+
54
+ static importDOM ( ) : DOMConversionMap | null {
55
+ return {
56
+ caption : ( node : Node ) => ( {
57
+ conversion ( domNode : Node ) {
58
+ return {
59
+ node : $createCaptionNode ( ) ,
60
+ }
61
+ } ,
62
+ priority : 0 ,
63
+ } ) ,
64
+ } ;
65
+ }
66
+ }
67
+
68
+ export function $createCaptionNode ( ) : CaptionNode {
69
+ return new CaptionNode ( ) ;
70
+ }
71
+
72
+ export function $isCaptionNode ( node : LexicalNode | null | undefined ) : node is CaptionNode {
73
+ return node instanceof CaptionNode ;
74
+ }
Original file line number Diff line number Diff line change @@ -139,6 +139,8 @@ export class TableNode extends CommonBlockNode {
139
139
for ( const child of Array . from ( tableElement . children ) ) {
140
140
if ( child . nodeName === 'TR' ) {
141
141
tBody . append ( child ) ;
142
+ } else if ( child . nodeName === 'CAPTION' ) {
143
+ newElement . insertBefore ( child , newElement . firstChild ) ;
142
144
} else {
143
145
newElement . append ( child ) ;
144
146
}
Original file line number Diff line number Diff line change @@ -18,6 +18,7 @@ import {EditorUiContext} from "./ui/framework/core";
18
18
import { MediaNode } from "@lexical/rich-text/LexicalMediaNode" ;
19
19
import { HeadingNode } from "@lexical/rich-text/LexicalHeadingNode" ;
20
20
import { QuoteNode } from "@lexical/rich-text/LexicalQuoteNode" ;
21
+ import { CaptionNode } from "@lexical/table/LexicalCaptionNode" ;
21
22
22
23
/**
23
24
* Load the nodes for lexical.
@@ -32,6 +33,7 @@ export function getNodesForPageEditor(): (KlassConstructor<typeof LexicalNode> |
32
33
TableNode ,
33
34
TableRowNode ,
34
35
TableCellNode ,
36
+ CaptionNode ,
35
37
ImageNode , // TODO - Alignment
36
38
HorizontalRuleNode ,
37
39
DetailsNode ,
You can’t perform that action at this time.
0 commit comments