@portone/docx-editor 0.3.0 → 0.5.0
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/CHANGELOG.md +205 -0
- package/assets/editor.png +0 -0
- package/dist/DocxEditor.d.ts +1 -1
- package/dist/DocxEditor.js +45 -25
- package/dist/core.d.ts +1 -1
- package/dist/docx/cloning.js +4 -9
- package/dist/docx/commentOnlyChange.d.ts +5 -3
- package/dist/docx/comments/grammar.d.ts +27 -10
- package/dist/docx/comments/grammar.js +18 -67
- package/dist/docx/comments/model.d.ts +5 -6
- package/dist/docx/comments/model.js +0 -9
- package/dist/docx/comments/parts.d.ts +16 -10
- package/dist/docx/comments/parts.js +65 -13
- package/dist/docx/comments/people.d.ts +11 -3
- package/dist/docx/comments/people.js +20 -6
- package/dist/docx/comments/policy.js +7 -1
- package/dist/docx/comments/reading.d.ts +4 -2
- package/dist/docx/comments/reading.js +1 -14
- package/dist/docx/comments/writing.js +78 -35
- package/dist/docx/exportDocx.js +30 -18
- package/dist/docx/exportRefs.d.ts +8 -3
- package/dist/docx/exportRefs.js +2 -1
- package/dist/docx/fidelity.js +24 -10
- package/dist/docx/fields.d.ts +42 -0
- package/dist/docx/fields.js +76 -0
- package/dist/docx/formatting/attrs.d.ts +20 -2
- package/dist/docx/formatting/attrs.js +57 -2
- package/dist/docx/formatting/context.d.ts +10 -2
- package/dist/docx/formatting/context.js +23 -5
- package/dist/docx/formatting/resolve.d.ts +10 -4
- package/dist/docx/formatting/resolve.js +31 -11
- package/dist/docx/formatting/styles.d.ts +25 -2
- package/dist/docx/formatting/styles.js +84 -3
- package/dist/docx/headersFooters.d.ts +89 -20
- package/dist/docx/headersFooters.js +163 -172
- package/dist/docx/hyperlink.d.ts +14 -4
- package/dist/docx/hyperlink.js +4 -1
- package/dist/docx/importDocx.d.ts +1 -1
- package/dist/docx/importDocx.js +135 -74
- package/dist/docx/importParagraph.d.ts +16 -4
- package/dist/docx/importParagraph.js +87 -93
- package/dist/docx/importPolicy.d.ts +70 -0
- package/dist/docx/importPolicy.js +190 -0
- package/dist/docx/importPreserved.d.ts +30 -0
- package/dist/docx/importPreserved.js +54 -0
- package/dist/docx/importTable.d.ts +2 -2
- package/dist/docx/importTable.js +107 -66
- package/dist/docx/invariants.js +42 -31
- package/dist/docx/newLists.d.ts +30 -0
- package/dist/docx/newLists.js +24 -1
- package/dist/docx/notes.d.ts +6 -1
- package/dist/docx/notes.js +6 -16
- package/dist/docx/numberingPlanner.d.ts +6 -3
- package/dist/docx/numberingPlanner.js +38 -7
- package/dist/docx/pageGeometry.d.ts +5 -14
- package/dist/docx/pageGeometry.js +0 -12
- package/dist/docx/protectionPolicy.d.ts +13 -5
- package/dist/docx/protectionPolicy.js +32 -22
- package/dist/docx/scan.d.ts +18 -8
- package/dist/docx/scan.js +17 -11
- package/dist/docx/sections.d.ts +126 -0
- package/dist/docx/sections.js +207 -0
- package/dist/docx/serializeBlock.d.ts +13 -4
- package/dist/docx/serializeBlock.js +16 -18
- package/dist/docx/serializeParagraph.d.ts +4 -0
- package/dist/docx/serializeParagraph.js +1 -0
- package/dist/docx/serializePreserved.d.ts +14 -0
- package/dist/docx/serializePreserved.js +24 -0
- package/dist/docx/serializeStory.d.ts +17 -0
- package/dist/docx/serializeStory.js +17 -0
- package/dist/docx/serializeTable.js +10 -13
- package/dist/docx/session.d.ts +24 -7
- package/dist/docx/session.js +37 -6
- package/dist/docx/story.d.ts +140 -0
- package/dist/docx/story.js +237 -0
- package/dist/docx/storyProjection.js +6 -1
- package/dist/docx/tableFormatting/conditions.d.ts +76 -0
- package/dist/docx/tableFormatting/conditions.js +196 -0
- package/dist/docx/tableFormatting/editing.d.ts +7 -3
- package/dist/docx/tableFormatting/editing.js +4 -5
- package/dist/docx/tableFormatting/reading.d.ts +49 -19
- package/dist/docx/tableFormatting/reading.js +109 -35
- package/dist/docx/tableFormatting.d.ts +1 -0
- package/dist/docx/tableFormatting.js +1 -0
- package/dist/docx/tableTemplate.js +12 -12
- package/dist/editor/clipboard/htmlReader.d.ts +30 -0
- package/dist/editor/clipboard/htmlReader.js +302 -0
- package/dist/editor/clipboard/internalChannel.d.ts +57 -0
- package/dist/editor/clipboard/internalChannel.js +58 -0
- package/dist/editor/clipboard/normalizers.d.ts +99 -0
- package/dist/editor/clipboard/normalizers.js +199 -0
- package/dist/editor/clipboard/parser.d.ts +34 -0
- package/dist/editor/clipboard/parser.js +58 -0
- package/dist/editor/clipboard/plugin.d.ts +21 -0
- package/dist/editor/clipboard/plugin.js +320 -0
- package/dist/editor/clipboard/readContext.d.ts +24 -0
- package/dist/editor/clipboard/readContext.js +19 -0
- package/dist/editor/clipboard/readers.d.ts +33 -0
- package/dist/editor/clipboard/readers.js +37 -0
- package/dist/editor/commands/comments/editing.d.ts +26 -6
- package/dist/editor/commands/comments/editing.js +175 -105
- package/dist/editor/commands/comments/model.d.ts +34 -17
- package/dist/editor/commands/comments/model.js +11 -0
- package/dist/editor/commands/comments/reading.d.ts +5 -3
- package/dist/editor/commands/comments/reading.js +8 -58
- package/dist/editor/commands/formatting/propertyCommands.js +6 -1
- package/dist/editor/commands/index.d.ts +2 -2
- package/dist/editor/commands/index.js +2 -0
- package/dist/editor/commands/listCommands.d.ts +12 -3
- package/dist/editor/commands/listCommands.js +76 -30
- package/dist/editor/commands/noteQueries.d.ts +22 -5
- package/dist/editor/commands/noteQueries.js +34 -6
- package/dist/editor/commands/paragraphCommands.js +6 -1
- package/dist/editor/createEditor.js +14 -4
- package/dist/editor/documentStyles.d.ts +26 -4
- package/dist/editor/documentStyles.js +9 -4
- package/dist/editor/editorDocument.d.ts +7 -6
- package/dist/editor/editorDocument.js +18 -6
- package/dist/editor/imageFiles.d.ts +2 -2
- package/dist/editor/imageFiles.js +2 -0
- package/dist/editor/insertTable.d.ts +1 -1
- package/dist/editor/insertTable.js +2 -2
- package/dist/editor/paragraphEdits.d.ts +16 -1
- package/dist/editor/paragraphEdits.js +13 -5
- package/dist/editor/paragraphPlacement.d.ts +11 -0
- package/dist/editor/paragraphPlacement.js +18 -0
- package/dist/editor/plainText.d.ts +12 -0
- package/dist/editor/plainText.js +2 -1
- package/dist/editor/plugins/columnResize.js +6 -3
- package/dist/editor/plugins/commentComposer.d.ts +28 -0
- package/dist/editor/plugins/commentComposer.js +46 -0
- package/dist/editor/plugins/commentDecorations.d.ts +29 -2
- package/dist/editor/plugins/commentDecorations.js +89 -15
- package/dist/editor/plugins/documentProjection.d.ts +31 -0
- package/dist/editor/plugins/documentProjection.js +22 -0
- package/dist/editor/plugins/imagePaste.js +20 -10
- package/dist/editor/plugins/linkPanel.d.ts +7 -3
- package/dist/editor/plugins/linkPanel.js +13 -27
- package/dist/editor/plugins/numberingDecorations.d.ts +10 -4
- package/dist/editor/plugins/numberingDecorations.js +43 -2
- package/dist/editor/plugins/panelState.d.ts +67 -0
- package/dist/editor/plugins/panelState.js +54 -0
- package/dist/editor/plugins/paragraphDisplay.js +9 -3
- package/dist/editor/plugins/tableContextMenu.d.ts +1 -1
- package/dist/editor/plugins/tableContextMenu.js +30 -47
- package/dist/editor/plugins/tableDisplay.js +19 -5
- package/dist/editor/plugins/textContextMenu.d.ts +1 -1
- package/dist/editor/plugins/textContextMenu.js +30 -47
- package/dist/model/format.d.ts +50 -0
- package/dist/model/format.js +65 -0
- package/dist/numbering/listRegistry.d.ts +37 -0
- package/dist/numbering/listRegistry.js +112 -0
- package/dist/numbering/listTemplate.d.ts +26 -17
- package/dist/numbering/listTemplate.js +66 -20
- package/dist/numbering/markers.d.ts +15 -6
- package/dist/numbering/markers.js +26 -59
- package/dist/numbering/parseNumbering.d.ts +70 -5
- package/dist/numbering/parseNumbering.js +100 -26
- package/dist/numbering/spellers.d.ts +15 -0
- package/dist/numbering/spellers.js +96 -0
- package/dist/numbering/writeNumbering.d.ts +5 -3
- package/dist/numbering/writeNumbering.js +15 -15
- package/dist/ooxml/conformance.d.ts +28 -0
- package/dist/ooxml/conformance.js +20 -0
- package/dist/ooxml/errors.d.ts +5 -5
- package/dist/ooxml/fragment.d.ts +11 -0
- package/dist/ooxml/fragment.js +14 -4
- package/dist/ooxml/image.d.ts +3 -4
- package/dist/ooxml/image.js +50 -5
- package/dist/ooxml/names.d.ts +15 -0
- package/dist/ooxml/names.js +10 -1
- package/dist/ooxml/partSplice.d.ts +1 -1
- package/dist/ooxml/partSplice.js +10 -3
- package/dist/ooxml/props.d.ts +8 -0
- package/dist/ooxml/props.js +14 -4
- package/dist/ooxml/rangeMarkers.d.ts +5 -0
- package/dist/ooxml/rangeMarkers.js +24 -0
- package/dist/ooxml/xml.d.ts +8 -9
- package/dist/ooxml/xml.js +6 -6
- package/dist/page/PageGuides.d.ts +8 -4
- package/dist/page/PageGuides.js +13 -37
- package/dist/page/pageLayout.d.ts +62 -13
- package/dist/page/pageLayout.js +91 -37
- package/dist/page/usePageLayout.d.ts +14 -11
- package/dist/page/usePageLayout.js +21 -29
- package/dist/schema/attrRoles.js +44 -19
- package/dist/schema/docxSchema.d.ts +9 -1
- package/dist/schema/docxSchema.js +220 -139
- package/dist/schema/editGuard.d.ts +1 -1
- package/dist/schema/guards.js +2 -2
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/preservedFragments.d.ts +12 -0
- package/dist/schema/preservedFragments.js +38 -0
- package/dist/schema/preservedGuards.d.ts +9 -7
- package/dist/schema/preservedGuards.js +112 -11
- package/dist/schema/protection.d.ts +34 -5
- package/dist/schema/protection.js +42 -14
- package/dist/schema/rendering.js +3 -1
- package/dist/schema/stories.d.ts +49 -0
- package/dist/schema/stories.js +78 -0
- package/dist/styles/classNames.d.ts +16 -7
- package/dist/styles/classNames.js +16 -7
- package/dist/styles.css +90 -30
- package/dist/table/cellFormatting.js +1 -2
- package/dist/table/gridBorders.d.ts +11 -15
- package/dist/table/gridBorders.js +32 -18
- package/dist/table/resize.d.ts +5 -3
- package/dist/ui/CommentsPanel.d.ts +1 -3
- package/dist/ui/CommentsPanel.js +24 -15
- package/dist/ui/NotesPanel.js +2 -2
- package/dist/ui/TextMenu.d.ts +1 -3
- package/dist/ui/TextMenu.js +10 -6
- package/dist/ui/comments/CommentComposer.d.ts +6 -1
- package/dist/ui/comments/CommentComposer.js +26 -3
- package/package.json +1 -1
- package/dist/editor/externalClipboard.d.ts +0 -11
- package/dist/editor/externalClipboard.js +0 -456
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// src/schema/docxSchema.ts
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Schema
|
|
4
|
+
} from "prosemirror-model";
|
|
3
5
|
import {
|
|
4
6
|
spanCount,
|
|
7
|
+
toBandSizes,
|
|
5
8
|
toCellFormat,
|
|
6
9
|
toCellMargins,
|
|
7
10
|
toColWidth,
|
|
@@ -11,10 +14,12 @@ import {
|
|
|
11
14
|
toRowFormat,
|
|
12
15
|
toRunFormat,
|
|
13
16
|
toTableFormat,
|
|
17
|
+
toTableStyleConditions,
|
|
14
18
|
toTableWidth
|
|
15
19
|
} from "../model/format.js";
|
|
16
20
|
import {
|
|
17
21
|
ANY_ELEMENT,
|
|
22
|
+
ANY_ELEMENTS,
|
|
18
23
|
ATTRIBUTES,
|
|
19
24
|
acceptRawXml,
|
|
20
25
|
ELEMENT
|
|
@@ -31,6 +36,7 @@ import {
|
|
|
31
36
|
} from "../styles/inlineStyle.js";
|
|
32
37
|
import { imageNodeSpec, runMarkSpec } from "./rendering.js";
|
|
33
38
|
import { imageNodeSpec as imageNodeSpec2, runMarkSpec as runMarkSpec2 } from "./rendering.js";
|
|
39
|
+
var NO_STORIES = Object.freeze({});
|
|
34
40
|
function isRecord(value) {
|
|
35
41
|
return typeof value === "object" && value !== null;
|
|
36
42
|
}
|
|
@@ -76,7 +82,7 @@ function repliesHoldTheirXml(value) {
|
|
|
76
82
|
const replies = value;
|
|
77
83
|
return replies.every((reply) => {
|
|
78
84
|
if (!isRecord(reply)) return true;
|
|
79
|
-
return acceptRawXml(
|
|
85
|
+
return acceptRawXml(ANY_ELEMENT, text(reply.extensionXml) ?? null) !== false;
|
|
80
86
|
});
|
|
81
87
|
}
|
|
82
88
|
var SDT_PREFIX = {
|
|
@@ -94,25 +100,90 @@ var LINK_PREFIX = {
|
|
|
94
100
|
function rawXml(dom, attribute, shape) {
|
|
95
101
|
return acceptRawXml(shape, dom.getAttribute(attribute));
|
|
96
102
|
}
|
|
103
|
+
function preservedDisplayOf(value) {
|
|
104
|
+
switch (value) {
|
|
105
|
+
case "text":
|
|
106
|
+
return "text";
|
|
107
|
+
case "break":
|
|
108
|
+
return "break";
|
|
109
|
+
case "chip":
|
|
110
|
+
return "chip";
|
|
111
|
+
default:
|
|
112
|
+
return "hidden";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function preservedAttributes(node, className) {
|
|
116
|
+
return {
|
|
117
|
+
class: className,
|
|
118
|
+
"data-xml": text(node.attrs.xml),
|
|
119
|
+
"data-element": text(node.attrs.element),
|
|
120
|
+
"data-display": preservedDisplayOf(node.attrs.display),
|
|
121
|
+
"data-text": text(node.attrs.text),
|
|
122
|
+
"data-guarded": node.attrs.guarded === true ? "1" : void 0
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function preservedDom(node, className) {
|
|
126
|
+
const attributes = preservedAttributes(node, className);
|
|
127
|
+
const display = preservedDisplayOf(node.attrs.display);
|
|
128
|
+
const preview = text(node.attrs.text);
|
|
129
|
+
const element = text(node.attrs.element);
|
|
130
|
+
if (display === "break") return ["span", attributes, ["br"]];
|
|
131
|
+
if (display === "text") return ["span", attributes, preview ?? ""];
|
|
132
|
+
if (display === "chip") {
|
|
133
|
+
return [
|
|
134
|
+
"span",
|
|
135
|
+
{ ...attributes, title: element ?? UNKNOWN_PLACEHOLDER },
|
|
136
|
+
preview !== void 0 && preview !== "" ? preview : element ?? "?"
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
return ["span", attributes];
|
|
140
|
+
}
|
|
141
|
+
function preservedAttrs(dom) {
|
|
142
|
+
const xml = rawXml(dom, "data-xml", ANY_ELEMENT);
|
|
143
|
+
if (xml === false) return false;
|
|
144
|
+
return {
|
|
145
|
+
xml,
|
|
146
|
+
element: dom.getAttribute("data-element"),
|
|
147
|
+
display: preservedDisplayOf(dom.getAttribute("data-display")),
|
|
148
|
+
text: dom.getAttribute("data-text"),
|
|
149
|
+
guarded: dom.getAttribute("data-guarded") === "1"
|
|
150
|
+
};
|
|
151
|
+
}
|
|
97
152
|
var TABLE_PLACEHOLDER = "Table (unsupported layout, original is preserved)";
|
|
98
153
|
var UNKNOWN_PLACEHOLDER = "Unsupported content (not editable, original is preserved)";
|
|
99
154
|
var TABLE_NAMES = ["w:tbl", "tbl"];
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
return { className: editorClassNames.rawBlock, label: UNKNOWN_PLACEHOLDER };
|
|
155
|
+
function placeholderLabel(name) {
|
|
156
|
+
return name !== void 0 && TABLE_NAMES.includes(name) ? TABLE_PLACEHOLDER : UNKNOWN_PLACEHOLDER;
|
|
157
|
+
}
|
|
158
|
+
function preservedNameOf(dom) {
|
|
159
|
+
const name = dom.getAttribute("data-name");
|
|
160
|
+
return name === null || name === "" ? null : name;
|
|
108
161
|
}
|
|
109
|
-
var DOCX_RAW_SELECTOR = [
|
|
110
|
-
editorClassNames.rawBlock,
|
|
111
|
-
editorClassNames.tablePlaceholder
|
|
112
|
-
].map((className) => `div[data-src].${className}`).join(", ");
|
|
113
162
|
var docxSchema = new Schema({
|
|
114
163
|
nodes: {
|
|
115
|
-
doc: {
|
|
164
|
+
doc: {
|
|
165
|
+
content: "block+",
|
|
166
|
+
attrs: {
|
|
167
|
+
/**
|
|
168
|
+
* The definitions of the lists started while editing, which the export writes into
|
|
169
|
+
* numbering.xml. Read back through `numbering/listRegistry`.
|
|
170
|
+
*/
|
|
171
|
+
newLists: { default: null },
|
|
172
|
+
/**
|
|
173
|
+
* The section properties that close the body: the paper the document's last section is
|
|
174
|
+
* written on, its headers and its page numbering (§17.6.18). Held as the fragment the
|
|
175
|
+
* document wrote, so an untouched document goes back out as the bytes it arrived as.
|
|
176
|
+
* Read through `docx/sections`.
|
|
177
|
+
*/
|
|
178
|
+
sectPr: { default: null },
|
|
179
|
+
/**
|
|
180
|
+
* What each side story - a comment's body, a footnote's - currently says, under the key
|
|
181
|
+
* naming it (`./stories`). Read and written through `docx/story`; it never reaches the
|
|
182
|
+
* DOM, so a copy out of the editor carries none of it.
|
|
183
|
+
*/
|
|
184
|
+
stories: { default: NO_STORIES }
|
|
185
|
+
}
|
|
186
|
+
},
|
|
116
187
|
paragraph: {
|
|
117
188
|
group: "block modelled",
|
|
118
189
|
content: "inline*",
|
|
@@ -202,7 +273,21 @@ var docxSchema = new Schema({
|
|
|
202
273
|
/** The lines between cells the table style laid down, so an edit can derive them again */
|
|
203
274
|
styleInside: { default: null },
|
|
204
275
|
/** The cell margins the table style laid down, carried along for the same reason */
|
|
205
|
-
styleCellMargins: { default: null }
|
|
276
|
+
styleCellMargins: { default: null },
|
|
277
|
+
/**
|
|
278
|
+
* What the table style dresses each part of a table with (`w:tblStylePr`), by the part it
|
|
279
|
+
* covers. Which of them a cell takes is worked out from where it sits and the table's own
|
|
280
|
+
* `w:tblLook`, so an edit that moves the grid derives them again
|
|
281
|
+
*/
|
|
282
|
+
styleConditions: { default: null },
|
|
283
|
+
/** How many rows and columns one band of the table style is made of */
|
|
284
|
+
styleBands: { default: null },
|
|
285
|
+
/**
|
|
286
|
+
* The markers that stood between this table's rows: the ones ahead of the first row
|
|
287
|
+
* (`docx/importTable`). They are invisible and belong to no row, so they ride along on
|
|
288
|
+
* the table and go back where they stood
|
|
289
|
+
*/
|
|
290
|
+
leadingXml: { default: null }
|
|
206
291
|
},
|
|
207
292
|
toDOM(node) {
|
|
208
293
|
const format = toTableFormat(node.attrs.format);
|
|
@@ -223,7 +308,12 @@ var docxSchema = new Schema({
|
|
|
223
308
|
),
|
|
224
309
|
"data-style-margins": formatJson(
|
|
225
310
|
toCellMargins(node.attrs.styleCellMargins)
|
|
226
|
-
)
|
|
311
|
+
),
|
|
312
|
+
"data-style-conditions": formatJson(
|
|
313
|
+
toTableStyleConditions(node.attrs.styleConditions)
|
|
314
|
+
),
|
|
315
|
+
"data-style-bands": formatJson(toBandSizes(node.attrs.styleBands)),
|
|
316
|
+
"data-leading": text(node.attrs.leadingXml)
|
|
227
317
|
};
|
|
228
318
|
const body = ["tbody", 0];
|
|
229
319
|
if (gridCols.length === 0) return ["table", attrs, body];
|
|
@@ -246,7 +336,8 @@ var docxSchema = new Schema({
|
|
|
246
336
|
"data-gridchange",
|
|
247
337
|
ELEMENT("tblGridChange")
|
|
248
338
|
);
|
|
249
|
-
|
|
339
|
+
const leadingXml = rawXml(dom, "data-leading", ANY_ELEMENTS);
|
|
340
|
+
if (tblAttrs === false || tblPr === false || gridChange === false || leadingXml === false) {
|
|
250
341
|
return false;
|
|
251
342
|
}
|
|
252
343
|
return {
|
|
@@ -262,7 +353,14 @@ var docxSchema = new Schema({
|
|
|
262
353
|
),
|
|
263
354
|
styleCellMargins: toCellMargins(
|
|
264
355
|
parseJson(dom.getAttribute("data-style-margins"))
|
|
265
|
-
)
|
|
356
|
+
),
|
|
357
|
+
styleConditions: toTableStyleConditions(
|
|
358
|
+
parseJson(dom.getAttribute("data-style-conditions"))
|
|
359
|
+
),
|
|
360
|
+
styleBands: toBandSizes(
|
|
361
|
+
parseJson(dom.getAttribute("data-style-bands"))
|
|
362
|
+
),
|
|
363
|
+
leadingXml
|
|
266
364
|
};
|
|
267
365
|
}
|
|
268
366
|
}
|
|
@@ -278,7 +376,11 @@ var docxSchema = new Schema({
|
|
|
278
376
|
tblPrEx: { default: null },
|
|
279
377
|
/** The whole `<w:trPr>...</w:trPr>` XML */
|
|
280
378
|
trPr: { default: null },
|
|
281
|
-
format: { default: null }
|
|
379
|
+
format: { default: null },
|
|
380
|
+
/** The markers that stood ahead of this row's first cell (`docx/importTable`) */
|
|
381
|
+
leadingXml: { default: null },
|
|
382
|
+
/** The markers that stood between this row and the next one, under the table */
|
|
383
|
+
trailingXml: { default: null }
|
|
282
384
|
},
|
|
283
385
|
toDOM(node) {
|
|
284
386
|
const format = toRowFormat(node.attrs.format);
|
|
@@ -290,7 +392,9 @@ var docxSchema = new Schema({
|
|
|
290
392
|
"data-trattrs": text(node.attrs.trAttrs),
|
|
291
393
|
"data-tblprex": text(node.attrs.tblPrEx),
|
|
292
394
|
"data-trpr": text(node.attrs.trPr),
|
|
293
|
-
"data-fmt": formatJson(format)
|
|
395
|
+
"data-fmt": formatJson(format),
|
|
396
|
+
"data-leading": text(node.attrs.leadingXml),
|
|
397
|
+
"data-trailing": text(node.attrs.trailingXml)
|
|
294
398
|
},
|
|
295
399
|
0
|
|
296
400
|
];
|
|
@@ -302,14 +406,18 @@ var docxSchema = new Schema({
|
|
|
302
406
|
const trAttrs = rawXml(dom, "data-trattrs", ATTRIBUTES);
|
|
303
407
|
const tblPrEx = rawXml(dom, "data-tblprex", ELEMENT("tblPrEx"));
|
|
304
408
|
const trPr = rawXml(dom, "data-trpr", ELEMENT("trPr"));
|
|
305
|
-
|
|
409
|
+
const leadingXml = rawXml(dom, "data-leading", ANY_ELEMENTS);
|
|
410
|
+
const trailingXml = rawXml(dom, "data-trailing", ANY_ELEMENTS);
|
|
411
|
+
if (trAttrs === false || tblPrEx === false || trPr === false || leadingXml === false || trailingXml === false) {
|
|
306
412
|
return false;
|
|
307
413
|
}
|
|
308
414
|
return {
|
|
309
415
|
trAttrs,
|
|
310
416
|
tblPrEx,
|
|
311
417
|
trPr,
|
|
312
|
-
format: toRowFormat(parseJson(dom.getAttribute("data-fmt")))
|
|
418
|
+
format: toRowFormat(parseJson(dom.getAttribute("data-fmt"))),
|
|
419
|
+
leadingXml,
|
|
420
|
+
trailingXml
|
|
313
421
|
};
|
|
314
422
|
}
|
|
315
423
|
}
|
|
@@ -343,7 +451,9 @@ var docxSchema = new Schema({
|
|
|
343
451
|
* the lock lives inside that very XML.
|
|
344
452
|
*/
|
|
345
453
|
sdtContentsLocked: { default: false },
|
|
346
|
-
sdtDeletionLocked: { default: false }
|
|
454
|
+
sdtDeletionLocked: { default: false },
|
|
455
|
+
/** The markers that stood between this cell and the next one, under the row */
|
|
456
|
+
trailingXml: { default: null }
|
|
347
457
|
},
|
|
348
458
|
toDOM(node) {
|
|
349
459
|
const format = toCellFormat(node.attrs.format);
|
|
@@ -365,7 +475,8 @@ var docxSchema = new Schema({
|
|
|
365
475
|
"data-fmt": formatJson(format),
|
|
366
476
|
"data-sdt-prefix": text(node.attrs.sdtPrefix),
|
|
367
477
|
"data-sdt-contents-locked": locked ? "1" : void 0,
|
|
368
|
-
"data-sdt-deletion-locked": node.attrs.sdtDeletionLocked === true ? "1" : void 0
|
|
478
|
+
"data-sdt-deletion-locked": node.attrs.sdtDeletionLocked === true ? "1" : void 0,
|
|
479
|
+
"data-trailing": text(node.attrs.trailingXml)
|
|
369
480
|
},
|
|
370
481
|
0
|
|
371
482
|
];
|
|
@@ -377,7 +488,8 @@ var docxSchema = new Schema({
|
|
|
377
488
|
const tcAttrs = rawXml(dom, "data-tcattrs", ATTRIBUTES);
|
|
378
489
|
const tcPr = rawXml(dom, "data-tcpr", ELEMENT("tcPr"));
|
|
379
490
|
const sdtPrefix = rawXml(dom, "data-sdt-prefix", SDT_PREFIX);
|
|
380
|
-
|
|
491
|
+
const trailingXml = rawXml(dom, "data-trailing", ANY_ELEMENTS);
|
|
492
|
+
if (tcAttrs === false || tcPr === false || sdtPrefix === false || trailingXml === false) {
|
|
381
493
|
return false;
|
|
382
494
|
}
|
|
383
495
|
return {
|
|
@@ -392,109 +504,68 @@ var docxSchema = new Schema({
|
|
|
392
504
|
format: toCellFormat(parseJson(dom.getAttribute("data-fmt"))),
|
|
393
505
|
sdtPrefix,
|
|
394
506
|
sdtContentsLocked: dom.getAttribute("data-sdt-contents-locked") === "1",
|
|
395
|
-
sdtDeletionLocked: dom.getAttribute("data-sdt-deletion-locked") === "1"
|
|
507
|
+
sdtDeletionLocked: dom.getAttribute("data-sdt-deletion-locked") === "1",
|
|
508
|
+
trailingXml
|
|
396
509
|
};
|
|
397
510
|
}
|
|
398
511
|
}
|
|
399
512
|
]
|
|
400
513
|
},
|
|
401
514
|
/**
|
|
402
|
-
* The node
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
515
|
+
* The one node a block the editor has no model for stands as, wherever it stood: under the
|
|
516
|
+
* body, or inside a table cell.
|
|
517
|
+
*
|
|
518
|
+
* Which of the two it came from is what it carries the original as. A body block is one of the
|
|
519
|
+
* fragments the session holds, so it names that fragment and the bytes go back out untouched;
|
|
520
|
+
* a block inside a cell was never a fragment of its own, so it carries its XML with it.
|
|
521
|
+
*
|
|
522
|
+
* `display` says whether anything of it is on screen. A range marker draws nothing - it stands
|
|
523
|
+
* between blocks and marks a spot rather than holding content - while a table nobody could take
|
|
524
|
+
* apart draws a box saying so.
|
|
406
525
|
*/
|
|
407
526
|
rawBlock: {
|
|
408
527
|
group: "block preserved",
|
|
409
528
|
atom: true,
|
|
410
529
|
selectable: false,
|
|
411
530
|
attrs: {
|
|
531
|
+
/** The element, verbatim, for a block the session holds no fragment of */
|
|
412
532
|
xml: { default: null },
|
|
533
|
+
/** The fragment of the session this block was opened from */
|
|
534
|
+
srcId: { default: null },
|
|
413
535
|
/** The original element name (for example `w:tbl`) */
|
|
414
|
-
name: { default: null }
|
|
536
|
+
name: { default: null },
|
|
537
|
+
display: { default: "chip" },
|
|
538
|
+
/** Whether the deletion guard answers for this block (`./preservedGuards`) */
|
|
539
|
+
guarded: { default: false }
|
|
415
540
|
},
|
|
416
541
|
toDOM(node) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
542
|
+
const name = text(node.attrs.name);
|
|
543
|
+
const display = preservedDisplayOf(node.attrs.display);
|
|
544
|
+
const attributes = {
|
|
545
|
+
class: editorClassNames.rawBlock,
|
|
546
|
+
"data-xml": text(node.attrs.xml),
|
|
547
|
+
"data-src": text(node.attrs.srcId) ?? "",
|
|
548
|
+
"data-name": name ?? "",
|
|
549
|
+
"data-display": display,
|
|
550
|
+
"data-guarded": node.attrs.guarded === true ? "1" : void 0
|
|
551
|
+
};
|
|
552
|
+
if (display !== "chip") return ["div", attributes];
|
|
553
|
+
return ["div", attributes, placeholderLabel(name)];
|
|
426
554
|
},
|
|
427
555
|
parseDOM: [
|
|
428
556
|
{
|
|
429
|
-
tag: `div.${editorClassNames.
|
|
557
|
+
tag: `div.${editorClassNames.rawBlock}[data-name]`,
|
|
430
558
|
getAttrs: (dom) => {
|
|
431
559
|
const xml = rawXml(dom, "data-xml", ANY_ELEMENT);
|
|
432
560
|
if (xml === false) return false;
|
|
433
|
-
return {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
group: "block preserved",
|
|
441
|
-
atom: true,
|
|
442
|
-
selectable: false,
|
|
443
|
-
attrs: {
|
|
444
|
-
srcId: { default: null },
|
|
445
|
-
/** The original element name (for example `w:tbl`) */
|
|
446
|
-
name: { default: null }
|
|
447
|
-
},
|
|
448
|
-
toDOM(node) {
|
|
449
|
-
const { className, label } = rawBlockDom(text(node.attrs.name));
|
|
450
|
-
return [
|
|
451
|
-
"div",
|
|
452
|
-
{
|
|
453
|
-
class: className,
|
|
454
|
-
"data-src": text(node.attrs.srcId) ?? "",
|
|
455
|
-
"data-name": text(node.attrs.name)
|
|
456
|
-
},
|
|
457
|
-
label
|
|
458
|
-
];
|
|
459
|
-
},
|
|
460
|
-
parseDOM: [
|
|
461
|
-
{
|
|
462
|
-
tag: DOCX_RAW_SELECTOR,
|
|
463
|
-
getAttrs: (dom) => ({
|
|
464
|
-
srcId: srcIdOf(dom),
|
|
465
|
-
name: dom.getAttribute("data-name")
|
|
466
|
-
})
|
|
467
|
-
}
|
|
468
|
-
]
|
|
469
|
-
},
|
|
470
|
-
/** A bookmark range marker that occurs directly under w:body rather than inside a paragraph */
|
|
471
|
-
bookmarkBlock: {
|
|
472
|
-
group: "block preserved",
|
|
473
|
-
atom: true,
|
|
474
|
-
isolating: true,
|
|
475
|
-
selectable: false,
|
|
476
|
-
attrs: {
|
|
477
|
-
srcId: { default: null },
|
|
478
|
-
name: { default: null }
|
|
479
|
-
},
|
|
480
|
-
toDOM(node) {
|
|
481
|
-
return [
|
|
482
|
-
"div",
|
|
483
|
-
{
|
|
484
|
-
class: editorClassNames.bookmarkBlock,
|
|
485
|
-
"data-src": text(node.attrs.srcId) ?? "",
|
|
486
|
-
"data-name": text(node.attrs.name),
|
|
487
|
-
hidden: "hidden"
|
|
561
|
+
return {
|
|
562
|
+
xml,
|
|
563
|
+
srcId: srcIdOf(dom),
|
|
564
|
+
name: preservedNameOf(dom),
|
|
565
|
+
display: preservedDisplayOf(dom.getAttribute("data-display")),
|
|
566
|
+
guarded: dom.getAttribute("data-guarded") === "1"
|
|
567
|
+
};
|
|
488
568
|
}
|
|
489
|
-
];
|
|
490
|
-
},
|
|
491
|
-
parseDOM: [
|
|
492
|
-
{
|
|
493
|
-
tag: `div.${editorClassNames.bookmarkBlock}`,
|
|
494
|
-
getAttrs: (dom) => ({
|
|
495
|
-
srcId: srcIdOf(dom),
|
|
496
|
-
name: dom.getAttribute("data-name")
|
|
497
|
-
})
|
|
498
569
|
}
|
|
499
570
|
]
|
|
500
571
|
},
|
|
@@ -643,9 +714,6 @@ var docxSchema = new Schema({
|
|
|
643
714
|
authorId: { default: null },
|
|
644
715
|
initials: { default: null },
|
|
645
716
|
date: { default: null },
|
|
646
|
-
text: { default: "" },
|
|
647
|
-
commentXml: { default: null },
|
|
648
|
-
imported: { default: false },
|
|
649
717
|
paraId: { default: null },
|
|
650
718
|
resolved: { default: false },
|
|
651
719
|
extensionXml: { default: null },
|
|
@@ -664,9 +732,6 @@ var docxSchema = new Schema({
|
|
|
664
732
|
"data-comment-author-id": text(node.attrs.authorId),
|
|
665
733
|
"data-comment-initials": text(node.attrs.initials),
|
|
666
734
|
"data-comment-date": text(node.attrs.date),
|
|
667
|
-
"data-comment-text": text(node.attrs.text),
|
|
668
|
-
"data-comment-xml": text(node.attrs.commentXml),
|
|
669
|
-
"data-comment-imported": node.attrs.imported === true ? "1" : void 0,
|
|
670
735
|
"data-comment-para-id": text(node.attrs.paraId),
|
|
671
736
|
"data-comment-resolved": node.attrs.resolved === true ? "1" : void 0,
|
|
672
737
|
"data-comment-extension-xml": text(node.attrs.extensionXml),
|
|
@@ -684,18 +749,13 @@ var docxSchema = new Schema({
|
|
|
684
749
|
"data-reference-xml",
|
|
685
750
|
ELEMENT("commentReference")
|
|
686
751
|
);
|
|
687
|
-
const commentXml = rawXml(
|
|
688
|
-
dom,
|
|
689
|
-
"data-comment-xml",
|
|
690
|
-
ELEMENT("comment")
|
|
691
|
-
);
|
|
692
752
|
const extensionXml = rawXml(
|
|
693
753
|
dom,
|
|
694
754
|
"data-comment-extension-xml",
|
|
695
755
|
ANY_ELEMENT
|
|
696
756
|
);
|
|
697
757
|
const replies = parseJson(dom.getAttribute("data-comment-replies")) ?? [];
|
|
698
|
-
if (referenceXml === false ||
|
|
758
|
+
if (referenceXml === false || extensionXml === false || !repliesHoldTheirXml(replies)) {
|
|
699
759
|
return false;
|
|
700
760
|
}
|
|
701
761
|
return {
|
|
@@ -705,9 +765,6 @@ var docxSchema = new Schema({
|
|
|
705
765
|
authorId: dom.getAttribute("data-comment-author-id"),
|
|
706
766
|
initials: dom.getAttribute("data-comment-initials"),
|
|
707
767
|
date: dom.getAttribute("data-comment-date"),
|
|
708
|
-
text: dom.getAttribute("data-comment-text") ?? "",
|
|
709
|
-
commentXml,
|
|
710
|
-
imported: dom.getAttribute("data-comment-imported") === "1",
|
|
711
768
|
paraId: dom.getAttribute("data-comment-para-id"),
|
|
712
769
|
resolved: dom.getAttribute("data-comment-resolved") === "1",
|
|
713
770
|
extensionXml,
|
|
@@ -728,14 +785,12 @@ var docxSchema = new Schema({
|
|
|
728
785
|
kind: { default: "footnote" },
|
|
729
786
|
id: { default: null },
|
|
730
787
|
label: { default: "?" },
|
|
731
|
-
text: { default: "" },
|
|
732
788
|
customMarkFollows: { default: false },
|
|
733
789
|
referenceXml: { default: null }
|
|
734
790
|
},
|
|
735
791
|
toDOM(node) {
|
|
736
792
|
const kind = node.attrs.kind === "endnote" ? "Endnote" : "Footnote";
|
|
737
793
|
const label = text(node.attrs.label) ?? "?";
|
|
738
|
-
const body = text(node.attrs.text) ?? "";
|
|
739
794
|
return [
|
|
740
795
|
"sup",
|
|
741
796
|
{
|
|
@@ -743,11 +798,9 @@ var docxSchema = new Schema({
|
|
|
743
798
|
"data-note-kind": text(node.attrs.kind),
|
|
744
799
|
"data-note-id": text(node.attrs.id),
|
|
745
800
|
"data-note-label": label,
|
|
746
|
-
"data-note-text": body,
|
|
747
801
|
"data-custom-mark-follows": node.attrs.customMarkFollows === true ? "1" : void 0,
|
|
748
802
|
"data-reference-xml": text(node.attrs.referenceXml),
|
|
749
|
-
"aria-label": `${kind} ${label}
|
|
750
|
-
title: body
|
|
803
|
+
"aria-label": `${kind} ${label}`
|
|
751
804
|
},
|
|
752
805
|
node.attrs.customMarkFollows === true ? "" : label
|
|
753
806
|
];
|
|
@@ -766,7 +819,6 @@ var docxSchema = new Schema({
|
|
|
766
819
|
kind: dom.getAttribute("data-note-kind") === "endnote" ? "endnote" : "footnote",
|
|
767
820
|
id: dom.getAttribute("data-note-id"),
|
|
768
821
|
label: dom.getAttribute("data-note-label") ?? "?",
|
|
769
|
-
text: dom.getAttribute("data-note-text") ?? "",
|
|
770
822
|
customMarkFollows: dom.getAttribute("data-custom-mark-follows") === "1",
|
|
771
823
|
referenceXml
|
|
772
824
|
};
|
|
@@ -774,29 +826,58 @@ var docxSchema = new Schema({
|
|
|
774
826
|
}
|
|
775
827
|
]
|
|
776
828
|
},
|
|
829
|
+
/**
|
|
830
|
+
* One child of a run the editor has no node for, kept as the XML it came as.
|
|
831
|
+
*
|
|
832
|
+
* It wears the run mark, so it is written back inside the same `<w:r>` as the text beside it,
|
|
833
|
+
* which is where `EG_RunInnerContent` says it may stand.
|
|
834
|
+
*/
|
|
835
|
+
rawRunContent: {
|
|
836
|
+
group: "inline",
|
|
837
|
+
inline: true,
|
|
838
|
+
atom: true,
|
|
839
|
+
marks: "run sdt link",
|
|
840
|
+
attrs: {
|
|
841
|
+
xml: { default: null },
|
|
842
|
+
/** The local name of the element, for example `fldChar` */
|
|
843
|
+
element: { default: null },
|
|
844
|
+
display: { default: "hidden" },
|
|
845
|
+
/** What a `text` display draws, and the preview a chip shows */
|
|
846
|
+
text: { default: null },
|
|
847
|
+
/** Whether the deletion guard answers for this fragment (`schema/preservedGuards`) */
|
|
848
|
+
guarded: { default: false }
|
|
849
|
+
},
|
|
850
|
+
toDOM(node) {
|
|
851
|
+
return preservedDom(node, editorClassNames.rawRunContent);
|
|
852
|
+
},
|
|
853
|
+
parseDOM: [
|
|
854
|
+
{
|
|
855
|
+
tag: `span.${editorClassNames.rawRunContent}`,
|
|
856
|
+
getAttrs: preservedAttrs
|
|
857
|
+
}
|
|
858
|
+
]
|
|
859
|
+
},
|
|
777
860
|
/** The node that carries a non-run element inside a paragraph (a bookmark, for instance) exactly as it came */
|
|
778
861
|
rawInline: {
|
|
779
862
|
group: "inline",
|
|
780
863
|
inline: true,
|
|
781
864
|
atom: true,
|
|
782
865
|
marks: "sdt link",
|
|
783
|
-
attrs: {
|
|
866
|
+
attrs: {
|
|
867
|
+
xml: { default: null },
|
|
868
|
+
/** The local name of the element; `r` for a run with no content, kept whole */
|
|
869
|
+
element: { default: null },
|
|
870
|
+
display: { default: "hidden" },
|
|
871
|
+
text: { default: null },
|
|
872
|
+
guarded: { default: false }
|
|
873
|
+
},
|
|
784
874
|
toDOM(node) {
|
|
785
|
-
return
|
|
786
|
-
"span",
|
|
787
|
-
{
|
|
788
|
-
class: editorClassNames.rawInline,
|
|
789
|
-
"data-xml": text(node.attrs.xml)
|
|
790
|
-
}
|
|
791
|
-
];
|
|
875
|
+
return preservedDom(node, editorClassNames.rawInline);
|
|
792
876
|
},
|
|
793
877
|
parseDOM: [
|
|
794
878
|
{
|
|
795
879
|
tag: `span.${editorClassNames.rawInline}`,
|
|
796
|
-
getAttrs:
|
|
797
|
-
const xml = rawXml(dom, "data-xml", ANY_ELEMENT);
|
|
798
|
-
return xml === false ? false : { xml };
|
|
799
|
-
}
|
|
880
|
+
getAttrs: preservedAttrs
|
|
800
881
|
}
|
|
801
882
|
]
|
|
802
883
|
},
|
|
@@ -46,7 +46,7 @@ export type EditIntent =
|
|
|
46
46
|
* against the places it puts that guard to the test, and a place naming a guard that no longer
|
|
47
47
|
* stands has to be a mistake the compiler catches rather than an annotation answering for nothing.
|
|
48
48
|
*/
|
|
49
|
-
export type EditGuardName = "protection" | "lock" | "
|
|
49
|
+
export type EditGuardName = "protection" | "lock" | "preserved" | "note" | "section";
|
|
50
50
|
/** What every guard answers, whichever of the two judgements it is written as */
|
|
51
51
|
interface GuardCommon {
|
|
52
52
|
readonly name: EditGuardName;
|
package/dist/schema/guards.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
transactionReaches
|
|
5
5
|
} from "./editGuard.js";
|
|
6
6
|
import { lockGuard } from "./locks.js";
|
|
7
|
-
import {
|
|
7
|
+
import { noteGuard, preservedGuard, sectionGuard } from "./preservedGuards.js";
|
|
8
8
|
import {
|
|
9
9
|
isCommentNode,
|
|
10
10
|
protectionAllows
|
|
@@ -36,7 +36,7 @@ var protectionGuard = {
|
|
|
36
36
|
var EDIT_GUARDS = [
|
|
37
37
|
protectionGuard,
|
|
38
38
|
lockGuard,
|
|
39
|
-
|
|
39
|
+
preservedGuard,
|
|
40
40
|
noteGuard,
|
|
41
41
|
sectionGuard
|
|
42
42
|
];
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Node as PMNode } from "prosemirror-model";
|
|
2
|
+
type MarkerAttr = "leadingXml" | "trailingXml";
|
|
3
|
+
/**
|
|
4
|
+
* Whether this node is content the editor keeps as it came rather than one it models.
|
|
5
|
+
*
|
|
6
|
+
* The block placeholder declares it as a group; the two inline ones cannot, since their group says
|
|
7
|
+
* where they may stand, so they are named here and asked for by name everywhere else.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isPreservedNode(node: PMNode): boolean;
|
|
10
|
+
/** Visit preserved XML in the order the writer places it around editable content. */
|
|
11
|
+
export declare function visitPreservedFragments(doc: PMNode, visit: (node: PMNode, pos: number, xml: string | null, attr?: MarkerAttr) => void): void;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/schema/preservedFragments.ts
|
|
2
|
+
function isPreservedNode(node) {
|
|
3
|
+
return node.type.name === "rawInline" || node.type.name === "rawRunContent" || node.type.isInGroup("preserved");
|
|
4
|
+
}
|
|
5
|
+
function visitPreservedFragments(doc, visit) {
|
|
6
|
+
const visitAttr = (node, pos, attr) => {
|
|
7
|
+
const xml = node.attrs[attr];
|
|
8
|
+
if (typeof xml === "string" && xml.length > 0) {
|
|
9
|
+
visit(node, pos, xml, attr);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const walk = (node, pos) => {
|
|
13
|
+
if (isPreservedNode(node)) {
|
|
14
|
+
visit(
|
|
15
|
+
node,
|
|
16
|
+
pos,
|
|
17
|
+
typeof node.attrs.xml === "string" ? node.attrs.xml : null
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
if (node.type.name === "table" || node.type.name === "tableRow") {
|
|
21
|
+
visitAttr(node, pos, "leadingXml");
|
|
22
|
+
}
|
|
23
|
+
node.forEach((child, offset) => {
|
|
24
|
+
walk(child, pos + 1 + offset);
|
|
25
|
+
});
|
|
26
|
+
if (node.type.name === "tableRow" || node.type.name === "tableCell") {
|
|
27
|
+
visitAttr(node, pos, "trailingXml");
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
doc.descendants((node, pos) => {
|
|
31
|
+
walk(node, pos);
|
|
32
|
+
return false;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
isPreservedNode,
|
|
37
|
+
visitPreservedFragments
|
|
38
|
+
};
|