@harbour-enterprises/superdoc 1.5.0 → 1.6.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{PdfViewer-B_zxY1AJ.cjs → PdfViewer-Dr4K1JKD.cjs} +2 -2
- package/dist/chunks/{PdfViewer-DOsj8296.es.js → PdfViewer-DzppMlfu.es.js} +2 -2
- package/dist/chunks/{SuperConverter-Dfxp14RO.es.js → SuperConverter-Cyn9peRO.es.js} +1282 -875
- package/dist/chunks/{SuperConverter-DmX1tktl.cjs → SuperConverter-DpKjVrPl.cjs} +1282 -875
- package/dist/chunks/{index-B6UxxE5v.es.js → index-C7KECpDt.es.js} +1257 -15
- package/dist/chunks/{index-BqmzYr4Q.cjs → index-CmZ15rIJ.cjs} +4 -4
- package/dist/chunks/{index-BFU5qWH7.cjs → index-Cto-XsBE.cjs} +1257 -15
- package/dist/chunks/{index-zeVoYVRM.es.js → index-DrcLOCfC.es.js} +4 -4
- package/dist/style.css +7 -0
- package/dist/super-editor/converter.cjs +1 -1
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor/docx-zipper.cjs +10 -0
- package/dist/super-editor/docx-zipper.es.js +10 -0
- package/dist/super-editor.cjs +2 -2
- package/dist/super-editor.es.js +3 -3
- package/dist/superdoc.cjs +3 -3
- package/dist/superdoc.es.js +3 -3
- package/dist/superdoc.umd.js +2549 -890
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { B as Buffer$2 } from "./jszip-B1fkPkPJ.es.js";
|
|
2
2
|
import { t as twipsToInches, i as inchesToTwips, p as ptToTwips, l as linesToTwips, a as twipsToLines, b as pixelsToTwips, h as halfPointToPoints, c as twipsToPixels$2, d as convertSizeToCSS, e as inchesToPixels } from "./helpers-C8e9wR5l.es.js";
|
|
3
|
-
import { g as generateDocxRandomId, T as TextSelection$1, o as objectIncludes, w as wrapTextsInRuns, D as DOMParser$1, c as createDocFromMarkdown, a as createDocFromHTML, b as chainableEditorState, d as convertMarkdownToHTML, f as findParentNode, e as findParentNodeClosestToPos, h as generateRandom32BitHex, i as generateRandomSigned32BitIntStrId, P as PluginKey, j as Plugin, M as Mapping, N as NodeSelection, k as Selection, l as Slice, m as DOMSerializer, F as Fragment, n as Mark$1, p as dropPoint, A as AllSelection, q as Schema$1, s as canSplit, t as resolveRunProperties, u as encodeMarksFromRPr, v as liftTarget, x as canJoin, y as joinPoint, z as replaceStep$1, R as ReplaceAroundStep$1, B as htmlHandler, C as ReplaceStep, E as getResolvedParagraphProperties, G as changeListLevel, H as isList$1, I as updateNumberingProperties, L as ListHelpers, J as inputRulesPlugin, K as TrackDeleteMarkName$1, O as TrackInsertMarkName$1, Q as TrackFormatMarkName$1, U as AddMarkStep, V as RemoveMarkStep, W as CommandService, S as SuperConverter, X as EditorState, Y as unflattenListsInHtml, Z as SelectionRange, _ as Transform, $ as createOoxmlResolver, a0 as translator, a1 as translator$1, a2 as resolveDocxFontFamily, a3 as combineIndentProperties, a4 as _getReferencedTableStyles, a5 as decodeRPrFromMarks, a6 as calculateResolvedParagraphProperties, a7 as encodeCSSFromPPr, a8 as encodeCSSFromRPr, a9 as generateOrderedListIndex, aa as docxNumberingHelpers, ab as InputRule, ac as insertNewRelationship, ad as kebabCase$1, ae as getUnderlineCssString } from "./SuperConverter-
|
|
3
|
+
import { g as generateDocxRandomId, T as TextSelection$1, o as objectIncludes, w as wrapTextsInRuns, D as DOMParser$1, c as createDocFromMarkdown, a as createDocFromHTML, b as chainableEditorState, d as convertMarkdownToHTML, f as findParentNode, e as findParentNodeClosestToPos, h as generateRandom32BitHex, i as generateRandomSigned32BitIntStrId, P as PluginKey, j as Plugin, M as Mapping, N as NodeSelection, k as Selection, l as Slice, m as DOMSerializer, F as Fragment, n as Mark$1, p as dropPoint, A as AllSelection, q as Schema$1, s as canSplit, t as resolveRunProperties, u as encodeMarksFromRPr, v as liftTarget, x as canJoin, y as joinPoint, z as replaceStep$1, R as ReplaceAroundStep$1, B as htmlHandler, C as ReplaceStep, E as getResolvedParagraphProperties, G as changeListLevel, H as isList$1, I as updateNumberingProperties, L as ListHelpers, J as inputRulesPlugin, K as TrackDeleteMarkName$1, O as TrackInsertMarkName$1, Q as TrackFormatMarkName$1, U as AddMarkStep, V as RemoveMarkStep, W as CommandService, S as SuperConverter, X as EditorState, Y as unflattenListsInHtml, Z as SelectionRange, _ as Transform, $ as createOoxmlResolver, a0 as translator, a1 as translator$1, a2 as resolveDocxFontFamily, a3 as combineIndentProperties, a4 as _getReferencedTableStyles, a5 as decodeRPrFromMarks, a6 as calculateResolvedParagraphProperties, a7 as encodeCSSFromPPr, a8 as encodeCSSFromRPr, a9 as generateOrderedListIndex, aa as docxNumberingHelpers, ab as InputRule, ac as insertNewRelationship, ad as kebabCase$1, ae as getUnderlineCssString } from "./SuperConverter-Cyn9peRO.es.js";
|
|
4
4
|
import { p as process$1, r as ref, C as global$1, c as computed, E as createElementBlock, F as Fragment$1, S as renderList, O as withModifiers, G as openBlock, P as normalizeClass, M as createCommentVNode, H as toDisplayString, K as createBaseVNode, U as createApp, f as onMounted, X as onUnmounted, R as withDirectives, v as unref, Y as vModelText, y as nextTick, L as normalizeStyle, u as watch, Z as withKeys, _ as createTextVNode, I as createVNode, h as h$1, $ as readonly, s as getCurrentInstance, o as onBeforeUnmount, j as reactive, b as onBeforeMount, i as inject, a0 as onActivated, a1 as onDeactivated, a2 as Comment, d as defineComponent, a as provide, g as Teleport, t as toRef, a3 as renderSlot, a4 as isVNode, D as shallowRef, w as watchEffect, T as Transition, a5 as mergeProps, a6 as vShow, a7 as cloneVNode, a8 as Text$2, m as markRaw, N as createBlock, J as withCtx, a9 as useCssVars, V as resolveDynamicComponent, aa as normalizeProps, ab as guardReactiveProps } from "./vue-BnBKJwCW.es.js";
|
|
5
5
|
import "./jszip.min-DCl8qkFO.es.js";
|
|
6
6
|
import { E as EventEmitter$1 } from "./eventemitter3-CwrdEv8r.es.js";
|
|
@@ -15507,7 +15507,7 @@ const canUseDOM = () => {
|
|
|
15507
15507
|
return false;
|
|
15508
15508
|
}
|
|
15509
15509
|
};
|
|
15510
|
-
const summaryVersion = "1.
|
|
15510
|
+
const summaryVersion = "1.6.0-next.1";
|
|
15511
15511
|
const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
|
|
15512
15512
|
const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
|
|
15513
15513
|
function mapAttributes(attrs) {
|
|
@@ -17764,6 +17764,10 @@ class Editor extends EventEmitter {
|
|
|
17764
17764
|
const hasCustomSettings = !!this.converter.convertedXml["word/settings.xml"]?.elements?.length;
|
|
17765
17765
|
const customSettings = hasCustomSettings ? this.converter.schemaToXml(this.converter.convertedXml["word/settings.xml"]?.elements?.[0]) : null;
|
|
17766
17766
|
const rels = this.converter.schemaToXml(this.converter.convertedXml["word/_rels/document.xml.rels"].elements[0]);
|
|
17767
|
+
const footnotesData = this.converter.convertedXml["word/footnotes.xml"];
|
|
17768
|
+
const footnotesXml = footnotesData?.elements?.[0] ? this.converter.schemaToXml(footnotesData.elements[0]) : null;
|
|
17769
|
+
const footnotesRelsData = this.converter.convertedXml["word/_rels/footnotes.xml.rels"];
|
|
17770
|
+
const footnotesRelsXml = footnotesRelsData?.elements?.[0] ? this.converter.schemaToXml(footnotesRelsData.elements[0]) : null;
|
|
17767
17771
|
const media = this.converter.addedMedia;
|
|
17768
17772
|
const updatedHeadersFooters = {};
|
|
17769
17773
|
Object.entries(this.converter.convertedXml).forEach(([name, json2]) => {
|
|
@@ -17788,6 +17792,12 @@ class Editor extends EventEmitter {
|
|
|
17788
17792
|
if (hasCustomSettings) {
|
|
17789
17793
|
updatedDocs["word/settings.xml"] = String(customSettings);
|
|
17790
17794
|
}
|
|
17795
|
+
if (footnotesXml) {
|
|
17796
|
+
updatedDocs["word/footnotes.xml"] = String(footnotesXml);
|
|
17797
|
+
}
|
|
17798
|
+
if (footnotesRelsXml) {
|
|
17799
|
+
updatedDocs["word/_rels/footnotes.xml.rels"] = String(footnotesRelsXml);
|
|
17800
|
+
}
|
|
17791
17801
|
if (comments.length) {
|
|
17792
17802
|
const commentsXml = this.converter.schemaToXml(this.converter.convertedXml["word/comments.xml"].elements[0]);
|
|
17793
17803
|
const commentsExtendedXml = this.converter.schemaToXml(
|
|
@@ -18164,7 +18174,7 @@ class Editor extends EventEmitter {
|
|
|
18164
18174
|
* Process collaboration migrations
|
|
18165
18175
|
*/
|
|
18166
18176
|
processCollaborationMigrations() {
|
|
18167
|
-
console.debug("[checkVersionMigrations] Current editor version", "1.
|
|
18177
|
+
console.debug("[checkVersionMigrations] Current editor version", "1.6.0-next.1");
|
|
18168
18178
|
if (!this.options.ydoc) return;
|
|
18169
18179
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
18170
18180
|
let docVersion = metaMap.get("version");
|
|
@@ -34045,7 +34055,7 @@ function getParagraphSpacingBefore(block) {
|
|
|
34045
34055
|
const value = spacing?.before ?? spacing?.lineSpaceBefore;
|
|
34046
34056
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
34047
34057
|
}
|
|
34048
|
-
function getParagraphSpacingAfter(block) {
|
|
34058
|
+
function getParagraphSpacingAfter$1(block) {
|
|
34049
34059
|
const spacing = block.attrs?.spacing;
|
|
34050
34060
|
const value = spacing?.after ?? spacing?.lineSpaceAfter;
|
|
34051
34061
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
@@ -34072,7 +34082,7 @@ function getMeasureHeight(block, measure) {
|
|
|
34072
34082
|
}
|
|
34073
34083
|
const DEFAULT_PAGE_SIZE$2 = { w: 612, h: 792 };
|
|
34074
34084
|
const DEFAULT_MARGINS$2 = { top: 72, right: 72, bottom: 72, left: 72 };
|
|
34075
|
-
const COLUMN_EPSILON = 1e-4;
|
|
34085
|
+
const COLUMN_EPSILON$1 = 1e-4;
|
|
34076
34086
|
const layoutDebugEnabled$1 = typeof process$1 !== "undefined" && typeof process$1.env !== "undefined" && Boolean(process$1.env.SD_DEBUG_LAYOUT);
|
|
34077
34087
|
const layoutLog = (...args) => {
|
|
34078
34088
|
if (!layoutDebugEnabled$1) return;
|
|
@@ -34383,7 +34393,13 @@ function layoutDocument(blocks, measures, options = {}) {
|
|
|
34383
34393
|
const paginator = createPaginator({
|
|
34384
34394
|
margins: paginatorMargins,
|
|
34385
34395
|
getActiveTopMargin: () => activeTopMargin,
|
|
34386
|
-
getActiveBottomMargin: () =>
|
|
34396
|
+
getActiveBottomMargin: () => {
|
|
34397
|
+
const reserves = options.footnoteReservedByPageIndex;
|
|
34398
|
+
const pageIndex = Math.max(0, pageCount - 1);
|
|
34399
|
+
const reserve = Array.isArray(reserves) ? reserves[pageIndex] : 0;
|
|
34400
|
+
const reservePx = typeof reserve === "number" && Number.isFinite(reserve) && reserve > 0 ? reserve : 0;
|
|
34401
|
+
return activeBottomMargin + reservePx;
|
|
34402
|
+
},
|
|
34387
34403
|
getActiveHeaderDistance: () => activeHeaderDistance,
|
|
34388
34404
|
getActiveFooterDistance: () => activeFooterDistance,
|
|
34389
34405
|
getActivePageSize: () => activePageSize,
|
|
@@ -34867,7 +34883,7 @@ function layoutDocument(blocks, measures, options = {}) {
|
|
|
34867
34883
|
if (!shouldSkipAnchoredTable) {
|
|
34868
34884
|
let state = paginator.ensurePage();
|
|
34869
34885
|
const availableHeight = state.contentBottom - state.cursorY;
|
|
34870
|
-
const spacingAfter = getParagraphSpacingAfter(paraBlock);
|
|
34886
|
+
const spacingAfter = getParagraphSpacingAfter$1(paraBlock);
|
|
34871
34887
|
const currentHeight = getMeasureHeight(paraBlock, measure);
|
|
34872
34888
|
const nextHeight = getMeasureHeight(nextBlock, nextMeasure);
|
|
34873
34889
|
const nextIsParagraph = nextBlock.kind === "paragraph" && nextMeasure.kind === "paragraph";
|
|
@@ -35180,7 +35196,7 @@ function normalizeColumns(input, contentWidth) {
|
|
|
35180
35196
|
const gap = Math.max(0, input?.gap ?? 0);
|
|
35181
35197
|
const totalGap = gap * (count - 1);
|
|
35182
35198
|
const width = (contentWidth - totalGap) / count;
|
|
35183
|
-
if (width <= COLUMN_EPSILON) {
|
|
35199
|
+
if (width <= COLUMN_EPSILON$1) {
|
|
35184
35200
|
return {
|
|
35185
35201
|
count: 1,
|
|
35186
35202
|
gap: 0,
|
|
@@ -36943,6 +36959,417 @@ const perfLog = (...args) => {
|
|
|
36943
36959
|
if (!layoutDebugEnabled) return;
|
|
36944
36960
|
console.log(...args);
|
|
36945
36961
|
};
|
|
36962
|
+
const isFootnotesLayoutInput = (value) => {
|
|
36963
|
+
if (!value || typeof value !== "object") return false;
|
|
36964
|
+
const v = value;
|
|
36965
|
+
if (!Array.isArray(v.refs)) return false;
|
|
36966
|
+
if (!(v.blocksById instanceof Map)) return false;
|
|
36967
|
+
return true;
|
|
36968
|
+
};
|
|
36969
|
+
const findPageIndexForPos = (layout, pos) => {
|
|
36970
|
+
if (!Number.isFinite(pos)) return null;
|
|
36971
|
+
const fallbackRanges = [];
|
|
36972
|
+
for (let pageIndex = 0; pageIndex < layout.pages.length; pageIndex++) {
|
|
36973
|
+
const page = layout.pages[pageIndex];
|
|
36974
|
+
let minStart = null;
|
|
36975
|
+
let maxEnd = null;
|
|
36976
|
+
for (const fragment of page.fragments) {
|
|
36977
|
+
const pmStart = fragment.pmStart;
|
|
36978
|
+
const pmEnd = fragment.pmEnd;
|
|
36979
|
+
if (pmStart == null || pmEnd == null) continue;
|
|
36980
|
+
if (minStart == null || pmStart < minStart) minStart = pmStart;
|
|
36981
|
+
if (maxEnd == null || pmEnd > maxEnd) maxEnd = pmEnd;
|
|
36982
|
+
if (pos >= pmStart && pos <= pmEnd) {
|
|
36983
|
+
return pageIndex;
|
|
36984
|
+
}
|
|
36985
|
+
}
|
|
36986
|
+
fallbackRanges[pageIndex] = minStart != null && maxEnd != null ? { pageIndex, minStart, maxEnd } : null;
|
|
36987
|
+
}
|
|
36988
|
+
let best = null;
|
|
36989
|
+
for (const entry of fallbackRanges) {
|
|
36990
|
+
if (!entry) continue;
|
|
36991
|
+
const distance = pos < entry.minStart ? entry.minStart - pos : pos > entry.maxEnd ? pos - entry.maxEnd : 0;
|
|
36992
|
+
if (!best || distance < best.distance) {
|
|
36993
|
+
best = { pageIndex: entry.pageIndex, distance };
|
|
36994
|
+
}
|
|
36995
|
+
}
|
|
36996
|
+
if (best) return best.pageIndex;
|
|
36997
|
+
if (layout.pages.length > 0) return layout.pages.length - 1;
|
|
36998
|
+
return null;
|
|
36999
|
+
};
|
|
37000
|
+
const footnoteColumnKey = (pageIndex, columnIndex) => `${pageIndex}:${columnIndex}`;
|
|
37001
|
+
const COLUMN_EPSILON = 0.01;
|
|
37002
|
+
const normalizeColumnsForFootnotes = (input, contentWidth) => {
|
|
37003
|
+
const rawCount = Number.isFinite(input?.count) ? Math.floor(input.count) : 1;
|
|
37004
|
+
const count = Math.max(1, rawCount || 1);
|
|
37005
|
+
const gap = Math.max(0, input?.gap ?? 0);
|
|
37006
|
+
const totalGap = gap * (count - 1);
|
|
37007
|
+
const width = (contentWidth - totalGap) / count;
|
|
37008
|
+
if (!Number.isFinite(width) || width <= COLUMN_EPSILON) {
|
|
37009
|
+
return {
|
|
37010
|
+
count: 1,
|
|
37011
|
+
gap: 0,
|
|
37012
|
+
width: Math.max(0, contentWidth)
|
|
37013
|
+
};
|
|
37014
|
+
}
|
|
37015
|
+
return { count, gap, width };
|
|
37016
|
+
};
|
|
37017
|
+
const resolveSectionColumnsByIndex = (options, blocks) => {
|
|
37018
|
+
const result = /* @__PURE__ */ new Map();
|
|
37019
|
+
let activeColumns = options.columns ?? { count: 1, gap: 0 };
|
|
37020
|
+
if (blocks && blocks.length > 0) {
|
|
37021
|
+
for (const block of blocks) {
|
|
37022
|
+
if (block.kind !== "sectionBreak") continue;
|
|
37023
|
+
const sectionIndexRaw = block.attrs?.sectionIndex;
|
|
37024
|
+
const sectionIndex = typeof sectionIndexRaw === "number" && Number.isFinite(sectionIndexRaw) ? sectionIndexRaw : result.size;
|
|
37025
|
+
if (block.columns) {
|
|
37026
|
+
activeColumns = { count: block.columns.count, gap: block.columns.gap };
|
|
37027
|
+
}
|
|
37028
|
+
result.set(sectionIndex, { ...activeColumns });
|
|
37029
|
+
}
|
|
37030
|
+
}
|
|
37031
|
+
if (result.size === 0) {
|
|
37032
|
+
result.set(0, { ...activeColumns });
|
|
37033
|
+
}
|
|
37034
|
+
return result;
|
|
37035
|
+
};
|
|
37036
|
+
const resolvePageColumns = (layout, options, blocks) => {
|
|
37037
|
+
const sectionColumns = resolveSectionColumnsByIndex(options, blocks);
|
|
37038
|
+
const result = /* @__PURE__ */ new Map();
|
|
37039
|
+
for (let pageIndex = 0; pageIndex < layout.pages.length; pageIndex += 1) {
|
|
37040
|
+
const page = layout.pages[pageIndex];
|
|
37041
|
+
const pageSize = page.size ?? layout.pageSize ?? DEFAULT_PAGE_SIZE$1;
|
|
37042
|
+
const marginLeft = normalizeMargin(
|
|
37043
|
+
page.margins?.left,
|
|
37044
|
+
normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
|
|
37045
|
+
);
|
|
37046
|
+
const marginRight = normalizeMargin(
|
|
37047
|
+
page.margins?.right,
|
|
37048
|
+
normalizeMargin(options.margins?.right, DEFAULT_MARGINS$1.right)
|
|
37049
|
+
);
|
|
37050
|
+
const contentWidth = pageSize.w - (marginLeft + marginRight);
|
|
37051
|
+
const sectionIndex = page.sectionIndex ?? 0;
|
|
37052
|
+
const columnsConfig = sectionColumns.get(sectionIndex) ?? options.columns ?? { count: 1, gap: 0 };
|
|
37053
|
+
const normalized = normalizeColumnsForFootnotes(columnsConfig, contentWidth);
|
|
37054
|
+
result.set(pageIndex, { ...normalized, left: marginLeft, contentWidth });
|
|
37055
|
+
}
|
|
37056
|
+
return result;
|
|
37057
|
+
};
|
|
37058
|
+
const findFragmentForPos = (page, pos) => {
|
|
37059
|
+
for (const fragment of page.fragments) {
|
|
37060
|
+
const pmStart = fragment.pmStart;
|
|
37061
|
+
const pmEnd = fragment.pmEnd;
|
|
37062
|
+
if (pmStart == null || pmEnd == null) continue;
|
|
37063
|
+
if (pos >= pmStart && pos <= pmEnd) {
|
|
37064
|
+
return fragment;
|
|
37065
|
+
}
|
|
37066
|
+
}
|
|
37067
|
+
return null;
|
|
37068
|
+
};
|
|
37069
|
+
const assignFootnotesToColumns = (layout, refs, pageColumns) => {
|
|
37070
|
+
const result = /* @__PURE__ */ new Map();
|
|
37071
|
+
const seenByColumn = /* @__PURE__ */ new Map();
|
|
37072
|
+
for (const ref2 of refs) {
|
|
37073
|
+
const pageIndex = findPageIndexForPos(layout, ref2.pos);
|
|
37074
|
+
if (pageIndex == null) continue;
|
|
37075
|
+
const columns = pageColumns.get(pageIndex);
|
|
37076
|
+
const page = layout.pages[pageIndex];
|
|
37077
|
+
let columnIndex = 0;
|
|
37078
|
+
if (columns && columns.count > 1 && page) {
|
|
37079
|
+
const fragment = findFragmentForPos(page, ref2.pos);
|
|
37080
|
+
if (fragment && typeof fragment.x === "number") {
|
|
37081
|
+
const columnStride = columns.width + columns.gap;
|
|
37082
|
+
const rawIndex = columnStride > 0 ? Math.floor((fragment.x - columns.left) / columnStride) : 0;
|
|
37083
|
+
columnIndex = Math.max(0, Math.min(columns.count - 1, rawIndex));
|
|
37084
|
+
}
|
|
37085
|
+
}
|
|
37086
|
+
const key2 = footnoteColumnKey(pageIndex, columnIndex);
|
|
37087
|
+
let seen = seenByColumn.get(key2);
|
|
37088
|
+
if (!seen) {
|
|
37089
|
+
seen = /* @__PURE__ */ new Set();
|
|
37090
|
+
seenByColumn.set(key2, seen);
|
|
37091
|
+
}
|
|
37092
|
+
if (seen.has(ref2.id)) continue;
|
|
37093
|
+
seen.add(ref2.id);
|
|
37094
|
+
const pageMap = result.get(pageIndex) ?? /* @__PURE__ */ new Map();
|
|
37095
|
+
const list = pageMap.get(columnIndex) ?? [];
|
|
37096
|
+
list.push(ref2.id);
|
|
37097
|
+
pageMap.set(columnIndex, list);
|
|
37098
|
+
result.set(pageIndex, pageMap);
|
|
37099
|
+
}
|
|
37100
|
+
return result;
|
|
37101
|
+
};
|
|
37102
|
+
const resolveFootnoteMeasurementWidth = (options, blocks) => {
|
|
37103
|
+
const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
|
|
37104
|
+
const margins = {
|
|
37105
|
+
right: normalizeMargin(options.margins?.right, DEFAULT_MARGINS$1.right),
|
|
37106
|
+
left: normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
|
|
37107
|
+
};
|
|
37108
|
+
let width = pageSize.w - (margins.left + margins.right);
|
|
37109
|
+
let activeColumns = options.columns ?? { count: 1, gap: 0 };
|
|
37110
|
+
let activePageSize = pageSize;
|
|
37111
|
+
let activeMargins = { ...margins };
|
|
37112
|
+
const resolveColumnWidth = () => {
|
|
37113
|
+
const contentWidth = activePageSize.w - (activeMargins.left + activeMargins.right);
|
|
37114
|
+
const normalized = normalizeColumnsForFootnotes(activeColumns, contentWidth);
|
|
37115
|
+
return normalized.width;
|
|
37116
|
+
};
|
|
37117
|
+
width = resolveColumnWidth();
|
|
37118
|
+
if (blocks && blocks.length > 0) {
|
|
37119
|
+
for (const block of blocks) {
|
|
37120
|
+
if (block.kind !== "sectionBreak") continue;
|
|
37121
|
+
activePageSize = block.pageSize ?? activePageSize;
|
|
37122
|
+
activeMargins = {
|
|
37123
|
+
right: normalizeMargin(block.margins?.right, activeMargins.right),
|
|
37124
|
+
left: normalizeMargin(block.margins?.left, activeMargins.left)
|
|
37125
|
+
};
|
|
37126
|
+
if (block.columns) {
|
|
37127
|
+
activeColumns = { count: block.columns.count, gap: block.columns.gap };
|
|
37128
|
+
}
|
|
37129
|
+
const w = resolveColumnWidth();
|
|
37130
|
+
if (w > 0 && w < width) width = w;
|
|
37131
|
+
}
|
|
37132
|
+
}
|
|
37133
|
+
if (!Number.isFinite(width) || width <= 0) return 0;
|
|
37134
|
+
return width;
|
|
37135
|
+
};
|
|
37136
|
+
const MIN_FOOTNOTE_BODY_HEIGHT = 1;
|
|
37137
|
+
const DEFAULT_FOOTNOTE_SEPARATOR_SPACING_BEFORE = 12;
|
|
37138
|
+
const computeMaxFootnoteReserve = (layoutForPages, pageIndex, baseReserve = 0) => {
|
|
37139
|
+
const page = layoutForPages.pages?.[pageIndex];
|
|
37140
|
+
if (!page) return 0;
|
|
37141
|
+
const pageSize = page.size ?? layoutForPages.pageSize ?? DEFAULT_PAGE_SIZE$1;
|
|
37142
|
+
const topMargin = normalizeMargin(page.margins?.top, DEFAULT_MARGINS$1.top);
|
|
37143
|
+
const bottomWithReserve = normalizeMargin(page.margins?.bottom, DEFAULT_MARGINS$1.bottom);
|
|
37144
|
+
const baseReserveSafe = Number.isFinite(baseReserve) ? Math.max(0, baseReserve) : 0;
|
|
37145
|
+
const bottomMargin = Math.max(0, bottomWithReserve - baseReserveSafe);
|
|
37146
|
+
const availableForBody = pageSize.h - topMargin - bottomMargin;
|
|
37147
|
+
if (!Number.isFinite(availableForBody)) return 0;
|
|
37148
|
+
return Math.max(0, availableForBody - MIN_FOOTNOTE_BODY_HEIGHT);
|
|
37149
|
+
};
|
|
37150
|
+
const sumLineHeights$1 = (lines, fromLine, toLine) => {
|
|
37151
|
+
if (!lines || fromLine >= toLine) return 0;
|
|
37152
|
+
let total = 0;
|
|
37153
|
+
for (let i = fromLine; i < toLine; i += 1) {
|
|
37154
|
+
total += lines[i]?.lineHeight ?? 0;
|
|
37155
|
+
}
|
|
37156
|
+
return total;
|
|
37157
|
+
};
|
|
37158
|
+
const getParagraphSpacingAfter = (block) => {
|
|
37159
|
+
const spacing = block.attrs?.spacing;
|
|
37160
|
+
const value = spacing?.after ?? spacing?.lineSpaceAfter;
|
|
37161
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
37162
|
+
};
|
|
37163
|
+
const resolveSeparatorSpacingBefore = (rangesByFootnoteId, measuresById, explicitValue, fallbackValue) => {
|
|
37164
|
+
if (typeof explicitValue === "number" && Number.isFinite(explicitValue)) {
|
|
37165
|
+
return Math.max(0, explicitValue);
|
|
37166
|
+
}
|
|
37167
|
+
for (const ranges of rangesByFootnoteId.values()) {
|
|
37168
|
+
for (const range of ranges) {
|
|
37169
|
+
if (range.kind === "paragraph") {
|
|
37170
|
+
const measure = measuresById.get(range.blockId);
|
|
37171
|
+
if (measure?.kind !== "paragraph") continue;
|
|
37172
|
+
const lineHeight2 = measure.lines?.[range.fromLine]?.lineHeight ?? measure.lines?.[0]?.lineHeight;
|
|
37173
|
+
if (typeof lineHeight2 === "number" && Number.isFinite(lineHeight2) && lineHeight2 > 0) {
|
|
37174
|
+
return lineHeight2;
|
|
37175
|
+
}
|
|
37176
|
+
}
|
|
37177
|
+
if (range.kind === "list-item") {
|
|
37178
|
+
const measure = measuresById.get(range.blockId);
|
|
37179
|
+
if (measure?.kind !== "list") continue;
|
|
37180
|
+
const itemMeasure = measure.items.find((item) => item.itemId === range.itemId);
|
|
37181
|
+
const lineHeight2 = itemMeasure?.paragraph?.lines?.[range.fromLine]?.lineHeight ?? itemMeasure?.paragraph?.lines?.[0]?.lineHeight;
|
|
37182
|
+
if (typeof lineHeight2 === "number" && Number.isFinite(lineHeight2) && lineHeight2 > 0) {
|
|
37183
|
+
return lineHeight2;
|
|
37184
|
+
}
|
|
37185
|
+
}
|
|
37186
|
+
}
|
|
37187
|
+
}
|
|
37188
|
+
return Math.max(0, fallbackValue);
|
|
37189
|
+
};
|
|
37190
|
+
const getRangeRenderHeight = (range) => {
|
|
37191
|
+
if (range.kind === "paragraph" || range.kind === "list-item") {
|
|
37192
|
+
const spacing = range.toLine >= range.totalLines ? range.spacingAfter : 0;
|
|
37193
|
+
return range.height + spacing;
|
|
37194
|
+
}
|
|
37195
|
+
return range.height;
|
|
37196
|
+
};
|
|
37197
|
+
const buildFootnoteRanges = (blocks, measuresById) => {
|
|
37198
|
+
const ranges = [];
|
|
37199
|
+
blocks.forEach((block) => {
|
|
37200
|
+
const measure = measuresById.get(block.id);
|
|
37201
|
+
if (!measure) return;
|
|
37202
|
+
if (block.kind === "paragraph") {
|
|
37203
|
+
if (measure.kind !== "paragraph") return;
|
|
37204
|
+
const lineCount = measure.lines?.length ?? 0;
|
|
37205
|
+
if (lineCount === 0) return;
|
|
37206
|
+
ranges.push({
|
|
37207
|
+
kind: "paragraph",
|
|
37208
|
+
blockId: block.id,
|
|
37209
|
+
fromLine: 0,
|
|
37210
|
+
toLine: lineCount,
|
|
37211
|
+
totalLines: lineCount,
|
|
37212
|
+
height: sumLineHeights$1(measure.lines, 0, lineCount),
|
|
37213
|
+
spacingAfter: getParagraphSpacingAfter(block)
|
|
37214
|
+
});
|
|
37215
|
+
return;
|
|
37216
|
+
}
|
|
37217
|
+
if (block.kind === "list") {
|
|
37218
|
+
if (measure.kind !== "list") return;
|
|
37219
|
+
block.items.forEach((item) => {
|
|
37220
|
+
const itemMeasure = measure.items.find((entry) => entry.itemId === item.id);
|
|
37221
|
+
if (!itemMeasure) return;
|
|
37222
|
+
const lineCount = itemMeasure.paragraph.lines?.length ?? 0;
|
|
37223
|
+
if (lineCount === 0) return;
|
|
37224
|
+
ranges.push({
|
|
37225
|
+
kind: "list-item",
|
|
37226
|
+
blockId: block.id,
|
|
37227
|
+
itemId: item.id,
|
|
37228
|
+
fromLine: 0,
|
|
37229
|
+
toLine: lineCount,
|
|
37230
|
+
totalLines: lineCount,
|
|
37231
|
+
height: sumLineHeights$1(itemMeasure.paragraph.lines, 0, lineCount),
|
|
37232
|
+
spacingAfter: getParagraphSpacingAfter(item.paragraph)
|
|
37233
|
+
});
|
|
37234
|
+
});
|
|
37235
|
+
return;
|
|
37236
|
+
}
|
|
37237
|
+
if (block.kind === "table" && measure.kind === "table") {
|
|
37238
|
+
const height = Math.max(0, measure.totalHeight ?? 0);
|
|
37239
|
+
if (height > 0) {
|
|
37240
|
+
ranges.push({ kind: "table", blockId: block.id, height });
|
|
37241
|
+
}
|
|
37242
|
+
return;
|
|
37243
|
+
}
|
|
37244
|
+
if (block.kind === "image" && measure.kind === "image") {
|
|
37245
|
+
const height = Math.max(0, measure.height ?? 0);
|
|
37246
|
+
if (height > 0) {
|
|
37247
|
+
ranges.push({ kind: "image", blockId: block.id, height });
|
|
37248
|
+
}
|
|
37249
|
+
return;
|
|
37250
|
+
}
|
|
37251
|
+
if (block.kind === "drawing" && measure.kind === "drawing") {
|
|
37252
|
+
const height = Math.max(0, measure.height ?? 0);
|
|
37253
|
+
if (height > 0) {
|
|
37254
|
+
ranges.push({ kind: "drawing", blockId: block.id, height });
|
|
37255
|
+
}
|
|
37256
|
+
}
|
|
37257
|
+
});
|
|
37258
|
+
return ranges;
|
|
37259
|
+
};
|
|
37260
|
+
const splitRangeAtHeight = (range, availableHeight, measuresById) => {
|
|
37261
|
+
if (availableHeight <= 0) return { fitted: null, remaining: range };
|
|
37262
|
+
if (range.kind !== "paragraph") {
|
|
37263
|
+
return getRangeRenderHeight(range) <= availableHeight ? { fitted: range, remaining: null } : { fitted: null, remaining: range };
|
|
37264
|
+
}
|
|
37265
|
+
const measure = measuresById.get(range.blockId);
|
|
37266
|
+
if (!measure || measure.kind !== "paragraph" || !measure.lines) {
|
|
37267
|
+
return getRangeRenderHeight(range) <= availableHeight ? { fitted: range, remaining: null } : { fitted: null, remaining: range };
|
|
37268
|
+
}
|
|
37269
|
+
let accumulatedHeight = 0;
|
|
37270
|
+
let splitLine = range.fromLine;
|
|
37271
|
+
for (let i = range.fromLine; i < range.toLine; i += 1) {
|
|
37272
|
+
const lineHeight2 = measure.lines[i]?.lineHeight ?? 0;
|
|
37273
|
+
if (accumulatedHeight + lineHeight2 > availableHeight) break;
|
|
37274
|
+
accumulatedHeight += lineHeight2;
|
|
37275
|
+
splitLine = i + 1;
|
|
37276
|
+
}
|
|
37277
|
+
if (splitLine === range.fromLine) {
|
|
37278
|
+
return { fitted: null, remaining: range };
|
|
37279
|
+
}
|
|
37280
|
+
const fitted = {
|
|
37281
|
+
...range,
|
|
37282
|
+
toLine: splitLine,
|
|
37283
|
+
height: sumLineHeights$1(measure.lines, range.fromLine, splitLine)
|
|
37284
|
+
};
|
|
37285
|
+
if (splitLine >= range.toLine) {
|
|
37286
|
+
return getRangeRenderHeight(fitted) <= availableHeight ? { fitted, remaining: null } : { fitted: null, remaining: range };
|
|
37287
|
+
}
|
|
37288
|
+
const remaining = {
|
|
37289
|
+
...range,
|
|
37290
|
+
fromLine: splitLine,
|
|
37291
|
+
height: sumLineHeights$1(measure.lines, splitLine, range.toLine)
|
|
37292
|
+
};
|
|
37293
|
+
return { fitted, remaining };
|
|
37294
|
+
};
|
|
37295
|
+
const forceFitFirstRange = (range, measuresById) => {
|
|
37296
|
+
if (range.kind !== "paragraph") {
|
|
37297
|
+
return { fitted: range, remaining: null };
|
|
37298
|
+
}
|
|
37299
|
+
const measure = measuresById.get(range.blockId);
|
|
37300
|
+
if (!measure || measure.kind !== "paragraph" || !measure.lines?.length) {
|
|
37301
|
+
return { fitted: range, remaining: null };
|
|
37302
|
+
}
|
|
37303
|
+
const nextLine = Math.min(range.fromLine + 1, range.toLine);
|
|
37304
|
+
const fitted = {
|
|
37305
|
+
...range,
|
|
37306
|
+
toLine: nextLine,
|
|
37307
|
+
height: sumLineHeights$1(measure.lines, range.fromLine, nextLine)
|
|
37308
|
+
};
|
|
37309
|
+
if (nextLine >= range.toLine) {
|
|
37310
|
+
return { fitted, remaining: null };
|
|
37311
|
+
}
|
|
37312
|
+
const remaining = {
|
|
37313
|
+
...range,
|
|
37314
|
+
fromLine: nextLine,
|
|
37315
|
+
height: sumLineHeights$1(measure.lines, nextLine, range.toLine)
|
|
37316
|
+
};
|
|
37317
|
+
return { fitted, remaining };
|
|
37318
|
+
};
|
|
37319
|
+
const fitFootnoteContent = (id, inputRanges, availableHeight, pageIndex, columnIndex, isContinuation, measuresById, forceFirstRange) => {
|
|
37320
|
+
const fittedRanges = [];
|
|
37321
|
+
let remainingRanges = [];
|
|
37322
|
+
let usedHeight = 0;
|
|
37323
|
+
const maxHeight = Math.max(0, availableHeight);
|
|
37324
|
+
for (let index2 = 0; index2 < inputRanges.length; index2 += 1) {
|
|
37325
|
+
const range = inputRanges[index2];
|
|
37326
|
+
const remainingSpace = maxHeight - usedHeight;
|
|
37327
|
+
const rangeHeight = getRangeRenderHeight(range);
|
|
37328
|
+
if (rangeHeight <= remainingSpace) {
|
|
37329
|
+
fittedRanges.push(range);
|
|
37330
|
+
usedHeight += rangeHeight;
|
|
37331
|
+
continue;
|
|
37332
|
+
}
|
|
37333
|
+
if (range.kind === "paragraph") {
|
|
37334
|
+
const split = splitRangeAtHeight(range, remainingSpace, measuresById);
|
|
37335
|
+
if (split.fitted && getRangeRenderHeight(split.fitted) <= remainingSpace) {
|
|
37336
|
+
fittedRanges.push(split.fitted);
|
|
37337
|
+
usedHeight += getRangeRenderHeight(split.fitted);
|
|
37338
|
+
}
|
|
37339
|
+
if (split.remaining) {
|
|
37340
|
+
remainingRanges = [split.remaining, ...inputRanges.slice(index2 + 1)];
|
|
37341
|
+
} else {
|
|
37342
|
+
remainingRanges = inputRanges.slice(index2 + 1);
|
|
37343
|
+
}
|
|
37344
|
+
break;
|
|
37345
|
+
}
|
|
37346
|
+
remainingRanges = [range, ...inputRanges.slice(index2 + 1)];
|
|
37347
|
+
break;
|
|
37348
|
+
}
|
|
37349
|
+
if (fittedRanges.length === 0 && forceFirstRange && inputRanges.length > 0) {
|
|
37350
|
+
const forced = forceFitFirstRange(inputRanges[0], measuresById);
|
|
37351
|
+
if (forced.fitted) {
|
|
37352
|
+
fittedRanges.push(forced.fitted);
|
|
37353
|
+
usedHeight = getRangeRenderHeight(forced.fitted);
|
|
37354
|
+
remainingRanges = [];
|
|
37355
|
+
if (forced.remaining) {
|
|
37356
|
+
remainingRanges.push(forced.remaining);
|
|
37357
|
+
}
|
|
37358
|
+
remainingRanges.push(...inputRanges.slice(1));
|
|
37359
|
+
}
|
|
37360
|
+
}
|
|
37361
|
+
return {
|
|
37362
|
+
slice: {
|
|
37363
|
+
id,
|
|
37364
|
+
pageIndex,
|
|
37365
|
+
columnIndex,
|
|
37366
|
+
isContinuation,
|
|
37367
|
+
ranges: fittedRanges,
|
|
37368
|
+
totalHeight: usedHeight
|
|
37369
|
+
},
|
|
37370
|
+
remainingRanges
|
|
37371
|
+
};
|
|
37372
|
+
};
|
|
36946
37373
|
async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, options, measureBlock2, headerFooter) {
|
|
36947
37374
|
performance.now();
|
|
36948
37375
|
const dirty = computeDirtyRegions(previousBlocks, nextBlocks);
|
|
@@ -37206,6 +37633,497 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
|
|
|
37206
37633
|
converged
|
|
37207
37634
|
});
|
|
37208
37635
|
}
|
|
37636
|
+
let extraBlocks;
|
|
37637
|
+
let extraMeasures;
|
|
37638
|
+
const footnotesInput = isFootnotesLayoutInput(options.footnotes) ? options.footnotes : null;
|
|
37639
|
+
if (footnotesInput && footnotesInput.refs.length > 0 && footnotesInput.blocksById.size > 0) {
|
|
37640
|
+
const gap = typeof footnotesInput.gap === "number" && Number.isFinite(footnotesInput.gap) ? footnotesInput.gap : 2;
|
|
37641
|
+
const topPadding = typeof footnotesInput.topPadding === "number" && Number.isFinite(footnotesInput.topPadding) ? footnotesInput.topPadding : 6;
|
|
37642
|
+
const dividerHeight = typeof footnotesInput.dividerHeight === "number" && Number.isFinite(footnotesInput.dividerHeight) ? footnotesInput.dividerHeight : 6;
|
|
37643
|
+
const safeGap = Math.max(0, gap);
|
|
37644
|
+
const safeTopPadding = Math.max(0, topPadding);
|
|
37645
|
+
const safeDividerHeight = Math.max(0, dividerHeight);
|
|
37646
|
+
const continuationDividerHeight = safeDividerHeight;
|
|
37647
|
+
const continuationDividerWidthFactor = 0.3;
|
|
37648
|
+
const footnoteWidth = resolveFootnoteMeasurementWidth(options, currentBlocks);
|
|
37649
|
+
if (footnoteWidth > 0) {
|
|
37650
|
+
const footnoteConstraints = { maxWidth: footnoteWidth, maxHeight: measurementHeight };
|
|
37651
|
+
const collectFootnoteIdsByColumn = (idsByColumn2) => {
|
|
37652
|
+
const ids = /* @__PURE__ */ new Set();
|
|
37653
|
+
idsByColumn2.forEach((columns) => {
|
|
37654
|
+
columns.forEach((list) => {
|
|
37655
|
+
list.forEach((id) => ids.add(id));
|
|
37656
|
+
});
|
|
37657
|
+
});
|
|
37658
|
+
return ids;
|
|
37659
|
+
};
|
|
37660
|
+
const measureFootnoteBlocks = async (ids) => {
|
|
37661
|
+
const needed = /* @__PURE__ */ new Map();
|
|
37662
|
+
ids.forEach((id) => {
|
|
37663
|
+
const blocks2 = footnotesInput.blocksById.get(id) ?? [];
|
|
37664
|
+
blocks2.forEach((block) => {
|
|
37665
|
+
if (block?.id && !needed.has(block.id)) {
|
|
37666
|
+
needed.set(block.id, block);
|
|
37667
|
+
}
|
|
37668
|
+
});
|
|
37669
|
+
});
|
|
37670
|
+
const blocks = Array.from(needed.values());
|
|
37671
|
+
const measuresById2 = /* @__PURE__ */ new Map();
|
|
37672
|
+
await Promise.all(
|
|
37673
|
+
blocks.map(async (block) => {
|
|
37674
|
+
const cached = measureCache.get(block, footnoteConstraints.maxWidth, footnoteConstraints.maxHeight);
|
|
37675
|
+
if (cached) {
|
|
37676
|
+
measuresById2.set(block.id, cached);
|
|
37677
|
+
return;
|
|
37678
|
+
}
|
|
37679
|
+
const measurement = await measureBlock2(block, footnoteConstraints);
|
|
37680
|
+
measureCache.set(block, footnoteConstraints.maxWidth, footnoteConstraints.maxHeight, measurement);
|
|
37681
|
+
measuresById2.set(block.id, measurement);
|
|
37682
|
+
})
|
|
37683
|
+
);
|
|
37684
|
+
return { blocks, measuresById: measuresById2 };
|
|
37685
|
+
};
|
|
37686
|
+
const computeFootnoteLayoutPlan = (layoutForPages, idsByColumn2, measuresById2, baseReserves = [], pageColumns2) => {
|
|
37687
|
+
const pageCount = layoutForPages.pages.length;
|
|
37688
|
+
const slicesByPage = /* @__PURE__ */ new Map();
|
|
37689
|
+
const reserves2 = new Array(pageCount).fill(0);
|
|
37690
|
+
const hasContinuationByColumn = /* @__PURE__ */ new Map();
|
|
37691
|
+
const rangesByFootnoteId = /* @__PURE__ */ new Map();
|
|
37692
|
+
const cappedPages = /* @__PURE__ */ new Set();
|
|
37693
|
+
const allIds = collectFootnoteIdsByColumn(idsByColumn2);
|
|
37694
|
+
allIds.forEach((id) => {
|
|
37695
|
+
const blocks = footnotesInput.blocksById.get(id) ?? [];
|
|
37696
|
+
rangesByFootnoteId.set(id, buildFootnoteRanges(blocks, measuresById2));
|
|
37697
|
+
});
|
|
37698
|
+
const separatorSpacingBefore = resolveSeparatorSpacingBefore(
|
|
37699
|
+
rangesByFootnoteId,
|
|
37700
|
+
measuresById2,
|
|
37701
|
+
footnotesInput.separatorSpacingBefore,
|
|
37702
|
+
DEFAULT_FOOTNOTE_SEPARATOR_SPACING_BEFORE
|
|
37703
|
+
);
|
|
37704
|
+
const safeSeparatorSpacingBefore = Math.max(0, separatorSpacingBefore);
|
|
37705
|
+
let pendingByColumn = /* @__PURE__ */ new Map();
|
|
37706
|
+
for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
|
|
37707
|
+
const baseReserve = Number.isFinite(baseReserves?.[pageIndex]) ? Math.max(0, baseReserves[pageIndex]) : 0;
|
|
37708
|
+
const maxReserve = computeMaxFootnoteReserve(layoutForPages, pageIndex, baseReserve);
|
|
37709
|
+
const columns = pageColumns2.get(pageIndex);
|
|
37710
|
+
const columnCount = Math.max(1, Math.floor(columns?.count ?? 1));
|
|
37711
|
+
const pendingForPage = /* @__PURE__ */ new Map();
|
|
37712
|
+
pendingByColumn.forEach((entries, columnIndex) => {
|
|
37713
|
+
const targetIndex = columnIndex < columnCount ? columnIndex : Math.max(0, columnCount - 1);
|
|
37714
|
+
const list = pendingForPage.get(targetIndex) ?? [];
|
|
37715
|
+
list.push(...entries);
|
|
37716
|
+
pendingForPage.set(targetIndex, list);
|
|
37717
|
+
});
|
|
37718
|
+
pendingByColumn = /* @__PURE__ */ new Map();
|
|
37719
|
+
const pageSlices = [];
|
|
37720
|
+
let pageReserve = 0;
|
|
37721
|
+
for (let columnIndex = 0; columnIndex < columnCount; columnIndex += 1) {
|
|
37722
|
+
let usedHeight = 0;
|
|
37723
|
+
const columnSlices = [];
|
|
37724
|
+
const nextPending = [];
|
|
37725
|
+
let stopPlacement = false;
|
|
37726
|
+
const columnKey = footnoteColumnKey(pageIndex, columnIndex);
|
|
37727
|
+
const placeFootnote = (id, ranges, isContinuation) => {
|
|
37728
|
+
if (!ranges || ranges.length === 0) {
|
|
37729
|
+
return { placed: false, remaining: [] };
|
|
37730
|
+
}
|
|
37731
|
+
const isFirstSlice = columnSlices.length === 0;
|
|
37732
|
+
const separatorBefore = isFirstSlice ? safeSeparatorSpacingBefore : 0;
|
|
37733
|
+
const separatorHeight = isFirstSlice ? isContinuation ? continuationDividerHeight : safeDividerHeight : 0;
|
|
37734
|
+
const overhead = isFirstSlice ? separatorBefore + separatorHeight + safeTopPadding : 0;
|
|
37735
|
+
const gapBefore = !isFirstSlice ? safeGap : 0;
|
|
37736
|
+
const availableHeight = Math.max(0, maxReserve - usedHeight - overhead - gapBefore);
|
|
37737
|
+
const { slice: slice2, remainingRanges } = fitFootnoteContent(
|
|
37738
|
+
id,
|
|
37739
|
+
ranges,
|
|
37740
|
+
availableHeight,
|
|
37741
|
+
pageIndex,
|
|
37742
|
+
columnIndex,
|
|
37743
|
+
isContinuation,
|
|
37744
|
+
measuresById2,
|
|
37745
|
+
isFirstSlice && maxReserve > 0
|
|
37746
|
+
);
|
|
37747
|
+
if (slice2.ranges.length === 0) {
|
|
37748
|
+
return { placed: false, remaining: ranges };
|
|
37749
|
+
}
|
|
37750
|
+
if (isFirstSlice) {
|
|
37751
|
+
usedHeight += overhead;
|
|
37752
|
+
if (isContinuation) {
|
|
37753
|
+
hasContinuationByColumn.set(columnKey, true);
|
|
37754
|
+
}
|
|
37755
|
+
}
|
|
37756
|
+
if (gapBefore > 0) {
|
|
37757
|
+
usedHeight += gapBefore;
|
|
37758
|
+
}
|
|
37759
|
+
usedHeight += slice2.totalHeight;
|
|
37760
|
+
columnSlices.push(slice2);
|
|
37761
|
+
return { placed: true, remaining: remainingRanges };
|
|
37762
|
+
};
|
|
37763
|
+
const pending = pendingForPage.get(columnIndex) ?? [];
|
|
37764
|
+
for (const entry of pending) {
|
|
37765
|
+
if (stopPlacement) {
|
|
37766
|
+
nextPending.push(entry);
|
|
37767
|
+
continue;
|
|
37768
|
+
}
|
|
37769
|
+
if (!entry.ranges || entry.ranges.length === 0) continue;
|
|
37770
|
+
const result = placeFootnote(entry.id, entry.ranges, true);
|
|
37771
|
+
if (!result.placed) {
|
|
37772
|
+
nextPending.push(entry);
|
|
37773
|
+
stopPlacement = true;
|
|
37774
|
+
continue;
|
|
37775
|
+
}
|
|
37776
|
+
if (result.remaining.length > 0) {
|
|
37777
|
+
nextPending.push({ id: entry.id, ranges: result.remaining });
|
|
37778
|
+
}
|
|
37779
|
+
}
|
|
37780
|
+
if (!stopPlacement) {
|
|
37781
|
+
const ids = idsByColumn2.get(pageIndex)?.get(columnIndex) ?? [];
|
|
37782
|
+
for (let idIndex = 0; idIndex < ids.length; idIndex += 1) {
|
|
37783
|
+
const id = ids[idIndex];
|
|
37784
|
+
const ranges = rangesByFootnoteId.get(id) ?? [];
|
|
37785
|
+
if (ranges.length === 0) continue;
|
|
37786
|
+
const result = placeFootnote(id, ranges, false);
|
|
37787
|
+
if (!result.placed) {
|
|
37788
|
+
nextPending.push({ id, ranges });
|
|
37789
|
+
for (let remainingIndex = idIndex + 1; remainingIndex < ids.length; remainingIndex += 1) {
|
|
37790
|
+
const remainingId = ids[remainingIndex];
|
|
37791
|
+
const remainingRanges = rangesByFootnoteId.get(remainingId) ?? [];
|
|
37792
|
+
nextPending.push({ id: remainingId, ranges: remainingRanges });
|
|
37793
|
+
}
|
|
37794
|
+
stopPlacement = true;
|
|
37795
|
+
break;
|
|
37796
|
+
}
|
|
37797
|
+
if (result.remaining.length > 0) {
|
|
37798
|
+
nextPending.push({ id, ranges: result.remaining });
|
|
37799
|
+
}
|
|
37800
|
+
}
|
|
37801
|
+
}
|
|
37802
|
+
if (columnSlices.length > 0) {
|
|
37803
|
+
const rawReserve = Math.max(0, Math.ceil(usedHeight));
|
|
37804
|
+
const cappedReserve = Math.min(rawReserve, maxReserve);
|
|
37805
|
+
if (cappedReserve < rawReserve) {
|
|
37806
|
+
cappedPages.add(pageIndex);
|
|
37807
|
+
}
|
|
37808
|
+
pageReserve = Math.max(pageReserve, cappedReserve);
|
|
37809
|
+
pageSlices.push(...columnSlices);
|
|
37810
|
+
}
|
|
37811
|
+
if (nextPending.length > 0) {
|
|
37812
|
+
pendingByColumn.set(columnIndex, nextPending);
|
|
37813
|
+
}
|
|
37814
|
+
}
|
|
37815
|
+
if (pageSlices.length > 0) {
|
|
37816
|
+
slicesByPage.set(pageIndex, pageSlices);
|
|
37817
|
+
}
|
|
37818
|
+
reserves2[pageIndex] = pageReserve;
|
|
37819
|
+
}
|
|
37820
|
+
if (cappedPages.size > 0) {
|
|
37821
|
+
console.warn("[layout] Footnote reserve capped to preserve body area", {
|
|
37822
|
+
pages: Array.from(cappedPages)
|
|
37823
|
+
});
|
|
37824
|
+
}
|
|
37825
|
+
if (pendingByColumn.size > 0) {
|
|
37826
|
+
const pendingIds = /* @__PURE__ */ new Set();
|
|
37827
|
+
pendingByColumn.forEach((entries) => entries.forEach((entry) => pendingIds.add(entry.id)));
|
|
37828
|
+
console.warn("[layout] Footnote content truncated: extends beyond document pages", {
|
|
37829
|
+
ids: Array.from(pendingIds)
|
|
37830
|
+
});
|
|
37831
|
+
}
|
|
37832
|
+
return { slicesByPage, reserves: reserves2, hasContinuationByColumn, separatorSpacingBefore: safeSeparatorSpacingBefore };
|
|
37833
|
+
};
|
|
37834
|
+
const injectFragments = (layoutForPages, plan2, measuresById2, reservesByPageIndex, blockById, pageColumns2) => {
|
|
37835
|
+
const decorativeBlocks = [];
|
|
37836
|
+
const decorativeMeasures = [];
|
|
37837
|
+
for (let pageIndex = 0; pageIndex < layoutForPages.pages.length; pageIndex++) {
|
|
37838
|
+
const page = layoutForPages.pages[pageIndex];
|
|
37839
|
+
page.footnoteReserved = Math.max(0, reservesByPageIndex[pageIndex] ?? plan2.reserves[pageIndex] ?? 0);
|
|
37840
|
+
const slices = plan2.slicesByPage.get(pageIndex) ?? [];
|
|
37841
|
+
if (slices.length === 0) continue;
|
|
37842
|
+
if (!page.margins) continue;
|
|
37843
|
+
const pageSize = page.size ?? layoutForPages.pageSize;
|
|
37844
|
+
const marginLeft = normalizeMargin(
|
|
37845
|
+
page.margins.left,
|
|
37846
|
+
normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
|
|
37847
|
+
);
|
|
37848
|
+
const marginRight = normalizeMargin(
|
|
37849
|
+
page.margins.right,
|
|
37850
|
+
normalizeMargin(options.margins?.right, DEFAULT_MARGINS$1.right)
|
|
37851
|
+
);
|
|
37852
|
+
const pageContentWidth = pageSize.w - (marginLeft + marginRight);
|
|
37853
|
+
const fallbackColumns = normalizeColumnsForFootnotes(
|
|
37854
|
+
options.columns ?? { count: 1, gap: 0 },
|
|
37855
|
+
pageContentWidth
|
|
37856
|
+
);
|
|
37857
|
+
const columns = pageColumns2.get(pageIndex) ?? {
|
|
37858
|
+
...fallbackColumns,
|
|
37859
|
+
left: marginLeft
|
|
37860
|
+
};
|
|
37861
|
+
const bandTopY = pageSize.h - (page.margins.bottom ?? 0);
|
|
37862
|
+
const slicesByColumn = /* @__PURE__ */ new Map();
|
|
37863
|
+
slices.forEach((slice2) => {
|
|
37864
|
+
const columnIndex = Number.isFinite(slice2.columnIndex) ? slice2.columnIndex : 0;
|
|
37865
|
+
const list = slicesByColumn.get(columnIndex) ?? [];
|
|
37866
|
+
list.push(slice2);
|
|
37867
|
+
slicesByColumn.set(columnIndex, list);
|
|
37868
|
+
});
|
|
37869
|
+
slicesByColumn.forEach((columnSlices, rawColumnIndex) => {
|
|
37870
|
+
if (columnSlices.length === 0) return;
|
|
37871
|
+
const columnIndex = Math.max(0, Math.min(columns.count - 1, rawColumnIndex));
|
|
37872
|
+
const columnStride = columns.width + columns.gap;
|
|
37873
|
+
const columnX = columns.left + columnIndex * columnStride;
|
|
37874
|
+
const contentWidth = Math.min(columns.width, footnoteWidth);
|
|
37875
|
+
if (!Number.isFinite(contentWidth) || contentWidth <= 0) return;
|
|
37876
|
+
const columnKey = footnoteColumnKey(pageIndex, columnIndex);
|
|
37877
|
+
const isContinuation = plan2.hasContinuationByColumn.get(columnKey) ?? false;
|
|
37878
|
+
let cursorY = bandTopY + Math.max(0, plan2.separatorSpacingBefore);
|
|
37879
|
+
const separatorHeight = isContinuation ? continuationDividerHeight : safeDividerHeight;
|
|
37880
|
+
const separatorWidth = isContinuation ? Math.max(0, contentWidth * continuationDividerWidthFactor) : contentWidth;
|
|
37881
|
+
if (separatorHeight > 0 && separatorWidth > 0) {
|
|
37882
|
+
const separatorId = isContinuation ? `footnote-continuation-separator-page-${page.number}-col-${columnIndex}` : `footnote-separator-page-${page.number}-col-${columnIndex}`;
|
|
37883
|
+
decorativeBlocks.push({
|
|
37884
|
+
kind: "drawing",
|
|
37885
|
+
id: separatorId,
|
|
37886
|
+
drawingKind: "vectorShape",
|
|
37887
|
+
geometry: { width: separatorWidth, height: separatorHeight },
|
|
37888
|
+
shapeKind: "rect",
|
|
37889
|
+
fillColor: "#000000",
|
|
37890
|
+
strokeColor: null,
|
|
37891
|
+
strokeWidth: 0
|
|
37892
|
+
});
|
|
37893
|
+
decorativeMeasures.push({
|
|
37894
|
+
kind: "drawing",
|
|
37895
|
+
drawingKind: "vectorShape",
|
|
37896
|
+
width: separatorWidth,
|
|
37897
|
+
height: separatorHeight,
|
|
37898
|
+
scale: 1,
|
|
37899
|
+
naturalWidth: separatorWidth,
|
|
37900
|
+
naturalHeight: separatorHeight,
|
|
37901
|
+
geometry: { width: separatorWidth, height: separatorHeight }
|
|
37902
|
+
});
|
|
37903
|
+
page.fragments.push({
|
|
37904
|
+
kind: "drawing",
|
|
37905
|
+
blockId: separatorId,
|
|
37906
|
+
drawingKind: "vectorShape",
|
|
37907
|
+
x: columnX,
|
|
37908
|
+
y: cursorY,
|
|
37909
|
+
width: separatorWidth,
|
|
37910
|
+
height: separatorHeight,
|
|
37911
|
+
geometry: { width: separatorWidth, height: separatorHeight },
|
|
37912
|
+
scale: 1
|
|
37913
|
+
});
|
|
37914
|
+
cursorY += separatorHeight;
|
|
37915
|
+
}
|
|
37916
|
+
cursorY += safeTopPadding;
|
|
37917
|
+
columnSlices.forEach((slice2, sliceIndex) => {
|
|
37918
|
+
slice2.ranges.forEach((range) => {
|
|
37919
|
+
if (range.kind === "paragraph") {
|
|
37920
|
+
const measure = measuresById2.get(range.blockId);
|
|
37921
|
+
if (!measure || measure.kind !== "paragraph") return;
|
|
37922
|
+
const marker = measure.marker;
|
|
37923
|
+
page.fragments.push({
|
|
37924
|
+
kind: "para",
|
|
37925
|
+
blockId: range.blockId,
|
|
37926
|
+
fromLine: range.fromLine,
|
|
37927
|
+
toLine: range.toLine,
|
|
37928
|
+
x: columnX,
|
|
37929
|
+
y: cursorY,
|
|
37930
|
+
width: contentWidth,
|
|
37931
|
+
continuesFromPrev: range.fromLine > 0,
|
|
37932
|
+
continuesOnNext: range.toLine < range.totalLines,
|
|
37933
|
+
...marker?.markerWidth != null ? { markerWidth: marker.markerWidth } : {},
|
|
37934
|
+
...marker?.markerTextWidth != null ? { markerTextWidth: marker.markerTextWidth } : {},
|
|
37935
|
+
...marker?.gutterWidth != null ? { markerGutter: marker.gutterWidth } : {}
|
|
37936
|
+
});
|
|
37937
|
+
cursorY += getRangeRenderHeight(range);
|
|
37938
|
+
return;
|
|
37939
|
+
}
|
|
37940
|
+
if (range.kind === "list-item") {
|
|
37941
|
+
const measure = measuresById2.get(range.blockId);
|
|
37942
|
+
const block = blockById.get(range.blockId);
|
|
37943
|
+
if (!measure || measure.kind !== "list") return;
|
|
37944
|
+
if (!block || block.kind !== "list") return;
|
|
37945
|
+
const itemMeasure = measure.items.find((entry) => entry.itemId === range.itemId);
|
|
37946
|
+
if (!itemMeasure) return;
|
|
37947
|
+
const indentLeft = Number.isFinite(itemMeasure.indentLeft) ? itemMeasure.indentLeft : 0;
|
|
37948
|
+
const markerWidth = Number.isFinite(itemMeasure.markerWidth) ? itemMeasure.markerWidth : 0;
|
|
37949
|
+
const itemWidth = Math.max(0, contentWidth - indentLeft - markerWidth);
|
|
37950
|
+
page.fragments.push({
|
|
37951
|
+
kind: "list-item",
|
|
37952
|
+
blockId: range.blockId,
|
|
37953
|
+
itemId: range.itemId,
|
|
37954
|
+
fromLine: range.fromLine,
|
|
37955
|
+
toLine: range.toLine,
|
|
37956
|
+
x: columnX + indentLeft + markerWidth,
|
|
37957
|
+
y: cursorY,
|
|
37958
|
+
width: itemWidth,
|
|
37959
|
+
markerWidth,
|
|
37960
|
+
continuesFromPrev: range.fromLine > 0,
|
|
37961
|
+
continuesOnNext: range.toLine < range.totalLines
|
|
37962
|
+
});
|
|
37963
|
+
cursorY += getRangeRenderHeight(range);
|
|
37964
|
+
return;
|
|
37965
|
+
}
|
|
37966
|
+
if (range.kind === "table") {
|
|
37967
|
+
const measure = measuresById2.get(range.blockId);
|
|
37968
|
+
const block = blockById.get(range.blockId);
|
|
37969
|
+
if (!measure || measure.kind !== "table") return;
|
|
37970
|
+
if (!block || block.kind !== "table") return;
|
|
37971
|
+
const tableWidthRaw = Math.max(0, measure.totalWidth ?? 0);
|
|
37972
|
+
let tableWidth = Math.min(contentWidth, tableWidthRaw);
|
|
37973
|
+
let tableX = columnX;
|
|
37974
|
+
const justification = typeof block.attrs?.justification === "string" ? block.attrs.justification : void 0;
|
|
37975
|
+
if (justification === "center") {
|
|
37976
|
+
tableX = columnX + Math.max(0, (contentWidth - tableWidth) / 2);
|
|
37977
|
+
} else if (justification === "right" || justification === "end") {
|
|
37978
|
+
tableX = columnX + Math.max(0, contentWidth - tableWidth);
|
|
37979
|
+
} else {
|
|
37980
|
+
const indentValue = block.attrs?.tableIndent?.width;
|
|
37981
|
+
const indent = typeof indentValue === "number" && Number.isFinite(indentValue) ? indentValue : 0;
|
|
37982
|
+
tableX += indent;
|
|
37983
|
+
tableWidth = Math.max(0, tableWidth - indent);
|
|
37984
|
+
}
|
|
37985
|
+
page.fragments.push({
|
|
37986
|
+
kind: "table",
|
|
37987
|
+
blockId: range.blockId,
|
|
37988
|
+
fromRow: 0,
|
|
37989
|
+
toRow: block.rows.length,
|
|
37990
|
+
x: tableX,
|
|
37991
|
+
y: cursorY,
|
|
37992
|
+
width: tableWidth,
|
|
37993
|
+
height: Math.max(0, measure.totalHeight ?? 0)
|
|
37994
|
+
});
|
|
37995
|
+
cursorY += getRangeRenderHeight(range);
|
|
37996
|
+
return;
|
|
37997
|
+
}
|
|
37998
|
+
if (range.kind === "image") {
|
|
37999
|
+
const measure = measuresById2.get(range.blockId);
|
|
38000
|
+
if (!measure || measure.kind !== "image") return;
|
|
38001
|
+
page.fragments.push({
|
|
38002
|
+
kind: "image",
|
|
38003
|
+
blockId: range.blockId,
|
|
38004
|
+
x: columnX,
|
|
38005
|
+
y: cursorY,
|
|
38006
|
+
width: Math.min(contentWidth, Math.max(0, measure.width ?? 0)),
|
|
38007
|
+
height: Math.max(0, measure.height ?? 0)
|
|
38008
|
+
});
|
|
38009
|
+
cursorY += getRangeRenderHeight(range);
|
|
38010
|
+
return;
|
|
38011
|
+
}
|
|
38012
|
+
if (range.kind === "drawing") {
|
|
38013
|
+
const measure = measuresById2.get(range.blockId);
|
|
38014
|
+
const block = blockById.get(range.blockId);
|
|
38015
|
+
if (!measure || measure.kind !== "drawing") return;
|
|
38016
|
+
if (!block || block.kind !== "drawing") return;
|
|
38017
|
+
page.fragments.push({
|
|
38018
|
+
kind: "drawing",
|
|
38019
|
+
blockId: range.blockId,
|
|
38020
|
+
drawingKind: block.drawingKind,
|
|
38021
|
+
x: columnX,
|
|
38022
|
+
y: cursorY,
|
|
38023
|
+
width: Math.min(contentWidth, Math.max(0, measure.width ?? 0)),
|
|
38024
|
+
height: Math.max(0, measure.height ?? 0),
|
|
38025
|
+
geometry: measure.geometry,
|
|
38026
|
+
scale: measure.scale
|
|
38027
|
+
});
|
|
38028
|
+
cursorY += getRangeRenderHeight(range);
|
|
38029
|
+
}
|
|
38030
|
+
});
|
|
38031
|
+
if (sliceIndex < columnSlices.length - 1) {
|
|
38032
|
+
cursorY += safeGap;
|
|
38033
|
+
}
|
|
38034
|
+
});
|
|
38035
|
+
});
|
|
38036
|
+
}
|
|
38037
|
+
return { decorativeBlocks, decorativeMeasures };
|
|
38038
|
+
};
|
|
38039
|
+
const resolveFootnoteAssignments = (layoutForPages) => {
|
|
38040
|
+
const columns = resolvePageColumns(layoutForPages, options, currentBlocks);
|
|
38041
|
+
const idsByColumn2 = assignFootnotesToColumns(layoutForPages, footnotesInput.refs, columns);
|
|
38042
|
+
return { columns, idsByColumn: idsByColumn2 };
|
|
38043
|
+
};
|
|
38044
|
+
let { columns: pageColumns, idsByColumn } = resolveFootnoteAssignments(layout);
|
|
38045
|
+
let { measuresById } = await measureFootnoteBlocks(collectFootnoteIdsByColumn(idsByColumn));
|
|
38046
|
+
let plan = computeFootnoteLayoutPlan(layout, idsByColumn, measuresById, [], pageColumns);
|
|
38047
|
+
let reserves = plan.reserves;
|
|
38048
|
+
if (reserves.some((h2) => h2 > 0)) {
|
|
38049
|
+
layout = layoutDocument(currentBlocks, currentMeasures, {
|
|
38050
|
+
...options,
|
|
38051
|
+
footnoteReservedByPageIndex: reserves,
|
|
38052
|
+
headerContentHeights,
|
|
38053
|
+
footerContentHeights,
|
|
38054
|
+
remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
|
|
38055
|
+
});
|
|
38056
|
+
({ columns: pageColumns, idsByColumn } = resolveFootnoteAssignments(layout));
|
|
38057
|
+
({ measuresById } = await measureFootnoteBlocks(collectFootnoteIdsByColumn(idsByColumn)));
|
|
38058
|
+
plan = computeFootnoteLayoutPlan(layout, idsByColumn, measuresById, reserves, pageColumns);
|
|
38059
|
+
reserves = plan.reserves;
|
|
38060
|
+
layout = layoutDocument(currentBlocks, currentMeasures, {
|
|
38061
|
+
...options,
|
|
38062
|
+
footnoteReservedByPageIndex: reserves,
|
|
38063
|
+
headerContentHeights,
|
|
38064
|
+
footerContentHeights,
|
|
38065
|
+
remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
|
|
38066
|
+
});
|
|
38067
|
+
let { columns: finalPageColumns, idsByColumn: finalIdsByColumn } = resolveFootnoteAssignments(layout);
|
|
38068
|
+
let { blocks: finalBlocks, measuresById: finalMeasuresById } = await measureFootnoteBlocks(
|
|
38069
|
+
collectFootnoteIdsByColumn(finalIdsByColumn)
|
|
38070
|
+
);
|
|
38071
|
+
let finalPlan = computeFootnoteLayoutPlan(
|
|
38072
|
+
layout,
|
|
38073
|
+
finalIdsByColumn,
|
|
38074
|
+
finalMeasuresById,
|
|
38075
|
+
reserves,
|
|
38076
|
+
finalPageColumns
|
|
38077
|
+
);
|
|
38078
|
+
const finalReserves = finalPlan.reserves;
|
|
38079
|
+
let reservesAppliedToLayout = reserves;
|
|
38080
|
+
const reservesDiffer = finalReserves.length !== reserves.length || finalReserves.some((h2, i) => (reserves[i] ?? 0) !== h2) || reserves.some((h2, i) => (finalReserves[i] ?? 0) !== h2);
|
|
38081
|
+
if (reservesDiffer) {
|
|
38082
|
+
layout = layoutDocument(currentBlocks, currentMeasures, {
|
|
38083
|
+
...options,
|
|
38084
|
+
footnoteReservedByPageIndex: finalReserves,
|
|
38085
|
+
headerContentHeights,
|
|
38086
|
+
footerContentHeights,
|
|
38087
|
+
remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
|
|
38088
|
+
});
|
|
38089
|
+
reservesAppliedToLayout = finalReserves;
|
|
38090
|
+
({ columns: finalPageColumns, idsByColumn: finalIdsByColumn } = resolveFootnoteAssignments(layout));
|
|
38091
|
+
({ blocks: finalBlocks, measuresById: finalMeasuresById } = await measureFootnoteBlocks(
|
|
38092
|
+
collectFootnoteIdsByColumn(finalIdsByColumn)
|
|
38093
|
+
));
|
|
38094
|
+
finalPlan = computeFootnoteLayoutPlan(
|
|
38095
|
+
layout,
|
|
38096
|
+
finalIdsByColumn,
|
|
38097
|
+
finalMeasuresById,
|
|
38098
|
+
reservesAppliedToLayout,
|
|
38099
|
+
finalPageColumns
|
|
38100
|
+
);
|
|
38101
|
+
}
|
|
38102
|
+
const blockById = /* @__PURE__ */ new Map();
|
|
38103
|
+
finalBlocks.forEach((block) => {
|
|
38104
|
+
blockById.set(block.id, block);
|
|
38105
|
+
});
|
|
38106
|
+
const injected = injectFragments(
|
|
38107
|
+
layout,
|
|
38108
|
+
finalPlan,
|
|
38109
|
+
finalMeasuresById,
|
|
38110
|
+
reservesAppliedToLayout,
|
|
38111
|
+
blockById,
|
|
38112
|
+
finalPageColumns
|
|
38113
|
+
);
|
|
38114
|
+
const alignedBlocks = [];
|
|
38115
|
+
const alignedMeasures = [];
|
|
38116
|
+
finalBlocks.forEach((block) => {
|
|
38117
|
+
const measure = finalMeasuresById.get(block.id);
|
|
38118
|
+
if (!measure) return;
|
|
38119
|
+
alignedBlocks.push(block);
|
|
38120
|
+
alignedMeasures.push(measure);
|
|
38121
|
+
});
|
|
38122
|
+
extraBlocks = injected ? alignedBlocks.concat(injected.decorativeBlocks) : alignedBlocks;
|
|
38123
|
+
extraMeasures = injected ? alignedMeasures.concat(injected.decorativeMeasures) : alignedMeasures;
|
|
38124
|
+
}
|
|
38125
|
+
}
|
|
38126
|
+
}
|
|
37209
38127
|
let headers;
|
|
37210
38128
|
let footers;
|
|
37211
38129
|
if (headerFooter?.constraints && (headerFooter.headerBlocks || headerFooter.footerBlocks)) {
|
|
@@ -37266,7 +38184,9 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
|
|
|
37266
38184
|
measures: currentMeasures,
|
|
37267
38185
|
dirty,
|
|
37268
38186
|
headers,
|
|
37269
|
-
footers
|
|
38187
|
+
footers,
|
|
38188
|
+
extraBlocks,
|
|
38189
|
+
extraMeasures
|
|
37270
38190
|
};
|
|
37271
38191
|
}
|
|
37272
38192
|
const DEFAULT_PAGE_SIZE$1 = { w: 612, h: 792 };
|
|
@@ -41305,6 +42225,7 @@ const ATOMIC_INLINE_TYPES = /* @__PURE__ */ new Set([
|
|
|
41305
42225
|
"lineBreak",
|
|
41306
42226
|
"page-number",
|
|
41307
42227
|
"total-page-number",
|
|
42228
|
+
"footnoteReference",
|
|
41308
42229
|
"passthroughInline",
|
|
41309
42230
|
"bookmarkEnd"
|
|
41310
42231
|
]);
|
|
@@ -46329,6 +47250,28 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
|
|
|
46329
47250
|
let partIndex = 0;
|
|
46330
47251
|
let tabOrdinal = 0;
|
|
46331
47252
|
let suppressedByVanish = false;
|
|
47253
|
+
const toSuperscriptDigits2 = (value) => {
|
|
47254
|
+
const map3 = {
|
|
47255
|
+
"0": "⁰",
|
|
47256
|
+
"1": "¹",
|
|
47257
|
+
"2": "²",
|
|
47258
|
+
"3": "³",
|
|
47259
|
+
"4": "⁴",
|
|
47260
|
+
"5": "⁵",
|
|
47261
|
+
"6": "⁶",
|
|
47262
|
+
"7": "⁷",
|
|
47263
|
+
"8": "⁸",
|
|
47264
|
+
"9": "⁹"
|
|
47265
|
+
};
|
|
47266
|
+
return String(value ?? "").split("").map((ch) => map3[ch] ?? ch).join("");
|
|
47267
|
+
};
|
|
47268
|
+
const resolveFootnoteDisplayNumber2 = (id) => {
|
|
47269
|
+
const key2 = id == null ? null : String(id);
|
|
47270
|
+
if (!key2) return null;
|
|
47271
|
+
const mapping = converterContext?.footnoteNumberById;
|
|
47272
|
+
const mapped = mapping && typeof mapping === "object" ? mapping[key2] : void 0;
|
|
47273
|
+
return typeof mapped === "number" && Number.isFinite(mapped) && mapped > 0 ? mapped : null;
|
|
47274
|
+
};
|
|
46332
47275
|
const nextId = () => partIndex === 0 ? baseBlockId : `${baseBlockId}-${partIndex}`;
|
|
46333
47276
|
const attachAnchorParagraphId = (block, anchorParagraphId) => {
|
|
46334
47277
|
const applicableKinds = /* @__PURE__ */ new Set(["drawing", "image", "table"]);
|
|
@@ -46374,6 +47317,34 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
|
|
|
46374
47317
|
});
|
|
46375
47318
|
};
|
|
46376
47319
|
const visitNode = (node, inheritedMarks = [], activeSdt, activeRunStyleId = null, activeRunProperties, activeHidden = false) => {
|
|
47320
|
+
if (node.type === "footnoteReference") {
|
|
47321
|
+
const mergedMarks = [...node.marks ?? [], ...inheritedMarks ?? []];
|
|
47322
|
+
const refPos = positions.get(node);
|
|
47323
|
+
const id = node.attrs?.id;
|
|
47324
|
+
const displayId = resolveFootnoteDisplayNumber2(id) ?? id ?? "*";
|
|
47325
|
+
const displayText = toSuperscriptDigits2(displayId);
|
|
47326
|
+
const run = textNodeToRun(
|
|
47327
|
+
{ type: "text", text: displayText },
|
|
47328
|
+
positions,
|
|
47329
|
+
defaultFont,
|
|
47330
|
+
defaultSize,
|
|
47331
|
+
[],
|
|
47332
|
+
// marks applied after linked styles/base defaults
|
|
47333
|
+
activeSdt,
|
|
47334
|
+
hyperlinkConfig,
|
|
47335
|
+
themeColors
|
|
47336
|
+
);
|
|
47337
|
+
const inlineStyleId = getInlineStyleId(mergedMarks);
|
|
47338
|
+
applyRunStyles2(run, inlineStyleId, activeRunStyleId);
|
|
47339
|
+
applyBaseRunDefaults(run, baseRunDefaults, defaultFont, defaultSize);
|
|
47340
|
+
applyMarksToRun(run, mergedMarks, hyperlinkConfig, themeColors);
|
|
47341
|
+
if (refPos) {
|
|
47342
|
+
run.pmStart = refPos.start;
|
|
47343
|
+
run.pmEnd = refPos.end;
|
|
47344
|
+
}
|
|
47345
|
+
currentRuns.push(run);
|
|
47346
|
+
return;
|
|
47347
|
+
}
|
|
46377
47348
|
if (activeHidden && node.type !== "run") {
|
|
46378
47349
|
suppressedByVanish = true;
|
|
46379
47350
|
return;
|
|
@@ -54774,12 +55745,36 @@ class PresentationEditor extends EventEmitter {
|
|
|
54774
55745
|
const sectionMetadata = [];
|
|
54775
55746
|
let blocks;
|
|
54776
55747
|
let bookmarks = /* @__PURE__ */ new Map();
|
|
55748
|
+
let converterContext = void 0;
|
|
54777
55749
|
try {
|
|
54778
55750
|
const converter2 = this.#editor.converter;
|
|
54779
|
-
const
|
|
55751
|
+
const footnoteNumberById = {};
|
|
55752
|
+
try {
|
|
55753
|
+
const seen = /* @__PURE__ */ new Set();
|
|
55754
|
+
let counter = 1;
|
|
55755
|
+
this.#editor?.state?.doc?.descendants?.((node) => {
|
|
55756
|
+
if (node?.type?.name !== "footnoteReference") return;
|
|
55757
|
+
const rawId = node?.attrs?.id;
|
|
55758
|
+
if (rawId == null) return;
|
|
55759
|
+
const key2 = String(rawId);
|
|
55760
|
+
if (!key2 || seen.has(key2)) return;
|
|
55761
|
+
seen.add(key2);
|
|
55762
|
+
footnoteNumberById[key2] = counter;
|
|
55763
|
+
counter += 1;
|
|
55764
|
+
});
|
|
55765
|
+
} catch {
|
|
55766
|
+
}
|
|
55767
|
+
try {
|
|
55768
|
+
if (converter2 && typeof converter2 === "object") {
|
|
55769
|
+
converter2["footnoteNumberById"] = footnoteNumberById;
|
|
55770
|
+
}
|
|
55771
|
+
} catch {
|
|
55772
|
+
}
|
|
55773
|
+
converterContext = converter2 ? {
|
|
54780
55774
|
docx: converter2.convertedXml,
|
|
54781
55775
|
numbering: converter2.numbering,
|
|
54782
|
-
linkedStyles: converter2.linkedStyles
|
|
55776
|
+
linkedStyles: converter2.linkedStyles,
|
|
55777
|
+
...Object.keys(footnoteNumberById).length ? { footnoteNumberById } : {}
|
|
54783
55778
|
} : void 0;
|
|
54784
55779
|
const atomNodeTypes = getAtomNodeTypes(this.#editor?.schema ?? null);
|
|
54785
55780
|
const positionMap = this.#editor?.state?.doc && docJson ? buildPositionMapFromPmDoc(this.#editor.state.doc, docJson) : null;
|
|
@@ -54807,13 +55802,20 @@ class PresentationEditor extends EventEmitter {
|
|
|
54807
55802
|
this.#handleLayoutError("render", new Error("toFlowBlocks returned undefined blocks"));
|
|
54808
55803
|
return;
|
|
54809
55804
|
}
|
|
54810
|
-
const
|
|
55805
|
+
const baseLayoutOptions = this.#resolveLayoutOptions(blocks, sectionMetadata);
|
|
55806
|
+
const footnotesLayoutInput = this.#buildFootnotesLayoutInput({
|
|
55807
|
+
converterContext,
|
|
55808
|
+
themeColors: this.#editor?.converter?.themeColors ?? void 0
|
|
55809
|
+
});
|
|
55810
|
+
const layoutOptions = footnotesLayoutInput ? { ...baseLayoutOptions, footnotes: footnotesLayoutInput } : baseLayoutOptions;
|
|
54811
55811
|
const previousBlocks = this.#layoutState.blocks;
|
|
54812
55812
|
const previousLayout = this.#layoutState.layout;
|
|
54813
55813
|
let layout;
|
|
54814
55814
|
let measures;
|
|
54815
55815
|
let headerLayouts;
|
|
54816
55816
|
let footerLayouts;
|
|
55817
|
+
let extraBlocks;
|
|
55818
|
+
let extraMeasures;
|
|
54817
55819
|
const headerFooterInput = this.#buildHeaderFooterInput();
|
|
54818
55820
|
try {
|
|
54819
55821
|
const result = await incrementalLayout(
|
|
@@ -54837,6 +55839,8 @@ class PresentationEditor extends EventEmitter {
|
|
|
54837
55839
|
return;
|
|
54838
55840
|
}
|
|
54839
55841
|
({ layout, measures } = result);
|
|
55842
|
+
extraBlocks = Array.isArray(result.extraBlocks) ? result.extraBlocks : void 0;
|
|
55843
|
+
extraMeasures = Array.isArray(result.extraMeasures) ? result.extraMeasures : void 0;
|
|
54840
55844
|
layout.pageGap = this.#getEffectivePageGap();
|
|
54841
55845
|
layout.layoutEpoch = layoutEpoch;
|
|
54842
55846
|
headerLayouts = result.headers;
|
|
@@ -54896,6 +55900,10 @@ class PresentationEditor extends EventEmitter {
|
|
|
54896
55900
|
footerBlocks.push(...rIdResult.blocks);
|
|
54897
55901
|
footerMeasures.push(...rIdResult.measures);
|
|
54898
55902
|
}
|
|
55903
|
+
if (extraBlocks && extraMeasures && extraBlocks.length === extraMeasures.length && extraBlocks.length > 0) {
|
|
55904
|
+
footerBlocks.push(...extraBlocks);
|
|
55905
|
+
footerMeasures.push(...extraMeasures);
|
|
55906
|
+
}
|
|
54899
55907
|
painter.setData?.(
|
|
54900
55908
|
blocks,
|
|
54901
55909
|
measures,
|
|
@@ -55182,6 +56190,123 @@ class PresentationEditor extends EventEmitter {
|
|
|
55182
56190
|
sectionMetadata
|
|
55183
56191
|
};
|
|
55184
56192
|
}
|
|
56193
|
+
#buildFootnotesLayoutInput({
|
|
56194
|
+
converterContext,
|
|
56195
|
+
themeColors
|
|
56196
|
+
}) {
|
|
56197
|
+
const footnoteNumberById = converterContext?.footnoteNumberById;
|
|
56198
|
+
const toSuperscriptDigits2 = (value) => {
|
|
56199
|
+
const map3 = {
|
|
56200
|
+
"0": "⁰",
|
|
56201
|
+
"1": "¹",
|
|
56202
|
+
"2": "²",
|
|
56203
|
+
"3": "³",
|
|
56204
|
+
"4": "⁴",
|
|
56205
|
+
"5": "⁵",
|
|
56206
|
+
"6": "⁶",
|
|
56207
|
+
"7": "⁷",
|
|
56208
|
+
"8": "⁸",
|
|
56209
|
+
"9": "⁹"
|
|
56210
|
+
};
|
|
56211
|
+
const str = String(value ?? "");
|
|
56212
|
+
return str.split("").map((ch) => map3[ch] ?? ch).join("");
|
|
56213
|
+
};
|
|
56214
|
+
const ensureFootnoteMarker = (blocks, id) => {
|
|
56215
|
+
const displayNumberRaw = footnoteNumberById && typeof footnoteNumberById === "object" ? footnoteNumberById[id] : void 0;
|
|
56216
|
+
const displayNumber = typeof displayNumberRaw === "number" && Number.isFinite(displayNumberRaw) && displayNumberRaw > 0 ? displayNumberRaw : 1;
|
|
56217
|
+
const firstParagraph = blocks.find((b2) => b2?.kind === "paragraph");
|
|
56218
|
+
if (!firstParagraph) return;
|
|
56219
|
+
const runs = Array.isArray(firstParagraph.runs) ? firstParagraph.runs : [];
|
|
56220
|
+
const markerText = toSuperscriptDigits2(displayNumber);
|
|
56221
|
+
const baseRun = runs.find((r2) => {
|
|
56222
|
+
const dataAttrs = r2.dataAttrs;
|
|
56223
|
+
if (dataAttrs?.["data-sd-footnote-number"]) return false;
|
|
56224
|
+
const pmStart = r2.pmStart;
|
|
56225
|
+
const pmEnd = r2.pmEnd;
|
|
56226
|
+
return typeof pmStart === "number" && Number.isFinite(pmStart) && typeof pmEnd === "number" && Number.isFinite(pmEnd);
|
|
56227
|
+
});
|
|
56228
|
+
const markerPmStart = baseRun?.pmStart ?? null;
|
|
56229
|
+
const markerPmEnd = markerPmStart != null ? baseRun?.pmEnd != null ? Math.max(markerPmStart, Math.min(baseRun.pmEnd, markerPmStart + markerText.length)) : markerPmStart + markerText.length : null;
|
|
56230
|
+
const alreadyHasMarker = runs.some((r2) => {
|
|
56231
|
+
const dataAttrs = r2.dataAttrs;
|
|
56232
|
+
return Boolean(dataAttrs?.["data-sd-footnote-number"]);
|
|
56233
|
+
});
|
|
56234
|
+
if (alreadyHasMarker) {
|
|
56235
|
+
if (markerPmStart != null && markerPmEnd != null) {
|
|
56236
|
+
const markerRun2 = runs.find((r2) => {
|
|
56237
|
+
const dataAttrs = r2.dataAttrs;
|
|
56238
|
+
return Boolean(dataAttrs?.["data-sd-footnote-number"]);
|
|
56239
|
+
});
|
|
56240
|
+
if (markerRun2) {
|
|
56241
|
+
if (markerRun2.pmStart == null) markerRun2.pmStart = markerPmStart;
|
|
56242
|
+
if (markerRun2.pmEnd == null) markerRun2.pmEnd = markerPmEnd;
|
|
56243
|
+
}
|
|
56244
|
+
}
|
|
56245
|
+
return;
|
|
56246
|
+
}
|
|
56247
|
+
const firstTextRun = runs.find((r2) => typeof r2.text === "string");
|
|
56248
|
+
const markerRun = {
|
|
56249
|
+
kind: "text",
|
|
56250
|
+
text: markerText,
|
|
56251
|
+
dataAttrs: {
|
|
56252
|
+
"data-sd-footnote-number": "true"
|
|
56253
|
+
},
|
|
56254
|
+
...markerPmStart != null ? { pmStart: markerPmStart } : {},
|
|
56255
|
+
...markerPmEnd != null ? { pmEnd: markerPmEnd } : {}
|
|
56256
|
+
};
|
|
56257
|
+
markerRun.fontFamily = typeof firstTextRun?.fontFamily === "string" ? firstTextRun.fontFamily : "Arial";
|
|
56258
|
+
markerRun.fontSize = typeof firstTextRun?.fontSize === "number" && Number.isFinite(firstTextRun.fontSize) ? firstTextRun.fontSize : 12;
|
|
56259
|
+
if (firstTextRun?.color != null) markerRun.color = firstTextRun.color;
|
|
56260
|
+
runs.unshift(markerRun);
|
|
56261
|
+
firstParagraph.runs = runs;
|
|
56262
|
+
};
|
|
56263
|
+
const state = this.#editor?.state;
|
|
56264
|
+
if (!state) return null;
|
|
56265
|
+
const converter = this.#editor?.converter;
|
|
56266
|
+
const importedFootnotes = Array.isArray(converter?.footnotes) ? converter.footnotes : [];
|
|
56267
|
+
if (importedFootnotes.length === 0) return null;
|
|
56268
|
+
const refs = [];
|
|
56269
|
+
const idsInUse = /* @__PURE__ */ new Set();
|
|
56270
|
+
state.doc.descendants((node, pos) => {
|
|
56271
|
+
if (node.type?.name !== "footnoteReference") return;
|
|
56272
|
+
const id = node.attrs?.id;
|
|
56273
|
+
if (id == null) return;
|
|
56274
|
+
const key2 = String(id);
|
|
56275
|
+
const insidePos = Math.min(pos + 1, state.doc.content.size);
|
|
56276
|
+
refs.push({ id: key2, pos: insidePos });
|
|
56277
|
+
idsInUse.add(key2);
|
|
56278
|
+
});
|
|
56279
|
+
if (refs.length === 0) return null;
|
|
56280
|
+
const blocksById = /* @__PURE__ */ new Map();
|
|
56281
|
+
idsInUse.forEach((id) => {
|
|
56282
|
+
const entry = importedFootnotes.find((f) => String(f?.id) === id);
|
|
56283
|
+
const content = entry?.content;
|
|
56284
|
+
if (!Array.isArray(content) || content.length === 0) return;
|
|
56285
|
+
try {
|
|
56286
|
+
const clonedContent = JSON.parse(JSON.stringify(content));
|
|
56287
|
+
const footnoteDoc = { type: "doc", content: clonedContent };
|
|
56288
|
+
const result = toFlowBlocks(footnoteDoc, {
|
|
56289
|
+
blockIdPrefix: `footnote-${id}-`,
|
|
56290
|
+
enableRichHyperlinks: true,
|
|
56291
|
+
themeColors,
|
|
56292
|
+
converterContext
|
|
56293
|
+
});
|
|
56294
|
+
if (result?.blocks?.length) {
|
|
56295
|
+
ensureFootnoteMarker(result.blocks, id);
|
|
56296
|
+
blocksById.set(id, result.blocks);
|
|
56297
|
+
}
|
|
56298
|
+
} catch {
|
|
56299
|
+
}
|
|
56300
|
+
});
|
|
56301
|
+
if (blocksById.size === 0) return null;
|
|
56302
|
+
return {
|
|
56303
|
+
refs,
|
|
56304
|
+
blocksById,
|
|
56305
|
+
gap: 2,
|
|
56306
|
+
topPadding: 4,
|
|
56307
|
+
dividerHeight: 1
|
|
56308
|
+
};
|
|
56309
|
+
}
|
|
55185
56310
|
#buildHeaderFooterInput() {
|
|
55186
56311
|
if (!this.#headerFooterAdapter) {
|
|
55187
56312
|
return null;
|
|
@@ -55371,7 +56496,8 @@ class PresentationEditor extends EventEmitter {
|
|
|
55371
56496
|
const fragments2 = slotPage2.fragments ?? [];
|
|
55372
56497
|
const pageHeight2 = page?.size?.h ?? layout.pageSize?.h ?? this.#layoutOptions.pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
|
|
55373
56498
|
const margins2 = pageMargins ?? layout.pages[0]?.margins ?? this.#layoutOptions.margins ?? DEFAULT_MARGINS;
|
|
55374
|
-
const
|
|
56499
|
+
const decorationMargins2 = kind === "footer" ? this.#stripFootnoteReserveFromBottomMargin(margins2, page ?? null) : margins2;
|
|
56500
|
+
const box2 = this.#computeDecorationBox(kind, decorationMargins2, pageHeight2);
|
|
55375
56501
|
const rawLayoutHeight2 = rIdLayout.layout.height ?? 0;
|
|
55376
56502
|
const metrics2 = this.#computeHeaderFooterMetrics(
|
|
55377
56503
|
kind,
|
|
@@ -55422,7 +56548,8 @@ class PresentationEditor extends EventEmitter {
|
|
|
55422
56548
|
const fragments = slotPage.fragments ?? [];
|
|
55423
56549
|
const pageHeight = page?.size?.h ?? layout.pageSize?.h ?? this.#layoutOptions.pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
|
|
55424
56550
|
const margins = pageMargins ?? layout.pages[0]?.margins ?? this.#layoutOptions.margins ?? DEFAULT_MARGINS;
|
|
55425
|
-
const
|
|
56551
|
+
const decorationMargins = kind === "footer" ? this.#stripFootnoteReserveFromBottomMargin(margins, page ?? null) : margins;
|
|
56552
|
+
const box = this.#computeDecorationBox(kind, decorationMargins, pageHeight);
|
|
55426
56553
|
const rawLayoutHeight = variant.layout.height ?? 0;
|
|
55427
56554
|
const metrics = this.#computeHeaderFooterMetrics(kind, rawLayoutHeight, box, pageHeight, margins.footer ?? 0);
|
|
55428
56555
|
const fallbackId = this.#headerFooterManager?.getVariantId(kind, headerFooterType);
|
|
@@ -55509,6 +56636,16 @@ class PresentationEditor extends EventEmitter {
|
|
|
55509
56636
|
return { x: left2, width, height, offset: offset2 };
|
|
55510
56637
|
}
|
|
55511
56638
|
}
|
|
56639
|
+
#stripFootnoteReserveFromBottomMargin(pageMargins, page) {
|
|
56640
|
+
const reserveRaw = page?.footnoteReserved;
|
|
56641
|
+
const reserve = typeof reserveRaw === "number" && Number.isFinite(reserveRaw) && reserveRaw > 0 ? reserveRaw : 0;
|
|
56642
|
+
if (!reserve) return pageMargins;
|
|
56643
|
+
const bottomRaw = pageMargins.bottom;
|
|
56644
|
+
const bottom2 = typeof bottomRaw === "number" && Number.isFinite(bottomRaw) ? bottomRaw : 0;
|
|
56645
|
+
const nextBottom = Math.max(0, bottom2 - reserve);
|
|
56646
|
+
if (nextBottom === bottom2) return pageMargins;
|
|
56647
|
+
return { ...pageMargins, bottom: nextBottom };
|
|
56648
|
+
}
|
|
55512
56649
|
/**
|
|
55513
56650
|
* Computes the expected header/footer section type for a page based on document configuration.
|
|
55514
56651
|
*
|
|
@@ -55573,7 +56710,8 @@ class PresentationEditor extends EventEmitter {
|
|
|
55573
56710
|
height: headerPayload?.hitRegion?.height ?? headerBox.height
|
|
55574
56711
|
});
|
|
55575
56712
|
const footerPayload = this.#footerDecorationProvider?.(page.number, margins, page);
|
|
55576
|
-
const
|
|
56713
|
+
const footerBoxMargins = this.#stripFootnoteReserveFromBottomMargin(margins, page);
|
|
56714
|
+
const footerBox = this.#computeDecorationBox("footer", footerBoxMargins, actualPageHeight);
|
|
55577
56715
|
this.#footerRegions.set(pageIndex, {
|
|
55578
56716
|
kind: "footer",
|
|
55579
56717
|
headerId: footerPayload?.headerId,
|
|
@@ -61474,6 +62612,109 @@ const CommentsMark = Mark.create({
|
|
|
61474
62612
|
return [CommentMarkName$1, Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
61475
62613
|
}
|
|
61476
62614
|
});
|
|
62615
|
+
const toSuperscriptDigits = (value) => {
|
|
62616
|
+
const map3 = {
|
|
62617
|
+
0: "⁰",
|
|
62618
|
+
1: "¹",
|
|
62619
|
+
2: "²",
|
|
62620
|
+
3: "³",
|
|
62621
|
+
4: "⁴",
|
|
62622
|
+
5: "⁵",
|
|
62623
|
+
6: "⁶",
|
|
62624
|
+
7: "⁷",
|
|
62625
|
+
8: "⁸",
|
|
62626
|
+
9: "⁹"
|
|
62627
|
+
};
|
|
62628
|
+
return String(value ?? "").split("").map((ch) => map3[ch] ?? ch).join("");
|
|
62629
|
+
};
|
|
62630
|
+
const resolveFootnoteDisplayNumber = (editor, id) => {
|
|
62631
|
+
const key2 = id == null ? null : String(id);
|
|
62632
|
+
if (!key2) return null;
|
|
62633
|
+
const map3 = editor?.converter?.footnoteNumberById;
|
|
62634
|
+
const mapped = map3 && typeof map3 === "object" ? map3[key2] : void 0;
|
|
62635
|
+
return typeof mapped === "number" && Number.isFinite(mapped) && mapped > 0 ? mapped : null;
|
|
62636
|
+
};
|
|
62637
|
+
class FootnoteReferenceNodeView {
|
|
62638
|
+
constructor(node, getPos, decorations, editor, htmlAttributes = {}) {
|
|
62639
|
+
this.node = node;
|
|
62640
|
+
this.getPos = getPos;
|
|
62641
|
+
this.editor = editor;
|
|
62642
|
+
this.dom = this.#renderDom(node, htmlAttributes);
|
|
62643
|
+
}
|
|
62644
|
+
#renderDom(node, htmlAttributes) {
|
|
62645
|
+
const el = document.createElement("sup");
|
|
62646
|
+
el.className = "sd-footnote-ref";
|
|
62647
|
+
el.setAttribute("contenteditable", "false");
|
|
62648
|
+
el.setAttribute("aria-label", "Footnote reference");
|
|
62649
|
+
Object.entries(htmlAttributes).forEach(([key2, value]) => {
|
|
62650
|
+
if (value != null && value !== false) {
|
|
62651
|
+
el.setAttribute(key2, String(value));
|
|
62652
|
+
}
|
|
62653
|
+
});
|
|
62654
|
+
const id = node?.attrs?.id;
|
|
62655
|
+
if (id != null) {
|
|
62656
|
+
el.setAttribute("data-footnote-id", String(id));
|
|
62657
|
+
const display = resolveFootnoteDisplayNumber(this.editor, id) ?? id;
|
|
62658
|
+
el.textContent = toSuperscriptDigits(display);
|
|
62659
|
+
} else {
|
|
62660
|
+
el.textContent = "*";
|
|
62661
|
+
}
|
|
62662
|
+
return el;
|
|
62663
|
+
}
|
|
62664
|
+
update(node) {
|
|
62665
|
+
const incomingType = node?.type?.name;
|
|
62666
|
+
const currentType = this.node?.type?.name;
|
|
62667
|
+
if (!incomingType || incomingType !== currentType) return false;
|
|
62668
|
+
this.node = node;
|
|
62669
|
+
const id = node?.attrs?.id;
|
|
62670
|
+
if (id != null) {
|
|
62671
|
+
this.dom.setAttribute("data-footnote-id", String(id));
|
|
62672
|
+
const display = resolveFootnoteDisplayNumber(this.editor, id) ?? id;
|
|
62673
|
+
this.dom.textContent = toSuperscriptDigits(display);
|
|
62674
|
+
} else {
|
|
62675
|
+
this.dom.removeAttribute("data-footnote-id");
|
|
62676
|
+
this.dom.textContent = "*";
|
|
62677
|
+
}
|
|
62678
|
+
return true;
|
|
62679
|
+
}
|
|
62680
|
+
}
|
|
62681
|
+
const FootnoteReference = Node$1.create({
|
|
62682
|
+
name: "footnoteReference",
|
|
62683
|
+
group: "inline",
|
|
62684
|
+
inline: true,
|
|
62685
|
+
atom: true,
|
|
62686
|
+
selectable: false,
|
|
62687
|
+
draggable: false,
|
|
62688
|
+
addOptions() {
|
|
62689
|
+
return {
|
|
62690
|
+
htmlAttributes: {
|
|
62691
|
+
"data-footnote-ref": "true"
|
|
62692
|
+
}
|
|
62693
|
+
};
|
|
62694
|
+
},
|
|
62695
|
+
addAttributes() {
|
|
62696
|
+
return {
|
|
62697
|
+
id: {
|
|
62698
|
+
default: null
|
|
62699
|
+
},
|
|
62700
|
+
customMarkFollows: {
|
|
62701
|
+
default: null
|
|
62702
|
+
}
|
|
62703
|
+
};
|
|
62704
|
+
},
|
|
62705
|
+
addNodeView() {
|
|
62706
|
+
return ({ node, editor, getPos, decorations }) => {
|
|
62707
|
+
const htmlAttributes = this.options.htmlAttributes;
|
|
62708
|
+
return new FootnoteReferenceNodeView(node, getPos, decorations, editor, htmlAttributes);
|
|
62709
|
+
};
|
|
62710
|
+
},
|
|
62711
|
+
parseDOM() {
|
|
62712
|
+
return [{ tag: "sup[data-footnote-id]" }];
|
|
62713
|
+
},
|
|
62714
|
+
renderDOM({ htmlAttributes }) {
|
|
62715
|
+
return ["sup", Attribute.mergeAttributes(this.options.htmlAttributes, htmlAttributes)];
|
|
62716
|
+
}
|
|
62717
|
+
});
|
|
61477
62718
|
let cache$1 = /* @__PURE__ */ new WeakMap();
|
|
61478
62719
|
function getParagraphContext(paragraph, startPos, helpers2, revision, compute) {
|
|
61479
62720
|
const cached = cache$1.get(paragraph);
|
|
@@ -75085,6 +76326,7 @@ const getStarterExtensions = () => {
|
|
|
75085
76326
|
CommentRangeStart,
|
|
75086
76327
|
CommentRangeEnd,
|
|
75087
76328
|
CommentReference,
|
|
76329
|
+
FootnoteReference,
|
|
75088
76330
|
Document,
|
|
75089
76331
|
FontFamily,
|
|
75090
76332
|
FontSize,
|