docxodus 8.0.0 → 9.0.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/README.md +65 -24
- package/dist/editor-headerfooter.d.ts +39 -3
- package/dist/editor-headerfooter.d.ts.map +1 -1
- package/dist/editor-headerfooter.js +118 -2
- package/dist/editor-headerfooter.js.map +1 -1
- package/dist/editor-reconcile.d.ts +75 -0
- package/dist/editor-reconcile.d.ts.map +1 -0
- package/dist/editor-reconcile.js +125 -0
- package/dist/editor-reconcile.js.map +1 -0
- package/dist/editor.bundle.js +799 -42
- package/dist/editor.d.ts +121 -5
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +572 -31
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/page-number-format.d.ts +22 -0
- package/dist/page-number-format.d.ts.map +1 -0
- package/dist/page-number-format.js +60 -0
- package/dist/page-number-format.js.map +1 -0
- package/dist/pagination.bundle.js +158 -21
- package/dist/pagination.d.ts +38 -0
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +181 -29
- package/dist/pagination.js.map +1 -1
- package/dist/session.bundle.js +226 -4
- package/dist/session.d.ts +147 -6
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +187 -4
- package/dist/session.js.map +1 -1
- package/dist/types.d.ts +191 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/wasm/_framework/Docxodus.wasm +0 -0
- package/dist/wasm/_framework/DocxodusWasm.wasm +0 -0
- package/dist/wasm/_framework/System.IO.Compression.wasm +0 -0
- package/dist/wasm/_framework/System.Linq.wasm +0 -0
- package/dist/wasm/_framework/System.Private.CoreLib.wasm +0 -0
- package/dist/wasm/_framework/System.Private.Xml.Linq.wasm +0 -0
- package/dist/wasm/_framework/System.Runtime.wasm +0 -0
- package/dist/wasm/_framework/System.Text.RegularExpressions.wasm +0 -0
- package/dist/wasm/_framework/dotnet.boot.js +10 -10
- package/dist/wasm/_framework/dotnet.native.js.symbols +2102 -2101
- package/dist/wasm/_framework/dotnet.native.wasm +0 -0
- package/package.json +17 -4
|
@@ -24,6 +24,42 @@ var DocxodusPagination = (() => {
|
|
|
24
24
|
PaginationEngine: () => PaginationEngine,
|
|
25
25
|
paginateHtml: () => paginateHtml
|
|
26
26
|
});
|
|
27
|
+
|
|
28
|
+
// src/page-number-format.ts
|
|
29
|
+
var ROMAN_ONES = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"];
|
|
30
|
+
var ROMAN_TENS = ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"];
|
|
31
|
+
var ROMAN_HUNDREDS = ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"];
|
|
32
|
+
var ROMAN_THOUSANDS = ["", "m", "mm", "mmm"];
|
|
33
|
+
function toRoman(value) {
|
|
34
|
+
if (value <= 0 || value >= 4e3) return String(value);
|
|
35
|
+
return ROMAN_THOUSANDS[Math.floor(value / 1e3)] + ROMAN_HUNDREDS[Math.floor(value % 1e3 / 100)] + ROMAN_TENS[Math.floor(value % 100 / 10)] + ROMAN_ONES[value % 10];
|
|
36
|
+
}
|
|
37
|
+
function toLetter(value) {
|
|
38
|
+
if (value <= 0) return String(value);
|
|
39
|
+
const wrapped = value % 780 === 0 ? 780 : value % 780;
|
|
40
|
+
const repeats = Math.floor((wrapped - 1) / 26) + 1;
|
|
41
|
+
return "abcdefghijklmnopqrstuvwxyz".charAt((wrapped - 1) % 26).repeat(repeats);
|
|
42
|
+
}
|
|
43
|
+
var RENDERERS = {
|
|
44
|
+
// ST_NumberFormat tokens (w:pgNumType/@w:fmt, w:numFmt).
|
|
45
|
+
decimal: (v) => String(v),
|
|
46
|
+
lowerRoman: toRoman,
|
|
47
|
+
upperRoman: (v) => toRoman(v).toUpperCase(),
|
|
48
|
+
lowerLetter: toLetter,
|
|
49
|
+
upperLetter: (v) => toLetter(v).toUpperCase(),
|
|
50
|
+
// Field `\*` general-formatting switch arguments.
|
|
51
|
+
Arabic: (v) => String(v),
|
|
52
|
+
roman: toRoman,
|
|
53
|
+
ROMAN: (v) => toRoman(v).toUpperCase(),
|
|
54
|
+
alphabetic: toLetter,
|
|
55
|
+
ALPHABETIC: (v) => toLetter(v).toUpperCase()
|
|
56
|
+
};
|
|
57
|
+
function formatPageNumber(value, format) {
|
|
58
|
+
const renderer = format ? RENDERERS[format] : void 0;
|
|
59
|
+
return (renderer ?? RENDERERS.decimal)(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/pagination.ts
|
|
27
63
|
var DEFAULT_PAGE_WIDTH = 612;
|
|
28
64
|
var DEFAULT_PAGE_HEIGHT = 792;
|
|
29
65
|
var DEFAULT_MARGIN = 72;
|
|
@@ -70,6 +106,8 @@ var DocxodusPagination = (() => {
|
|
|
70
106
|
*/
|
|
71
107
|
constructor(staging, container, options = {}) {
|
|
72
108
|
this.pendingFootnoteContinuation = null;
|
|
109
|
+
/** Per-section `w:pgNumType` (start / format), read off the section wrappers. */
|
|
110
|
+
this.pageNumbering = /* @__PURE__ */ new Map();
|
|
73
111
|
this.stagingElement = typeof staging === "string" ? document.getElementById(staging) : staging;
|
|
74
112
|
this.containerElement = typeof container === "string" ? document.getElementById(container) : container;
|
|
75
113
|
if (!this.stagingElement) {
|
|
@@ -99,6 +137,7 @@ var DocxodusPagination = (() => {
|
|
|
99
137
|
const sections = this.stagingElement.querySelectorAll(
|
|
100
138
|
"[data-section-index]"
|
|
101
139
|
);
|
|
140
|
+
this.pageNumbering = this.parsePageNumbering(sections);
|
|
102
141
|
const sectionsToProcess = sections.length > 0 ? Array.from(sections) : [this.stagingElement];
|
|
103
142
|
for (const section of sectionsToProcess) {
|
|
104
143
|
const sectionIndex = parseInt(section.dataset.sectionIndex || "0", 10);
|
|
@@ -114,8 +153,62 @@ var DocxodusPagination = (() => {
|
|
|
114
153
|
pageNumber += sectionPages.length;
|
|
115
154
|
}
|
|
116
155
|
this.stagingElement.style.display = "none";
|
|
156
|
+
this.substitutePageNumberFields(pages.length);
|
|
117
157
|
return { totalPages: pages.length, pages };
|
|
118
158
|
}
|
|
159
|
+
/** Read each section's `w:pgNumType` off its wrapper (see {@link SectionPageNumbering}). */
|
|
160
|
+
parsePageNumbering(sections) {
|
|
161
|
+
const map = /* @__PURE__ */ new Map();
|
|
162
|
+
for (const section of Array.from(sections)) {
|
|
163
|
+
const index = parseInt(section.dataset.sectionIndex || "0", 10);
|
|
164
|
+
const rawStart = section.dataset.pageNumStart;
|
|
165
|
+
const start = rawStart === void 0 ? void 0 : parseInt(rawStart, 10);
|
|
166
|
+
map.set(index, {
|
|
167
|
+
start: start !== void 0 && Number.isFinite(start) ? start : void 0,
|
|
168
|
+
format: section.dataset.pageNumFmt
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return map;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Fill in the page-number fields inside every page's cloned header/footer.
|
|
175
|
+
*
|
|
176
|
+
* A header/footer is authored once and cloned onto each page, so a PAGE field's single cached
|
|
177
|
+
* result would otherwise show the same number on every page — the whole reason the converter
|
|
178
|
+
* marks these. `data-field-format` (the field's own `\*` switch) wins over the section's format
|
|
179
|
+
* when present, which is exactly how Word resolves the two.
|
|
180
|
+
*
|
|
181
|
+
* Runs after layout because NUMPAGES cannot be known before the last page exists. The
|
|
182
|
+
* substituted text can therefore be marginally wider than the cached result the header was
|
|
183
|
+
* measured with; the header band clips, so the failure mode is a hair of overflow rather than
|
|
184
|
+
* a layout that disagrees with itself.
|
|
185
|
+
*
|
|
186
|
+
* Scoped to the CLONED header/footer regions on purpose. A page-number field in body text is
|
|
187
|
+
* ordinary run content that the editor may make editable, and committing an edited block writes
|
|
188
|
+
* back whatever text the DOM holds — rewriting it here would mean a body field commits a number
|
|
189
|
+
* the document never contained. Body content is also not cloned, so it does not have the problem
|
|
190
|
+
* this method exists to solve.
|
|
191
|
+
*/
|
|
192
|
+
substitutePageNumberFields(totalPages) {
|
|
193
|
+
const boxes = this.containerElement.querySelectorAll(`.${this.cssPrefix}box`);
|
|
194
|
+
for (const box of Array.from(boxes)) {
|
|
195
|
+
const markers = box.querySelectorAll(
|
|
196
|
+
`.${this.cssPrefix}header [data-field], .${this.cssPrefix}footer [data-field]`
|
|
197
|
+
);
|
|
198
|
+
if (markers.length === 0) continue;
|
|
199
|
+
const sectionIndex = parseInt(box.dataset.sectionIndex || "0", 10);
|
|
200
|
+
const pageNumber = parseInt(box.dataset.pageNumber || "1", 10);
|
|
201
|
+
const pageInSection = parseInt(box.dataset.pageInSection || "1", 10);
|
|
202
|
+
const numbering = this.pageNumbering.get(sectionIndex) ?? {};
|
|
203
|
+
const displayed = numbering.start !== void 0 ? numbering.start + pageInSection - 1 : pageNumber;
|
|
204
|
+
for (const marker of Array.from(markers)) {
|
|
205
|
+
const kind = marker.dataset.field;
|
|
206
|
+
if (kind !== "PAGE" && kind !== "NUMPAGES") continue;
|
|
207
|
+
const format = marker.dataset.fieldFormat ?? numbering.format;
|
|
208
|
+
marker.textContent = formatPageNumber(kind === "PAGE" ? displayed : totalPages, format);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
119
212
|
/**
|
|
120
213
|
* Measures all content blocks in a section.
|
|
121
214
|
*/
|
|
@@ -639,6 +732,7 @@ var DocxodusPagination = (() => {
|
|
|
639
732
|
measureContainer.style.visibility = "hidden";
|
|
640
733
|
measureContainer.style.width = `${contentWidth}pt`;
|
|
641
734
|
measureContainer.style.left = "-9999px";
|
|
735
|
+
measureContainer.className = this.cssPrefix + "footnotes";
|
|
642
736
|
const hr = document.createElement("hr");
|
|
643
737
|
measureContainer.appendChild(hr);
|
|
644
738
|
if (hasContinuation) {
|
|
@@ -673,6 +767,7 @@ var DocxodusPagination = (() => {
|
|
|
673
767
|
measureContainer.style.visibility = "hidden";
|
|
674
768
|
measureContainer.style.width = `${contentWidth}pt`;
|
|
675
769
|
measureContainer.style.left = "-9999px";
|
|
770
|
+
measureContainer.className = this.cssPrefix + "footnotes";
|
|
676
771
|
const hr = document.createElement("hr");
|
|
677
772
|
measureContainer.appendChild(hr);
|
|
678
773
|
for (const el of continuation.remainingElements) {
|
|
@@ -691,11 +786,17 @@ var DocxodusPagination = (() => {
|
|
|
691
786
|
splitFootnoteToFit(footnoteElement, availableHeightPt, contentWidth) {
|
|
692
787
|
const footnoteContent = footnoteElement.querySelector(".footnote-content");
|
|
693
788
|
if (!footnoteContent) {
|
|
694
|
-
return {
|
|
789
|
+
return {
|
|
790
|
+
fits: Array.from(footnoteElement.children).map((el) => el.cloneNode(true)),
|
|
791
|
+
overflow: []
|
|
792
|
+
};
|
|
695
793
|
}
|
|
696
794
|
const children = Array.from(footnoteContent.children);
|
|
697
795
|
if (children.length <= 1) {
|
|
698
|
-
return {
|
|
796
|
+
return {
|
|
797
|
+
fits: children.map((el) => el.cloneNode(true)),
|
|
798
|
+
overflow: []
|
|
799
|
+
};
|
|
699
800
|
}
|
|
700
801
|
const fits = [];
|
|
701
802
|
const overflow = [];
|
|
@@ -705,6 +806,7 @@ var DocxodusPagination = (() => {
|
|
|
705
806
|
hrMeasure.style.visibility = "hidden";
|
|
706
807
|
hrMeasure.style.width = `${contentWidth}pt`;
|
|
707
808
|
hrMeasure.style.left = "-9999px";
|
|
809
|
+
hrMeasure.className = this.cssPrefix + "footnotes";
|
|
708
810
|
const hr = document.createElement("hr");
|
|
709
811
|
hrMeasure.appendChild(hr);
|
|
710
812
|
this.stagingElement.appendChild(hrMeasure);
|
|
@@ -719,6 +821,7 @@ var DocxodusPagination = (() => {
|
|
|
719
821
|
measureContainer.style.visibility = "hidden";
|
|
720
822
|
measureContainer.style.width = `${contentWidth}pt`;
|
|
721
823
|
measureContainer.style.left = "-9999px";
|
|
824
|
+
measureContainer.className = this.cssPrefix + "footnotes";
|
|
722
825
|
measureContainer.appendChild(child.cloneNode(true));
|
|
723
826
|
this.stagingElement.appendChild(measureContainer);
|
|
724
827
|
const childHeight = pxToPt(measureContainer.getBoundingClientRect().height);
|
|
@@ -746,6 +849,7 @@ var DocxodusPagination = (() => {
|
|
|
746
849
|
measureContainer.style.visibility = "hidden";
|
|
747
850
|
measureContainer.style.width = `${contentWidth}pt`;
|
|
748
851
|
measureContainer.style.left = "-9999px";
|
|
852
|
+
measureContainer.className = this.cssPrefix + "footnotes";
|
|
749
853
|
measureContainer.appendChild(footnote.cloneNode(true));
|
|
750
854
|
this.stagingElement.appendChild(measureContainer);
|
|
751
855
|
const rect = measureContainer.getBoundingClientRect();
|
|
@@ -929,6 +1033,7 @@ var DocxodusPagination = (() => {
|
|
|
929
1033
|
let currentFootnoteHeight = 0;
|
|
930
1034
|
let currentContinuation = this.pendingFootnoteContinuation;
|
|
931
1035
|
let nextPageContinuation = null;
|
|
1036
|
+
let deferredFootnoteIds = [];
|
|
932
1037
|
let currentPartialFootnotes = [];
|
|
933
1038
|
if (currentContinuation && currentContinuation.remainingElements.length > 0) {
|
|
934
1039
|
currentFootnoteHeight = this.measureContinuationHeight(currentContinuation, dims.contentWidth);
|
|
@@ -959,11 +1064,22 @@ var DocxodusPagination = (() => {
|
|
|
959
1064
|
currentPartialFootnotes = [];
|
|
960
1065
|
currentContinuation = nextPageContinuation;
|
|
961
1066
|
nextPageContinuation = null;
|
|
1067
|
+
if (deferredFootnoteIds.length > 0) {
|
|
1068
|
+
currentFootnoteIds = [...deferredFootnoteIds];
|
|
1069
|
+
deferredFootnoteIds = [];
|
|
1070
|
+
}
|
|
962
1071
|
if (currentContinuation && currentContinuation.remainingElements.length > 0) {
|
|
963
1072
|
currentFootnoteHeight = this.measureContinuationHeight(currentContinuation, dims.contentWidth);
|
|
964
1073
|
} else {
|
|
965
1074
|
currentFootnoteHeight = 0;
|
|
966
1075
|
}
|
|
1076
|
+
if (currentFootnoteIds.length > 0) {
|
|
1077
|
+
currentFootnoteHeight += this.measureFootnotesHeight(
|
|
1078
|
+
currentFootnoteIds,
|
|
1079
|
+
dims.contentWidth,
|
|
1080
|
+
null
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
967
1083
|
};
|
|
968
1084
|
for (let i = 0; i < blocks.length; i++) {
|
|
969
1085
|
const block = blocks[i];
|
|
@@ -1109,22 +1225,10 @@ var DocxodusPagination = (() => {
|
|
|
1109
1225
|
}
|
|
1110
1226
|
currentFootnoteHeight = availableForFootnotes;
|
|
1111
1227
|
} else {
|
|
1112
|
-
|
|
1113
|
-
footnoteId,
|
|
1114
|
-
remainingElements: Array.from(footnote.querySelectorAll(".footnote-content > *")).map((el) => el.cloneNode(true))
|
|
1115
|
-
};
|
|
1116
|
-
if (nextPageContinuation.remainingElements.length === 0) {
|
|
1117
|
-
nextPageContinuation.remainingElements = [footnote.cloneNode(true)];
|
|
1118
|
-
}
|
|
1228
|
+
deferredFootnoteIds.push(footnoteId);
|
|
1119
1229
|
}
|
|
1120
1230
|
} else {
|
|
1121
|
-
|
|
1122
|
-
footnoteId,
|
|
1123
|
-
remainingElements: Array.from(footnote.querySelectorAll(".footnote-content > *")).map((el) => el.cloneNode(true))
|
|
1124
|
-
};
|
|
1125
|
-
if (nextPageContinuation.remainingElements.length === 0) {
|
|
1126
|
-
nextPageContinuation.remainingElements = [footnote.cloneNode(true)];
|
|
1127
|
-
}
|
|
1231
|
+
deferredFootnoteIds.push(footnoteId);
|
|
1128
1232
|
}
|
|
1129
1233
|
}
|
|
1130
1234
|
}
|
|
@@ -1144,7 +1248,7 @@ var DocxodusPagination = (() => {
|
|
|
1144
1248
|
currentContent.push(block.element.cloneNode(true));
|
|
1145
1249
|
remainingHeight = effectiveContentHeight - newPageSpace;
|
|
1146
1250
|
prevMarginBottomPt = block.marginBottomPt;
|
|
1147
|
-
currentFootnoteIds = [...allBlockFootnoteIds];
|
|
1251
|
+
currentFootnoteIds = [...currentFootnoteIds, ...allBlockFootnoteIds];
|
|
1148
1252
|
currentFootnoteHeight = newPageFootnoteHeight;
|
|
1149
1253
|
}
|
|
1150
1254
|
} else {
|
|
@@ -1154,7 +1258,7 @@ var DocxodusPagination = (() => {
|
|
|
1154
1258
|
currentContent.push(block.element.cloneNode(true));
|
|
1155
1259
|
remainingHeight = effectiveContentHeight - newPageSpace;
|
|
1156
1260
|
prevMarginBottomPt = block.marginBottomPt;
|
|
1157
|
-
currentFootnoteIds = [...allBlockFootnoteIds];
|
|
1261
|
+
currentFootnoteIds = [...currentFootnoteIds, ...allBlockFootnoteIds];
|
|
1158
1262
|
currentFootnoteHeight = newPageFootnoteHeight;
|
|
1159
1263
|
}
|
|
1160
1264
|
} else {
|
|
@@ -1171,7 +1275,7 @@ var DocxodusPagination = (() => {
|
|
|
1171
1275
|
finishPage();
|
|
1172
1276
|
}
|
|
1173
1277
|
currentContent.push(block.element.cloneNode(true));
|
|
1174
|
-
currentFootnoteIds = [...allBlockFootnoteIds];
|
|
1278
|
+
currentFootnoteIds = [...currentFootnoteIds, ...allBlockFootnoteIds];
|
|
1175
1279
|
finishPage();
|
|
1176
1280
|
}
|
|
1177
1281
|
}
|
|
@@ -1179,6 +1283,27 @@ var DocxodusPagination = (() => {
|
|
|
1179
1283
|
this.pendingFootnoteContinuation = nextPageContinuation;
|
|
1180
1284
|
return pages;
|
|
1181
1285
|
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Strip block addressing from a header/footer node cloned into a page box.
|
|
1288
|
+
*
|
|
1289
|
+
* A running story is authored ONCE and cloned onto every page, so the clones all carry the same
|
|
1290
|
+
* `data-anchor` — on this document, 42 page boxes claiming one footer paragraph. Left editable,
|
|
1291
|
+
* committing any one of them writes back through that single shared anchor, and the per-page
|
|
1292
|
+
* page-number substitution makes it worse: each clone shows a DIFFERENT number, so a commit
|
|
1293
|
+
* writes that page's number into the story as literal text and destroys the PAGE field.
|
|
1294
|
+
*
|
|
1295
|
+
* Page-box header/footer content is presentation. The docked editing bands
|
|
1296
|
+
* (`editor-headerfooter.ts`) are the addressable affordance, and they exist precisely because a
|
|
1297
|
+
* cloned node cannot be uniquely addressed.
|
|
1298
|
+
*/
|
|
1299
|
+
makeClonedStoryInert(root) {
|
|
1300
|
+
const nodes = [root, ...Array.from(root.querySelectorAll("*"))];
|
|
1301
|
+
for (const el of nodes) {
|
|
1302
|
+
el.removeAttribute("data-anchor");
|
|
1303
|
+
el.removeAttribute("data-committed-text");
|
|
1304
|
+
if (el.getAttribute("contenteditable") !== null) el.setAttribute("contenteditable", "false");
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1182
1307
|
/**
|
|
1183
1308
|
* Creates a page container element.
|
|
1184
1309
|
*/
|
|
@@ -1204,6 +1329,7 @@ var DocxodusPagination = (() => {
|
|
|
1204
1329
|
pageBox.style.contain = "layout paint";
|
|
1205
1330
|
pageBox.dataset.pageNumber = String(pageNumber);
|
|
1206
1331
|
pageBox.dataset.sectionIndex = String(sectionIndex);
|
|
1332
|
+
pageBox.dataset.pageInSection = String(pageInSection);
|
|
1207
1333
|
const effectiveHeights = this.getEffectiveHeights(dims, sectionIndex, pageInSection, pageNumber);
|
|
1208
1334
|
const headerSource = this.selectHeader(sectionIndex, pageInSection, pageNumber);
|
|
1209
1335
|
if (headerSource) {
|
|
@@ -1221,7 +1347,9 @@ var DocxodusPagination = (() => {
|
|
|
1221
1347
|
headerDiv.style.justifyContent = "flex-end";
|
|
1222
1348
|
headerDiv.style.paddingBottom = "4pt";
|
|
1223
1349
|
for (const child of Array.from(headerSource.childNodes)) {
|
|
1224
|
-
|
|
1350
|
+
const clonedheaderDiv = child.cloneNode(true);
|
|
1351
|
+
if (clonedheaderDiv.nodeType === 1) this.makeClonedStoryInert(clonedheaderDiv);
|
|
1352
|
+
headerDiv.appendChild(clonedheaderDiv);
|
|
1225
1353
|
}
|
|
1226
1354
|
pageBox.appendChild(headerDiv);
|
|
1227
1355
|
}
|
|
@@ -1259,7 +1387,9 @@ var DocxodusPagination = (() => {
|
|
|
1259
1387
|
footerDiv.style.justifyContent = "flex-start";
|
|
1260
1388
|
footerDiv.style.paddingTop = "4pt";
|
|
1261
1389
|
for (const child of Array.from(footerSource.childNodes)) {
|
|
1262
|
-
|
|
1390
|
+
const clonedfooterDiv = child.cloneNode(true);
|
|
1391
|
+
if (clonedfooterDiv.nodeType === 1) this.makeClonedStoryInert(clonedfooterDiv);
|
|
1392
|
+
footerDiv.appendChild(clonedfooterDiv);
|
|
1263
1393
|
}
|
|
1264
1394
|
pageBox.appendChild(footerDiv);
|
|
1265
1395
|
}
|
|
@@ -1270,6 +1400,13 @@ var DocxodusPagination = (() => {
|
|
|
1270
1400
|
pageBox.appendChild(pageNum);
|
|
1271
1401
|
}
|
|
1272
1402
|
this.containerElement.appendChild(pageBox);
|
|
1403
|
+
const notesEl = pageBox.querySelector(`.${this.cssPrefix}footnotes`);
|
|
1404
|
+
if (notesEl) {
|
|
1405
|
+
const notesHeightPt = pxToPt(notesEl.getBoundingClientRect().height);
|
|
1406
|
+
if (notesHeightPt > 0) {
|
|
1407
|
+
contentArea.style.height = `${Math.max(0, contentAreaHeight - notesHeightPt)}pt`;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1273
1410
|
return {
|
|
1274
1411
|
pageNumber,
|
|
1275
1412
|
sectionIndex,
|
package/dist/pagination.d.ts
CHANGED
|
@@ -143,6 +143,8 @@ export declare class PaginationEngine {
|
|
|
143
143
|
private hfRegistry;
|
|
144
144
|
private footnoteRegistry;
|
|
145
145
|
private pendingFootnoteContinuation;
|
|
146
|
+
/** Per-section `w:pgNumType` (start / format), read off the section wrappers. */
|
|
147
|
+
private pageNumbering;
|
|
146
148
|
/**
|
|
147
149
|
* Creates a new pagination engine.
|
|
148
150
|
*
|
|
@@ -157,6 +159,28 @@ export declare class PaginationEngine {
|
|
|
157
159
|
* @returns PaginationResult with page information
|
|
158
160
|
*/
|
|
159
161
|
paginate(): PaginationResult;
|
|
162
|
+
/** Read each section's `w:pgNumType` off its wrapper (see {@link SectionPageNumbering}). */
|
|
163
|
+
private parsePageNumbering;
|
|
164
|
+
/**
|
|
165
|
+
* Fill in the page-number fields inside every page's cloned header/footer.
|
|
166
|
+
*
|
|
167
|
+
* A header/footer is authored once and cloned onto each page, so a PAGE field's single cached
|
|
168
|
+
* result would otherwise show the same number on every page — the whole reason the converter
|
|
169
|
+
* marks these. `data-field-format` (the field's own `\*` switch) wins over the section's format
|
|
170
|
+
* when present, which is exactly how Word resolves the two.
|
|
171
|
+
*
|
|
172
|
+
* Runs after layout because NUMPAGES cannot be known before the last page exists. The
|
|
173
|
+
* substituted text can therefore be marginally wider than the cached result the header was
|
|
174
|
+
* measured with; the header band clips, so the failure mode is a hair of overflow rather than
|
|
175
|
+
* a layout that disagrees with itself.
|
|
176
|
+
*
|
|
177
|
+
* Scoped to the CLONED header/footer regions on purpose. A page-number field in body text is
|
|
178
|
+
* ordinary run content that the editor may make editable, and committing an edited block writes
|
|
179
|
+
* back whatever text the DOM holds — rewriting it here would mean a body field commits a number
|
|
180
|
+
* the document never contained. Body content is also not cloned, so it does not have the problem
|
|
181
|
+
* this method exists to solve.
|
|
182
|
+
*/
|
|
183
|
+
private substitutePageNumberFields;
|
|
160
184
|
/**
|
|
161
185
|
* Measures all content blocks in a section.
|
|
162
186
|
*/
|
|
@@ -300,6 +324,20 @@ export declare class PaginationEngine {
|
|
|
300
324
|
* Supports footnote continuation - long footnotes can split across pages.
|
|
301
325
|
*/
|
|
302
326
|
private flowToPages;
|
|
327
|
+
/**
|
|
328
|
+
* Strip block addressing from a header/footer node cloned into a page box.
|
|
329
|
+
*
|
|
330
|
+
* A running story is authored ONCE and cloned onto every page, so the clones all carry the same
|
|
331
|
+
* `data-anchor` — on this document, 42 page boxes claiming one footer paragraph. Left editable,
|
|
332
|
+
* committing any one of them writes back through that single shared anchor, and the per-page
|
|
333
|
+
* page-number substitution makes it worse: each clone shows a DIFFERENT number, so a commit
|
|
334
|
+
* writes that page's number into the story as literal text and destroys the PAGE field.
|
|
335
|
+
*
|
|
336
|
+
* Page-box header/footer content is presentation. The docked editing bands
|
|
337
|
+
* (`editor-headerfooter.ts`) are the addressable affordance, and they exist precisely because a
|
|
338
|
+
* cloned node cannot be uniquely addressed.
|
|
339
|
+
*/
|
|
340
|
+
private makeClonedStoryInert;
|
|
303
341
|
/**
|
|
304
342
|
* Creates a page container element.
|
|
305
343
|
*/
|
package/dist/pagination.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"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"}
|