@liminis/editor 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +34 -0
- package/README.md +376 -0
- package/dist/annotations/anchor-align.d.ts +50 -0
- package/dist/annotations/anchor-align.js +74 -0
- package/dist/annotations/anchor-model.d.ts +81 -0
- package/dist/annotations/anchor-model.js +80 -0
- package/dist/annotations/anchor-resolver.d.ts +92 -0
- package/dist/annotations/anchor-resolver.js +231 -0
- package/dist/annotations/block-structure.d.ts +65 -0
- package/dist/annotations/block-structure.js +113 -0
- package/dist/annotations/types.d.ts +159 -0
- package/dist/annotations/types.js +50 -0
- package/dist/annotations.d.ts +25 -0
- package/dist/annotations.js +27 -0
- package/dist/app/App.d.ts +64 -0
- package/dist/app/App.js +180 -0
- package/dist/app/editor/AmbientCorrectionPlugin.d.ts +18 -0
- package/dist/app/editor/AmbientCorrectionPlugin.js +185 -0
- package/dist/app/editor/AnchorScrollPlugin.d.ts +16 -0
- package/dist/app/editor/AnchorScrollPlugin.js +134 -0
- package/dist/app/editor/AnnotationMarkerPlugin.d.ts +24 -0
- package/dist/app/editor/AnnotationMarkerPlugin.js +224 -0
- package/dist/app/editor/AnnotationPlugin.d.ts +42 -0
- package/dist/app/editor/AnnotationPlugin.js +135 -0
- package/dist/app/editor/AnnotationSurface.d.ts +34 -0
- package/dist/app/editor/AnnotationSurface.js +115 -0
- package/dist/app/editor/AssetContext.d.ts +20 -0
- package/dist/app/editor/AssetContext.js +81 -0
- package/dist/app/editor/BlockClickPlugin.d.ts +8 -0
- package/dist/app/editor/BlockClickPlugin.js +126 -0
- package/dist/app/editor/CodeBlockPlugin.d.ts +1 -0
- package/dist/app/editor/CodeBlockPlugin.js +219 -0
- package/dist/app/editor/CorrectionPanelPlugin.d.ts +14 -0
- package/dist/app/editor/CorrectionPanelPlugin.js +333 -0
- package/dist/app/editor/DragHandlePlugin.d.ts +1 -0
- package/dist/app/editor/DragHandlePlugin.js +300 -0
- package/dist/app/editor/Editor.d.ts +84 -0
- package/dist/app/editor/Editor.js +539 -0
- package/dist/app/editor/FrontmatterPlugin.d.ts +19 -0
- package/dist/app/editor/FrontmatterPlugin.js +301 -0
- package/dist/app/editor/ImageModal.d.ts +13 -0
- package/dist/app/editor/ImageModal.js +267 -0
- package/dist/app/editor/ImagePlugin.d.ts +3 -0
- package/dist/app/editor/ImagePlugin.js +187 -0
- package/dist/app/editor/LinkClickPlugin.d.ts +23 -0
- package/dist/app/editor/LinkClickPlugin.js +90 -0
- package/dist/app/editor/MarkdownShortcutsPlugin.d.ts +49 -0
- package/dist/app/editor/MarkdownShortcutsPlugin.js +373 -0
- package/dist/app/editor/OrderedTaskListPlugin.d.ts +21 -0
- package/dist/app/editor/OrderedTaskListPlugin.js +78 -0
- package/dist/app/editor/SearchPlugin.d.ts +1 -0
- package/dist/app/editor/SearchPlugin.js +379 -0
- package/dist/app/editor/SelectionContextMenuPlugin.d.ts +29 -0
- package/dist/app/editor/SelectionContextMenuPlugin.js +160 -0
- package/dist/app/editor/SlashMenu.d.ts +11 -0
- package/dist/app/editor/SlashMenu.js +494 -0
- package/dist/app/editor/SlashMenuPlugin.d.ts +1 -0
- package/dist/app/editor/SlashMenuPlugin.js +168 -0
- package/dist/app/editor/TableActionsPlugin.d.ts +1 -0
- package/dist/app/editor/TableActionsPlugin.js +398 -0
- package/dist/app/editor/TogglePlugin.d.ts +1 -0
- package/dist/app/editor/TogglePlugin.js +159 -0
- package/dist/app/editor/Toolbar.d.ts +10 -0
- package/dist/app/editor/Toolbar.js +263 -0
- package/dist/app/editor/WikiLinkExistencePlugin.d.ts +17 -0
- package/dist/app/editor/WikiLinkExistencePlugin.js +104 -0
- package/dist/app/editor/WikiLinkFormatPlugin.d.ts +17 -0
- package/dist/app/editor/WikiLinkFormatPlugin.js +203 -0
- package/dist/app/editor/annotation-marks.d.ts +177 -0
- package/dist/app/editor/annotation-marks.js +750 -0
- package/dist/app/editor/annotationCommands.d.ts +13 -0
- package/dist/app/editor/annotationCommands.js +11 -0
- package/dist/app/editor/c4/C4InteractiveRenderer.d.ts +35 -0
- package/dist/app/editor/c4/C4InteractiveRenderer.js +299 -0
- package/dist/app/editor/c4/edge-clipping.d.ts +24 -0
- package/dist/app/editor/c4/edge-clipping.js +139 -0
- package/dist/app/editor/c4/hooks/useC4DiagramDrag.d.ts +38 -0
- package/dist/app/editor/c4/hooks/useC4DiagramDrag.js +112 -0
- package/dist/app/editor/c4/layout.d.ts +25 -0
- package/dist/app/editor/c4/layout.js +839 -0
- package/dist/app/editor/c4/parser.d.ts +19 -0
- package/dist/app/editor/c4/parser.js +410 -0
- package/dist/app/editor/c4/render-to-string.d.ts +24 -0
- package/dist/app/editor/c4/render-to-string.js +34 -0
- package/dist/app/editor/c4/renderer.d.ts +64 -0
- package/dist/app/editor/c4/renderer.js +569 -0
- package/dist/app/editor/c4/types.d.ts +203 -0
- package/dist/app/editor/c4/types.js +43 -0
- package/dist/app/editor/correction-yaml.d.ts +10 -0
- package/dist/app/editor/correction-yaml.js +40 -0
- package/dist/app/editor/editorNodes.d.ts +9 -0
- package/dist/app/editor/editorNodes.js +36 -0
- package/dist/app/editor/index.d.ts +1 -0
- package/dist/app/editor/index.js +1 -0
- package/dist/app/editor/mark-overlap-resolver.d.ts +6 -0
- package/dist/app/editor/mark-overlap-resolver.js +45 -0
- package/dist/app/editor/nodes/C4Component.d.ts +14 -0
- package/dist/app/editor/nodes/C4Component.js +284 -0
- package/dist/app/editor/nodes/C4Node.d.ts +32 -0
- package/dist/app/editor/nodes/C4Node.js +112 -0
- package/dist/app/editor/nodes/CalloutNode.d.ts +23 -0
- package/dist/app/editor/nodes/CalloutNode.js +94 -0
- package/dist/app/editor/nodes/CustomLinkNode.d.ts +57 -0
- package/dist/app/editor/nodes/CustomLinkNode.js +209 -0
- package/dist/app/editor/nodes/CustomListItemNode.d.ts +46 -0
- package/dist/app/editor/nodes/CustomListItemNode.js +120 -0
- package/dist/app/editor/nodes/CustomListNode.d.ts +27 -0
- package/dist/app/editor/nodes/CustomListNode.js +54 -0
- package/dist/app/editor/nodes/DefinitionListNode.d.ts +44 -0
- package/dist/app/editor/nodes/DefinitionListNode.js +151 -0
- package/dist/app/editor/nodes/DiagramContextMenu.d.ts +45 -0
- package/dist/app/editor/nodes/DiagramContextMenu.js +116 -0
- package/dist/app/editor/nodes/EquationComponent.d.ts +17 -0
- package/dist/app/editor/nodes/EquationComponent.js +130 -0
- package/dist/app/editor/nodes/EquationNode.d.ts +43 -0
- package/dist/app/editor/nodes/EquationNode.js +179 -0
- package/dist/app/editor/nodes/FootnoteNode.d.ts +40 -0
- package/dist/app/editor/nodes/FootnoteNode.js +151 -0
- package/dist/app/editor/nodes/FrontmatterNode.d.ts +24 -0
- package/dist/app/editor/nodes/FrontmatterNode.js +88 -0
- package/dist/app/editor/nodes/HorizontalRuleNode.d.ts +17 -0
- package/dist/app/editor/nodes/HorizontalRuleNode.js +57 -0
- package/dist/app/editor/nodes/HtmlNode.d.ts +32 -0
- package/dist/app/editor/nodes/HtmlNode.js +121 -0
- package/dist/app/editor/nodes/ImageComponent.d.ts +11 -0
- package/dist/app/editor/nodes/ImageComponent.js +228 -0
- package/dist/app/editor/nodes/ImageNode.d.ts +53 -0
- package/dist/app/editor/nodes/ImageNode.js +183 -0
- package/dist/app/editor/nodes/ListItemParagraphBreakNode.d.ts +42 -0
- package/dist/app/editor/nodes/ListItemParagraphBreakNode.js +95 -0
- package/dist/app/editor/nodes/MermaidComponent.d.ts +11 -0
- package/dist/app/editor/nodes/MermaidComponent.js +216 -0
- package/dist/app/editor/nodes/MermaidNode.d.ts +27 -0
- package/dist/app/editor/nodes/MermaidNode.js +96 -0
- package/dist/app/editor/nodes/ToggleNode.d.ts +56 -0
- package/dist/app/editor/nodes/ToggleNode.js +237 -0
- package/dist/app/editor/nodes/diagram-context-menu.d.ts +11 -0
- package/dist/app/editor/nodes/diagram-context-menu.js +70 -0
- package/dist/app/editor/nodes/diagram-utils.d.ts +13 -0
- package/dist/app/editor/nodes/diagram-utils.js +29 -0
- package/dist/app/editor/nodes/index.d.ts +30 -0
- package/dist/app/editor/nodes/index.js +17 -0
- package/dist/app/editor/utils.d.ts +2 -0
- package/dist/app/editor/utils.js +17 -0
- package/dist/app/mapper/index.d.ts +3 -0
- package/dist/app/mapper/index.js +2 -0
- package/dist/app/mapper/lexicalToMdast.d.ts +62 -0
- package/dist/app/mapper/lexicalToMdast.js +1937 -0
- package/dist/app/mapper/mdastToLexical.d.ts +31 -0
- package/dist/app/mapper/mdastToLexical.js +1075 -0
- package/dist/contract.d.ts +8 -0
- package/dist/contract.js +8 -0
- package/dist/headless.d.ts +40 -0
- package/dist/headless.js +45 -0
- package/dist/host/context.d.ts +20 -0
- package/dist/host/context.js +24 -0
- package/dist/host/defaults.d.ts +21 -0
- package/dist/host/defaults.js +47 -0
- package/dist/host/messages.d.ts +26 -0
- package/dist/host/messages.js +47 -0
- package/dist/host/types.d.ts +75 -0
- package/dist/host/types.js +13 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +51 -0
- package/dist/markdown/annotate-sentinels.d.ts +42 -0
- package/dist/markdown/annotate-sentinels.js +86 -0
- package/dist/markdown/parse.d.ts +56 -0
- package/dist/markdown/parse.js +516 -0
- package/dist/markdown/stringify.d.ts +7 -0
- package/dist/markdown/stringify.js +439 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/LICENSE +21 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/README.md +41 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/from-markdown.d.ts +72 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/from-markdown.js +127 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/index.d.ts +8 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/index.js +6 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/to-markdown.d.ts +17 -0
- package/dist/markdown/vendor/mdast-util-wiki-link/to-markdown.js +33 -0
- package/dist/markdown.d.ts +28 -0
- package/dist/markdown.js +44 -0
- package/dist/mathjax-config.d.ts +89 -0
- package/dist/mathjax-config.js +133 -0
- package/dist/nodes.d.ts +34 -0
- package/dist/nodes.js +34 -0
- package/dist/stores/correctionStore.d.ts +15 -0
- package/dist/stores/correctionStore.js +12 -0
- package/dist/stores/editorStore.d.ts +16 -0
- package/dist/stores/editorStore.js +27 -0
- package/dist/styles.css +2477 -0
- package/dist/types.d.ts +296 -0
- package/dist/types.js +91 -0
- package/dist/utils/file-types.d.ts +10 -0
- package/dist/utils/file-types.js +46 -0
- package/docs/annotations.md +134 -0
- package/docs/decisions/README.md +72 -0
- package/docs/decisions/adr-002.md +27 -0
- package/docs/decisions/adr-007.md +27 -0
- package/docs/decisions/adr-010.md +26 -0
- package/docs/decisions/adr-024.md +124 -0
- package/docs/decisions/adr-024b.md +0 -0
- package/docs/decisions/adr-025.md +103 -0
- package/docs/decisions/adr-027.md +66 -0
- package/docs/decisions/adr-057.md +67 -0
- package/docs/decisions/adr-070.md +131 -0
- package/docs/decisions/adr-075.md +410 -0
- package/docs/decisions/adr-076.md +183 -0
- package/docs/decisions/adr-077.md +410 -0
- package/docs/decisions/adr-078.md +243 -0
- package/docs/decisions/adr-079.md +167 -0
- package/docs/decisions/adr-080.md +325 -0
- package/docs/decisions/adr-081.md +108 -0
- package/docs/decisions/adr-082.md +123 -0
- package/docs/decisions/adr-083.md +204 -0
- package/docs/decisions/adr-084.md +179 -0
- package/docs/editor-api.md +106 -0
- package/docs/markdown-pipeline.md +282 -0
- package/docs/provenance.md +106 -0
- package/docs/zusammen-editor-capability-map.md +232 -0
- package/package.json +175 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { LinkNode } from '@lexical/link';
|
|
2
|
+
/**
|
|
3
|
+
* CustomLinkNode - Extends Lexical's LinkNode to prevent VS Code webview link interception
|
|
4
|
+
*
|
|
5
|
+
* The standard LinkNode renders `<a href="...">` which VS Code webviews intercept and
|
|
6
|
+
* open automatically on click. This custom node renders `<a data-href="...">` instead,
|
|
7
|
+
* allowing us to control navigation via JavaScript (Cmd+click to open).
|
|
8
|
+
*/
|
|
9
|
+
export class CustomLinkNode extends LinkNode {
|
|
10
|
+
/** @internal */
|
|
11
|
+
__wikiAliasState;
|
|
12
|
+
/**
|
|
13
|
+
* Whether this link was parsed from genuine `[[target]]` / `[[target|alias]]`
|
|
14
|
+
* wiki-link syntax, as opposed to a standard `[text](url)` link whose URL
|
|
15
|
+
* merely looks wiki-link-shaped. Export (`convertLinkNode` in
|
|
16
|
+
* `lexicalToMdast.ts`) always promotes a node with this flag set back to
|
|
17
|
+
* wiki-link syntax, regardless of `wikiLinkPromotionMode` — an opted-out
|
|
18
|
+
* host still must not corrupt a document's existing wiki-links (liminis#951).
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
__wikiLinkOrigin;
|
|
22
|
+
constructor(url, attributes, key) {
|
|
23
|
+
super(url, attributes, key);
|
|
24
|
+
this.__wikiAliasState = null;
|
|
25
|
+
this.__wikiLinkOrigin = false;
|
|
26
|
+
}
|
|
27
|
+
static getType() {
|
|
28
|
+
return 'link'; // Use same type to replace the default LinkNode
|
|
29
|
+
}
|
|
30
|
+
static clone(node) {
|
|
31
|
+
const cloned = new CustomLinkNode(node.__url, { rel: node.__rel, target: node.__target, title: node.__title }, node.__key);
|
|
32
|
+
cloned.__wikiAliasState = node.__wikiAliasState;
|
|
33
|
+
cloned.__wikiLinkOrigin = node.__wikiLinkOrigin;
|
|
34
|
+
return cloned;
|
|
35
|
+
}
|
|
36
|
+
createDOM(config) {
|
|
37
|
+
void config;
|
|
38
|
+
const element = document.createElement('a');
|
|
39
|
+
// Store URL in data-href instead of href to prevent webview interception
|
|
40
|
+
element.setAttribute('data-href', this.__url);
|
|
41
|
+
if (this.__target !== null) {
|
|
42
|
+
element.target = this.__target;
|
|
43
|
+
}
|
|
44
|
+
if (this.__rel !== null) {
|
|
45
|
+
element.rel = this.__rel;
|
|
46
|
+
}
|
|
47
|
+
if (this.__title !== null) {
|
|
48
|
+
element.title = this.__title;
|
|
49
|
+
}
|
|
50
|
+
// Add visual styling class
|
|
51
|
+
element.className = 'editor-link';
|
|
52
|
+
// Mark wiki-links (internal .md links) with a data attribute
|
|
53
|
+
// This allows the WikiLinkExistencePlugin to check and style broken links
|
|
54
|
+
if (this.isWikiLink()) {
|
|
55
|
+
element.setAttribute('data-wiki-link', 'true');
|
|
56
|
+
element.setAttribute('data-wiki-target', this.__url);
|
|
57
|
+
}
|
|
58
|
+
else if (this.isExternalLink()) {
|
|
59
|
+
// External links get blue styling to differentiate from wiki-links
|
|
60
|
+
element.classList.add('editor-link-external');
|
|
61
|
+
}
|
|
62
|
+
return element;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if this link is a wiki-link (internal markdown file)
|
|
66
|
+
*/
|
|
67
|
+
isWikiLink() {
|
|
68
|
+
const url = this.__url;
|
|
69
|
+
// Wiki-links are internal paths that don't start with http/https/mailto
|
|
70
|
+
// and typically end in .md or have no extension
|
|
71
|
+
return !url.startsWith('http://') &&
|
|
72
|
+
!url.startsWith('https://') &&
|
|
73
|
+
!url.startsWith('mailto:') &&
|
|
74
|
+
!url.startsWith('#');
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Check if this link is an external link (http/https/mailto)
|
|
78
|
+
*/
|
|
79
|
+
isExternalLink() {
|
|
80
|
+
const url = this.__url;
|
|
81
|
+
return url.startsWith('http://') || url.startsWith('https://') || url.startsWith('mailto:');
|
|
82
|
+
}
|
|
83
|
+
updateDOM(prevNode, anchor, config) {
|
|
84
|
+
void config;
|
|
85
|
+
const url = this.__url;
|
|
86
|
+
const target = this.__target;
|
|
87
|
+
const rel = this.__rel;
|
|
88
|
+
const title = this.__title;
|
|
89
|
+
if (url !== prevNode.__url) {
|
|
90
|
+
anchor.setAttribute('data-href', url);
|
|
91
|
+
// Update wiki-link attributes and external link class when URL changes
|
|
92
|
+
if (this.isWikiLink()) {
|
|
93
|
+
anchor.setAttribute('data-wiki-link', 'true');
|
|
94
|
+
anchor.setAttribute('data-wiki-target', url);
|
|
95
|
+
anchor.classList.remove('editor-link-external');
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
anchor.removeAttribute('data-wiki-link');
|
|
99
|
+
anchor.removeAttribute('data-wiki-target');
|
|
100
|
+
anchor.classList.remove('editor-link-broken');
|
|
101
|
+
if (this.isExternalLink()) {
|
|
102
|
+
anchor.classList.add('editor-link-external');
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
anchor.classList.remove('editor-link-external');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (target !== prevNode.__target) {
|
|
110
|
+
if (target) {
|
|
111
|
+
anchor.target = target;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
anchor.removeAttribute('target');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (rel !== prevNode.__rel) {
|
|
118
|
+
if (rel) {
|
|
119
|
+
anchor.rel = rel;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
anchor.removeAttribute('rel');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (title !== prevNode.__title) {
|
|
126
|
+
if (title) {
|
|
127
|
+
anchor.title = title;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
anchor.removeAttribute('title');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
static importDOM() {
|
|
136
|
+
return {
|
|
137
|
+
a: (node) => {
|
|
138
|
+
void node;
|
|
139
|
+
return {
|
|
140
|
+
conversion: convertAnchorElement,
|
|
141
|
+
priority: 1,
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
static importJSON(serializedNode) {
|
|
147
|
+
const node = $createCustomLinkNode(serializedNode.url, {
|
|
148
|
+
rel: serializedNode.rel,
|
|
149
|
+
target: serializedNode.target,
|
|
150
|
+
title: serializedNode.title,
|
|
151
|
+
});
|
|
152
|
+
if (serializedNode.wikiAliasState === 'empty') {
|
|
153
|
+
node.__wikiAliasState = 'empty';
|
|
154
|
+
}
|
|
155
|
+
if (serializedNode.wikiLinkOrigin) {
|
|
156
|
+
node.__wikiLinkOrigin = true;
|
|
157
|
+
}
|
|
158
|
+
node.setFormat(serializedNode.format);
|
|
159
|
+
node.setIndent(serializedNode.indent);
|
|
160
|
+
node.setDirection(serializedNode.direction);
|
|
161
|
+
return node;
|
|
162
|
+
}
|
|
163
|
+
exportJSON() {
|
|
164
|
+
return {
|
|
165
|
+
...super.exportJSON(),
|
|
166
|
+
type: 'link',
|
|
167
|
+
version: 1,
|
|
168
|
+
wikiAliasState: this.__wikiAliasState ?? undefined,
|
|
169
|
+
wikiLinkOrigin: this.__wikiLinkOrigin ? true : undefined,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
setWikiAliasState(state) {
|
|
173
|
+
const writable = this.getWritable();
|
|
174
|
+
writable.__wikiAliasState = state;
|
|
175
|
+
}
|
|
176
|
+
getWikiAliasState() {
|
|
177
|
+
return this.__wikiAliasState ?? null;
|
|
178
|
+
}
|
|
179
|
+
setWikiLinkOrigin(origin) {
|
|
180
|
+
const writable = this.getWritable();
|
|
181
|
+
writable.__wikiLinkOrigin = origin;
|
|
182
|
+
}
|
|
183
|
+
getWikiLinkOrigin() {
|
|
184
|
+
return this.__wikiLinkOrigin;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function convertAnchorElement(domNode) {
|
|
188
|
+
let node = null;
|
|
189
|
+
if (domNode instanceof HTMLAnchorElement) {
|
|
190
|
+
// Check data-href first (our custom attribute), then fall back to href
|
|
191
|
+
const url = domNode.getAttribute('data-href') || domNode.getAttribute('href');
|
|
192
|
+
if (url) {
|
|
193
|
+
node = $createCustomLinkNode(url, {
|
|
194
|
+
rel: domNode.getAttribute('rel'),
|
|
195
|
+
target: domNode.getAttribute('target'),
|
|
196
|
+
title: domNode.getAttribute('title'),
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return { node };
|
|
201
|
+
}
|
|
202
|
+
export function $createCustomLinkNode(url, attributes) {
|
|
203
|
+
const node = new CustomLinkNode(url, attributes);
|
|
204
|
+
node.__wikiAliasState = null;
|
|
205
|
+
return node;
|
|
206
|
+
}
|
|
207
|
+
export function $isCustomLinkNode(node) {
|
|
208
|
+
return node instanceof CustomLinkNode;
|
|
209
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ListItemNode, SerializedListItemNode } from '@lexical/list';
|
|
2
|
+
import { LexicalNode, NodeKey, EditorConfig } from 'lexical';
|
|
3
|
+
export declare const ORDERED_TASK_CHECKED_CLASS = "editor-listitem-ordered-checked";
|
|
4
|
+
export declare const ORDERED_TASK_UNCHECKED_CLASS = "editor-listitem-ordered-unchecked";
|
|
5
|
+
export type SerializedCustomListItemNode = SerializedListItemNode & {
|
|
6
|
+
taskChecked?: boolean | null;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* CustomListItemNode - Extends Lexical's ListItemNode to carry each item's true
|
|
10
|
+
* per-item task-checkbox state through the markdown round trip.
|
|
11
|
+
*
|
|
12
|
+
* Stock ListItemNode.getChecked() is not a stored value — it's derived as
|
|
13
|
+
* `parentList.getListType() === 'check' ? Boolean(__checked) : undefined`. In a
|
|
14
|
+
* list that mixes checkbox and plain items, the list is typed 'check' (so the
|
|
15
|
+
* items that need checkbox UI get it), which makes every plain item's
|
|
16
|
+
* getChecked() coerce `Boolean(undefined)` to `false` — indistinguishable from
|
|
17
|
+
* a genuine unchecked task. This subclass stores the tri-state
|
|
18
|
+
* (checked / unchecked / not-a-task) independent of the parent list's type, so
|
|
19
|
+
* export can tell plain items and unchecked tasks apart.
|
|
20
|
+
*/
|
|
21
|
+
export declare class CustomListItemNode extends ListItemNode {
|
|
22
|
+
/** @internal */
|
|
23
|
+
__taskChecked: boolean | null;
|
|
24
|
+
constructor(value?: number, checked?: boolean, key?: NodeKey);
|
|
25
|
+
static getType(): string;
|
|
26
|
+
static clone(node: CustomListItemNode): CustomListItemNode;
|
|
27
|
+
static importJSON(serializedNode: SerializedCustomListItemNode): CustomListItemNode;
|
|
28
|
+
exportJSON(): SerializedCustomListItemNode;
|
|
29
|
+
setChecked(checked?: boolean): this;
|
|
30
|
+
setTaskChecked(taskChecked: boolean | null): void;
|
|
31
|
+
getTaskChecked(): boolean | null;
|
|
32
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
33
|
+
updateDOM(prevNode: CustomListItemNode, dom: HTMLElement, config: EditorConfig): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Applies (or clears) the ordered-task checkbox affordance. Only fires for
|
|
36
|
+
* a leaf item (mirrors stock's own `!$isListNode(getFirstChild())` guard —
|
|
37
|
+
* a list item whose only child is a nested list isn't itself a task) whose
|
|
38
|
+
* parent list is `'number'`-typed and whose own `__taskChecked` (this
|
|
39
|
+
* item's field, not the list's) is non-null — a plain item in a mixed
|
|
40
|
+
* ordered list is left with no checkbox, same as a plain item in a mixed
|
|
41
|
+
* unordered list today.
|
|
42
|
+
*/
|
|
43
|
+
private updateOrderedTaskDOM;
|
|
44
|
+
}
|
|
45
|
+
export declare function $createCustomListItemNode(checked?: boolean): CustomListItemNode;
|
|
46
|
+
export declare function $isCustomListItemNode(node: LexicalNode | null | undefined): node is CustomListItemNode;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { ListItemNode, $isListNode } from '@lexical/list';
|
|
2
|
+
// Ordered-task checkbox rendering is owned entirely by this node rather than
|
|
3
|
+
// by @lexical/list's own checklist support, which only renders a checkbox
|
|
4
|
+
// (DOM attributes, theme classes, click/keyboard handling) when the *parent
|
|
5
|
+
// list's* listType is 'check' — and Lexical has no 'check'-typed list that is
|
|
6
|
+
// also numbered. These class names are deliberately separate from the
|
|
7
|
+
// editorTheme's listitemChecked/listitemUnchecked (Editor.tsx), which apply
|
|
8
|
+
// `list-style-type: none` and would suppress <ol> numbering.
|
|
9
|
+
export const ORDERED_TASK_CHECKED_CLASS = 'editor-listitem-ordered-checked';
|
|
10
|
+
export const ORDERED_TASK_UNCHECKED_CLASS = 'editor-listitem-ordered-unchecked';
|
|
11
|
+
/**
|
|
12
|
+
* CustomListItemNode - Extends Lexical's ListItemNode to carry each item's true
|
|
13
|
+
* per-item task-checkbox state through the markdown round trip.
|
|
14
|
+
*
|
|
15
|
+
* Stock ListItemNode.getChecked() is not a stored value — it's derived as
|
|
16
|
+
* `parentList.getListType() === 'check' ? Boolean(__checked) : undefined`. In a
|
|
17
|
+
* list that mixes checkbox and plain items, the list is typed 'check' (so the
|
|
18
|
+
* items that need checkbox UI get it), which makes every plain item's
|
|
19
|
+
* getChecked() coerce `Boolean(undefined)` to `false` — indistinguishable from
|
|
20
|
+
* a genuine unchecked task. This subclass stores the tri-state
|
|
21
|
+
* (checked / unchecked / not-a-task) independent of the parent list's type, so
|
|
22
|
+
* export can tell plain items and unchecked tasks apart.
|
|
23
|
+
*/
|
|
24
|
+
export class CustomListItemNode extends ListItemNode {
|
|
25
|
+
/** @internal */
|
|
26
|
+
__taskChecked;
|
|
27
|
+
constructor(value, checked, key) {
|
|
28
|
+
super(value, checked, key);
|
|
29
|
+
this.__taskChecked = checked ?? null;
|
|
30
|
+
}
|
|
31
|
+
static getType() {
|
|
32
|
+
return 'listitem'; // Use same type to replace the default ListItemNode
|
|
33
|
+
}
|
|
34
|
+
static clone(node) {
|
|
35
|
+
const cloned = new CustomListItemNode(node.__value, node.__checked, node.__key);
|
|
36
|
+
cloned.__taskChecked = $isCustomListItemNode(node) ? node.__taskChecked : null;
|
|
37
|
+
return cloned;
|
|
38
|
+
}
|
|
39
|
+
static importJSON(serializedNode) {
|
|
40
|
+
const node = $createCustomListItemNode(serializedNode.checked);
|
|
41
|
+
// Only fall back to the legacy `checked` field when `taskChecked` is
|
|
42
|
+
// absent (older serialized documents predating this field) — an
|
|
43
|
+
// explicit `taskChecked: null` means "plain item" and must not be
|
|
44
|
+
// coerced into `checked`'s boolean via `??`, or a plain item in a
|
|
45
|
+
// mixed list would be rehydrated as an unchecked task.
|
|
46
|
+
node.__taskChecked = serializedNode.taskChecked !== undefined ? serializedNode.taskChecked : (serializedNode.checked ?? null);
|
|
47
|
+
node.setValue(serializedNode.value);
|
|
48
|
+
node.setFormat(serializedNode.format);
|
|
49
|
+
node.setIndent(serializedNode.indent);
|
|
50
|
+
node.setDirection(serializedNode.direction);
|
|
51
|
+
return node;
|
|
52
|
+
}
|
|
53
|
+
exportJSON() {
|
|
54
|
+
return {
|
|
55
|
+
...super.exportJSON(),
|
|
56
|
+
type: 'listitem',
|
|
57
|
+
taskChecked: this.__taskChecked,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Lexical's own CheckListPlugin/registerList() transforms call setChecked()
|
|
61
|
+
// directly during live editing, bypassing the mapper entirely. Syncing
|
|
62
|
+
// __taskChecked here means toggling a checkbox on a previously-plain item
|
|
63
|
+
// in a mixed list correctly promotes it to a real task.
|
|
64
|
+
setChecked(checked) {
|
|
65
|
+
const writable = super.setChecked(checked);
|
|
66
|
+
writable.__taskChecked = checked ?? null;
|
|
67
|
+
return writable;
|
|
68
|
+
}
|
|
69
|
+
setTaskChecked(taskChecked) {
|
|
70
|
+
const writable = this.getWritable();
|
|
71
|
+
writable.__taskChecked = taskChecked;
|
|
72
|
+
}
|
|
73
|
+
getTaskChecked() {
|
|
74
|
+
return this.__taskChecked;
|
|
75
|
+
}
|
|
76
|
+
createDOM(config) {
|
|
77
|
+
const dom = super.createDOM(config);
|
|
78
|
+
this.updateOrderedTaskDOM(dom);
|
|
79
|
+
return dom;
|
|
80
|
+
}
|
|
81
|
+
updateDOM(prevNode, dom, config) {
|
|
82
|
+
const result = super.updateDOM(prevNode, dom, config);
|
|
83
|
+
this.updateOrderedTaskDOM(dom);
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Applies (or clears) the ordered-task checkbox affordance. Only fires for
|
|
88
|
+
* a leaf item (mirrors stock's own `!$isListNode(getFirstChild())` guard —
|
|
89
|
+
* a list item whose only child is a nested list isn't itself a task) whose
|
|
90
|
+
* parent list is `'number'`-typed and whose own `__taskChecked` (this
|
|
91
|
+
* item's field, not the list's) is non-null — a plain item in a mixed
|
|
92
|
+
* ordered list is left with no checkbox, same as a plain item in a mixed
|
|
93
|
+
* unordered list today.
|
|
94
|
+
*/
|
|
95
|
+
updateOrderedTaskDOM(dom) {
|
|
96
|
+
const parent = this.getParent();
|
|
97
|
+
const isOrderedTask = $isListNode(parent) && parent.getListType() === 'number' && !$isListNode(this.getFirstChild()) && this.__taskChecked !== null;
|
|
98
|
+
dom.classList.remove(ORDERED_TASK_CHECKED_CLASS, ORDERED_TASK_UNCHECKED_CLASS);
|
|
99
|
+
if (!isOrderedTask) {
|
|
100
|
+
// Stock updateListItemChecked already clears these for any non-'check'
|
|
101
|
+
// parent list, but that runs before this item's own listType/parent may
|
|
102
|
+
// have changed shape (e.g. an ordered task item demoted to plain) — so
|
|
103
|
+
// clear explicitly here too rather than relying on ordering.
|
|
104
|
+
dom.removeAttribute('role');
|
|
105
|
+
dom.removeAttribute('tabIndex');
|
|
106
|
+
dom.removeAttribute('aria-checked');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
dom.classList.add(this.__taskChecked ? ORDERED_TASK_CHECKED_CLASS : ORDERED_TASK_UNCHECKED_CLASS);
|
|
110
|
+
dom.setAttribute('role', 'checkbox');
|
|
111
|
+
dom.setAttribute('tabIndex', '-1');
|
|
112
|
+
dom.setAttribute('aria-checked', this.__taskChecked ? 'true' : 'false');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export function $createCustomListItemNode(checked) {
|
|
116
|
+
return new CustomListItemNode(undefined, checked);
|
|
117
|
+
}
|
|
118
|
+
export function $isCustomListItemNode(node) {
|
|
119
|
+
return node instanceof CustomListItemNode;
|
|
120
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ListNode, SerializedListNode, ListType } from '@lexical/list';
|
|
2
|
+
import { LexicalNode } from 'lexical';
|
|
3
|
+
export type SerializedCustomListNode = SerializedListNode & {
|
|
4
|
+
spread?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* CustomListNode - Extends Lexical's ListNode to carry the CommonMark "spread"
|
|
8
|
+
* (loose vs. tight) state through the markdown round trip.
|
|
9
|
+
*
|
|
10
|
+
* Stock ListNode has no field for this — the loose/tight distinction (blank
|
|
11
|
+
* lines between list items) exists on the parsed mdast List node but is
|
|
12
|
+
* otherwise discarded once imported into Lexical. This subclass preserves it
|
|
13
|
+
* so it can be written back out on export.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CustomListNode extends ListNode {
|
|
16
|
+
/** @internal */
|
|
17
|
+
__spread: boolean;
|
|
18
|
+
constructor(listType: ListType, start: number, key?: string);
|
|
19
|
+
static getType(): string;
|
|
20
|
+
static clone(node: CustomListNode): CustomListNode;
|
|
21
|
+
static importJSON(serializedNode: SerializedCustomListNode): CustomListNode;
|
|
22
|
+
exportJSON(): SerializedCustomListNode;
|
|
23
|
+
setSpread(spread: boolean): void;
|
|
24
|
+
getSpread(): boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function $createCustomListNode(listType: ListType, start?: number): CustomListNode;
|
|
27
|
+
export declare function $isCustomListNode(node: LexicalNode | null | undefined): node is CustomListNode;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ListNode } from '@lexical/list';
|
|
2
|
+
/**
|
|
3
|
+
* CustomListNode - Extends Lexical's ListNode to carry the CommonMark "spread"
|
|
4
|
+
* (loose vs. tight) state through the markdown round trip.
|
|
5
|
+
*
|
|
6
|
+
* Stock ListNode has no field for this — the loose/tight distinction (blank
|
|
7
|
+
* lines between list items) exists on the parsed mdast List node but is
|
|
8
|
+
* otherwise discarded once imported into Lexical. This subclass preserves it
|
|
9
|
+
* so it can be written back out on export.
|
|
10
|
+
*/
|
|
11
|
+
export class CustomListNode extends ListNode {
|
|
12
|
+
/** @internal */
|
|
13
|
+
__spread;
|
|
14
|
+
constructor(listType, start, key) {
|
|
15
|
+
super(listType, start, key);
|
|
16
|
+
this.__spread = false;
|
|
17
|
+
}
|
|
18
|
+
static getType() {
|
|
19
|
+
return 'list'; // Use same type to replace the default ListNode
|
|
20
|
+
}
|
|
21
|
+
static clone(node) {
|
|
22
|
+
const cloned = new CustomListNode(node.__listType, node.__start, node.__key);
|
|
23
|
+
cloned.__spread = $isCustomListNode(node) ? node.__spread : false;
|
|
24
|
+
return cloned;
|
|
25
|
+
}
|
|
26
|
+
static importJSON(serializedNode) {
|
|
27
|
+
const node = $createCustomListNode(serializedNode.listType, serializedNode.start);
|
|
28
|
+
node.__spread = serializedNode.spread ?? false;
|
|
29
|
+
node.setFormat(serializedNode.format);
|
|
30
|
+
node.setIndent(serializedNode.indent);
|
|
31
|
+
node.setDirection(serializedNode.direction);
|
|
32
|
+
return node;
|
|
33
|
+
}
|
|
34
|
+
exportJSON() {
|
|
35
|
+
return {
|
|
36
|
+
...super.exportJSON(),
|
|
37
|
+
type: 'list',
|
|
38
|
+
spread: this.__spread,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
setSpread(spread) {
|
|
42
|
+
const writable = this.getWritable();
|
|
43
|
+
writable.__spread = spread;
|
|
44
|
+
}
|
|
45
|
+
getSpread() {
|
|
46
|
+
return this.__spread;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function $createCustomListNode(listType, start = 1) {
|
|
50
|
+
return new CustomListNode(listType, start);
|
|
51
|
+
}
|
|
52
|
+
export function $isCustomListNode(node) {
|
|
53
|
+
return node instanceof CustomListNode;
|
|
54
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { DOMConversionMap, DOMExportOutput, EditorConfig, ElementNode, LexicalNode, SerializedElementNode } from 'lexical';
|
|
2
|
+
export type SerializedDefinitionListNode = SerializedElementNode;
|
|
3
|
+
export declare class DefinitionListNode extends ElementNode {
|
|
4
|
+
static getType(): string;
|
|
5
|
+
static clone(node: DefinitionListNode): DefinitionListNode;
|
|
6
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
7
|
+
updateDOM(): boolean;
|
|
8
|
+
static importDOM(): DOMConversionMap | null;
|
|
9
|
+
exportDOM(): DOMExportOutput;
|
|
10
|
+
static importJSON(serializedNode: SerializedDefinitionListNode): DefinitionListNode;
|
|
11
|
+
exportJSON(): SerializedDefinitionListNode;
|
|
12
|
+
isShadowRoot(): boolean;
|
|
13
|
+
canBeEmpty(): boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function $createDefinitionListNode(): DefinitionListNode;
|
|
16
|
+
export declare function $isDefinitionListNode(node: LexicalNode | null | undefined): node is DefinitionListNode;
|
|
17
|
+
export type SerializedDefinitionTermNode = SerializedElementNode;
|
|
18
|
+
export declare class DefinitionTermNode extends ElementNode {
|
|
19
|
+
static getType(): string;
|
|
20
|
+
static clone(node: DefinitionTermNode): DefinitionTermNode;
|
|
21
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
22
|
+
updateDOM(): boolean;
|
|
23
|
+
static importDOM(): DOMConversionMap | null;
|
|
24
|
+
exportDOM(): DOMExportOutput;
|
|
25
|
+
static importJSON(serializedNode: SerializedDefinitionTermNode): DefinitionTermNode;
|
|
26
|
+
exportJSON(): SerializedDefinitionTermNode;
|
|
27
|
+
}
|
|
28
|
+
export declare function $createDefinitionTermNode(): DefinitionTermNode;
|
|
29
|
+
export declare function $isDefinitionTermNode(node: LexicalNode | null | undefined): node is DefinitionTermNode;
|
|
30
|
+
export type SerializedDefinitionDescriptionNode = SerializedElementNode;
|
|
31
|
+
export declare class DefinitionDescriptionNode extends ElementNode {
|
|
32
|
+
static getType(): string;
|
|
33
|
+
static clone(node: DefinitionDescriptionNode): DefinitionDescriptionNode;
|
|
34
|
+
createDOM(config: EditorConfig): HTMLElement;
|
|
35
|
+
updateDOM(): boolean;
|
|
36
|
+
static importDOM(): DOMConversionMap | null;
|
|
37
|
+
exportDOM(): DOMExportOutput;
|
|
38
|
+
static importJSON(serializedNode: SerializedDefinitionDescriptionNode): DefinitionDescriptionNode;
|
|
39
|
+
exportJSON(): SerializedDefinitionDescriptionNode;
|
|
40
|
+
isShadowRoot(): boolean;
|
|
41
|
+
canBeEmpty(): boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function $createDefinitionDescriptionNode(): DefinitionDescriptionNode;
|
|
44
|
+
export declare function $isDefinitionDescriptionNode(node: LexicalNode | null | undefined): node is DefinitionDescriptionNode;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { ElementNode, } from 'lexical';
|
|
2
|
+
export class DefinitionListNode extends ElementNode {
|
|
3
|
+
static getType() {
|
|
4
|
+
return 'definition-list';
|
|
5
|
+
}
|
|
6
|
+
static clone(node) {
|
|
7
|
+
return new DefinitionListNode(node.__key);
|
|
8
|
+
}
|
|
9
|
+
createDOM(config) {
|
|
10
|
+
void config;
|
|
11
|
+
return document.createElement('dl');
|
|
12
|
+
}
|
|
13
|
+
updateDOM() {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
static importDOM() {
|
|
17
|
+
return {
|
|
18
|
+
dl: () => ({
|
|
19
|
+
conversion: convertDefinitionListElement,
|
|
20
|
+
priority: 1,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
exportDOM() {
|
|
25
|
+
return { element: document.createElement('dl') };
|
|
26
|
+
}
|
|
27
|
+
static importJSON(serializedNode) {
|
|
28
|
+
void serializedNode;
|
|
29
|
+
return $createDefinitionListNode();
|
|
30
|
+
}
|
|
31
|
+
exportJSON() {
|
|
32
|
+
return {
|
|
33
|
+
...super.exportJSON(),
|
|
34
|
+
type: 'definition-list',
|
|
35
|
+
version: 1,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
isShadowRoot() {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
canBeEmpty() {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function convertDefinitionListElement() {
|
|
46
|
+
return { node: $createDefinitionListNode() };
|
|
47
|
+
}
|
|
48
|
+
export function $createDefinitionListNode() {
|
|
49
|
+
return new DefinitionListNode();
|
|
50
|
+
}
|
|
51
|
+
export function $isDefinitionListNode(node) {
|
|
52
|
+
return node instanceof DefinitionListNode;
|
|
53
|
+
}
|
|
54
|
+
export class DefinitionTermNode extends ElementNode {
|
|
55
|
+
static getType() {
|
|
56
|
+
return 'definition-term';
|
|
57
|
+
}
|
|
58
|
+
static clone(node) {
|
|
59
|
+
return new DefinitionTermNode(node.__key);
|
|
60
|
+
}
|
|
61
|
+
createDOM(config) {
|
|
62
|
+
void config;
|
|
63
|
+
return document.createElement('dt');
|
|
64
|
+
}
|
|
65
|
+
updateDOM() {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
static importDOM() {
|
|
69
|
+
return {
|
|
70
|
+
dt: () => ({
|
|
71
|
+
conversion: convertDefinitionTermElement,
|
|
72
|
+
priority: 1,
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
exportDOM() {
|
|
77
|
+
return { element: document.createElement('dt') };
|
|
78
|
+
}
|
|
79
|
+
static importJSON(serializedNode) {
|
|
80
|
+
void serializedNode;
|
|
81
|
+
return $createDefinitionTermNode();
|
|
82
|
+
}
|
|
83
|
+
exportJSON() {
|
|
84
|
+
return {
|
|
85
|
+
...super.exportJSON(),
|
|
86
|
+
type: 'definition-term',
|
|
87
|
+
version: 1,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function convertDefinitionTermElement() {
|
|
92
|
+
return { node: $createDefinitionTermNode() };
|
|
93
|
+
}
|
|
94
|
+
export function $createDefinitionTermNode() {
|
|
95
|
+
return new DefinitionTermNode();
|
|
96
|
+
}
|
|
97
|
+
export function $isDefinitionTermNode(node) {
|
|
98
|
+
return node instanceof DefinitionTermNode;
|
|
99
|
+
}
|
|
100
|
+
export class DefinitionDescriptionNode extends ElementNode {
|
|
101
|
+
static getType() {
|
|
102
|
+
return 'definition-description';
|
|
103
|
+
}
|
|
104
|
+
static clone(node) {
|
|
105
|
+
return new DefinitionDescriptionNode(node.__key);
|
|
106
|
+
}
|
|
107
|
+
createDOM(config) {
|
|
108
|
+
void config;
|
|
109
|
+
return document.createElement('dd');
|
|
110
|
+
}
|
|
111
|
+
updateDOM() {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
static importDOM() {
|
|
115
|
+
return {
|
|
116
|
+
dd: () => ({
|
|
117
|
+
conversion: convertDefinitionDescriptionElement,
|
|
118
|
+
priority: 1,
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
exportDOM() {
|
|
123
|
+
return { element: document.createElement('dd') };
|
|
124
|
+
}
|
|
125
|
+
static importJSON(serializedNode) {
|
|
126
|
+
void serializedNode;
|
|
127
|
+
return $createDefinitionDescriptionNode();
|
|
128
|
+
}
|
|
129
|
+
exportJSON() {
|
|
130
|
+
return {
|
|
131
|
+
...super.exportJSON(),
|
|
132
|
+
type: 'definition-description',
|
|
133
|
+
version: 1,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
isShadowRoot() {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
canBeEmpty() {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function convertDefinitionDescriptionElement() {
|
|
144
|
+
return { node: $createDefinitionDescriptionNode() };
|
|
145
|
+
}
|
|
146
|
+
export function $createDefinitionDescriptionNode() {
|
|
147
|
+
return new DefinitionDescriptionNode();
|
|
148
|
+
}
|
|
149
|
+
export function $isDefinitionDescriptionNode(node) {
|
|
150
|
+
return node instanceof DefinitionDescriptionNode;
|
|
151
|
+
}
|