ooxml-ui 1.8.4 → 1.9.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.
Files changed (87) hide show
  1. package/dist/{chunk-CTPXTRDT.js → chunk-PH7IBZOZ.js} +1 -1
  2. package/dist/docx/columns-dialog.d.ts +1 -1
  3. package/dist/docx/editor-core.d.ts +2 -0
  4. package/dist/docx/page-controller.d.ts +3 -2
  5. package/dist/docx/print-drag-scroll.d.ts +7 -0
  6. package/dist/docx/print-editing-geometry.d.ts +2 -0
  7. package/dist/docx/print-editing-index.d.ts +30 -0
  8. package/dist/docx/print-editing.d.ts +12 -0
  9. package/dist/docx/print-keyboard-navigation.d.ts +18 -0
  10. package/dist/docx/print-layout-view.d.ts +6 -10
  11. package/dist/docx/print-layout.d.ts +2 -2
  12. package/dist/docx/print-picture.d.ts +1 -0
  13. package/dist/docx.js +677 -20
  14. package/dist/index.js +2 -2
  15. package/dist/pptx/{chunk-KMNNTEGF.cjs → chunk-BFZDO2DY.cjs} +429 -194
  16. package/dist/pptx/{chunk-VRFNAF3Q.mjs → chunk-F7BBPOVJ.mjs} +9 -0
  17. package/dist/pptx/{chunk-STXGHV25.cjs → chunk-HWW2UVUP.cjs} +161 -4
  18. package/dist/pptx/{chunk-GHFJ46NS.mjs → chunk-KBCKCW5M.mjs} +371 -161
  19. package/dist/pptx/{chunk-NVYVHNPD.mjs → chunk-MKVKISFW.mjs} +1 -1
  20. package/dist/pptx/{chunk-NKHPE4PS.cjs → chunk-PKDISDDZ.cjs} +2 -2
  21. package/dist/pptx/{chunk-SM3CWDIQ.cjs → chunk-QVYJB7G2.cjs} +9 -0
  22. package/dist/pptx/chunk-SABFKDRM.mjs +286 -0
  23. package/dist/pptx/dom/elements/image.d.ts.map +1 -1
  24. package/dist/pptx/dom/index.cjs +221 -213
  25. package/dist/pptx/dom/index.mjs +24 -16
  26. package/dist/pptx/i18n/index.cjs +6 -6
  27. package/dist/pptx/i18n/index.mjs +1 -1
  28. package/dist/pptx/i18n/translations-en.d.ts.map +1 -1
  29. package/dist/pptx/index.cjs +2834 -2766
  30. package/dist/pptx/index.mjs +4 -4
  31. package/dist/pptx/render/find-replace.d.ts +1 -1
  32. package/dist/pptx/render/find-replace.d.ts.map +1 -1
  33. package/dist/pptx/render/format-painter.cjs +5 -5
  34. package/dist/pptx/render/format-painter.mjs +2 -2
  35. package/dist/pptx/render/index.d.ts +3 -0
  36. package/dist/pptx/render/index.d.ts.map +1 -1
  37. package/dist/pptx/render/inspector-helpers.cjs +12 -12
  38. package/dist/pptx/render/inspector-helpers.d.ts.map +1 -1
  39. package/dist/pptx/render/inspector-helpers.mjs +1 -1
  40. package/dist/pptx/render/inspector-number.d.ts +15 -0
  41. package/dist/pptx/render/inspector-number.d.ts.map +1 -0
  42. package/dist/pptx/render/picture-frame.d.ts +52 -0
  43. package/dist/pptx/render/picture-frame.d.ts.map +1 -0
  44. package/dist/pptx/render/ribbon-home-commands.d.ts +11 -2
  45. package/dist/pptx/render/ribbon-home-commands.d.ts.map +1 -1
  46. package/dist/pptx/render/share-session.d.ts.map +1 -1
  47. package/dist/pptx/render/slide-operations.d.ts +2 -1
  48. package/dist/pptx/render/slide-operations.d.ts.map +1 -1
  49. package/dist/pptx/render/slide-package-clipboard.d.ts +31 -0
  50. package/dist/pptx/render/slide-package-clipboard.d.ts.map +1 -0
  51. package/dist/pptx/render/slide-sorter-context-menu.d.ts +3 -5
  52. package/dist/pptx/render/slide-sorter-context-menu.d.ts.map +1 -1
  53. package/dist/pptx/render/slide-sorter-state.d.ts +8 -1
  54. package/dist/pptx/render/slide-sorter-state.d.ts.map +1 -1
  55. package/dist/pptx/render/text-advanced.d.ts.map +1 -1
  56. package/dist/pptx/render/text-style-scope.d.ts +41 -1
  57. package/dist/pptx/render/text-style-scope.d.ts.map +1 -1
  58. package/dist/pptx/render/text-style-update.d.ts.map +1 -1
  59. package/dist/pptx/web-components/index.d.ts +2 -0
  60. package/dist/pptx/web-components/index.d.ts.map +1 -1
  61. package/dist/pptx/web-components/slide-clipboard.d.ts +14 -0
  62. package/dist/pptx/web-components/slide-clipboard.d.ts.map +1 -0
  63. package/dist/teams.js +1 -1
  64. package/dist/visio/format-pane-fields.d.ts +2 -0
  65. package/dist/visio/page-setup-action.d.ts +1 -1
  66. package/dist/visio/page-setup-dialog-form.d.ts +1 -1
  67. package/dist/visio/ribbon-action.d.ts +1 -1
  68. package/dist/visio/viewer-accessibility.d.ts +17 -0
  69. package/dist/visio/viewer-insert-dialog.d.ts +2 -1
  70. package/dist/visio/viewer-review.d.ts +2 -0
  71. package/dist/visio.js +304 -14
  72. package/dist/xlsx/commands/pivots.d.ts +2 -0
  73. package/dist/xlsx/commands/sparklines.d.ts +2 -0
  74. package/dist/xlsx/dialogs/help-dialogs.d.ts +2 -2
  75. package/dist/xlsx/dialogs/page-header.d.ts +4 -0
  76. package/dist/xlsx/dialogs/page-setup-tabs.d.ts +6 -1
  77. package/dist/xlsx/dialogs/pivots.d.ts +2 -0
  78. package/dist/xlsx/dialogs/print-preview.d.ts +2 -0
  79. package/dist/xlsx/dialogs/sparklines.d.ts +4 -0
  80. package/dist/xlsx/print-cell.d.ts +4 -0
  81. package/dist/xlsx/print-header.d.ts +7 -0
  82. package/dist/xlsx/print-pages.d.ts +4 -0
  83. package/dist/xlsx/print.d.ts +4 -12
  84. package/dist/xlsx.js +1078 -287
  85. package/package.json +3 -3
  86. package/dist/pptx/chunk-VD7HRMTA.mjs +0 -137
  87. /package/dist/{chunk-SUHT5S2P.js → chunk-SKYBYVYH.js} +0 -0
package/dist/docx.js CHANGED
@@ -10,7 +10,7 @@ import './chunk-SPNWHKSR.js';
10
10
  import { normalizeLocale, SUPPORTED_OFFICE_LOCALES, interpolate } from 'ooxml-core/i18n';
11
11
  import { createDocument, saveDocx, sectionsFromLayout, sectionLayoutJson, sectionsOf, pageSizeOf, columnPreset, applyPageSetup, withSection, computeListLabels, numberNotesInOrder, tocEntries, tableOfFiguresInstruction, findTableOfContents, ensureListDefinition, resolveNumberingLevel, equalColumnDraft, readColumnDraft, PAGE_SIZE_OPTIONS, PAGE_SIZES, readPageSetup, isRunHiddenForReview, resolveTableStyleFormatting, resolveParagraphFormatting, displayListLabel, setTitlePage, setLineNumbering, setVerticalAlign, setPageNumbering, ST_NumberFormat, unequalColumnPreset, setColumns, setOrientation, setPageSize, setMargins, lineSpacingLabel, formatNoteNumber, reviewDocumentFormatting, reviewFormattingWarnings, listRevisions, plainText, tocHyperlinks, DEFAULT_TOC_INSTRUCTION, tocBookmarks, buildTableOfContents, tocCaptionLabel, isFieldLocked, twips as twips$1, signedTwips, formatListNumber, columnTextWidth, validColumnDraft, validatePageSetup, presetOf, LIGATURE_VALUES, isLigatures, reviewRunFormatting, resolveRunFormatting, reviewParagraphFormatting, resolveThemeColorReference, lineSpacingValue, isStHighlightColor, transformCase, DEFAULT_TABLE_BORDERS, parseLineSpacingValue, twipsAttr, twipsFromPixels, headingLevel, isValidLanguageTag, WORD, isHeadingListKind, fieldName, lineSpacingOptions, halfPointsFromPoints, changeColumnWidth, changeColumnGap, createListDefinition, linkStylesToList, headingListLevels, documentStats } from 'ooxml-core/docx';
12
12
  import { Schema, DOMSerializer, Fragment } from 'prosemirror-model';
