@portone/docx-editor 0.2.1 → 0.4.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 +155 -0
- package/CONTRIBUTING.md +5 -1
- package/dist/DocxEditor.d.ts +6 -0
- package/dist/DocxEditor.js +13 -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 +12 -7
- package/dist/docx/commentOnlyChange.js +9 -156
- package/dist/docx/comments/constants.d.ts +0 -1
- package/dist/docx/comments/constants.js +0 -2
- package/dist/docx/comments/grammar.d.ts +10 -4
- package/dist/docx/comments/grammar.js +12 -2
- package/dist/docx/comments/{verifying.d.ts → parts.d.ts} +26 -18
- package/dist/docx/comments/parts.js +279 -0
- package/dist/docx/comments/people.d.ts +11 -2
- package/dist/docx/comments/people.js +16 -92
- package/dist/docx/comments/policy.d.ts +7 -0
- package/dist/docx/comments/policy.js +43 -0
- package/dist/docx/comments/reading.js +8 -10
- package/dist/docx/comments/writing.d.ts +19 -7
- package/dist/docx/comments/writing.js +59 -112
- 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 +88 -74
- 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 +45 -0
- package/dist/docx/formatting/attrs.js +86 -0
- package/dist/docx/formatting/context.d.ts +39 -0
- package/dist/docx/formatting/context.js +60 -0
- package/dist/docx/formatting/direct.d.ts +6 -5
- package/dist/docx/formatting/direct.js +52 -78
- package/dist/docx/formatting/resolve.d.ts +51 -0
- package/dist/docx/formatting/resolve.js +160 -0
- package/dist/docx/formatting/runProperties.d.ts +93 -0
- package/dist/docx/formatting/runProperties.js +316 -0
- package/dist/docx/formatting/styles.d.ts +25 -2
- package/dist/docx/formatting/styles.js +87 -6
- 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 +6 -13
- package/dist/docx/hyperlink.d.ts +14 -4
- package/dist/docx/hyperlink.js +4 -1
- 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 +90 -88
- package/dist/docx/importParagraph.d.ts +1 -1
- package/dist/docx/importParagraph.js +4 -3
- package/dist/docx/importTable.d.ts +2 -2
- package/dist/docx/importTable.js +69 -56
- package/dist/docx/invariants.d.ts +33 -0
- package/dist/docx/invariants.js +269 -0
- package/dist/docx/media.d.ts +6 -4
- package/dist/docx/media.js +6 -37
- package/dist/docx/newLists.d.ts +50 -0
- package/dist/docx/newLists.js +59 -0
- package/dist/docx/notes.js +3 -7
- package/dist/docx/numberingPlanner.d.ts +11 -0
- package/dist/docx/numberingPlanner.js +50 -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 +47 -76
- 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 +8 -13
- 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 +9 -34
- 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 +8 -5
- package/dist/docx/serializeTable.js +32 -15
- package/dist/docx/session.d.ts +42 -14
- package/dist/docx/session.js +53 -17
- 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 +111 -143
- package/dist/docx/tableFormatting/reading.d.ts +63 -23
- package/dist/docx/tableFormatting/reading.js +132 -38
- package/dist/docx/tableFormatting.d.ts +1 -0
- package/dist/docx/tableFormatting.js +1 -0
- package/dist/docx/tableTemplate.js +30 -19
- package/dist/download.d.ts +8 -5
- package/dist/download.js +2 -0
- package/dist/editor/clipboard/inlineFormatting.js +19 -30
- package/dist/editor/commands/comments/editing.d.ts +6 -2
- package/dist/editor/commands/comments/editing.js +19 -31
- 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 +108 -0
- package/dist/editor/commands/formatting/shared.d.ts +3 -3
- package/dist/editor/commands/formatting/shared.js +5 -2
- 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.d.ts +6 -3
- package/dist/editor/commands/listCommands.js +73 -30
- package/dist/editor/commands/lockCommands.d.ts +7 -1
- package/dist/editor/commands/lockCommands.js +35 -46
- package/dist/editor/commands/paragraphCommands.js +33 -31
- package/dist/editor/commands/spacingCommands.js +1 -1
- package/dist/editor/createEditor.d.ts +17 -29
- package/dist/editor/createEditor.js +58 -58
- package/dist/editor/documentStyles.d.ts +11 -35
- package/dist/editor/documentStyles.js +9 -52
- package/dist/editor/editorDocument.d.ts +57 -0
- package/dist/editor/editorDocument.js +86 -0
- package/dist/editor/externalClipboard.d.ts +13 -2
- package/dist/editor/externalClipboard.js +76 -75
- package/dist/editor/insertTable.js +4 -3
- package/dist/editor/paragraphEdits.d.ts +27 -19
- package/dist/editor/paragraphEdits.js +18 -19
- package/dist/editor/paragraphPlacement.d.ts +11 -0
- package/dist/editor/paragraphPlacement.js +18 -0
- package/dist/editor/plugins/displayDerivation.d.ts +47 -0
- package/dist/editor/plugins/displayDerivation.js +78 -0
- package/dist/editor/plugins/imagePaste.js +11 -7
- package/dist/editor/plugins/keymap.js +18 -3
- package/dist/editor/plugins/numberingDecorations.d.ts +14 -14
- package/dist/editor/plugins/numberingDecorations.js +50 -19
- package/dist/editor/plugins/paragraphDisplay.d.ts +7 -0
- package/dist/editor/plugins/paragraphDisplay.js +57 -0
- package/dist/editor/plugins/tabLayout.js +1 -1
- package/dist/editor/plugins/tableDisplay.d.ts +6 -0
- package/dist/editor/plugins/tableDisplay.js +30 -0
- package/dist/index.d.ts +2 -0
- package/dist/model/format.d.ts +80 -8
- package/dist/model/format.js +100 -22
- package/dist/model/tabStops.d.ts +9 -0
- package/dist/model/tabStops.js +18 -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 +88 -25
- package/dist/numbering/markers.d.ts +15 -6
- package/dist/numbering/markers.js +26 -59
- package/dist/numbering/parseNumbering.d.ts +84 -6
- package/dist/numbering/parseNumbering.js +131 -44
- package/dist/numbering/spellers.d.ts +15 -0
- package/dist/numbering/spellers.js +96 -0
- package/dist/numbering/writeNumbering.d.ts +8 -7
- package/dist/numbering/writeNumbering.js +28 -39
- package/dist/ooxml/childOrder.d.ts +34 -0
- package/dist/ooxml/childOrder.js +496 -0
- package/dist/ooxml/conformance.d.ts +28 -0
- package/dist/ooxml/conformance.js +20 -0
- package/dist/ooxml/element.d.ts +24 -11
- package/dist/ooxml/element.js +31 -12
- package/dist/ooxml/errors.d.ts +6 -5
- package/dist/ooxml/image.d.ts +4 -0
- package/dist/ooxml/image.js +2 -5
- package/dist/ooxml/names.d.ts +9 -0
- package/dist/ooxml/names.js +8 -1
- package/dist/ooxml/partSplice.d.ts +67 -0
- package/dist/ooxml/partSplice.js +176 -0
- package/dist/ooxml/props.d.ts +112 -0
- package/dist/{docx/propsXml.js → ooxml/props.js} +72 -200
- 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 +35 -15
- package/dist/ooxml/xml.js +43 -11
- package/dist/page/PageGuides.d.ts +1 -1
- package/dist/page/PageGuides.js +0 -13
- package/dist/page/blockKinds.d.ts +61 -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 -14
- package/dist/page/measureBlocks.js +24 -45
- package/dist/page/pageDecorations.d.ts +27 -44
- package/dist/page/pageDecorations.js +70 -152
- package/dist/page/pageLayout.d.ts +2 -29
- package/dist/page/pageLayout.js +39 -16
- package/dist/page/usePageLayout.d.ts +2 -24
- package/dist/page/usePageLayout.js +5 -48
- package/dist/schema/attrRoles.d.ts +25 -18
- package/dist/schema/attrRoles.js +110 -68
- package/dist/schema/displayDerivation.d.ts +82 -0
- package/dist/schema/displayDerivation.js +130 -0
- package/dist/schema/docxSchema.d.ts +3 -0
- package/dist/schema/docxSchema.js +58 -17
- package/dist/schema/editGuard.d.ts +1 -1
- package/dist/schema/guards.d.ts +37 -14
- package/dist/schema/guards.js +29 -3
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/locks.d.ts +11 -44
- package/dist/schema/locks.js +0 -9
- package/dist/schema/preservedGuards.d.ts +26 -6
- package/dist/schema/preservedGuards.js +31 -1
- package/dist/schema/protection.d.ts +7 -1
- package/dist/schema/protection.js +2 -1
- package/dist/schema/sourceEquality.d.ts +1 -9
- package/dist/schema/sourceEquality.js +1 -27
- package/dist/styles/classNames.d.ts +13 -2
- package/dist/styles/classNames.js +13 -2
- package/dist/styles/inlineStyle.js +15 -6
- package/dist/styles.css +16 -18
- package/dist/table/cellFormatting.d.ts +8 -1
- package/dist/table/cellFormatting.js +11 -20
- 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 +24 -30
- package/dist/table/gridBorders.js +35 -59
- package/dist/table/merge.d.ts +2 -6
- package/dist/table/merge.js +5 -5
- package/package.json +7 -3
- package/dist/docx/comments/contentTypes.d.ts +0 -7
- package/dist/docx/comments/contentTypes.js +0 -38
- package/dist/docx/comments/verifying.js +0 -206
- package/dist/docx/formatting/effectiveParagraph.d.ts +0 -15
- package/dist/docx/formatting/effectiveParagraph.js +0 -81
- package/dist/docx/propsXml.d.ts +0 -67
- package/dist/docx/uniqueControls.d.ts +0 -14
- package/dist/docx/uniqueControls.js +0 -62
- package/dist/editor/plugins/commentReservations.d.ts +0 -5
- package/dist/editor/plugins/commentReservations.js +0 -26
- package/dist/editor/plugins/styledParagraphs.d.ts +0 -15
- package/dist/editor/plugins/styledParagraphs.js +0 -65
- package/dist/page/tableMeasurements.d.ts +0 -18
- package/dist/page/tableMeasurements.js +0 -119
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
// src/docx/tableFormatting/editing.ts
|
|
2
|
-
import {
|
|
2
|
+
import { elementXml, wAttrValue } from "../../ooxml/element.js";
|
|
3
3
|
import { wName } from "../../ooxml/names.js";
|
|
4
4
|
import { setAttr } from "../../ooxml/precedence.js";
|
|
5
|
-
import { normalizeHex, wAttr } from "../../ooxml/units.js";
|
|
6
|
-
import { childByLocalName } from "../../ooxml/xml.js";
|
|
7
5
|
import {
|
|
6
|
+
childElement,
|
|
7
|
+
editChild,
|
|
8
8
|
parseProps,
|
|
9
9
|
parsePropsXml,
|
|
10
10
|
propsChild,
|
|
11
11
|
renderProps,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "../propsXml.js";
|
|
12
|
+
setChild,
|
|
13
|
+
withAttrs
|
|
14
|
+
} from "../../ooxml/props.js";
|
|
16
15
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
ST_EighthPointMeasure,
|
|
17
|
+
ST_TwipsMeasure,
|
|
18
|
+
TWIPS_PER_PT
|
|
19
|
+
} from "../../ooxml/simpleTypes.js";
|
|
20
|
+
import { normalizeHex } from "../../ooxml/units.js";
|
|
21
|
+
import {
|
|
22
|
+
NO_CELL_DEFAULTS,
|
|
19
23
|
readCellProps,
|
|
20
24
|
readRowFormat
|
|
21
25
|
} from "./reading.js";
|
|
@@ -25,18 +29,6 @@ var ALL_CELL_SIDES = [
|
|
|
25
29
|
"left",
|
|
26
30
|
"right"
|
|
27
31
|
];
|
|
28
|
-
var TC_BORDERS_ORDER = [
|
|
29
|
-
"top",
|
|
30
|
-
"start",
|
|
31
|
-
"left",
|
|
32
|
-
"bottom",
|
|
33
|
-
"end",
|
|
34
|
-
"right",
|
|
35
|
-
"insideH",
|
|
36
|
-
"insideV",
|
|
37
|
-
"tl2br",
|
|
38
|
-
"tr2bl"
|
|
39
|
-
];
|
|
40
32
|
var SIDE_NAMES = {
|
|
41
33
|
top: ["top"],
|
|
42
34
|
bottom: ["bottom"],
|
|
@@ -46,22 +38,24 @@ var SIDE_NAMES = {
|
|
|
46
38
|
var PRESET_BORDER_EIGHTHS = 4;
|
|
47
39
|
var EMPTY_TC_PR = { tag: "w:tcPr", attrs: null, children: [] };
|
|
48
40
|
function drawsLine(side) {
|
|
49
|
-
if (
|
|
50
|
-
const val =
|
|
41
|
+
if (side.tag === null) return false;
|
|
42
|
+
const val = wAttrValue(side.attrs, "val");
|
|
51
43
|
return val !== null && val !== "nil" && val !== "none";
|
|
52
44
|
}
|
|
53
45
|
function sideAttrs(name, current, edit, fallback = null) {
|
|
54
46
|
if (edit.kind === "color") {
|
|
55
47
|
if (!drawsLine(current)) {
|
|
56
|
-
if (current ||
|
|
48
|
+
if (current.tag !== null || fallback === null || fallback.val === "none") {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
57
51
|
return inheritedBorderAttrs(fallback, edit.hex);
|
|
58
52
|
}
|
|
59
|
-
return setAttr(
|
|
53
|
+
return setAttr(current.attrs, name, "color", edit.hex ?? "auto");
|
|
60
54
|
}
|
|
61
55
|
if (edit.line === "none") {
|
|
62
|
-
return current ? setAttr(
|
|
56
|
+
return current.tag !== null ? setAttr(current.attrs, name, "val", "none") : [[wName("val"), "none"]];
|
|
63
57
|
}
|
|
64
|
-
if (
|
|
58
|
+
if (current.tag === null) {
|
|
65
59
|
return [
|
|
66
60
|
[wName("val"), "single"],
|
|
67
61
|
[wName("sz"), `${PRESET_BORDER_EIGHTHS}`],
|
|
@@ -70,217 +64,191 @@ function sideAttrs(name, current, edit, fallback = null) {
|
|
|
70
64
|
];
|
|
71
65
|
}
|
|
72
66
|
return setAttr(
|
|
73
|
-
setAttr(
|
|
67
|
+
setAttr(current.attrs, name, "val", "single"),
|
|
74
68
|
name,
|
|
75
69
|
"sz",
|
|
76
70
|
`${PRESET_BORDER_EIGHTHS}`
|
|
77
71
|
);
|
|
78
72
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
};
|
|
85
|
-
function inheritedBorderAttrs(border, hex) {
|
|
86
|
-
const matched = border.match(
|
|
87
|
-
/^(\d+(?:\.\d+)?)pt (solid|double|dashed|dotted) (#[0-9a-f]{6})$/i
|
|
88
|
-
);
|
|
89
|
-
if (!matched) return null;
|
|
90
|
-
const [, widthText, style, currentColor] = matched;
|
|
91
|
-
if (hex !== null && normalizeHex(currentColor) === hex) return null;
|
|
92
|
-
const eighths = Math.round(Number.parseFloat(widthText) * 8);
|
|
93
|
-
if (!Number.isSafeInteger(eighths) || eighths <= 0) return null;
|
|
73
|
+
function inheritedBorderAttrs(line, hex) {
|
|
74
|
+
const current = line.color.kind === "rgb" ? normalizeHex(line.color.hex) : null;
|
|
75
|
+
if (hex !== null && current === hex) return null;
|
|
76
|
+
const thickness = ST_EighthPointMeasure.format(line.eighths);
|
|
77
|
+
if (thickness === null) return null;
|
|
94
78
|
return [
|
|
95
|
-
[wName("val"),
|
|
96
|
-
[wName("sz"),
|
|
79
|
+
[wName("val"), line.val],
|
|
80
|
+
[wName("sz"), thickness],
|
|
97
81
|
[wName("space"), "0"],
|
|
98
82
|
[wName("color"), hex ?? "auto"]
|
|
99
83
|
];
|
|
100
84
|
}
|
|
101
85
|
function sideNames(borders, side) {
|
|
102
86
|
const [primary, alternate] = SIDE_NAMES[side];
|
|
103
|
-
const usesAlternate = alternate !== void 0 &&
|
|
87
|
+
const usesAlternate = alternate !== void 0 && propsChild(borders.children, primary) === void 0 && propsChild(borders.children, alternate) !== void 0;
|
|
104
88
|
if (usesAlternate) return { write: alternate, drop: null };
|
|
105
89
|
return { write: primary, drop: alternate ?? null };
|
|
106
90
|
}
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
91
|
+
function leafElement(tag, attrs) {
|
|
92
|
+
return withAttrs({ tag, attrs: null, children: [] }, attrs);
|
|
93
|
+
}
|
|
94
|
+
function containerOf(props, name) {
|
|
95
|
+
const current = propsChild(props.children, name)?.xml;
|
|
96
|
+
if (current === void 0) {
|
|
97
|
+
return { tag: wName(name), attrs: null, children: [] };
|
|
98
|
+
}
|
|
99
|
+
return parseProps(current);
|
|
100
|
+
}
|
|
101
|
+
function editedBorders(props, edit, defaults) {
|
|
102
|
+
const borders = containerOf(props, "tcBorders");
|
|
103
|
+
if (!borders) return null;
|
|
111
104
|
const sides = edit.kind === "line" ? edit.sides : ALL_CELL_SIDES;
|
|
112
|
-
|
|
105
|
+
return sides.reduce((kept, side) => {
|
|
106
|
+
if (kept === null) return null;
|
|
113
107
|
const { write, drop } = sideNames(borders, side);
|
|
114
|
-
const currentSide =
|
|
108
|
+
const currentSide = childElement(borders, write);
|
|
109
|
+
if (!currentSide) return null;
|
|
115
110
|
const attrs = sideAttrs(write, currentSide, edit, defaults[side]);
|
|
116
111
|
if (!attrs) return kept;
|
|
117
|
-
const
|
|
118
|
-
const written = setPropsChild(
|
|
112
|
+
const written = editChild(
|
|
119
113
|
kept,
|
|
120
|
-
write,
|
|
121
|
-
|
|
122
|
-
TC_BORDERS_ORDER
|
|
114
|
+
["tcBorders", write],
|
|
115
|
+
() => leafElement(currentSide.tag ?? wName(write), attrs)
|
|
123
116
|
);
|
|
124
|
-
|
|
117
|
+
if (written === null || drop === null) return written;
|
|
118
|
+
return editChild(written, ["tcBorders", drop], () => null);
|
|
125
119
|
}, props);
|
|
126
|
-
const xml = renderProps(edited);
|
|
127
|
-
return { xml: xml === "" ? null : xml };
|
|
128
120
|
}
|
|
129
121
|
function hasPattern(shd) {
|
|
130
|
-
const val =
|
|
122
|
+
const val = wAttrValue(shd.attrs, "val");
|
|
131
123
|
return val !== null && val !== "clear" && val !== "nil";
|
|
132
124
|
}
|
|
133
125
|
function editedShading(current, fill) {
|
|
134
|
-
const tag = current
|
|
126
|
+
const tag = current.tag ?? wName("shd");
|
|
135
127
|
if (fill === null) {
|
|
136
128
|
if (!hasPattern(current)) return null;
|
|
137
|
-
return elementXml(tag, setAttr(
|
|
129
|
+
return elementXml(tag, setAttr(current.attrs, "shd", "fill", "auto"));
|
|
138
130
|
}
|
|
139
|
-
if (
|
|
131
|
+
if (current.tag === null) {
|
|
140
132
|
return elementXml(tag, [
|
|
141
133
|
[wName("val"), "clear"],
|
|
142
134
|
[wName("color"), "auto"],
|
|
143
135
|
[wName("fill"), fill]
|
|
144
136
|
]);
|
|
145
137
|
}
|
|
146
|
-
const painting = hasPattern(current) ?
|
|
138
|
+
const painting = hasPattern(current) ? current.attrs : setAttr(current.attrs, "shd", "val", "clear");
|
|
147
139
|
return elementXml(tag, setAttr(painting, "shd", "fill", fill));
|
|
148
140
|
}
|
|
149
|
-
function bordersChange(props, edit, defaults) {
|
|
150
|
-
const current = propsChild(props.children, "tcBorders")?.xml ?? null;
|
|
151
|
-
const edited = editedBorders(current, edit, defaults);
|
|
152
|
-
return edited === null ? null : { name: "tcBorders", xml: edited.xml };
|
|
153
|
-
}
|
|
154
|
-
var TC_MAR_ORDER = [
|
|
155
|
-
"top",
|
|
156
|
-
"start",
|
|
157
|
-
"left",
|
|
158
|
-
"bottom",
|
|
159
|
-
"end",
|
|
160
|
-
"right"
|
|
161
|
-
];
|
|
162
141
|
var MARGIN_SIDE_NAMES = {
|
|
163
142
|
top: ["top"],
|
|
164
143
|
right: ["end", "right"],
|
|
165
144
|
bottom: ["bottom"],
|
|
166
145
|
left: ["start", "left"]
|
|
167
146
|
};
|
|
168
|
-
function
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (!parsed || current !== null && !margins) return null;
|
|
173
|
-
let edited = parsed;
|
|
147
|
+
function editedPadding(props, values) {
|
|
148
|
+
const margins = containerOf(props, "tcMar");
|
|
149
|
+
if (!margins) return null;
|
|
150
|
+
let edited = props;
|
|
174
151
|
let wrote = false;
|
|
175
152
|
for (const side of ALL_CELL_SIDES) {
|
|
176
153
|
const points = values[side];
|
|
177
154
|
if (points === void 0) continue;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
155
|
+
if (points < 0) return null;
|
|
156
|
+
const twips = ST_TwipsMeasure.format(Math.round(points * TWIPS_PER_PT));
|
|
157
|
+
if (twips === null) return null;
|
|
158
|
+
const name = MARGIN_SIDE_NAMES[side].find(
|
|
159
|
+
(spelling) => propsChild(margins.children, spelling) !== void 0
|
|
160
|
+
) ?? side;
|
|
161
|
+
const existing = childElement(margins, name);
|
|
162
|
+
if (existing === null || edited === null) return null;
|
|
184
163
|
const attrs = setAttr(
|
|
185
|
-
setAttr(
|
|
164
|
+
setAttr(existing.attrs, name, "w", twips),
|
|
186
165
|
name,
|
|
187
166
|
"type",
|
|
188
167
|
"dxa"
|
|
189
168
|
);
|
|
190
|
-
edited =
|
|
169
|
+
edited = editChild(
|
|
191
170
|
edited,
|
|
192
|
-
name,
|
|
193
|
-
|
|
194
|
-
TC_MAR_ORDER
|
|
171
|
+
["tcMar", name],
|
|
172
|
+
() => leafElement(existing.tag ?? wName(side), attrs)
|
|
195
173
|
);
|
|
196
174
|
wrote = true;
|
|
197
175
|
}
|
|
198
|
-
|
|
199
|
-
return { name: "tcMar", xml: renderProps(edited) };
|
|
176
|
+
return wrote ? edited : null;
|
|
200
177
|
}
|
|
201
|
-
function
|
|
178
|
+
function editedProps(edit, props, defaults) {
|
|
202
179
|
switch (edit.kind) {
|
|
203
180
|
case "background": {
|
|
204
181
|
const fill = edit.hex === null ? null : normalizeHex(edit.hex);
|
|
205
182
|
if (edit.hex !== null && fill === null) return null;
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return { name: "shd", xml: editedShading(shd, fill) };
|
|
183
|
+
const shd = childElement(props, "shd");
|
|
184
|
+
if (!shd) return null;
|
|
185
|
+
return setChild(props, "shd", editedShading(shd, fill));
|
|
210
186
|
}
|
|
211
187
|
case "borders":
|
|
212
|
-
return
|
|
188
|
+
return editedBorders(
|
|
213
189
|
props,
|
|
214
|
-
{
|
|
215
|
-
kind: "line",
|
|
216
|
-
line: edit.line,
|
|
217
|
-
sides: edit.sides
|
|
218
|
-
},
|
|
190
|
+
{ kind: "line", line: edit.line, sides: edit.sides },
|
|
219
191
|
defaults
|
|
220
192
|
);
|
|
221
193
|
case "borderColor": {
|
|
222
194
|
const hex = edit.hex === null ? null : normalizeHex(edit.hex);
|
|
223
195
|
if (edit.hex !== null && hex === null) return null;
|
|
224
|
-
return
|
|
196
|
+
return editedBorders(props, { kind: "color", hex }, defaults);
|
|
225
197
|
}
|
|
226
198
|
case "verticalAlign": {
|
|
227
|
-
const current =
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
setAttr(
|
|
199
|
+
const current = childElement(props, "vAlign");
|
|
200
|
+
if (!current) return null;
|
|
201
|
+
return setChild(
|
|
202
|
+
props,
|
|
203
|
+
"vAlign",
|
|
204
|
+
elementXml(
|
|
205
|
+
current.tag ?? wName("vAlign"),
|
|
206
|
+
setAttr(current.attrs, "vAlign", "val", edit.align)
|
|
235
207
|
)
|
|
236
|
-
|
|
208
|
+
);
|
|
237
209
|
}
|
|
238
210
|
case "padding":
|
|
239
|
-
return
|
|
211
|
+
return editedPadding(props, edit.values);
|
|
240
212
|
}
|
|
241
213
|
}
|
|
242
|
-
function editCellProps(tcPr, edit, defaults =
|
|
214
|
+
function editCellProps(tcPr, edit, defaults = NO_CELL_DEFAULTS) {
|
|
243
215
|
const props = tcPr === null ? EMPTY_TC_PR : parseProps(tcPr);
|
|
244
216
|
if (!props) return null;
|
|
245
|
-
const
|
|
246
|
-
if (!
|
|
247
|
-
const rendered = renderProps(
|
|
248
|
-
setPropsChild(props, change.name, change.xml, TC_PR_ORDER)
|
|
249
|
-
);
|
|
217
|
+
const edited = editedProps(edit, props, defaults.borders);
|
|
218
|
+
if (!edited) return null;
|
|
219
|
+
const rendered = renderProps(edited);
|
|
250
220
|
const next = rendered === "" ? null : rendered;
|
|
251
221
|
if (next === tcPr) return null;
|
|
252
|
-
return { tcPr: next, format: readCellProps(next, defaults
|
|
222
|
+
return { tcPr: next, format: readCellProps(next, defaults) };
|
|
253
223
|
}
|
|
254
224
|
function drawsOwnCellBorder(tcPr) {
|
|
255
|
-
const
|
|
256
|
-
const borders =
|
|
225
|
+
const props = tcPr === null ? null : parseProps(tcPr);
|
|
226
|
+
const borders = props && containerOf(props, "tcBorders");
|
|
257
227
|
if (!borders) return false;
|
|
258
228
|
return ALL_CELL_SIDES.some(
|
|
259
|
-
(side) => SIDE_NAMES[side].some((name) =>
|
|
229
|
+
(side) => SIDE_NAMES[side].some((name) => {
|
|
230
|
+
const element = childElement(borders, name);
|
|
231
|
+
return element !== null && drawsLine(element);
|
|
232
|
+
})
|
|
260
233
|
);
|
|
261
234
|
}
|
|
262
235
|
function editRowHeight(trPr, heightPt) {
|
|
263
|
-
const twips = Math.round(heightPt *
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
const props = trPr === null ? { tag: "w:trPr", attrs: null, children: [] } : parseProps(trPr);
|
|
236
|
+
const twips = heightPt > 0 ? ST_TwipsMeasure.format(Math.round(heightPt * TWIPS_PER_PT)) : null;
|
|
237
|
+
if (twips === null) return null;
|
|
238
|
+
const props = trPr === null ? { tag: wName("trPr"), attrs: null, children: [] } : parseProps(trPr);
|
|
268
239
|
if (!props) return null;
|
|
269
|
-
const current =
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const
|
|
273
|
-
const attrs = setAttr(attrPairs(element), "trHeight", "val", `${twips}`);
|
|
240
|
+
const current = childElement(props, "trHeight");
|
|
241
|
+
if (!current) return null;
|
|
242
|
+
const writtenRule = wAttrValue(current.attrs, "hRule");
|
|
243
|
+
const attrs = setAttr(current.attrs, "trHeight", "val", twips);
|
|
274
244
|
const nextAttrs = setAttr(
|
|
275
245
|
attrs,
|
|
276
246
|
"trHeight",
|
|
277
247
|
"hRule",
|
|
278
248
|
writtenRule === "exact" ? "exact" : "atLeast"
|
|
279
249
|
);
|
|
280
|
-
const child = elementXml(
|
|
281
|
-
const rendered = renderProps(
|
|
282
|
-
setPropsChild(props, "trHeight", child, TR_PR_ORDER)
|
|
283
|
-
);
|
|
250
|
+
const child = elementXml(current.tag ?? wName("trHeight"), nextAttrs);
|
|
251
|
+
const rendered = renderProps(setChild(props, "trHeight", child));
|
|
284
252
|
if (rendered === trPr) return null;
|
|
285
253
|
const parsed = parsePropsXml(rendered);
|
|
286
254
|
const format = parsed ? readRowFormat(parsed) : null;
|
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
* Reads table formatting for display. Table borders and margins are folded into cell values so CSS
|
|
3
3
|
* collapsed-border resolution matches OOXML inheritance without changing exported XML.
|
|
4
4
|
*/
|
|
5
|
-
import type
|
|
6
|
-
|
|
5
|
+
import { type BandSizes, type CellFormat, type CellMargins, type CellStyleFormat, type CellVerticalAlign, type InsideBorders, type RowFormat, type RunFormat, type TableFormat, type TableStyleConditions, type TableStyleOverrideType, type TableWidth } from "../../model/format";
|
|
6
|
+
import { type BorderLine } from "../../ooxml/units";
|
|
7
|
+
import type { ParagraphPlacement } from "../formatting/resolve";
|
|
8
|
+
import type { ParagraphFormatLayer } from "../formatting/tabStops";
|
|
9
|
+
export type { BandSizes, CellMargins, CellStyleFormat, InsideBorders, TableStyleConditions, TableStyleOverrideType, } from "../../model/format";
|
|
7
10
|
/**
|
|
8
11
|
* The width written down by `<w:tblW>` or `<w:tcW>`.
|
|
9
12
|
* If we cannot make out what it means it is null, and such a width goes back out unchanged on export.
|
|
10
13
|
*
|
|
11
|
-
* `auto` and `nil` leave the width to the layout
|
|
14
|
+
* `auto` and `nil` leave the width to the layout unless the value carries an explicit percentage.
|
|
12
15
|
* A percentage may be written in fiftieths of a percent, as in `w:w="2500"`, or as `w:w="50%"`.
|
|
13
16
|
* Both have to be gathered into the same unit, or the table collapses into a thin strip on screen.
|
|
17
|
+
* Word lets an explicit `%` override `w:type` (MS-OI29500 §2.1.185(b)); see
|
|
18
|
+
* spec/notes/simpleTypes.md. A universal measure under `pct` remains unreadable here.
|
|
14
19
|
*/
|
|
15
20
|
export declare function readTableWidth(parent: Element | null, name: "tblW" | "tcW"): TableWidth | null;
|
|
16
21
|
/** The sequence of column widths (dxa) set by `<w:tblGrid>`. Revision markup (tblGridChange) is skipped */
|
|
@@ -32,15 +37,20 @@ export declare function readCellMarginsOf(parent: Element | null, name: "tblCell
|
|
|
32
37
|
* their cell padding from.
|
|
33
38
|
*/
|
|
34
39
|
export declare function layerCellMargins(style: CellMargins, direct: CellMargins): CellMargins;
|
|
35
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* The lines a cell falls back on, one per side, already resolved for its spot in the grid.
|
|
42
|
+
*
|
|
43
|
+
* They are held as the markup records them rather than as CSS, because a cell that takes one of
|
|
44
|
+
* them over as a border of its own writes it back into `w:tcBorders`.
|
|
45
|
+
*/
|
|
36
46
|
export interface CellBorderDefaults {
|
|
37
|
-
top:
|
|
38
|
-
bottom:
|
|
39
|
-
left:
|
|
40
|
-
right:
|
|
47
|
+
top: BorderLine | null;
|
|
48
|
+
bottom: BorderLine | null;
|
|
49
|
+
left: BorderLine | null;
|
|
50
|
+
right: BorderLine | null;
|
|
41
51
|
}
|
|
42
52
|
export declare const NO_BORDER_DEFAULTS: CellBorderDefaults;
|
|
43
|
-
/** Which sides of a cell lie on the edge of the table
|
|
53
|
+
/** Which sides of a cell lie on the edge of a part of the table */
|
|
44
54
|
export interface GridEdges {
|
|
45
55
|
top: boolean;
|
|
46
56
|
bottom: boolean;
|
|
@@ -59,19 +69,48 @@ export interface GridSize {
|
|
|
59
69
|
cols: number;
|
|
60
70
|
}
|
|
61
71
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
72
|
+
* Everything one cell falls back on for what it did not write down itself, worked out from where
|
|
73
|
+
* it sits in the grid by `cellDefaultsFor`. Everything that reads or edits a cell takes one of
|
|
74
|
+
* these, so the lines a cell draws and the lines an edit measures against are always the same.
|
|
65
75
|
*/
|
|
66
|
-
export
|
|
76
|
+
export interface CellDefaults {
|
|
77
|
+
borders: CellBorderDefaults;
|
|
78
|
+
margins: CellMargins;
|
|
79
|
+
background: string | null;
|
|
80
|
+
verticalAlign: CellVerticalAlign | null;
|
|
81
|
+
/** What the paragraphs inside the cell resolve their formatting against */
|
|
82
|
+
placement: ParagraphPlacement;
|
|
83
|
+
}
|
|
84
|
+
export declare const NO_CELL_DEFAULTS: CellDefaults;
|
|
85
|
+
export declare const NO_BAND_SIZES: BandSizes;
|
|
86
|
+
/** How many rows and columns one band of a table style is made of, read from the style's `w:tblPr` */
|
|
87
|
+
export declare function readBandSizes(tblPr: Element | null): BandSizes;
|
|
88
|
+
export declare function layerBandSizes(style: BandSizes, over: BandSizes): BandSizes;
|
|
89
|
+
export declare const NO_CELL_STYLE_FORMAT: CellStyleFormat;
|
|
90
|
+
export declare const NO_TABLE_STYLE_CONDITIONS: TableStyleConditions;
|
|
91
|
+
/**
|
|
92
|
+
* The formatting one conditional format of a table style lays down (`w:tblStylePr`).
|
|
93
|
+
* Its `w:tblPr` speaks for the region as a whole and its `w:tcPr` for the cells in it, so the
|
|
94
|
+
* cell values are read with the table values underneath them.
|
|
95
|
+
*/
|
|
96
|
+
export interface ConditionalTableFormat {
|
|
97
|
+
paragraph: ParagraphFormatLayer;
|
|
98
|
+
run: RunFormat;
|
|
99
|
+
table: TableFormat;
|
|
100
|
+
cell: CellStyleFormat;
|
|
101
|
+
}
|
|
67
102
|
/**
|
|
68
|
-
*
|
|
103
|
+
* What a conditional format lays down for the cells of its region.
|
|
69
104
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
105
|
+
* The `w:tcPr` of a conditional format writes the lines of the region rather than of every cell in
|
|
106
|
+
* it: `insideH` and `insideV` are the lines between the cells it covers, which is how the header
|
|
107
|
+
* row of a style with `insideV` set to `nil` is drawn as one unbroken band.
|
|
73
108
|
*/
|
|
74
|
-
export declare function
|
|
109
|
+
export declare function readCellStyleFormat(tcPr: Element | null, tblPr: Element | null): CellStyleFormat;
|
|
110
|
+
/** Lays one conditional format over the one a style further up the `basedOn` chain wrote for the same part */
|
|
111
|
+
export declare function layerCellStyleFormat(base: CellStyleFormat, over: CellStyleFormat): CellStyleFormat;
|
|
112
|
+
/** The conditions a table style lays down for its cells alone, which is what a table carries for its cells to draw */
|
|
113
|
+
export declare function cellConditionsOf(conditions: Readonly<Partial<Record<TableStyleOverrideType, ConditionalTableFormat>>>): TableStyleConditions;
|
|
75
114
|
/** The name of the table style `w:tblStyle` points at. null if it points at none */
|
|
76
115
|
export declare function tblStyleIdOf(tblPr: Element | null): string | null;
|
|
77
116
|
export declare function readTableFormat(tblPr: Element | null): TableFormat | null;
|
|
@@ -79,11 +118,12 @@ export declare function readRowFormat(trPr: Element | null): RowFormat | null;
|
|
|
79
118
|
/**
|
|
80
119
|
* Cell formatting.
|
|
81
120
|
* A side for which the cell has not written down its own border uses the line that side falls on,
|
|
82
|
-
* which is the table's outer border
|
|
83
|
-
*
|
|
84
|
-
*
|
|
121
|
+
* which is the table's outer border, its inside line, or the line a conditional format of its
|
|
122
|
+
* style draws there, depending on where the cell sits.
|
|
123
|
+
* The fill, the vertical alignment and the padding work the same way: what the cell wrote down
|
|
124
|
+
* wins, and what it falls back on lies underneath. null if there is nothing at all to draw.
|
|
85
125
|
*/
|
|
86
|
-
export declare function readCellFormat(tcPr: Element | null, defaults
|
|
126
|
+
export declare function readCellFormat(tcPr: Element | null, defaults?: CellDefaults): CellFormat | null;
|
|
87
127
|
/** The inside lines the table lays down, read from the table's own formatting XML */
|
|
88
128
|
export declare function insideBordersOf(tblPr: string | null): InsideBorders;
|
|
89
129
|
/** The cell margins the table lays down, read from the table's own formatting XML */
|
|
@@ -92,5 +132,5 @@ export declare function cellMarginsOf(tblPr: string | null): CellMargins;
|
|
|
92
132
|
* Reads a cell formatting fragment we operated on back into display values, along the same path
|
|
93
133
|
* the import takes. The same fragment always yields the same display values.
|
|
94
134
|
*/
|
|
95
|
-
export declare function readCellProps(tcPr: string | null, defaults
|
|
135
|
+
export declare function readCellProps(tcPr: string | null, defaults?: CellDefaults): CellFormat | null;
|
|
96
136
|
/** The formatting a cell holds. The original XML and the display values read out of it form a pair */
|