@portone/docx-editor 0.2.0 → 0.3.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 +174 -0
- package/CONTRIBUTING.md +9 -1
- package/dist/DocxEditor.d.ts +6 -0
- package/dist/DocxEditor.js +12 -29
- package/dist/core.d.ts +23 -8
- package/dist/core.js +9 -4
- package/dist/docx/cloning.d.ts +38 -0
- package/dist/docx/cloning.js +74 -0
- package/dist/docx/commentOnlyChange.d.ts +14 -7
- package/dist/docx/commentOnlyChange.js +9 -139
- package/dist/docx/comments/constants.d.ts +3 -4
- package/dist/docx/comments/constants.js +4 -5
- package/dist/docx/comments/grammar.d.ts +86 -0
- package/dist/docx/comments/grammar.js +223 -0
- package/dist/docx/comments/parts.d.ts +52 -0
- package/dist/docx/comments/parts.js +279 -0
- package/dist/docx/comments/people.d.ts +11 -2
- package/dist/docx/comments/people.js +28 -106
- package/dist/docx/comments/policy.d.ts +7 -0
- package/dist/docx/comments/policy.js +43 -0
- package/dist/docx/comments/reading.d.ts +5 -3
- package/dist/docx/comments/reading.js +30 -29
- package/dist/docx/comments/writing.d.ts +19 -7
- package/dist/docx/comments/writing.js +105 -137
- package/dist/docx/documentSettings.d.ts +7 -0
- package/dist/docx/documentSettings.js +10 -2
- package/dist/docx/exportDocx.d.ts +40 -5
- package/dist/docx/exportDocx.js +71 -72
- package/dist/docx/exportRefs.d.ts +5 -2
- package/dist/docx/exportRefs.js +3 -1
- package/dist/docx/fidelity.d.ts +43 -0
- package/dist/docx/fidelity.js +64 -0
- package/dist/docx/formatting/attrs.d.ts +27 -0
- package/dist/docx/formatting/attrs.js +31 -0
- package/dist/docx/formatting/context.d.ts +31 -0
- package/dist/docx/formatting/context.js +42 -0
- package/dist/docx/formatting/direct.d.ts +6 -5
- package/dist/docx/formatting/direct.js +52 -81
- package/dist/docx/formatting/resolve.d.ts +45 -0
- package/dist/docx/formatting/resolve.js +140 -0
- package/dist/docx/formatting/runProperties.d.ts +93 -0
- package/dist/docx/formatting/runProperties.js +316 -0
- package/dist/docx/formatting/styles.js +3 -3
- package/dist/docx/formatting/tabStops.js +7 -22
- package/dist/docx/formatting.d.ts +4 -1
- package/dist/docx/formatting.js +4 -1
- package/dist/docx/headersFooters.js +13 -22
- package/dist/docx/identities.d.ts +67 -0
- package/dist/docx/identities.js +174 -0
- package/dist/docx/importDocx.d.ts +12 -1
- package/dist/docx/importDocx.js +72 -79
- package/dist/docx/importParagraph.d.ts +1 -1
- package/dist/docx/importParagraph.js +4 -3
- package/dist/docx/importTable.d.ts +1 -1
- package/dist/docx/importTable.js +17 -1
- package/dist/docx/invariants.d.ts +33 -0
- package/dist/docx/invariants.js +256 -0
- package/dist/docx/media.d.ts +6 -4
- package/dist/docx/media.js +6 -37
- package/dist/docx/newLists.d.ts +20 -0
- package/dist/docx/newLists.js +36 -0
- package/dist/docx/notes.js +6 -12
- package/dist/docx/numberingPlanner.d.ts +8 -0
- package/dist/docx/numberingPlanner.js +19 -0
- package/dist/docx/packageParts.d.ts +42 -0
- package/dist/docx/packageParts.js +135 -0
- package/dist/docx/pageGeometry.d.ts +2 -0
- package/dist/docx/pageGeometry.js +18 -9
- package/dist/docx/paraProps.d.ts +10 -22
- package/dist/docx/paraProps.js +75 -99
- package/dist/docx/partPlan.d.ts +36 -0
- package/dist/docx/partPlan.js +59 -0
- package/dist/docx/protectionPolicy.d.ts +127 -0
- package/dist/docx/protectionPolicy.js +169 -0
- package/dist/docx/relationships.d.ts +1 -1
- package/dist/docx/relationships.js +15 -15
- package/dist/docx/runProps.d.ts +9 -22
- package/dist/docx/runProps.js +15 -168
- package/dist/docx/scan.js +20 -52
- package/dist/docx/sdt.js +14 -37
- package/dist/docx/sdtProps.d.ts +8 -1
- package/dist/docx/sdtProps.js +10 -0
- package/dist/docx/serializeBlock.d.ts +2 -0
- package/dist/docx/serializeBlock.js +9 -7
- package/dist/docx/serializeParagraph.d.ts +2 -1
- package/dist/docx/serializeParagraph.js +25 -14
- package/dist/docx/serializeTable.js +63 -32
- package/dist/docx/session.d.ts +42 -14
- package/dist/docx/session.js +43 -17
- package/dist/docx/storyProjection.d.ts +36 -0
- package/dist/docx/storyProjection.js +23 -0
- package/dist/docx/tableFormatting/editing.js +130 -185
- package/dist/docx/tableFormatting/reading.d.ts +16 -6
- package/dist/docx/tableFormatting/reading.js +40 -20
- package/dist/docx/tableTemplate.js +37 -5
- package/dist/docx/theme.d.ts +0 -6
- package/dist/docx/theme.js +0 -8
- package/dist/download.d.ts +8 -5
- package/dist/download.js +2 -0
- package/dist/editor/clipboard/images.js +17 -3
- package/dist/editor/clipboard/inlineFormatting.d.ts +7 -0
- package/dist/editor/clipboard/inlineFormatting.js +20 -30
- package/dist/editor/commands/breakCommands.js +4 -3
- package/dist/editor/commands/canRunCommand.d.ts +2 -2
- package/dist/editor/commands/canRunCommand.js +1 -1
- package/dist/editor/commands/comments/editing.d.ts +6 -2
- package/dist/editor/commands/comments/editing.js +21 -36
- package/dist/editor/commands/exportQueries.d.ts +15 -0
- package/dist/editor/commands/exportQueries.js +14 -0
- package/dist/editor/commands/fidelityQueries.d.ts +12 -0
- package/dist/editor/commands/fidelityQueries.js +8 -0
- package/dist/editor/commands/formatting/editing.d.ts +2 -2
- package/dist/editor/commands/formatting/editing.js +26 -108
- package/dist/editor/commands/formatting/propertyCommands.d.ts +21 -0
- package/dist/editor/commands/formatting/propertyCommands.js +103 -0
- package/dist/editor/commands/formatting/shared.d.ts +3 -3
- package/dist/editor/commands/formatting/shared.js +5 -2
- package/dist/editor/commands/historyCommands.js +2 -1
- package/dist/editor/commands/indentCommands.js +5 -4
- package/dist/editor/commands/index.d.ts +11 -0
- package/dist/editor/commands/index.js +5 -0
- package/dist/editor/commands/linkCommands.js +5 -6
- package/dist/editor/commands/listCommands.js +8 -10
- package/dist/editor/commands/lockCommands.d.ts +7 -1
- package/dist/editor/commands/lockCommands.js +35 -37
- package/dist/editor/commands/paragraphCommands.js +28 -31
- package/dist/editor/commands/spacingCommands.js +1 -1
- package/dist/editor/commands/tabCommands.js +4 -3
- package/dist/editor/createEditor.d.ts +17 -29
- package/dist/editor/createEditor.js +61 -67
- package/dist/editor/documentStyles.d.ts +11 -35
- package/dist/editor/documentStyles.js +9 -52
- package/dist/editor/editorDocument.d.ts +56 -0
- package/dist/editor/editorDocument.js +74 -0
- package/dist/editor/externalClipboard.js +166 -33
- package/dist/editor/insertImage.js +4 -3
- package/dist/editor/insertTable.js +4 -3
- package/dist/editor/paragraphEdits.d.ts +11 -18
- package/dist/editor/paragraphEdits.js +7 -16
- package/dist/editor/plugins/displayDerivation.d.ts +47 -0
- package/dist/editor/plugins/displayDerivation.js +78 -0
- package/dist/editor/plugins/documentProtection.d.ts +3 -3
- package/dist/editor/plugins/imagePaste.js +4 -3
- package/dist/editor/plugins/keymap.js +18 -3
- package/dist/editor/plugins/lockedContent.d.ts +4 -4
- package/dist/editor/plugins/lockedContent.js +1 -1
- package/dist/editor/plugins/numberingDecorations.d.ts +5 -11
- package/dist/editor/plugins/numberingDecorations.js +7 -17
- package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
- package/dist/editor/plugins/paragraphDisplay.js +51 -0
- package/dist/editor/plugins/tabLayout.js +1 -1
- package/dist/editor/plugins/tableDisplay.d.ts +6 -0
- package/dist/editor/plugins/tableDisplay.js +16 -0
- package/dist/index.d.ts +2 -0
- package/dist/model/format.d.ts +30 -8
- package/dist/model/format.js +35 -22
- package/dist/model/tabStops.d.ts +9 -0
- package/dist/model/tabStops.js +18 -0
- package/dist/numbering/listTemplate.js +49 -10
- package/dist/numbering/parseNumbering.d.ts +14 -1
- package/dist/numbering/parseNumbering.js +35 -22
- package/dist/numbering/writeNumbering.d.ts +3 -4
- package/dist/numbering/writeNumbering.js +14 -25
- package/dist/ooxml/childOrder.d.ts +34 -0
- package/dist/ooxml/childOrder.js +496 -0
- package/dist/ooxml/element.d.ts +65 -0
- package/dist/ooxml/element.js +68 -0
- package/dist/ooxml/errors.d.ts +3 -2
- package/dist/ooxml/fragment.d.ts +53 -0
- package/dist/ooxml/fragment.js +76 -0
- package/dist/ooxml/image.d.ts +4 -0
- package/dist/ooxml/image.js +3 -5
- package/dist/ooxml/names.d.ts +27 -0
- package/dist/ooxml/names.js +29 -0
- package/dist/ooxml/partSplice.d.ts +67 -0
- package/dist/ooxml/partSplice.js +169 -0
- package/dist/ooxml/precedence.d.ts +31 -0
- package/dist/ooxml/precedence.js +51 -0
- package/dist/ooxml/props.d.ts +112 -0
- package/dist/ooxml/props.js +214 -0
- package/dist/ooxml/simpleTypes.d.ts +103 -0
- package/dist/ooxml/simpleTypes.js +182 -0
- package/dist/ooxml/tabStops.js +8 -27
- package/dist/ooxml/tagScan.d.ts +34 -0
- package/dist/ooxml/tagScan.js +108 -0
- package/dist/ooxml/units.d.ts +25 -13
- package/dist/ooxml/units.js +65 -31
- package/dist/ooxml/xml.d.ts +52 -0
- package/dist/ooxml/xml.js +64 -5
- package/dist/page/blockKinds.d.ts +103 -0
- package/dist/page/blockKinds.js +11 -0
- package/dist/page/kinds/index.d.ts +6 -0
- package/dist/page/kinds/index.js +10 -0
- package/dist/page/kinds/paragraphKind.d.ts +10 -0
- package/dist/page/kinds/paragraphKind.js +71 -0
- package/dist/page/kinds/tableKind.d.ts +10 -0
- package/dist/page/kinds/tableKind.js +178 -0
- package/dist/page/measureBlocks.d.ts +3 -1
- package/dist/page/measureBlocks.js +24 -25
- package/dist/page/pageDecorations.d.ts +27 -28
- package/dist/page/pageDecorations.js +70 -151
- package/dist/page/pageLayout.d.ts +10 -62
- package/dist/page/pageLayout.js +60 -53
- package/dist/page/usePageLayout.d.ts +2 -2
- package/dist/page/usePageLayout.js +3 -11
- package/dist/schema/attrRoles.d.ts +42 -0
- package/dist/schema/attrRoles.js +141 -0
- package/dist/schema/displayDerivation.d.ts +82 -0
- package/dist/schema/displayDerivation.js +130 -0
- package/dist/schema/docxSchema.d.ts +9 -0
- package/dist/schema/docxSchema.js +237 -114
- package/dist/schema/editGuard.d.ts +99 -0
- package/dist/schema/editGuard.js +43 -0
- package/dist/schema/guards.d.ts +91 -0
- package/dist/schema/guards.js +108 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/locks.d.ts +17 -77
- package/dist/schema/locks.js +26 -70
- package/dist/schema/preservedGuards.d.ts +50 -0
- package/dist/schema/preservedGuards.js +80 -0
- package/dist/schema/protection.d.ts +17 -4
- package/dist/schema/protection.js +4 -2
- package/dist/schema/sourceEquality.d.ts +19 -0
- package/dist/schema/sourceEquality.js +39 -0
- package/dist/styles/inlineStyle.js +15 -6
- package/dist/table/cellFormatting.d.ts +8 -1
- package/dist/table/cellFormatting.js +10 -17
- package/dist/table/commands.d.ts +2 -2
- package/dist/table/commands.js +20 -18
- package/dist/table/format.d.ts +3 -0
- package/dist/table/format.js +3 -9
- package/dist/table/gridBorders.d.ts +14 -16
- package/dist/table/gridBorders.js +3 -41
- package/dist/table/index.d.ts +2 -2
- package/dist/table/merge.d.ts +4 -8
- package/dist/table/merge.js +5 -5
- package/package.json +10 -3
- package/dist/docx/comments/contentTypes.d.ts +0 -7
- package/dist/docx/comments/contentTypes.js +0 -38
- package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
- package/dist/docx/formatting/effectiveParagraph.js +0 -81
- package/dist/docx/propsXml.d.ts +0 -49
- package/dist/docx/propsXml.js +0 -302
- package/dist/docx/uniqueControls.d.ts +0 -14
- package/dist/docx/uniqueControls.js +0 -62
- package/dist/editor/plugins/bookmarkProtection.d.ts +0 -3
- package/dist/editor/plugins/bookmarkProtection.js +0 -28
- package/dist/editor/plugins/commentReservations.d.ts +0 -5
- package/dist/editor/plugins/commentReservations.js +0 -26
- package/dist/editor/plugins/noteProtection.d.ts +0 -3
- package/dist/editor/plugins/noteProtection.js +0 -25
- package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
- package/dist/editor/plugins/styledParagraphs.js +0 -65
- package/dist/page/tableMeasurements.d.ts +0 -10
- package/dist/page/tableMeasurements.js +0 -115
package/dist/ooxml/units.d.ts
CHANGED
|
@@ -1,30 +1,42 @@
|
|
|
1
1
|
import { type ParagraphAlign } from "../model/format";
|
|
2
|
+
import { type HexColor } from "./simpleTypes";
|
|
2
3
|
/** The alignment `w:jc` writes down, both for a paragraph and for a table */
|
|
3
4
|
export declare const ALIGN_BY_JC: Record<string, ParagraphAlign>;
|
|
4
5
|
/** A color as the document writes it, six hex digits and no `#`. Null for anything else */
|
|
5
6
|
export declare function normalizeHex(value: string): string | null;
|
|
6
7
|
export declare function wAttr(el: Element, name: string): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Whether a boolean property element states on (§17.17.4).
|
|
10
|
+
*
|
|
11
|
+
* An element carrying no `w:val` states on, and one that is not there at all states nothing, which
|
|
12
|
+
* a caller asking "is this on" reads as off. For malformed values, this project uses the same
|
|
13
|
+
* fallback as an absent attribute. That recovery policy is not a schema or Word guarantee.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isOnElement(el: Element | null): boolean;
|
|
7
16
|
/** `<w:b/>` means on, `<w:b w:val="0"/>` means off */
|
|
8
17
|
export declare function isOn(parent: Element, name: string): boolean;
|
|
9
18
|
export declare function childValue(parent: Element, name: string): string | null;
|
|
10
|
-
export declare function toNumber(value: string | null): number | null;
|
|
11
19
|
/** Cuts off the messy digits after the decimal point so the same input always yields the same value */
|
|
12
20
|
export declare function round(value: number): number;
|
|
13
21
|
/** twip (1/20 of a point) */
|
|
14
|
-
export declare function twipsToPt(
|
|
22
|
+
export declare function twipsToPt(twips: number | null): number | null;
|
|
15
23
|
/** half-point (w:sz 20 = 10pt) */
|
|
16
|
-
export declare function halfPointsToPt(
|
|
17
|
-
/**
|
|
18
|
-
export declare function eighthsToPt(value: string | null): number | null;
|
|
24
|
+
export declare function halfPointsToPt(half: number | null): number | null;
|
|
25
|
+
/** The color as CSS spells it. `auto` is not a color to paint with, so it reads as none */
|
|
19
26
|
export declare function toHexColor(value: string | null): string | null;
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
/** One border side as `CT_Border` records it (§17.3.4) */
|
|
28
|
+
export interface BorderLine {
|
|
29
|
+
/** ST_Border (§17.18.2). `none` states that this side draws nothing */
|
|
30
|
+
val: string;
|
|
31
|
+
/** The thickness, in eighths of a point */
|
|
32
|
+
eighths: number;
|
|
33
|
+
color: HexColor;
|
|
34
|
+
}
|
|
35
|
+
/** The CSS declaration one line is drawn with, and null for a line there is none of */
|
|
36
|
+
export declare function borderLineCss(line: BorderLine | null): string | null;
|
|
37
|
+
/** The line a CSS declaration this module wrote stands for, so no caller reads one back its own way */
|
|
38
|
+
export declare function borderLineOfCss(css: string | null): BorderLine | null;
|
|
39
|
+
/** Moves one border side into a CSS value */
|
|
28
40
|
export declare function borderCss(el: Element | null): string | null;
|
|
29
41
|
/** One side inside `w:tblBorders` or `w:tcBorders` */
|
|
30
42
|
export declare function borderSide(borders: Element | null, side: string): string | null;
|
package/dist/ooxml/units.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
// src/ooxml/units.ts
|
|
2
2
|
import { NO_FILL } from "../model/format.js";
|
|
3
|
+
import {
|
|
4
|
+
EIGHTHS_PER_PT,
|
|
5
|
+
HALF_POINTS_PER_PT,
|
|
6
|
+
ST_EighthPointMeasure,
|
|
7
|
+
ST_HexColor,
|
|
8
|
+
ST_OnOff,
|
|
9
|
+
TWIPS_PER_PT
|
|
10
|
+
} from "./simpleTypes.js";
|
|
3
11
|
import { childByLocalName, W_NS } from "./xml.js";
|
|
4
12
|
var ALIGN_BY_JC = {
|
|
5
13
|
left: "left",
|
|
@@ -17,39 +25,29 @@ function normalizeHex(value) {
|
|
|
17
25
|
function wAttr(el, name) {
|
|
18
26
|
return el.getAttributeNS(W_NS, name) ?? el.getAttribute(name);
|
|
19
27
|
}
|
|
20
|
-
function
|
|
21
|
-
const el = childByLocalName(parent, name);
|
|
28
|
+
function isOnElement(el) {
|
|
22
29
|
if (!el) return false;
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
return ST_OnOff.parse(wAttr(el, "val")) ?? true;
|
|
31
|
+
}
|
|
32
|
+
function isOn(parent, name) {
|
|
33
|
+
return isOnElement(childByLocalName(parent, name));
|
|
25
34
|
}
|
|
26
35
|
function childValue(parent, name) {
|
|
27
36
|
const el = childByLocalName(parent, name);
|
|
28
37
|
return el ? wAttr(el, "val") : null;
|
|
29
38
|
}
|
|
30
|
-
function toNumber(value) {
|
|
31
|
-
if (value === null) return null;
|
|
32
|
-
const parsed = Number.parseFloat(value);
|
|
33
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
34
|
-
}
|
|
35
39
|
function round(value) {
|
|
36
40
|
return Math.round(value * 100) / 100;
|
|
37
41
|
}
|
|
38
|
-
function twipsToPt(
|
|
39
|
-
|
|
40
|
-
return twips === null ? null : round(twips / 20);
|
|
41
|
-
}
|
|
42
|
-
function halfPointsToPt(value) {
|
|
43
|
-
const half = toNumber(value);
|
|
44
|
-
return half === null ? null : round(half / 2);
|
|
42
|
+
function twipsToPt(twips) {
|
|
43
|
+
return twips === null ? null : round(twips / TWIPS_PER_PT);
|
|
45
44
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
return eighths === null ? null : round(eighths / 8);
|
|
45
|
+
function halfPointsToPt(half) {
|
|
46
|
+
return half === null ? null : round(half / HALF_POINTS_PER_PT);
|
|
49
47
|
}
|
|
50
48
|
function toHexColor(value) {
|
|
51
|
-
|
|
52
|
-
return
|
|
49
|
+
const color = ST_HexColor.parse(value);
|
|
50
|
+
return color?.kind === "rgb" ? `#${color.hex}` : null;
|
|
53
51
|
}
|
|
54
52
|
var BORDER_STYLE_BY_VAL = {
|
|
55
53
|
single: "solid",
|
|
@@ -78,17 +76,52 @@ var BORDER_STYLE_BY_VAL = {
|
|
|
78
76
|
dotDotDash: "dashed",
|
|
79
77
|
dashDotStroked: "dashed"
|
|
80
78
|
};
|
|
81
|
-
var
|
|
82
|
-
|
|
79
|
+
var BORDER_VAL_BY_STYLE = {
|
|
80
|
+
solid: "single",
|
|
81
|
+
double: "double",
|
|
82
|
+
dashed: "dashed",
|
|
83
|
+
dotted: "dotted"
|
|
84
|
+
};
|
|
85
|
+
var FALLBACK_BORDER_EIGHTHS = 4;
|
|
86
|
+
var DEFAULT_BORDER_CSS_COLOR = "#000000";
|
|
87
|
+
var NO_LINE = {
|
|
88
|
+
val: "none",
|
|
89
|
+
eighths: 0,
|
|
90
|
+
color: { kind: "auto" }
|
|
91
|
+
};
|
|
92
|
+
function borderLineOf(el) {
|
|
83
93
|
if (!el) return null;
|
|
84
94
|
const val = wAttr(el, "val") ?? "";
|
|
85
|
-
if (val === "nil" || val === "none") return
|
|
86
|
-
|
|
95
|
+
if (val === "nil" || val === "none") return NO_LINE;
|
|
96
|
+
if (!BORDER_STYLE_BY_VAL[val]) return null;
|
|
97
|
+
const written = ST_EighthPointMeasure.parse(wAttr(el, "sz"));
|
|
98
|
+
return {
|
|
99
|
+
val,
|
|
100
|
+
eighths: written === null || written === 0 ? FALLBACK_BORDER_EIGHTHS : written,
|
|
101
|
+
color: ST_HexColor.parse(wAttr(el, "color")) ?? { kind: "auto" }
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function borderLineCss(line) {
|
|
105
|
+
if (!line) return null;
|
|
106
|
+
if (line.val === "none") return "none";
|
|
107
|
+
const style = BORDER_STYLE_BY_VAL[line.val];
|
|
87
108
|
if (!style) return null;
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
109
|
+
const color = line.color.kind === "rgb" ? `#${line.color.hex}` : DEFAULT_BORDER_CSS_COLOR;
|
|
110
|
+
return `${round(line.eighths / EIGHTHS_PER_PT)}pt ${style} ${color}`;
|
|
111
|
+
}
|
|
112
|
+
var BORDER_CSS = /^(\d+(?:\.\d+)?)pt (solid|double|dashed|dotted) (#[0-9a-f]{6})$/i;
|
|
113
|
+
function borderLineOfCss(css) {
|
|
114
|
+
if (css === null) return null;
|
|
115
|
+
if (css === "none") return NO_LINE;
|
|
116
|
+
const matched = BORDER_CSS.exec(css);
|
|
117
|
+
if (!matched) return null;
|
|
118
|
+
const eighths = Math.round(Number(matched[1]) * EIGHTHS_PER_PT);
|
|
119
|
+
const color = ST_HexColor.parse(matched[3].slice(1).toUpperCase());
|
|
120
|
+
if (eighths <= 0 || color === null) return null;
|
|
121
|
+
return { val: BORDER_VAL_BY_STYLE[matched[2].toLowerCase()], eighths, color };
|
|
122
|
+
}
|
|
123
|
+
function borderCss(el) {
|
|
124
|
+
return borderLineCss(borderLineOf(el));
|
|
92
125
|
}
|
|
93
126
|
function borderSide(borders, side) {
|
|
94
127
|
return borders ? borderCss(childByLocalName(borders, side)) : null;
|
|
@@ -101,16 +134,17 @@ function shadingOf(parent) {
|
|
|
101
134
|
export {
|
|
102
135
|
ALIGN_BY_JC,
|
|
103
136
|
borderCss,
|
|
137
|
+
borderLineCss,
|
|
138
|
+
borderLineOfCss,
|
|
104
139
|
borderSide,
|
|
105
140
|
childValue,
|
|
106
|
-
eighthsToPt,
|
|
107
141
|
halfPointsToPt,
|
|
108
142
|
isOn,
|
|
143
|
+
isOnElement,
|
|
109
144
|
normalizeHex,
|
|
110
145
|
round,
|
|
111
146
|
shadingOf,
|
|
112
147
|
toHexColor,
|
|
113
|
-
toNumber,
|
|
114
148
|
twipsToPt,
|
|
115
149
|
wAttr
|
|
116
150
|
};
|
package/dist/ooxml/xml.d.ts
CHANGED
|
@@ -5,6 +5,14 @@ export declare const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/
|
|
|
5
5
|
* every relationship type name is built on
|
|
6
6
|
*/
|
|
7
7
|
export declare const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
8
|
+
/**
|
|
9
|
+
* The prefixes whose meaning the editor depends on, and the namespace each one has to carry.
|
|
10
|
+
*
|
|
11
|
+
* Every element the writer spells out is a `w:` one, and the relationship a link or an image points
|
|
12
|
+
* at is named by `r:id` or `r:embed`, so a fragment that bound either prefix elsewhere would leave
|
|
13
|
+
* the writer's own markup meaning something else.
|
|
14
|
+
*/
|
|
15
|
+
export declare const RESERVED_PREFIXES: ReadonlyMap<string, string>;
|
|
8
16
|
/** The name with its namespace prefix stripped off (`w:ascii` -> `ascii`) */
|
|
9
17
|
export declare function localPart(name: string): string;
|
|
10
18
|
/**
|
|
@@ -21,11 +29,55 @@ export declare function decodeUtf8(bytes: Uint8Array): {
|
|
|
21
29
|
hadBom: boolean;
|
|
22
30
|
};
|
|
23
31
|
export declare function encodeUtf8(text: string, withBom: boolean): Uint8Array;
|
|
32
|
+
/**
|
|
33
|
+
* What reading a package part asks of a runtime: an XML string in, a document out.
|
|
34
|
+
*
|
|
35
|
+
* A browser's `DOMParser` is one, and so is a `DOMParser` from jsdom. The package ships none of
|
|
36
|
+
* them.
|
|
37
|
+
*
|
|
38
|
+
* Markup it cannot read may be answered either way a parser answers one: by handing back a
|
|
39
|
+
* document holding a `parsererror` element, or by throwing. Both are read as `malformed-xml`.
|
|
40
|
+
*/
|
|
41
|
+
export interface XmlParser {
|
|
42
|
+
parseFromString(source: string, type: "application/xml"): Document;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Runs `work` with every `parseXml` inside it reading through the one parser settled on here.
|
|
46
|
+
*
|
|
47
|
+
* Settling it at the boundary rather than at each read is what lets an entry point turn a runtime
|
|
48
|
+
* holding no parser down before it has read anything, instead of wherever the first part happens
|
|
49
|
+
* to be parsed; it also means one parser serves the whole call rather than a fresh `DOMParser`
|
|
50
|
+
* being built for every part.
|
|
51
|
+
*
|
|
52
|
+
* The public entry points are synchronous, so the scope covers exactly the work one of them does
|
|
53
|
+
* and nothing that runs after it. `undefined` keeps the enclosing scope's parser rather than
|
|
54
|
+
* clearing it, which is what lets an entry point opening a file through another one - the verifier
|
|
55
|
+
* running two imports - hand its own parser down without every inner call having to carry it.
|
|
56
|
+
*/
|
|
57
|
+
export declare function withXmlParser<T>(parser: XmlParser | undefined, work: () => T): T;
|
|
24
58
|
export declare function parseXml(source: string): Document;
|
|
59
|
+
/**
|
|
60
|
+
* Gathers the namespace prefixes used in the fragment and declares them.
|
|
61
|
+
* Only `w` carries real meaning; the rest are placeholders that keep the parser from stopping.
|
|
62
|
+
* All we read are element names and `w:` attributes, so placeholders still let the values be read as they are.
|
|
63
|
+
*
|
|
64
|
+
* An attribute standing at the very start of the string counts too, since a fragment may be an
|
|
65
|
+
* attribute list of its own (`attrString`) rather than an element.
|
|
66
|
+
*/
|
|
67
|
+
export declare function namespaceDecls(xml: string): string;
|
|
25
68
|
export declare function elementChildren(el: Element): Element[];
|
|
69
|
+
/**
|
|
70
|
+
* The value of the attribute with this local name, whatever prefix it was written under.
|
|
71
|
+
*
|
|
72
|
+
* A document is free to bind the WordprocessingML namespace to a prefix of its own, so an
|
|
73
|
+
* attribute is looked up by the name it carries rather than by the spelling a producer chose.
|
|
74
|
+
*/
|
|
75
|
+
export declare function attributeByLocalName(el: Element, localName: string): string | null;
|
|
26
76
|
export declare function childByLocalName(el: Element, name: string): Element | null;
|
|
27
77
|
/** Turns an opening tag's attributes into an `a="b" c="d"` string */
|
|
28
78
|
export declare function attrString(el: Element): string | null;
|
|
79
|
+
/** Whether this node is an element */
|
|
80
|
+
export declare function isElement(node: Node): node is Element;
|
|
29
81
|
/**
|
|
30
82
|
* Turns a single element back into an XML string.
|
|
31
83
|
*
|
package/dist/ooxml/xml.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import { DocxImportError } from "./errors.js";
|
|
3
3
|
var W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
4
4
|
var R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
5
|
+
var RESERVED_PREFIXES = /* @__PURE__ */ new Map([
|
|
6
|
+
["w", W_NS],
|
|
7
|
+
["r", R_NS]
|
|
8
|
+
]);
|
|
5
9
|
function localPart(name) {
|
|
6
10
|
const colon = name.indexOf(":");
|
|
7
11
|
return colon === -1 ? name : name.slice(colon + 1);
|
|
@@ -32,19 +36,65 @@ function declaresDtd(source) {
|
|
|
32
36
|
at = closes;
|
|
33
37
|
}
|
|
34
38
|
}
|
|
39
|
+
var scopedParser;
|
|
40
|
+
function resolveParser(parser) {
|
|
41
|
+
const named = parser ?? scopedParser;
|
|
42
|
+
if (named) return named;
|
|
43
|
+
if (typeof DOMParser === "function") return new DOMParser();
|
|
44
|
+
throw new DocxImportError(
|
|
45
|
+
"no-xml-parser",
|
|
46
|
+
"no XML parser: pass `xmlParser` or install a DOMParser global"
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
function withXmlParser(parser, work) {
|
|
50
|
+
const enclosing = scopedParser;
|
|
51
|
+
scopedParser = resolveParser(parser);
|
|
52
|
+
try {
|
|
53
|
+
return work();
|
|
54
|
+
} finally {
|
|
55
|
+
scopedParser = enclosing;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
35
58
|
function parseXml(source) {
|
|
36
59
|
if (declaresDtd(source)) {
|
|
37
60
|
throw new DocxImportError("malformed-xml", "the XML declares a DTD");
|
|
38
61
|
}
|
|
39
|
-
|
|
62
|
+
let doc;
|
|
63
|
+
try {
|
|
64
|
+
doc = resolveParser(void 0).parseFromString(source, "application/xml");
|
|
65
|
+
} catch (cause) {
|
|
66
|
+
if (cause instanceof DocxImportError) throw cause;
|
|
67
|
+
throw new DocxImportError("malformed-xml", "could not parse the XML", {
|
|
68
|
+
cause
|
|
69
|
+
});
|
|
70
|
+
}
|
|
40
71
|
if (doc.getElementsByTagName("parsererror").length > 0) {
|
|
41
72
|
throw new DocxImportError("malformed-xml", "could not parse the XML");
|
|
42
73
|
}
|
|
43
74
|
return doc;
|
|
44
75
|
}
|
|
76
|
+
function namespaceDecls(xml) {
|
|
77
|
+
const prefixes = /* @__PURE__ */ new Set(["w"]);
|
|
78
|
+
for (const [, prefix] of xml.matchAll(/<\/?([A-Za-z_][\w.-]*):/g)) {
|
|
79
|
+
prefixes.add(prefix);
|
|
80
|
+
}
|
|
81
|
+
for (const [, prefix] of xml.matchAll(
|
|
82
|
+
/(?:^|[\s"'])([A-Za-z_][\w.-]*):[\w.-]+=/g
|
|
83
|
+
)) {
|
|
84
|
+
prefixes.add(prefix);
|
|
85
|
+
}
|
|
86
|
+
prefixes.delete("xml");
|
|
87
|
+
prefixes.delete("xmlns");
|
|
88
|
+
return Array.from(prefixes).map(
|
|
89
|
+
(prefix) => `xmlns:${prefix}="${prefix === "w" ? W_NS : `urn:docx-editor:${prefix}`}"`
|
|
90
|
+
).join(" ");
|
|
91
|
+
}
|
|
45
92
|
function elementChildren(el) {
|
|
46
93
|
return Array.from(el.children);
|
|
47
94
|
}
|
|
95
|
+
function attributeByLocalName(el, localName) {
|
|
96
|
+
return Array.from(el.attributes).find((entry) => entry.localName === localName)?.value ?? null;
|
|
97
|
+
}
|
|
48
98
|
function childByLocalName(el, name) {
|
|
49
99
|
return elementChildren(el).find((child) => child.localName === name) ?? null;
|
|
50
100
|
}
|
|
@@ -52,15 +102,19 @@ function attrString(el) {
|
|
|
52
102
|
if (el.attributes.length === 0) return null;
|
|
53
103
|
return Array.from(el.attributes).map((attr) => `${attr.name}="${escapeXml(attr.value)}"`).join(" ");
|
|
54
104
|
}
|
|
105
|
+
var ELEMENT_NODE = 1;
|
|
106
|
+
var TEXT_NODE = 3;
|
|
107
|
+
var CDATA_SECTION_NODE = 4;
|
|
108
|
+
var COMMENT_NODE = 8;
|
|
55
109
|
function isElement(node) {
|
|
56
|
-
return node.nodeType ===
|
|
110
|
+
return node.nodeType === ELEMENT_NODE;
|
|
57
111
|
}
|
|
58
112
|
function serializeChildNode(node) {
|
|
59
113
|
if (isElement(node)) return serializeXml(node);
|
|
60
|
-
if (node.nodeType ===
|
|
114
|
+
if (node.nodeType === TEXT_NODE || node.nodeType === CDATA_SECTION_NODE) {
|
|
61
115
|
return escapeXml(node.nodeValue ?? "");
|
|
62
116
|
}
|
|
63
|
-
if (node.nodeType ===
|
|
117
|
+
if (node.nodeType === COMMENT_NODE) {
|
|
64
118
|
return `<!--${node.nodeValue ?? ""}-->`;
|
|
65
119
|
}
|
|
66
120
|
throw new DocxImportError(
|
|
@@ -75,15 +129,20 @@ function serializeXml(el) {
|
|
|
75
129
|
return inner ? `${open}>${inner}</${el.nodeName}>` : `${open}/>`;
|
|
76
130
|
}
|
|
77
131
|
export {
|
|
132
|
+
RESERVED_PREFIXES,
|
|
78
133
|
R_NS,
|
|
79
134
|
W_NS,
|
|
80
135
|
attrString,
|
|
136
|
+
attributeByLocalName,
|
|
81
137
|
childByLocalName,
|
|
82
138
|
decodeUtf8,
|
|
83
139
|
elementChildren,
|
|
84
140
|
encodeUtf8,
|
|
85
141
|
escapeXml,
|
|
142
|
+
isElement,
|
|
86
143
|
localPart,
|
|
144
|
+
namespaceDecls,
|
|
87
145
|
parseXml,
|
|
88
|
-
serializeXml
|
|
146
|
+
serializeXml,
|
|
147
|
+
withXmlParser
|
|
89
148
|
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the page engine knows about a block, whatever shape of block it is.
|
|
3
|
+
*
|
|
4
|
+
* A measurer says where a block may be parted and how much of it has to fit on the page it
|
|
5
|
+
* starts on; the layout (`page/pageLayout`) answers with the places it decided to part it at.
|
|
6
|
+
* Neither side names a paragraph or a table.
|
|
7
|
+
*
|
|
8
|
+
* Which measurer a block gets, and what draws the cuts it was given, is the block's kind
|
|
9
|
+
* (`page/kinds`).
|
|
10
|
+
*/
|
|
11
|
+
import type { Node as PMNode } from "prosemirror-model";
|
|
12
|
+
import type { Decoration, EditorView } from "prosemirror-view";
|
|
13
|
+
/** A place inside a block where the next page may, or must, start */
|
|
14
|
+
export interface BreakCandidate {
|
|
15
|
+
/**
|
|
16
|
+
* The document position the continued piece starts at: a page `br` for a paragraph, a row for a
|
|
17
|
+
* table. A position maps through an edit, which is why the marks are kept by position and not
|
|
18
|
+
* by ordinal (see `page/pageDecorations`)
|
|
19
|
+
*/
|
|
20
|
+
at: number;
|
|
21
|
+
/** The top of the continued piece, measured from the block's natural top with no space in it */
|
|
22
|
+
offset: number;
|
|
23
|
+
/** A forced candidate always cuts; an optional one cuts only when the piece after it would overflow */
|
|
24
|
+
forced: boolean;
|
|
25
|
+
/** Height the continued piece carries onto the next page ahead of its own content (a repeated header) */
|
|
26
|
+
repeatHeight: number;
|
|
27
|
+
}
|
|
28
|
+
/** One body block as drawn on screen */
|
|
29
|
+
export interface MeasuredBlock {
|
|
30
|
+
/** The position where this block starts in the document */
|
|
31
|
+
pos: number;
|
|
32
|
+
/** The height that naturally opens up between the previous block and this one */
|
|
33
|
+
gap: number;
|
|
34
|
+
height: number;
|
|
35
|
+
/** The document records that a new page starts at this block */
|
|
36
|
+
breakBefore: boolean;
|
|
37
|
+
/** The block holds a break it cannot open a space at (inside a cell), so the next block starts a page */
|
|
38
|
+
breakAfter: boolean;
|
|
39
|
+
candidates: readonly BreakCandidate[];
|
|
40
|
+
/** The smallest piece that has to fit on the page the block starts on */
|
|
41
|
+
minFirstPiece: number;
|
|
42
|
+
/** The document asks for this block to stand on the same page as the start of the block after it */
|
|
43
|
+
keepWithNext: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** A page cut the layout decided on: the space opened before the continued piece */
|
|
46
|
+
export interface PageCut {
|
|
47
|
+
at: number;
|
|
48
|
+
height: number;
|
|
49
|
+
}
|
|
50
|
+
/** One block as it stands on the sheet, handed to the kind about to measure it */
|
|
51
|
+
export interface MeasureTarget {
|
|
52
|
+
view: EditorView;
|
|
53
|
+
node: PMNode;
|
|
54
|
+
pos: number;
|
|
55
|
+
dom: HTMLElement;
|
|
56
|
+
/**
|
|
57
|
+
* Sheet coordinates from viewport coordinates: the visual scale taken out, and everything the
|
|
58
|
+
* engine has opened up above this block taken back off
|
|
59
|
+
*/
|
|
60
|
+
sheetY(viewportY: number): number;
|
|
61
|
+
/** The block's natural top: pushes and spaces opened above it already taken back off */
|
|
62
|
+
top: number;
|
|
63
|
+
/** The visual scale the sheet is drawn at, which a length read off the screen is divided by */
|
|
64
|
+
scale: number;
|
|
65
|
+
}
|
|
66
|
+
/** What a kind has to say about the block it measured */
|
|
67
|
+
export interface KindMeasure {
|
|
68
|
+
candidates: readonly BreakCandidate[];
|
|
69
|
+
/** The smallest piece that has to fit on the page the block starts on */
|
|
70
|
+
minFirstPiece: number;
|
|
71
|
+
/** The block holds a break it could not open a space at, so the next block starts a page */
|
|
72
|
+
breakAfter: boolean;
|
|
73
|
+
/** Height the engine's own marks add inside this block, taken off its measured bottom */
|
|
74
|
+
appliedHeight: number;
|
|
75
|
+
/**
|
|
76
|
+
* Whether the document asks for this block to stand on the same page as the start of the block
|
|
77
|
+
* after it. A kind whose blocks never do leaves it out
|
|
78
|
+
*/
|
|
79
|
+
keepWithNext?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Everything the engine does with one shape of breakable block: how one is measured, and how the
|
|
83
|
+
* cuts the layout gave it are drawn.
|
|
84
|
+
*
|
|
85
|
+
* A shape the engine learns later - a footnote area, a paragraph with a floating object hanging
|
|
86
|
+
* out of it - is one more kind rather than another branch in the measurer, in the decorations
|
|
87
|
+
* and in the plugin state at once.
|
|
88
|
+
*/
|
|
89
|
+
export interface BlockKind {
|
|
90
|
+
readonly name: string;
|
|
91
|
+
matches(node: PMNode): boolean;
|
|
92
|
+
measure(target: MeasureTarget): KindMeasure;
|
|
93
|
+
/** Whether `at` still names a place this kind can cut at in `doc`; a false drops the cut */
|
|
94
|
+
holdsCut(doc: PMNode, at: number): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* The decorations one block of this kind carries: the cuts the layout gave it, plus whatever it
|
|
97
|
+
* needs before any measurement (a paragraph puts an empty space on every page `br`, so the
|
|
98
|
+
* measurement has an element to read it off).
|
|
99
|
+
*/
|
|
100
|
+
decorate(pos: number, node: PMNode, cuts: readonly PageCut[], into: Decoration[]): void;
|
|
101
|
+
}
|
|
102
|
+
/** The first kind whose `matches` answers. The kind registered last has to match every block */
|
|
103
|
+
export declare function blockKindFor(kinds: readonly BlockKind[], node: PMNode): BlockKind;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/page/blockKinds.ts
|
|
2
|
+
function blockKindFor(kinds, node) {
|
|
3
|
+
const found = kinds.find((kind) => kind.matches(node));
|
|
4
|
+
if (!found) {
|
|
5
|
+
throw new Error(`no block kind matches a ${node.type.name} block`);
|
|
6
|
+
}
|
|
7
|
+
return found;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
blockKindFor
|
|
11
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BlockKind } from "../blockKinds";
|
|
2
|
+
/**
|
|
3
|
+
* The block shapes the editor pages, in the order they are asked. A new kind goes ahead of the
|
|
4
|
+
* kinds it is narrower than, and the last one claims every block none of the others did.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DEFAULT_BLOCK_KINDS: readonly BlockKind[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kind every block falls back to: a paragraph, and any other shape no kind ahead of it claims.
|
|
3
|
+
*
|
|
4
|
+
* A page `br` is the one place a paragraph is parted at, and the space opened at it is what the
|
|
5
|
+
* measurement reads the break's place off, so every `br` carries a space of its own before
|
|
6
|
+
* anything is measured. A break standing where no space can be opened - inside a table cell,
|
|
7
|
+
* where it would grow the cell rather than the page - is answered by the whole block instead.
|
|
8
|
+
*/
|
|
9
|
+
import type { BlockKind } from "../blockKinds";
|
|
10
|
+
export declare const paragraphKind: BlockKind;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// src/page/kinds/paragraphKind.ts
|
|
2
|
+
import { Decoration } from "prosemirror-view";
|
|
3
|
+
import { toParagraphFormat } from "../../model/format.js";
|
|
4
|
+
import { docxSchema, isPageBreak } from "../../schema/index.js";
|
|
5
|
+
import { editorAttributes } from "../../styles/classNames.js";
|
|
6
|
+
var PAGE_BREAK_BR = `br[${editorAttributes.breakType}="page"]`;
|
|
7
|
+
var BREAK_SPACE = `[${editorAttributes.pageBreakSpace}]`;
|
|
8
|
+
function spaceStyle(height) {
|
|
9
|
+
return `display:block;height:${height}px`;
|
|
10
|
+
}
|
|
11
|
+
function isPageBreakNode(node) {
|
|
12
|
+
return node?.type === docxSchema.nodes.hardBreak && isPageBreak(node.attrs.brAttrs);
|
|
13
|
+
}
|
|
14
|
+
function pageBreaksIn(block, blockPos) {
|
|
15
|
+
const found = [];
|
|
16
|
+
if (block.type !== docxSchema.nodes.paragraph) return found;
|
|
17
|
+
block.forEach((child, offset) => {
|
|
18
|
+
if (isPageBreakNode(child)) {
|
|
19
|
+
found.push({ at: blockPos + 1 + offset, size: child.nodeSize });
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return found;
|
|
23
|
+
}
|
|
24
|
+
var paragraphKind = {
|
|
25
|
+
name: "paragraph",
|
|
26
|
+
matches: () => true,
|
|
27
|
+
measure({ node, pos, dom, sheetY, top, scale }) {
|
|
28
|
+
const breaks = pageBreaksIn(node, pos);
|
|
29
|
+
const candidates = [];
|
|
30
|
+
let appliedHeight = 0;
|
|
31
|
+
dom.querySelectorAll(BREAK_SPACE).forEach((space, index) => {
|
|
32
|
+
const box = space.getBoundingClientRect();
|
|
33
|
+
const found = breaks.at(index);
|
|
34
|
+
if (found) {
|
|
35
|
+
candidates.push({
|
|
36
|
+
at: found.at,
|
|
37
|
+
offset: sheetY(box.top) - appliedHeight - top,
|
|
38
|
+
forced: true,
|
|
39
|
+
repeatHeight: 0
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
appliedHeight += box.height / scale;
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
candidates,
|
|
46
|
+
minFirstPiece: candidates[0]?.offset ?? dom.getBoundingClientRect().height / scale - appliedHeight,
|
|
47
|
+
// A break with no space of its own sits somewhere the space could not be opened. Those
|
|
48
|
+
// still start a new page, but only after the whole block
|
|
49
|
+
breakAfter: dom.querySelectorAll(PAGE_BREAK_BR).length > candidates.length,
|
|
50
|
+
appliedHeight,
|
|
51
|
+
keepWithNext: toParagraphFormat(node.attrs.format)?.keepNext === true
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
holdsCut: (doc, at) => isPageBreakNode(doc.nodeAt(at)),
|
|
55
|
+
decorate(pos, node, cuts, into) {
|
|
56
|
+
const heights = new Map(cuts.map((cut) => [cut.at, cut.height]));
|
|
57
|
+
for (const { at, size } of pageBreaksIn(node, pos)) {
|
|
58
|
+
const height = heights.get(at) ?? 0;
|
|
59
|
+
into.push(
|
|
60
|
+
Decoration.inline(at, at + size, {
|
|
61
|
+
nodeName: "span",
|
|
62
|
+
style: spaceStyle(height),
|
|
63
|
+
[editorAttributes.pageBreakSpace]: `${height}`
|
|
64
|
+
})
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export {
|
|
70
|
+
paragraphKind
|
|
71
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kind of a table: it is parted between rows, and a continued page opens a spacer row and
|
|
3
|
+
* repeats the headers the table opens with.
|
|
4
|
+
*
|
|
5
|
+
* Both sides read the table as it stands on screen without treating the rows this very engine
|
|
6
|
+
* drew as content: the measurement takes their heights back off, and the projection is derived
|
|
7
|
+
* again from the document, so an edit to a header row redraws it with nothing measured anew.
|
|
8
|
+
*/
|
|
9
|
+
import type { BlockKind } from "../blockKinds";
|
|
10
|
+
export declare const tableKind: BlockKind;
|