13
- import { markSpecs, imageNodeSpec, fieldMarkerNodeSpec, noteReferenceNodeSpec, pageBreakNodeSpec, hardBreakNodeSpec, commentHistoryAttributes, tableCellStyle, tableStyle, createToggleFormat, expectDefined, paragraphBoxCss, themeToCssVars, lightTheme, darkTheme, normalizeThemeMode, applyThemeColors, refreshWordYjsPresence, normalizeRibbonActions, DirtyState, isWordYjsRemoteTransaction, REMOTE_TRANSACTION_META, repairCollaborativeDocumentIds, HEADER_FOOTER_INPUT, restoreSectionParts, commentThreadsFromDoc, restoreNoteParts, CollaborationClient, createCollaborationIdGenerator, WordYjsCollaboration, sectionPartsJson, NotePartsStep, notePartsJson, SectionPartsStep, fitZoomPercent, hasChangeAtCursor, hasAnyChange, commentIdsAtSelection, commentAnchors, countWords, fieldGuardPlugin, trackChangesPlugin, wordYjsPresencePlugin, chartNodeSpec, placementClass, removeCommentThread, removeCommentAnchor, deleteComment, updateCommentThreads, addComment, toggleTrackChanges, goToNextChange, goToPreviousChange, rejectAllChanges, acceptAllChanges, rejectChangeAtCursor, acceptChangeAtCursor, goToComment, appendInlineNode, sameJson, sameRuns, PARAGRAPH_KEEP_KEYS, paragraphFromAttrs, parseBordersJson, isNavigableHref, wordYjsPluginKey, setReviewRecordingPreferences, nodeNumbering, paragraphFormattingRevision, inlineNodeRun, formattingRevision, insertWordHardBreak, paragraphAttrs, resolveCellVisuals, themeDrawing, ribbonActionIdForLabel, removeWordLink, fieldResultRanges, wordLinkRangeAt, ligatureCss as ligatureCss$1, wordYjsRedo, wordYjsUndo, runToInlineNodes as runToInlineNodes$1, backstageFocus, applyRunFormattingPatch, clearDirectRunFormatting, applyWordLink, ligatureStyle, wordHighlightColors, swatchColor, cssBorderSide, deleteFieldSelection, resolveComment, replyToComment, CollaborationAuthority } from 'ooxml-core/docx/ui';
13
+ import { markSpecs, imageNodeSpec, fieldMarkerNodeSpec, noteReferenceNodeSpec, pageBreakNodeSpec, hardBreakNodeSpec, commentHistoryAttributes, tableCellStyle, tableStyle, createToggleFormat, expectDefined, paragraphBoxCss, themeToCssVars, lightTheme, darkTheme, normalizeThemeMode, applyThemeColors, refreshWordYjsPresence, normalizeRibbonActions, DirtyState, isWordYjsRemoteTransaction, REMOTE_TRANSACTION_META, repairCollaborativeDocumentIds, HEADER_FOOTER_INPUT, restoreSectionParts, commentThreadsFromDoc, restoreNoteParts, CollaborationClient, createCollaborationIdGenerator, WordYjsCollaboration, sectionPartsJson, NotePartsStep, notePartsJson, SectionPartsStep, fitZoomPercent, hasChangeAtCursor, hasAnyChange, commentIdsAtSelection, commentAnchors, countWords, fieldGuardPlugin, tableStructureGuardPlugin, trackChangesPlugin, wordYjsPresencePlugin, chartNodeSpec, placementClass, removeCommentThread, removeCommentAnchor, deleteComment, updateCommentThreads, addComment, toggleTrackChanges, goToNextChange, goToPreviousChange, rejectAllChanges, acceptAllChanges, rejectChangeAtCursor, acceptChangeAtCursor, goToComment, appendInlineNode, sameJson, sameRuns, PARAGRAPH_KEEP_KEYS, paragraphFromAttrs, parseBordersJson, isNavigableHref, wordYjsPluginKey, setReviewRecordingPreferences, nodeNumbering, paragraphFormattingRevision, inlineNodeRun, formattingRevision, insertWordHardBreak, paragraphAttrs, resolveCellVisuals, themeDrawing, ribbonActionIdForLabel, removeWordLink, fieldResultRanges, wordLinkRangeAt, ligatureCss as ligatureCss$1, wordYjsRedo, wordYjsUndo, runToInlineNodes as runToInlineNodes$1, backstageFocus, applyRunFormattingPatch, clearDirectRunFormatting, applyWordLink, ligatureStyle, wordHighlightColors, swatchColor, cssBorderSide, deleteFieldSelection, resolveComment, replyToComment, CollaborationAuthority } from 'ooxml-core/docx/ui';
14
14
  export { CollaborationAuthority, CollaborationClient, RIBBON_ACTION_IDS, RIBBON_ACTION_LABELS, createCollaborationIdGenerator, darkTheme, isRibbonActionId, lightTheme, normalizeRibbonActions, repairCollaborativeDocumentIds, themeToCssVars } from 'ooxml-core/docx/ui';
15
15
  import { parseOmml, convertOmmlToLatex, convertOmmlToMathMl } from 'ooxml-core/math';
16
16
  import { PluginKey, EditorState, Plugin, NodeSelection, TextSelection, Selection } from 'prosemirror-state';
@@ -11528,6 +11528,7 @@ function createDropCapDialog(getView) {
11528
11528
  function createColumnsDialog(host) {
11529
11529
  const element = createDialogShell("Columns", "dve-format-dialog");
11530
11530
  const count = numberInput(1, 45, 1);
11531
+ const footnoteCount = numberInput(0, 2147483647, 1);
11531
11532
  const gap = numberInput(0, 22, 0.01);
11532
11533
  const width = document.createElement("output");
11533
11534
  const equal = checkbox("Equal column width");
@@ -11544,6 +11545,7 @@ function createColumnsDialog(host) {
11544
11545
  fieldset(
11545
11546
  "Columns",
11546
11547
  labelled("Number of columns", count),
11548
+ labelled("Footnote columns (0 matches section)", footnoteCount),
11547
11549
  row2(labelled("Column width (inches)", width), labelled("Column spacing (inches)", gap)),
11548
11550
  equal.wrapper,
11549
11551
  separator.wrapper,
@@ -11565,7 +11567,7 @@ function createColumnsDialog(host) {
11565
11567
  const spacing = Math.round(Number(gap.value) * 1440);
11566
11568
  const size = (total() - spacing * (number - 1)) / number;
11567
11569
  width.value = equal.input.checked && Number.isFinite(size) ? (size / 1440).toFixed(3) : "\u2014";
11568
- const valid = validCount() && (equal.input.checked ? gap.value !== "" && Number.isFinite(spacing) && spacing >= 0 && spacing <= 31680 && size >= 720 : draft.widths.length === number && validColumnDraft(draft, total()) && controls.every((control) => control.width.value !== "" && control.gap.value !== ""));
11570
+ const valid = validCount() && footnoteCount.value !== "" && Number.isInteger(Number(footnoteCount.value)) && Number(footnoteCount.value) >= 0 && Number(footnoteCount.value) <= 2147483647 && (equal.input.checked ? gap.value !== "" && Number.isFinite(spacing) && spacing >= 0 && spacing <= 31680 && size >= 720 : draft.widths.length === number && validColumnDraft(draft, total()) && controls.every((control) => control.width.value !== "" && control.gap.value !== ""));
11569
11571
  message.textContent = valid ? "" : "Enter whole columns and spacing that leaves at least 0.5 inch for each column.";
11570
11572
  localizeElement(message, locale);
11571
11573
  ok.disabled = !valid;
@@ -11623,6 +11625,7 @@ function createColumnsDialog(host) {
11623
11625
  validate();
11624
11626
  });
11625
11627
  gap.addEventListener("input", validate);
11628
+ footnoteCount.addEventListener("input", validate);
11626
11629
  equal.input.addEventListener("change", () => {
11627
11630
  if (!equal.input.checked && validCount()) {
11628
11631
  draft = equalColumnDraft(total(), Number(count.value), Math.round(Number(gap.value) * 1440));
@@ -11650,7 +11653,8 @@ function createColumnsDialog(host) {
11650
11653
  widthTwips: twips$1(value),
11651
11654
  ...i < draft.widths.length - 1 ? { spacingTwips: twips$1(draft.gaps[i]) } : {}
11652
11655
  }))
11653
- }
11656
+ },
11657
+ ...source.footnoteColumns === void 0 && Number(footnoteCount.value) === 0 ? [] : [Number(footnoteCount.value)]
11654
11658
  );
11655
11659
  hide();
11656
11660
  };
@@ -11678,6 +11682,7 @@ function createColumnsDialog(host) {
11678
11682
  element.replaceChildren(...content);
11679
11683
  localizeDialog(element, locale);
11680
11684
  count.value = String(source.columns.count);
11685
+ footnoteCount.value = String(source.footnoteColumns ?? 0);
11681
11686
  gap.value = String((source.columns.spacingTwips ?? 720) / 1440);
11682
11687
  equal.input.checked = source.columns.equalWidth;
11683
11688
  separator.input.checked = Boolean(source.columns.separator);
@@ -15365,12 +15370,16 @@ var PageController = class {
15365
15370
  this.dispatchSections(applyPageSetup(model, currentSectionIndex(view, model), values2));
15366
15371
  }
15367
15372
  /** Layout > More Columns, recorded as one undoable section edit. */
15368
- applyColumns(columns) {
15373
+ applyColumns(columns, footnoteColumns) {
15369
15374
  const view = this.host.view();
15370
15375
  if (!view?.editable || !this.host.canEditOutsideBody()) return;
15371
15376
  const model = this.host.model();
15372
15377
  this.dispatchSections(
15373
- withSection(model, currentSectionIndex(view, model), (section3) => ({ ...section3, columns }))
15378
+ withSection(model, currentSectionIndex(view, model), (section3) => ({
15379
+ ...section3,
15380
+ columns,
15381
+ ...footnoteColumns === void 0 ? {} : { footnoteColumns }
15382
+ }))
15374
15383
  );
15375
15384
  }
15376
15385
  /** Layout > Line Numbers options, recorded as one undoable section edit. */
@@ -15528,13 +15537,14 @@ var PageController = class {
15528
15537
  select2.value = String(percent);
15529
15538
  this.host.statusBar()?.setZoom(percent);
15530
15539
  }
15531
- /** Switches between the continuous editing surface and the paginated Print Layout render. */
15540
+ /** Switches between continuous and paginated presentations of the existing editor. */
15532
15541
  setViewMode(mode) {
15533
15542
  this.viewMode = mode;
15534
15543
  const printLayout = this.host.printLayout();
15535
15544
  printLayout?.setActive(mode === "print");
15536
15545
  const paper = this.host.paper();
15537
- if (paper) paper.hidden = mode === "print";
15546
+ if (paper) paper.hidden = false;
15547
+ this.host.printEditing?.(mode === "print");
15538
15548
  paper?.parentElement?.toggleAttribute("data-print-view", mode === "print");
15539
15549
  const toolbar = this.host.toolbar();
15540
15550
  const select2 = toolbar && findLocalizedControl(toolbar, "Layout view");
@@ -16226,7 +16236,7 @@ var EditorCore = class {
16226
16236
  columns: {
16227
16237
  section: () => this.pages.currentSection(),
16228
16238
  canEdit: () => !this.readOnly && !this.collab.active,
16229
- apply: (columns) => this.pages.applyColumns(columns)
16239
+ apply: (columns, footnoteColumns) => this.pages.applyColumns(columns, footnoteColumns)
16230
16240
  }
16231
16241
  });
16232
16242
  this.imageMedia = new ImageMediaCache(
@@ -16264,6 +16274,7 @@ var EditorCore = class {
16264
16274
  toolbar: () => this.shell.toolbar,
16265
16275
  statusBar: () => this.shell.chrome?.statusBar,
16266
16276
  printLayout: () => this.shell.printLayout,
16277
+ printEditing: (active) => this.shell.printEditing?.setActive(active),
16267
16278
  refreshControls: () => this.refreshControls()
16268
16279
  });
16269
16280
  }
@@ -16374,7 +16385,10 @@ var EditorCore = class {
16374
16385
  const { searchPanel, printLayout, review, chrome, toolbar } = this.shell;
16375
16386
  searchPanel?.refresh();
16376
16387
  if (review?.commentsOpen) review.commentsPanel.refresh();
16377
- if (this.pages.viewMode === "print") printLayout?.refreshCurrentPage();
16388
+ if (this.pages.viewMode === "print") {
16389
+ printLayout?.refreshCurrentPage();
16390
+ this.shell.printEditing?.refresh();
16391
+ }
16378
16392
  const status = refreshEditorControls(
16379
16393
  toolbar,
16380
16394
  this.targetView(),
@@ -16432,7 +16446,7 @@ var ribbon_polish_default = "/* Ribbon polish: distinct pressed state and Word's
16432
16446
  var document_default = ".dve-revision-insert {\n color: var(--dve-revision-color, inherit);\n text-decoration: underline;\n text-decoration-color: var(--dve-revision-color, currentColor);\n}\n.dve-revision-delete {\n color: var(--dve-revision-color, inherit);\n text-decoration: line-through;\n text-decoration-color: var(--dve-revision-color, currentColor);\n}\n/* Moved text, like Word: green, double underline at the destination, double strike at the source. */\n.dve-revision-move {\n --dve-revision-color: #2e7d32;\n text-decoration-style: double;\n}\n.ProseMirror .dve-revision-hidden {\n /* Review visibility takes precedence over picture/equation node-view display rules. */\n display: none !important;\n}\n[data-review-display]:not([data-review-display='all']) .dve-revision-insert,\n[data-review-display]:not([data-review-display='all']) .dve-revision-delete {\n color: inherit;\n text-decoration: none;\n}\n[data-review-display]:not([data-review-display='all']) .dve-comment-range {\n background: transparent;\n}\n.dve-revision-format-markup {\n outline: 1px dotted currentColor;\n outline-offset: 2px;\n}\n.dve-comment-range {\n background: rgba(255, 212, 0, 0.28);\n}\n.dve-paper {\n box-sizing: border-box;\n position: relative;\n flex: none;\n margin: 0 auto;\n background: var(--dve-page-color, #fff);\n color: #202124;\n box-shadow:\n 0 1px 3px #20212430,\n 0 4px 12px #20212420;\n outline: none;\n /* Single spacing and no paragraph gap unless the document's styles set them, as in Word. */\n font:\n 11pt/1.2 Calibri,\n Carlito,\n Arial,\n sans-serif;\n zoom: var(--dve-zoom, 1);\n}\n.dve-paper p {\n min-height: 1.2em;\n margin: 0;\n white-space: pre-wrap;\n}\n.dve-paper p:last-child {\n margin-bottom: 0;\n}\n/* The caret marks focus in the document, as in Word; no ring around the editable area. */\n.dve-paper .ProseMirror:focus,\n.dve-paper .ProseMirror:focus-visible {\n outline: none;\n}\n.dve-paper:focus {\n box-shadow:\n 0 1px 3px #20212430,\n 0 4px 12px #20212420,\n 0 0 0 1px var(--blue);\n}\n/* Columns follow the table's grid and cell widths (equal when it has none), as Word lays them out;\n tables add no space around themselves. */\n.dve-paper table {\n width: 100%;\n table-layout: fixed;\n border-collapse: collapse;\n margin: 0;\n}\n.dve-paper td {\n min-width: 44px;\n border: var(--dve-cell-border, 1px dashed #c8c6c4);\n vertical-align: top;\n}\n.dve-paper td p {\n margin: 0;\n}\n.dve-paper p[data-list-label]::before {\n content: attr(data-list-label);\n white-space: pre;\n user-select: none;\n}\n.dve-paper p[data-list-marker]:not([data-list-marker=''])::before {\n content: attr(data-list-marker);\n position: absolute;\n left: var(--dve-marker-left);\n text-indent: 0;\n font-family: var(--dve-marker-family);\n font-size: var(--dve-marker-size);\n font-weight: var(--dve-marker-weight);\n font-style: var(--dve-marker-style);\n color: var(--dve-marker-color);\n}\n.multilingual-controls {\n flex: 1 1 100%;\n align-items: flex-start;\n gap: 9px 14px;\n}\n.multilingual-language-control {\n display: grid;\n grid-template-columns: minmax(145px, 180px);\n gap: 4px;\n color: var(--muted);\n font-size: 11px;\n}\n.multilingual-language-control select,\n.multilingual-language-control input {\n box-sizing: border-box;\n width: 180px;\n}\n.multilingual-language-control input {\n height: 26px;\n border: 1px solid var(--line);\n border-radius: 3px;\n background: var(--surface);\n padding: 0 7px;\n color: var(--ink);\n font:\n 11px 'Segoe UI',\n Arial,\n sans-serif;\n}\n.multilingual-note {\n align-self: end;\n max-width: 240px;\n color: var(--muted);\n font-size: 11px;\n}\n@media (max-width: 650px) {\n .ribbon-panel {\n min-height: 96px;\n padding: 6px;\n gap: 4px;\n }\n .ribbon-group {\n padding-right: 7px;\n }\n .ribbon-panel[data-panel='Home'] .ribbon-group[data-label='Font'] {\n width: 340px;\n }\n .ribbon-panel[data-panel='Home'] .ribbon-group[data-label='Paragraph'] {\n width: 280px;\n }\n .ribbon-panel[data-panel='Home'] .ribbon-group[data-label='Editing'] {\n width: auto;\n }\n .ribbon-group button {\n min-width: 34px;\n min-height: 34px;\n }\n .ribbon-group select {\n max-width: min(150px, 42vw);\n }\n .dve-canvas {\n padding: 18px 8px 38px;\n align-items: flex-start;\n }\n .ribbon-group select.font-family-select {\n width: 120px;\n max-width: 38vw;\n }\n .ribbon-group select.font-size-select {\n width: 56px;\n }\n .ribbon-group select.spacing-select {\n width: min(128px, 36vw);\n }\n .ribbon-group select.line-spacing-select {\n width: min(112px, 32vw);\n }\n}\n.dve-break-marker {\n display: block;\n margin: 0.4em 0;\n padding: 2px 0;\n border-top: 1px dashed var(--muted);\n border-bottom: 1px dashed var(--muted);\n color: var(--muted);\n font-size: 10px;\n text-align: center;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n user-select: none;\n}\n.dve-note-reference {\n color: var(--blue);\n cursor: default;\n}\n.dve-header,\n.dve-footer {\n box-sizing: border-box;\n width: 816px;\n max-width: 100%;\n margin: 0 auto;\n padding: 10px clamp(16px, 5vw, 70px);\n background: var(--surface);\n color: var(--muted);\n font:\n 10pt/1.35 Calibri,\n Arial,\n sans-serif;\n}\n.dve-header {\n border-bottom: 1px dashed var(--line);\n}\n.dve-footer {\n border-top: 1px dashed var(--line);\n}\n.dve-header-footer-label {\n margin-bottom: 2px;\n color: var(--muted);\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n.dve-notes-container {\n box-sizing: border-box;\n width: 816px;\n max-width: 100%;\n margin: 12px auto 0;\n}\n.dve-notes {\n box-sizing: border-box;\n padding: 10px clamp(16px, 5vw, 70px);\n background: var(--surface);\n border-top: 1px solid var(--line);\n font:\n 10pt/1.35 Calibri,\n Arial,\n sans-serif;\n}\n.dve-notes-heading {\n margin: 0 0 6px;\n color: var(--ink);\n font-size: 12px;\n}\n.dve-note-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.dve-note-list li {\n display: flex;\n gap: 4px;\n align-items: baseline;\n margin-bottom: 4px;\n}\n.dve-note-marker {\n flex: none;\n color: var(--muted);\n}\n@media (prefers-reduced-motion: reduce) {\n * {\n scroll-behavior: auto !important;\n }\n}\n\n/* Print Layout: a read-only, paginated render kept beside the continuous\n editing surface (see print-layout.ts / print-layout-view.ts). */\n";
16433
16447
 
16434
16448
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/docx/styles/print.css?raw
16435
- var print_default = ".dve-print-pages {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n margin: 0 auto;\n zoom: var(--dve-zoom, 1);\n}\n.dve-print-pages[hidden] {\n display: none;\n}\n.dve-print-page {\n position: relative;\n flex: none;\n background: var(--dve-page-color, #fff);\n color: #202124;\n box-shadow:\n 0 1px 3px #20212430,\n 0 4px 12px #20212420;\n overflow: hidden;\n}\n.dve-print-column {\n position: absolute;\n z-index: 1;\n}\n/* Floating pictures sit in front of text unless anchored behind it (wp:anchor/@behindDoc). */\n.dve-print-float {\n z-index: 2;\n}\n.dve-print-float-behind {\n z-index: 0;\n}\n.dve-print-picture-missing {\n box-sizing: border-box;\n border: 1px dashed #8a8886;\n background: #f3f2f1;\n}\n.dve-print-chart {\n overflow: hidden;\n background: #fff;\n}\n.dve-print-chart > svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n.dve-print-chart-frame {\n display: grid;\n place-items: center;\n color: #605e5c;\n font-size: 11px;\n}\n.dve-print-block {\n position: absolute;\n left: 0;\n width: 100%;\n}\n.dve-print-line {\n position: absolute;\n left: 0;\n width: 100%;\n font:\n 11pt/1.2 Calibri,\n Arial,\n sans-serif;\n cursor: text;\n}\n.dve-print-line span {\n position: absolute;\n top: 0;\n}\n.dve-print-row {\n position: absolute;\n left: 0;\n width: 100%;\n}\n/* Cells sit at their grid positions; borders come from the document (Word prints no gridlines). */\n.dve-print-cell {\n position: absolute;\n top: 0;\n box-sizing: border-box;\n}\n.dve-print-cell-content {\n position: absolute;\n bottom: 0;\n}\n@media print {\n .dve-ribbon,\n .dve-status,\n .multilingual-controls {\n display: none !important;\n }\n .dve-canvas {\n overflow: visible !important;\n padding: 0 !important;\n }\n .dve-paper {\n display: none !important;\n }\n .dve-print-pages {\n gap: 0 !important;\n zoom: 1 !important;\n }\n .dve-print-page {\n /* Like Word, page colours are not printed unless asked for. */\n background: #fff !important;\n box-shadow: none !important;\n break-after: page;\n }\n}\n.dve-print-header,\n.dve-print-footer {\n position: absolute;\n color: var(--ink);\n font-size: 11pt;\n pointer-events: none;\n}\n.dve-print-header p,\n.dve-print-footer p {\n margin: 0;\n}\n.dve-print-header table,\n.dve-print-footer table {\n width: 100%;\n border-collapse: collapse;\n}\n\n/* Complex field begin/code/separate/end markers: kept in the document, never shown. */\n.dve-field-marker {\n display: inline;\n font-size: 0;\n}\n\n/* TOC entries link to hidden _Toc bookmarks; Word draws them in the entry's style, not as links. */\na.dve-link[data-anchor^='_Toc'] {\n color: inherit;\n text-decoration: none;\n}\n\n/* Tabs sized to Word's tab stops by tab-stops-view.ts; leaders fill the tab's width. */\n.dve-tab {\n display: inline-block;\n overflow: hidden;\n white-space: pre;\n vertical-align: baseline;\n text-indent: 0;\n}\n.dve-tab-leader-dot,\n.dve-tab-leader-middleDot {\n background-image: radial-gradient(circle, currentColor 0.8px, transparent 1.1px);\n background-size: 4px 4px;\n background-repeat: repeat-x;\n background-position: right 0 bottom 0.25em;\n}\n.dve-tab-leader-hyphen {\n background-image: linear-gradient(to right, currentColor 50%, transparent 50%);\n background-size: 6px 1px;\n background-repeat: repeat-x;\n background-position: right 0 bottom 0.4em;\n}\n.dve-tab-leader-underscore,\n.dve-tab-leader-heavy {\n border-bottom: 1px solid currentColor;\n}\n.dve-tab-leader-heavy {\n border-bottom-width: 2px;\n}\n\n/* Footnotes above the bottom margin; the separator is Word's 2-inch rule. */\n.dve-print-footnotes {\n position: absolute;\n z-index: 1;\n}\n.dve-print-footnote-separator {\n position: absolute;\n top: -7px;\n left: 0;\n width: 192px;\n border-top: 1px solid currentColor;\n}\n.dve-print-footnote {\n position: absolute;\n left: 0;\n width: 100%;\n}\n\n[data-print-view] .dve-notes-container {\n display: none;\n}\n\n/* Word draws superscript and subscript at about two thirds size without growing the line. */\n.dve-paper sup,\n.dve-paper sub {\n font-size: 0.65em;\n line-height: 0;\n}\n/* Exact-height rows clip content that does not fit, as Word does. */\n.dve-print-cell {\n overflow: hidden;\n}\n.dve-print-paragraph-frame {\n position: absolute;\n top: 0;\n box-sizing: border-box;\n}\n\n/* View > Multiple Pages: Print Layout's sheets sit side by side and wrap, instead of one column. */\n.dve-canvas[data-multipage] .dve-print-pages {\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: center;\n}\n\n/* Layout > Line Numbers: numbers in the left margin, one per printed line. */\n.dve-print-line-number {\n position: absolute;\n width: 40px;\n text-align: right;\n font:\n 10px 'Segoe UI',\n Arial,\n sans-serif;\n color: #444;\n pointer-events: none;\n}\n";
16449
+ var print_default = ".dve-print-pages {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n margin: 0 auto;\n zoom: var(--dve-zoom, 1);\n}\n.dve-print-pages[hidden] {\n display: none;\n}\n.dve-print-page {\n position: relative;\n flex: none;\n background: var(--dve-page-color, #fff);\n color: #202124;\n box-shadow:\n 0 1px 3px #20212430,\n 0 4px 12px #20212420;\n overflow: hidden;\n}\n.dve-print-column {\n position: absolute;\n z-index: 1;\n}\n/* Floating pictures sit in front of text unless anchored behind it (wp:anchor/@behindDoc). */\n.dve-print-float {\n z-index: 2;\n}\n.dve-print-float-behind {\n z-index: 0;\n}\n.dve-print-picture-missing {\n box-sizing: border-box;\n border: 1px dashed #8a8886;\n background: #f3f2f1;\n}\n.dve-print-chart {\n overflow: hidden;\n background: #fff;\n}\n.dve-print-chart > svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n.dve-print-chart-frame {\n display: grid;\n place-items: center;\n color: #605e5c;\n font-size: 11px;\n}\n.dve-print-block {\n position: absolute;\n left: 0;\n width: 100%;\n}\n.dve-print-line {\n position: absolute;\n left: 0;\n width: 100%;\n font:\n 11pt/1.2 Calibri,\n Arial,\n sans-serif;\n cursor: text;\n}\n.dve-print-line span {\n position: absolute;\n top: 0;\n}\n.dve-print-row {\n position: absolute;\n left: 0;\n width: 100%;\n}\n/* Cells sit at their grid positions; borders come from the document (Word prints no gridlines). */\n.dve-print-cell {\n position: absolute;\n top: 0;\n box-sizing: border-box;\n}\n.dve-print-cell-content {\n position: absolute;\n bottom: 0;\n}\n@media print {\n .dve-ribbon,\n .dve-status,\n .multilingual-controls {\n display: none !important;\n }\n .dve-canvas {\n overflow: visible !important;\n padding: 0 !important;\n }\n .dve-paper {\n display: none !important;\n }\n .dve-print-pages {\n gap: 0 !important;\n zoom: 1 !important;\n }\n .dve-print-page {\n /* Like Word, page colours are not printed unless asked for. */\n background: #fff !important;\n box-shadow: none !important;\n break-after: page;\n }\n}\n.dve-print-header,\n.dve-print-footer {\n position: absolute;\n color: var(--ink);\n font-size: 11pt;\n pointer-events: none;\n}\n.dve-print-header p,\n.dve-print-footer p {\n margin: 0;\n}\n.dve-print-header table,\n.dve-print-footer table {\n width: 100%;\n border-collapse: collapse;\n}\n\n/* Complex field begin/code/separate/end markers: kept in the document, never shown. */\n.dve-field-marker {\n display: inline;\n font-size: 0;\n}\n\n/* TOC entries link to hidden _Toc bookmarks; Word draws them in the entry's style, not as links. */\na.dve-link[data-anchor^='_Toc'] {\n color: inherit;\n text-decoration: none;\n}\n\n/* Tabs sized to Word's tab stops by tab-stops-view.ts; leaders fill the tab's width. */\n.dve-tab {\n display: inline-block;\n overflow: hidden;\n white-space: pre;\n vertical-align: baseline;\n text-indent: 0;\n}\n.dve-tab-leader-dot,\n.dve-tab-leader-middleDot {\n background-image: radial-gradient(circle, currentColor 0.8px, transparent 1.1px);\n background-size: 4px 4px;\n background-repeat: repeat-x;\n background-position: right 0 bottom 0.25em;\n}\n.dve-tab-leader-hyphen {\n background-image: linear-gradient(to right, currentColor 50%, transparent 50%);\n background-size: 6px 1px;\n background-repeat: repeat-x;\n background-position: right 0 bottom 0.4em;\n}\n.dve-tab-leader-underscore,\n.dve-tab-leader-heavy {\n border-bottom: 1px solid currentColor;\n}\n.dve-tab-leader-heavy {\n border-bottom-width: 2px;\n}\n\n/* Footnotes above the bottom margin; the separator is Word's 2-inch rule. */\n.dve-print-footnotes {\n position: absolute;\n z-index: 1;\n}\n.dve-print-footnote-separator {\n position: absolute;\n top: -7px;\n left: 0;\n width: 192px;\n border-top: 1px solid currentColor;\n}\n.dve-print-footnote-continuation-separator {\n width: 100%;\n}\n.dve-print-footnote {\n position: absolute;\n left: 0;\n width: 100%;\n}\n\n[data-print-view] .dve-notes-container {\n display: none;\n}\n\n/* Word draws superscript and subscript at about two thirds size without growing the line. */\n.dve-paper sup,\n.dve-paper sub {\n font-size: 0.65em;\n line-height: 0;\n}\n/* Exact-height rows clip content that does not fit, as Word does. */\n.dve-print-cell {\n overflow: hidden;\n}\n.dve-print-paragraph-frame {\n position: absolute;\n top: 0;\n box-sizing: border-box;\n}\n\n/* View > Multiple Pages: Print Layout's sheets sit side by side and wrap, instead of one column. */\n.dve-canvas[data-multipage] .dve-print-pages {\n flex-direction: row;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: center;\n}\n\n/* Layout > Line Numbers: numbers in the left margin, one per printed line. */\n.dve-print-line-number {\n position: absolute;\n width: 40px;\n text-align: right;\n font:\n 10px 'Segoe UI',\n Arial,\n sans-serif;\n color: #444;\n pointer-events: none;\n}\n\n/* Native input stays mounted while page geometry supplies the visible selection. */\n.dve-paper.dve-print-input {\n position: fixed;\n top: 0;\n left: 0;\n margin: 0;\n opacity: 0;\n max-height: 1px;\n overflow: hidden;\n pointer-events: none;\n z-index: -1;\n}\n.dve-print-pages {\n position: relative;\n}\n.dve-print-selection-layer {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 3;\n}\n.dve-print-caret,\n.dve-print-selection {\n position: absolute;\n pointer-events: none;\n}\n.dve-print-caret {\n background: currentColor;\n animation: dve-print-caret-blink 1s step-end infinite;\n}\n.dve-print-selection {\n background: Highlight;\n opacity: 0.3;\n}\n@keyframes dve-print-caret-blink {\n 50% {\n opacity: 0;\n }\n}\n@media print {\n .dve-print-input,\n .dve-print-selection-layer {\n display: none !important;\n }\n}\n";
16436
16450
 
16437
16451
  // raw-css:/home/runner/work/ooxml/ooxml/src/ui/src/docx/styles/chrome-titlebar.css?raw
16438
16452
  var chrome_titlebar_default = ".dve-frame {\n position: relative;\n border: 0;\n box-shadow: none;\n}\n.dve-icon {\n flex: none;\n}\n.dve-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 28px;\n height: 28px;\n padding: 0 6px;\n border: 0;\n border-radius: 4px;\n background: none;\n color: inherit;\n cursor: pointer;\n}\n.dve-icon-button:hover:not(:disabled),\n.dve-icon-button[aria-pressed='true'] {\n background: var(--word-soft);\n}\n.dve-icon-button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n/* Title bar: drawn by the shared office-ui-title-bar; these colour it. */\n.dve-titlebar {\n flex: none;\n --office-title-bar-height: 40px;\n --office-title-bar-background: var(--chrome);\n --office-title-bar-border: var(--line);\n --office-title-bar-mark-background: var(--word);\n --office-title-bar-mark-foreground: var(--dve-primary-foreground);\n}\n";
@@ -17013,6 +17027,17 @@ function chartElement(chart) {
17013
17027
  return element;
17014
17028
  }
17015
17029
  function pictureElement(object, pictureUrl) {
17030
+ if (object.noteSeparator) {
17031
+ const rule = document.createElement("span");
17032
+ rule.className = "dve-print-note-rule";
17033
+ Object.assign(rule.style, {
17034
+ position: "absolute",
17035
+ width: `${object.widthPx}px`,
17036
+ height: "1px",
17037
+ borderTop: "1px solid currentColor"
17038
+ });
17039
+ return rule;
17040
+ }
17016
17041
  if (object.chart) {
17017
17042
  const element2 = chartElement(object.chart);
17018
17043
  element2.classList.add("dve-print-picture");
@@ -17089,20 +17114,28 @@ function styleFragment(el, fragment) {
17089
17114
  function renderLine(line, blockId, hitboxes, pictureUrl) {
17090
17115
  const lineEl = document.createElement("div");
17091
17116
  lineEl.className = "dve-print-line";
17117
+ lineEl.dataset.blockId = blockId;
17118
+ lineEl.dataset.sourceStart = String(line.sourceStart);
17119
+ lineEl.dataset.sourceEnd = String(line.sourceEnd);
17092
17120
  lineEl.style.top = `${line.yPx}px`;
17093
17121
  lineEl.style.height = `${line.heightPx}px`;
17094
17122
  const fragments = [];
17095
17123
  for (const fragment of line.fragments) {
17096
17124
  if (fragment.object) {
17097
17125
  const picture = pictureElement(fragment.object, pictureUrl);
17126
+ if (fragment.color) picture.style.color = fragment.color;
17098
17127
  picture.style.left = `${fragment.xPx}px`;
17099
17128
  picture.style.top = `${fragment.topPx ?? 0}px`;
17129
+ picture.dataset.sourceStart = String(fragment.sourceStart ?? 0);
17130
+ picture.dataset.sourceEnd = String(fragment.sourceEnd ?? 0);
17100
17131
  lineEl.append(picture);
17101
17132
  fragments.push({ element: picture, fragment });
17102
17133
  continue;
17103
17134
  }
17104
17135
  if (fragment.leader) {
17105
17136
  const leader = leaderElement(fragment);
17137
+ leader.dataset.sourceStart = String(fragment.sourceStart ?? 0);
17138
+ leader.dataset.sourceEnd = String(fragment.sourceEnd ?? 0);
17106
17139
  lineEl.append(leader);
17107
17140
  fragments.push({ element: leader, fragment });
17108
17141
  continue;
@@ -17110,6 +17143,8 @@ function renderLine(line, blockId, hitboxes, pictureUrl) {
17110
17143
  if (!fragment.text && fragment.widthPx === 0) continue;
17111
17144
  const span = document.createElement("span");
17112
17145
  styleFragment(span, fragment);
17146
+ span.dataset.sourceStart = String(fragment.sourceStart ?? 0);
17147
+ span.dataset.sourceEnd = String(fragment.sourceEnd ?? 0);
17113
17148
  lineEl.append(span);
17114
17149
  fragments.push({ element: span, fragment });
17115
17150
  }
@@ -17144,6 +17179,12 @@ function renderBlock(box2, hitboxes, pictureUrl, columnWidthPx) {
17144
17179
  el.className = "dve-print-block";
17145
17180
  el.style.top = `${box2.yPx}px`;
17146
17181
  el.style.height = `${box2.heightPx}px`;
17182
+ if (box2.xPx !== void 0) el.style.left = `${box2.xPx}px`;
17183
+ if (box2.widthPx !== void 0) el.style.width = `${box2.widthPx}px`;
17184
+ if (box2.readOnly) {
17185
+ el.dataset.readOnly = "true";
17186
+ el.title = "Read-only nested table content";
17187
+ }
17147
17188
  if (box2.frame) el.append(paragraphFrame(box2.frame, box2.heightPx));
17148
17189
  for (const line of box2.lines) el.append(renderLine(line, box2.blockId, hitboxes, pictureUrl));
17149
17190
  return el;
@@ -17156,7 +17197,7 @@ function renderBlock(box2, hitboxes, pictureUrl, columnWidthPx) {
17156
17197
  }
17157
17198
  function footnoteArea(page2, hitboxes, pictureUrl) {
17158
17199
  const notes = page2.footnotes ?? [];
17159
- const heightPx = notes.reduce((sum, note) => sum + note.heightPx, 0);
17200
+ const heightPx = page2.footnoteHeightPx ?? notes.reduce((sum, note) => sum + note.heightPx, 0);
17160
17201
  const widthPx = page2.widthPx - page2.marginLeftPx - page2.marginRightPx;
17161
17202
  const area = document.createElement("div");
17162
17203
  area.className = "dve-print-footnotes";
@@ -17167,16 +17208,54 @@ function footnoteArea(page2, hitboxes, pictureUrl) {
17167
17208
  top: `${page2.heightPx - page2.marginBottomPx - heightPx}px`,
17168
17209
  height: `${heightPx}px`
17169
17210
  });
17170
- const separator = document.createElement("div");
17171
- separator.className = "dve-print-footnote-separator";
17172
- area.append(separator);
17211
+ const appendSeparator = (story, x, y, width, continued) => {
17212
+ const separator = document.createElement("div");
17213
+ if (story) {
17214
+ separator.className = "dve-print-custom-footnote-separator";
17215
+ Object.assign(separator.style, {
17216
+ position: "absolute",
17217
+ left: `${x}px`,
17218
+ top: `${y - story.heightPx}px`,
17219
+ width: `${width}px`,
17220
+ height: `${story.heightPx}px`
17221
+ });
17222
+ for (const paragraph2 of story.paragraphs)
17223
+ separator.append(renderBlock(paragraph2, [], pictureUrl, width));
17224
+ } else {
17225
+ separator.className = "dve-print-footnote-separator";
17226
+ if (continued) separator.classList.add("dve-print-footnote-continuation-separator");
17227
+ Object.assign(separator.style, {
17228
+ left: `${x}px`,
17229
+ top: `${y - 7}px`,
17230
+ width: `${continued ? width : Math.min(192, width)}px`
17231
+ });
17232
+ }
17233
+ area.append(separator);
17234
+ };
17235
+ if (page2.footnoteColumnAreas) {
17236
+ for (const column of page2.footnoteColumnAreas)
17237
+ appendSeparator(column.separator, column.xPx, column.yPx, column.widthPx, column.continued);
17238
+ } else
17239
+ appendSeparator(
17240
+ page2.footnoteSeparator,
17241
+ 0,
17242
+ 0,
17243
+ widthPx,
17244
+ notes.some((note) => note.continued)
17245
+ );
17173
17246
  for (const note of notes) {
17174
17247
  const noteEl = document.createElement("div");
17175
17248
  noteEl.className = "dve-print-footnote";
17176
17249
  noteEl.dataset.noteId = note.id;
17177
- Object.assign(noteEl.style, { top: `${note.yPx}px`, height: `${note.heightPx}px` });
17250
+ if (note.continued) noteEl.dataset.continued = "true";
17251
+ Object.assign(noteEl.style, {
17252
+ left: `${note.xPx ?? 0}px`,
17253
+ width: `${note.widthPx ?? widthPx}px`,
17254
+ top: `${note.yPx}px`,
17255
+ height: `${note.heightPx}px`
17256
+ });
17178
17257
  for (const paragraph2 of note.paragraphs)
17179
- noteEl.append(renderBlock(paragraph2, hitboxes, pictureUrl, widthPx));
17258
+ noteEl.append(renderBlock(paragraph2, hitboxes, pictureUrl, note.widthPx ?? widthPx));
17180
17259
  area.append(noteEl);
17181
17260
  }
17182
17261
  return area;
@@ -17268,7 +17347,7 @@ function renderPrintLayout(result, pictureUrl, options = {}) {
17268
17347
 
17269
17348
  // src/docx/print-layout-view.ts
17270
17349
  var RELAYOUT_DEBOUNCE_MS = 150;
17271
- function createPrintLayoutController(scrollContainer, onRequestCursor, pictureUrl, onLayout, getReviewMode = () => "all") {
17350
+ function createPrintLayoutController(scrollContainer, onRequestCursor, pictureUrl, onLayout, getReviewMode = () => "all", isEditing = () => false) {
17272
17351
  let measurer = createCanvasMeasurer();
17273
17352
  let lastModel = null;
17274
17353
  const fonts = typeof document === "undefined" ? void 0 : document.fonts;
@@ -17325,7 +17404,7 @@ function createPrintLayoutController(scrollContainer, onRequestCursor, pictureUr
17325
17404
  onLayout?.();
17326
17405
  }
17327
17406
  function onClick(event) {
17328
- if (!handle || !(event.target instanceof Element)) return;
17407
+ if (isEditing() || !handle || !(event.target instanceof Element)) return;
17329
17408
  const hit = handle.resolveClick(event.target, event.clientX);
17330
17409
  if (hit) onRequestCursor(hit.blockId, hit.offset);
17331
17410
  }
@@ -17350,6 +17429,7 @@ function createPrintLayoutController(scrollContainer, onRequestCursor, pictureUr
17350
17429
  }
17351
17430
  return {
17352
17431
  element,
17432
+ resolveClick: (target, clientX) => handle?.resolveClick(target, clientX) ?? null,
17353
17433
  setActive(active) {
17354
17434
  element.hidden = !active;
17355
17435
  },
@@ -17399,6 +17479,562 @@ function printLayoutResult(result, note) {
17399
17479
  window.print();
17400
17480
  style.remove();
17401
17481
  }
17482
+
17483
+ // src/docx/print-editing-geometry.ts
17484
+ function glyphRect(element, from2, to = from2) {
17485
+ const start = Number(element.dataset.sourceStart);
17486
+ const end = Number(element.dataset.sourceEnd);
17487
+ const text = element.firstChild;
17488
+ const box2 = element.getBoundingClientRect();
17489
+ if (text?.nodeType === Node.TEXT_NODE && end > start) {
17490
+ const length = text.textContent?.length ?? 0;
17491
+ const offset = (value) => Math.max(0, Math.min(length, Math.round((value - start) * length / (end - start))));
17492
+ const range = element.ownerDocument.createRange();
17493
+ range.setStart(text, offset(from2));
17494
+ range.setEnd(text, offset(to));
17495
+ if (typeof range.getBoundingClientRect === "function") {
17496
+ const measured = range.getBoundingClientRect();
17497
+ if (measured.height) return measured;
17498
+ }
17499
+ }
17500
+ const ratio = end > start ? Math.max(0, Math.min(1, (from2 - start) / (end - start))) : 0;
17501
+ const width = end > start ? box2.width * Math.max(0, Math.min(1, (to - from2) / (end - start))) : box2.width;
17502
+ return new DOMRect(box2.left + box2.width * ratio, box2.top, from2 === to ? 0 : width, box2.height);
17503
+ }
17504
+ function caretRect(line, offset) {
17505
+ const fragments = [...line.querySelectorAll("[data-source-start]")];
17506
+ const fragment = fragments.find(
17507
+ (el) => Number(el.dataset.sourceStart) <= offset && Number(el.dataset.sourceEnd) >= offset
17508
+ ) ?? fragments.at(-1);
17509
+ const rect = fragment ? glyphRect(fragment, offset) : line.getBoundingClientRect();
17510
+ const lineRect = line.getBoundingClientRect();
17511
+ return new DOMRect(fragment ? rect.left : lineRect.left, lineRect.top, 0, lineRect.height);
17512
+ }
17513
+
17514
+ // src/docx/print-keyboard-navigation.ts
17515
+ function printKeyboardNavigation(options) {
17516
+ const {
17517
+ active,
17518
+ getView,
17519
+ index,
17520
+ position,
17521
+ select: select2,
17522
+ resolveHit,
17523
+ scrollContainer,
17524
+ preferredPage,
17525
+ setPreferredPage
17526
+ } = options;
17527
+ let verticalX;
17528
+ return (event) => {
17529
+ const pageKey = event.key === "PageUp" || event.key === "PageDown";
17530
+ const boundaryKey = event.ctrlKey && (event.key === "Home" || event.key === "End");
17531
+ if (!active() || event.altKey || event.metaKey || event.ctrlKey && !pageKey && !boundaryKey || event.isComposing)
17532
+ return;
17533
+ const view = getView();
17534
+ if (!view || view.composing) return;
17535
+ if (boundaryKey) {
17536
+ index.update(view.state.doc);
17537
+ const boundary = (event.key === "Home" ? TextSelection.atStart(view.state.doc) : TextSelection.atEnd(view.state.doc)).head;
17538
+ const paragraph3 = index.at(boundary);
17539
+ if (paragraph3 && select2(paragraph3.id, boundary - paragraph3.start, event.shiftKey))
17540
+ event.preventDefault();
17541
+ return;
17542
+ }
17543
+ const keys2 = ["ArrowUp", "ArrowDown", "Home", "End", "PageUp", "PageDown"];
17544
+ if (!keys2.includes(event.key)) {
17545
+ verticalX = void 0;
17546
+ return;
17547
+ }
17548
+ index.update(view.state.doc);
17549
+ const head = view.state.selection.head;
17550
+ const paragraph2 = index.at(head);
17551
+ if (!paragraph2) return;
17552
+ const matches = index.block(paragraph2.id).filter(
17553
+ (line2) => head >= paragraph2.start + Number(line2.dataset.sourceStart) && head <= paragraph2.start + Number(line2.dataset.sourceEnd)
17554
+ );
17555
+ const line = matches.filter(
17556
+ (el) => el.closest(".dve-print-page")?.dataset.pageIndex === preferredPage()
17557
+ ).at(-1) ?? matches.at(-1);
17558
+ if (!line) return;
17559
+ let target = line;
17560
+ let offset;
17561
+ if (event.key === "Home" || event.key === "End") {
17562
+ verticalX = void 0;
17563
+ offset = event.key === "Home" ? Number(line.dataset.sourceStart) : Math.max(
17564
+ Number(line.dataset.sourceStart),
17565
+ ...[...line.querySelectorAll("[data-source-end]")].map(
17566
+ (fragment) => Number(fragment.dataset.sourceEnd)
17567
+ )
17568
+ );
17569
+ } else if (pageKey) {
17570
+ const direction = event.key === "PageUp" ? -1 : 1;
17571
+ verticalX ??= caretRect(line, head - paragraph2.start).left;
17572
+ if (event.ctrlKey) {
17573
+ target = index.pageStep(line, direction);
17574
+ offset = Number(target.dataset.sourceStart);
17575
+ } else {
17576
+ const viewport = scrollContainer.getBoundingClientRect(), caret = caretRect(line, head - paragraph2.start);
17577
+ const top = Math.max(0, viewport.top), bottom = Math.min(window.innerHeight, viewport.bottom);
17578
+ const y = event.shiftKey ? direction < 0 ? top + 1 : bottom - 1 : caret.top + direction * (bottom - top);
17579
+ target = index.nearest(verticalX, y) ?? line;
17580
+ offset = resolveHit(target, verticalX)?.offset ?? Number(target.dataset.sourceStart);
17581
+ if (!event.shiftKey) scrollContainer.scrollTop += direction * (bottom - top);
17582
+ }
17583
+ } else {
17584
+ const base = position(line.dataset.blockId, 0);
17585
+ verticalX ??= caretRect(line, head - base).left;
17586
+ target = index.adjacent(line, event.key === "ArrowUp" ? -1 : 1);
17587
+ offset = resolveHit(target, verticalX)?.offset ?? Number(target.dataset.sourceStart);
17588
+ }
17589
+ setPreferredPage(target.closest(".dve-print-page")?.dataset.pageIndex);
17590
+ if (select2(target.dataset.blockId, offset, event.shiftKey)) {
17591
+ event.preventDefault();
17592
+ target.scrollIntoView?.({ block: "nearest", inline: "nearest" });
17593
+ }
17594
+ };
17595
+ }
17596
+
17597
+ // src/docx/print-drag-scroll.ts
17598
+ function createPrintDragScroll(viewport, selectAt) {
17599
+ let frame, point, lastTime = 0, destroyed = false;
17600
+ function bounds() {
17601
+ const rect = viewport.getBoundingClientRect();
17602
+ return {
17603
+ left: rect.left,
17604
+ right: rect.right,
17605
+ top: Math.max(0, rect.top),
17606
+ bottom: Math.min(window.innerHeight, rect.bottom)
17607
+ };
17608
+ }
17609
+ function velocity(y, top, bottom) {
17610
+ const band = Math.min(32, (bottom - top) / 3);
17611
+ if (band <= 0) return 0;
17612
+ if (y < top + band) return -Math.min(24, 24 * (top + band - y) / band);
17613
+ if (y > bottom - band) return Math.min(24, 24 * (y - bottom + band) / band);
17614
+ return 0;
17615
+ }
17616
+ function tick(time) {
17617
+ frame = void 0;
17618
+ if (!point || destroyed) return;
17619
+ const box2 = bounds(), speed = velocity(point.y, box2.top, box2.bottom);
17620
+ if (!speed) return;
17621
+ const elapsed = lastTime ? Math.min(64, time - lastTime) : 16;
17622
+ lastTime = time;
17623
+ const old = viewport.scrollTop, max = Math.max(0, viewport.scrollHeight - viewport.clientHeight);
17624
+ viewport.scrollTop = Math.max(0, Math.min(max, old + speed * elapsed / 16));
17625
+ if (viewport.scrollTop === old) return;
17626
+ selectAt(
17627
+ Math.max(box2.left + 1, Math.min(box2.right - 1, point.x)),
17628
+ Math.max(box2.top + 1, Math.min(box2.bottom - 1, point.y))
17629
+ );
17630
+ frame = requestAnimationFrame(tick);
17631
+ }
17632
+ return {
17633
+ update(x, y) {
17634
+ if (destroyed) return;
17635
+ point = { x, y };
17636
+ const box2 = bounds();
17637
+ if (frame === void 0 && velocity(y, box2.top, box2.bottom)) {
17638
+ lastTime = 0;
17639
+ frame = requestAnimationFrame(tick);
17640
+ }
17641
+ },
17642
+ stop() {
17643
+ point = void 0;
17644
+ lastTime = 0;
17645
+ if (frame !== void 0) cancelAnimationFrame(frame);
17646
+ frame = void 0;
17647
+ },
17648
+ destroy() {
17649
+ this.stop();
17650
+ destroyed = true;
17651
+ }
17652
+ };
17653
+ }
17654
+
17655
+ // src/docx/print-editing-index.ts
17656
+ var PrintEditingIndex = class {
17657
+ constructor(pages) {
17658
+ this.pages = pages;
17659
+ }
17660
+ pages;
17661
+ doc;
17662
+ root;
17663
+ paragraphs = [];
17664
+ positions = /* @__PURE__ */ new Map();
17665
+ byBlock = /* @__PURE__ */ new Map();
17666
+ lines = [];
17667
+ renderedLines = [];
17668
+ pageLines = /* @__PURE__ */ new Map();
17669
+ linePositions = /* @__PURE__ */ new Map();
17670
+ update(doc) {
17671
+ const documentChanged = this.doc !== doc;
17672
+ if (documentChanged) {
17673
+ this.doc = doc;
17674
+ this.paragraphs = [];
17675
+ this.positions.clear();
17676
+ doc.descendants((node, pos) => {
17677
+ if (node.type.name !== "paragraph") return true;
17678
+ const paragraph2 = {
17679
+ id: String(node.attrs.id),
17680
+ start: pos + 1,
17681
+ end: pos + 1 + node.content.size
17682
+ };
17683
+ this.paragraphs.push(paragraph2);
17684
+ if (!this.positions.has(paragraph2.id)) this.positions.set(paragraph2.id, paragraph2);
17685
+ return false;
17686
+ });
17687
+ }
17688
+ const root = this.pages.firstElementChild;
17689
+ if (!documentChanged && root === this.root) return;
17690
+ if (root !== this.root)
17691
+ this.renderedLines = [
17692
+ ...this.pages.querySelectorAll(".dve-print-line[data-block-id]")
17693
+ ];
17694
+ this.root = root;
17695
+ this.byBlock.clear();
17696
+ this.pageLines.clear();
17697
+ this.linePositions.clear();
17698
+ this.lines = [];
17699
+ for (const line of this.renderedLines) {
17700
+ const id = line.dataset.blockId;
17701
+ if (!this.positions.has(id)) continue;
17702
+ const block = this.byBlock.get(id) ?? [];
17703
+ block.push(line);
17704
+ this.byBlock.set(id, block);
17705
+ const page2 = line.closest(".dve-print-page") ?? this.pages;
17706
+ const pageRows = this.pageLines.get(page2) ?? [];
17707
+ pageRows.push(line);
17708
+ this.pageLines.set(page2, pageRows);
17709
+ this.linePositions.set(line, this.lines.length);
17710
+ this.lines.push(line);
17711
+ }
17712
+ }
17713
+ position(id, offset) {
17714
+ const paragraph2 = this.positions.get(id);
17715
+ return paragraph2 ? paragraph2.start + Math.max(0, Math.min(offset, paragraph2.end - paragraph2.start)) : void 0;
17716
+ }
17717
+ firstEndingAtOrAfter(pos) {
17718
+ let low = 0, high = this.paragraphs.length;
17719
+ while (low < high) {
17720
+ const mid = low + high >>> 1;
17721
+ if (this.paragraphs[mid].end < pos) low = mid + 1;
17722
+ else high = mid;
17723
+ }
17724
+ return low;
17725
+ }
17726
+ *between(from2, to) {
17727
+ for (let i = this.firstEndingAtOrAfter(from2); i < this.paragraphs.length; i++) {
17728
+ const paragraph2 = this.paragraphs[i];
17729
+ if (paragraph2.start > to) break;
17730
+ yield paragraph2;
17731
+ }
17732
+ }
17733
+ at(pos) {
17734
+ const paragraph2 = this.paragraphs[this.firstEndingAtOrAfter(pos)];
17735
+ return paragraph2 && paragraph2.start <= pos ? paragraph2 : void 0;
17736
+ }
17737
+ block(id) {
17738
+ return this.byBlock.get(id) ?? [];
17739
+ }
17740
+ adjacent(line, direction) {
17741
+ return this.lines[(this.linePositions.get(line) ?? -1) + direction] ?? line;
17742
+ }
17743
+ pageStep(line, direction) {
17744
+ const page2 = line.closest(".dve-print-page") ?? this.pages;
17745
+ const pages = [...this.pageLines.keys()];
17746
+ return this.pageLines.get(pages[pages.indexOf(page2) + direction])?.[0] ?? line;
17747
+ }
17748
+ nearest(x, y) {
17749
+ const distance = (rect) => Math.hypot(
17750
+ Math.max(rect.left - x, x - rect.right, 0),
17751
+ Math.max(rect.top - y, y - rect.bottom, 0)
17752
+ );
17753
+ let bestPage, bestDistance = Infinity;
17754
+ for (const page2 of this.pageLines.keys()) {
17755
+ const score = distance(page2.getBoundingClientRect());
17756
+ if (score < bestDistance) {
17757
+ bestPage = page2;
17758
+ bestDistance = score;
17759
+ }
17760
+ }
17761
+ let best;
17762
+ bestDistance = Infinity;
17763
+ for (const line of this.pageLines.get(bestPage) ?? []) {
17764
+ const score = distance(line.getBoundingClientRect());
17765
+ if (score < bestDistance) {
17766
+ best = line;
17767
+ bestDistance = score;
17768
+ }
17769
+ }
17770
+ return best;
17771
+ }
17772
+ clear() {
17773
+ this.doc = void 0;
17774
+ this.root = void 0;
17775
+ this.paragraphs = [];
17776
+ this.positions.clear();
17777
+ this.pageLines.clear();
17778
+ this.byBlock.clear();
17779
+ this.lines = [];
17780
+ this.renderedLines = [];
17781
+ this.linePositions.clear();
17782
+ }
17783
+ };
17784
+ function createPrintEditingBridge(pages, paper, getView, resolveHit, scrollContainer = pages.parentElement ?? pages) {
17785
+ let active = false;
17786
+ let destroyed = false;
17787
+ const listeners = new AbortController();
17788
+ const index = new PrintEditingIndex(pages);
17789
+ const dragScroll = createPrintDragScroll(scrollContainer, extendAt);
17790
+ let nativeX = 0;
17791
+ let nativeY = 0;
17792
+ let dragging = false;
17793
+ let previousDoc;
17794
+ let previousHead = -1;
17795
+ let preferredPage;
17796
+ const overlay = document.createElement("div");
17797
+ overlay.className = "dve-print-selection-layer";
17798
+ overlay.setAttribute("aria-hidden", "true");
17799
+ let frame;
17800
+ function position(blockId, offset) {
17801
+ const view = getView();
17802
+ if (!view || view.isDestroyed || destroyed) return void 0;
17803
+ index.update(view.state.doc);
17804
+ return index.position(blockId, offset);
17805
+ }
17806
+ function addBox(rect, caret = false) {
17807
+ const parent = pages.getBoundingClientRect();
17808
+ const element = document.createElement("div");
17809
+ element.className = caret ? "dve-print-caret" : "dve-print-selection";
17810
+ const scale = pages.offsetWidth ? parent.width / pages.offsetWidth : 1;
17811
+ Object.assign(element.style, {
17812
+ left: `${(rect.left - parent.left) / (scale || 1)}px`,
17813
+ top: `${(rect.top - parent.top) / (scale || 1)}px`,
17814
+ width: `${caret ? 1 : rect.width / (scale || 1)}px`,
17815
+ height: `${rect.height / (scale || 1)}px`
17816
+ });
17817
+ overlay.append(element);
17818
+ return element;
17819
+ }
17820
+ function draw() {
17821
+ frame = void 0;
17822
+ overlay.replaceChildren();
17823
+ if (destroyed || !active || pages.hidden) return;
17824
+ const view = getView();
17825
+ if (!view || view.isDestroyed) return;
17826
+ if (!overlay.isConnected) pages.append(overlay);
17827
+ if (!view.dom.hasAttribute("tabindex")) {
17828
+ view.dom.tabIndex = 0;
17829
+ view.dom.dataset.printTabstop = "true";
17830
+ }
17831
+ const { from: from2, to, head, empty } = view.state.selection;
17832
+ let caret;
17833
+ index.update(view.state.doc);
17834
+ for (const { id, start, end } of index.between(from2, to)) {
17835
+ const block = index.block(id);
17836
+ if (head >= start && head <= end) {
17837
+ const offset = head - start;
17838
+ const candidates = block.filter(
17839
+ (el) => Number(el.dataset.sourceStart) <= offset && Number(el.dataset.sourceEnd) >= offset
17840
+ );
17841
+ const line = candidates.filter(
17842
+ (el) => el.closest(".dve-print-page")?.dataset.pageIndex === preferredPage
17843
+ ).at(-1) ?? candidates.at(-1);
17844
+ if (line) caret = caretRect(line, offset);
17845
+ }
17846
+ if (!empty && from2 <= end && to >= start) {
17847
+ for (const line of block) {
17848
+ const a = Math.max(from2 - start, Number(line.dataset.sourceStart));
17849
+ const b = Math.min(to - start, Number(line.dataset.sourceEnd));
17850
+ if (b <= a) continue;
17851
+ for (const fragment of line.querySelectorAll("[data-source-start]")) {
17852
+ const low = Math.max(a, Number(fragment.dataset.sourceStart));
17853
+ const high = Math.min(b, Number(fragment.dataset.sourceEnd));
17854
+ if (high > low) addBox(glyphRect(fragment, low, high));
17855
+ }
17856
+ }
17857
+ }
17858
+ }
17859
+ if (caret && view.hasFocus()) {
17860
+ const marker = addBox(caret, true);
17861
+ if (!empty) {
17862
+ marker.style.background = "transparent";
17863
+ marker.style.animation = "none";
17864
+ }
17865
+ if (!dragging && !view.composing && (previousDoc !== view.state.doc || previousHead !== head))
17866
+ marker.scrollIntoView?.({ block: "nearest", inline: "nearest" });
17867
+ previousDoc = view.state.doc;
17868
+ previousHead = head;
17869
+ if (!view.composing) {
17870
+ try {
17871
+ const source = view.coordsAtPos(head);
17872
+ const inputScale = paper.offsetWidth ? paper.getBoundingClientRect().width / paper.offsetWidth : 1;
17873
+ nativeX += (caret.left - source.left) / (inputScale || 1);
17874
+ nativeY += (caret.top - source.top) / (inputScale || 1);
17875
+ paper.style.translate = `${nativeX}px ${nativeY}px`;
17876
+ } catch {
17877
+ }
17878
+ }
17879
+ }
17880
+ }
17881
+ function refresh() {
17882
+ if (destroyed) return;
17883
+ if (frame !== void 0) cancelAnimationFrame(frame);
17884
+ frame = requestAnimationFrame(draw);
17885
+ }
17886
+ function select2(blockId, offset, extend = false) {
17887
+ const view = getView(), target = position(blockId, offset);
17888
+ if (!view || target === void 0) return false;
17889
+ view.dispatch(
17890
+ view.state.tr.setSelection(
17891
+ TextSelection.create(view.state.doc, extend ? view.state.selection.anchor : target, target)
17892
+ )
17893
+ );
17894
+ if (!view.dom.hasAttribute("tabindex")) {
17895
+ view.dom.tabIndex = 0;
17896
+ view.dom.dataset.printTabstop = "true";
17897
+ }
17898
+ view.focus();
17899
+ refresh();
17900
+ return true;
17901
+ }
17902
+ function hit(event) {
17903
+ const root = pages.getRootNode();
17904
+ const target = root.elementFromPoint?.(event.clientX, event.clientY);
17905
+ const line = target?.closest(".dve-print-line[data-block-id]");
17906
+ if (!line || !pages.contains(line)) return void 0;
17907
+ preferredPage = line.closest(".dve-print-page")?.dataset.pageIndex;
17908
+ return resolveHit(target, event.clientX) ?? void 0;
17909
+ }
17910
+ function extendAt(x, y) {
17911
+ const view = getView();
17912
+ if (!view || view.isDestroyed) return;
17913
+ index.update(view.state.doc);
17914
+ const line = index.nearest(x, y);
17915
+ if (!line) return;
17916
+ const target = resolveHit(line, x);
17917
+ if (!target) return;
17918
+ preferredPage = line.closest(".dve-print-page")?.dataset.pageIndex;
17919
+ select2(target.blockId, target.offset, true);
17920
+ }
17921
+ function move(event) {
17922
+ if (!dragging) return;
17923
+ extendAt(event.clientX, event.clientY);
17924
+ dragScroll.update(event.clientX, event.clientY);
17925
+ }
17926
+ function up() {
17927
+ dragging = false;
17928
+ dragScroll.stop();
17929
+ window.removeEventListener("pointermove", move);
17930
+ window.removeEventListener("pointerup", up);
17931
+ window.removeEventListener("pointercancel", up);
17932
+ window.removeEventListener("blur", up);
17933
+ }
17934
+ pages.addEventListener(
17935
+ "pointerdown",
17936
+ (event) => {
17937
+ if (!active || event.button !== 0) return;
17938
+ if (event.target instanceof Element && event.target.closest('[data-read-only="true"]')) {
17939
+ getView()?.dom.blur();
17940
+ return;
17941
+ }
17942
+ const target = hit(event);
17943
+ if (!target || !select2(target.blockId, target.offset, event.shiftKey)) return;
17944
+ event.preventDefault();
17945
+ dragging = true;
17946
+ window.addEventListener("pointermove", move);
17947
+ window.addEventListener("pointerup", up);
17948
+ window.addEventListener("pointercancel", up);
17949
+ window.addEventListener("blur", up);
17950
+ dragScroll.update(event.clientX, event.clientY);
17951
+ },
17952
+ { signal: listeners.signal }
17953
+ );
17954
+ paper.addEventListener(
17955
+ "keydown",
17956
+ printKeyboardNavigation({
17957
+ active: () => active,
17958
+ getView,
17959
+ index,
17960
+ position,
17961
+ select: select2,
17962
+ resolveHit,
17963
+ scrollContainer,
17964
+ preferredPage: () => preferredPage,
17965
+ setPreferredPage: (page2) => {
17966
+ preferredPage = page2;
17967
+ }
17968
+ }),
17969
+ { capture: true, signal: listeners.signal }
17970
+ );
17971
+ pages.addEventListener(
17972
+ "dblclick",
17973
+ (event) => {
17974
+ if (!active || !(event.target instanceof Element)) return;
17975
+ const target = resolveHit(event.target, event.clientX);
17976
+ const view = getView();
17977
+ const pos = target ? position(target.blockId, target.offset) : void 0;
17978
+ if (!view || pos === void 0) return;
17979
+ const resolved = view.state.doc.resolve(pos);
17980
+ const text = resolved.parent.textBetween(0, resolved.parent.content.size, "", "\uFFFC");
17981
+ const word = [...new Intl.Segmenter(void 0, { granularity: "word" }).segment(text)].find(
17982
+ (part) => part.isWordLike && resolved.parentOffset >= part.index && resolved.parentOffset <= part.index + part.segment.length
17983
+ );
17984
+ if (!word) return;
17985
+ view.dispatch(
17986
+ view.state.tr.setSelection(
17987
+ TextSelection.create(
17988
+ view.state.doc,
17989
+ resolved.start() + word.index,
17990
+ resolved.start() + word.index + word.segment.length
17991
+ )
17992
+ )
17993
+ );
17994
+ view.focus();
17995
+ refresh();
17996
+ event.preventDefault();
17997
+ },
17998
+ { signal: listeners.signal }
17999
+ );
18000
+ paper.addEventListener("focusin", refresh, { signal: listeners.signal });
18001
+ paper.addEventListener("focusout", refresh, { signal: listeners.signal });
18002
+ paper.addEventListener("compositionend", refresh, { signal: listeners.signal });
18003
+ return {
18004
+ setActive(value) {
18005
+ if (destroyed) return;
18006
+ active = value;
18007
+ paper.classList.toggle("dve-print-input", value);
18008
+ if (!value) {
18009
+ up();
18010
+ paper.style.translate = "";
18011
+ nativeX = 0;
18012
+ nativeY = 0;
18013
+ overlay.remove();
18014
+ const view = getView();
18015
+ if (view?.dom.dataset.printTabstop) {
18016
+ view.dom.removeAttribute("tabindex");
18017
+ delete view.dom.dataset.printTabstop;
18018
+ }
18019
+ }
18020
+ refresh();
18021
+ },
18022
+ destroy() {
18023
+ if (destroyed) return;
18024
+ this.setActive(false);
18025
+ destroyed = true;
18026
+ if (frame !== void 0) cancelAnimationFrame(frame);
18027
+ frame = void 0;
18028
+ up();
18029
+ listeners.abort();
18030
+ index.clear();
18031
+ dragScroll.destroy();
18032
+ previousDoc = void 0;
18033
+ },
18034
+ refresh,
18035
+ select: select2
18036
+ };
18037
+ }
17402
18038
  function moveCursorToBlock(view, blockId, offset) {
17403
18039
  let target;
17404
18040
  view.state.doc.descendants((node, pos) => {
@@ -20104,7 +20740,10 @@ function createChrome(core, api) {
20104
20740
  }
20105
20741
  function buildShell(core, api) {
20106
20742
  const { element, shell } = core;
20107
- if (shell.toolbar) return;
20743
+ if (shell.toolbar) {
20744
+ attachPrintEditing(core);
20745
+ return;
20746
+ }
20108
20747
  element.classList.add("dve-host");
20109
20748
  const root = element.attachShadow({ mode: "open" });
20110
20749
  const style = document.createElement("style");
@@ -20126,7 +20765,8 @@ function buildShell(core, api) {
20126
20765
  },
20127
20766
  (partName, contentType) => core.imageMedia.urlFor(partName, contentType),
20128
20767
  () => core.refreshControls(),
20129
- () => core.reviewDisplayMode
20768
+ () => core.reviewDisplayMode,
20769
+ () => core.pages.viewMode === "print"
20130
20770
  );
20131
20771
  canvas.append(printLayout.element);
20132
20772
  canvas.addEventListener("scroll", () => {
@@ -20202,6 +20842,7 @@ function buildShell(core, api) {
20202
20842
  if (core.pendingFileName) chrome.fileName = core.pendingFileName;
20203
20843
  root.append(style, frame);
20204
20844
  Object.assign(shell, { toolbar, canvas, paper });
20845
+ attachPrintEditing(core);
20205
20846
  applyRibbonAddIns(core);
20206
20847
  chrome.setLocale(core.locale);
20207
20848
  applyViewOptions(core);
@@ -20216,6 +20857,18 @@ function applyRibbonAddIns(core) {
20216
20857
  syncRibbonAddIns(toolbar, core.ribbonAddIns, { panelClass: "ribbon-panel" });
20217
20858
  if (toolbar.querySelector("[data-add-in]") !== before) refitRibbon(toolbar);
20218
20859
  }
20860
+ function attachPrintEditing(core) {
20861
+ const { shell } = core;
20862
+ if (shell.printEditing || !shell.printLayout || !shell.paper) return;
20863
+ shell.printEditing = createPrintEditingBridge(
20864
+ shell.printLayout.element,
20865
+ shell.paper,
20866
+ () => core.view,
20867
+ shell.printLayout.resolveClick,
20868
+ shell.canvas
20869
+ );
20870
+ shell.printEditing.setActive(core.pages.viewMode === "print");
20871
+ }
20219
20872
  var key = new PluginKey("dve-tab-stops");
20220
20873
  var MAX_PASSES = 4;
20221
20874
  var stopsOf = (paragraph2) => (paragraph2.attrs.tabStops ?? []).map((stop) => ({
@@ -20349,6 +21002,7 @@ function bodyPlugins(host) {
20349
21002
  noteNumberingPlugin(),
20350
21003
  sectionBreaksPlugin(),
20351
21004
  fieldGuardPlugin(),
21005
+ tableStructureGuardPlugin(),
20352
21006
  reviewRunMarksPlugin(() => host.reviewDisplayMode()),
20353
21007
  tabStopsPlugin(),
20354
21008
  keymap({
@@ -20478,6 +21132,7 @@ function renderDocument(core) {
20478
21132
  core.view = new EditorView(paper, {
20479
21133
  state,
20480
21134
  editable: () => core.canEditBody(),
21135
+ handleScrollToSelection: () => core.pages.viewMode === "print",
20481
21136
  dispatchTransaction(transaction) {
20482
21137
  const view = this;
20483
21138
  if (view.isDestroyed) return;
@@ -20812,6 +21467,8 @@ var DocxEditorElement = class extends DocxEditorApi {
20812
21467
  }
20813
21468
  disconnectedCallback() {
20814
21469
  const { core } = this;
21470
+ core.shell.printEditing?.destroy();
21471
+ delete core.shell.printEditing;
20815
21472
  core.collab.presence?.leave();
20816
21473
  core.detachedState = core.view?.state;
20817
21474
  core.view?.destroy();