@a3s-lab/office 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COLLABORATION_ROADMAP.md +426 -0
- package/README.md +649 -10
- package/dist/0~1403.js +1 -1
- package/dist/0~2805.js +1279 -0
- package/dist/{0~use-office-draft.js → 0~345.js} +30 -1
- package/dist/0~3539.js +1 -1
- package/dist/0~3557.js +1 -1
- package/dist/0~3635.js +1 -1
- package/dist/0~4595.js +123 -12
- package/dist/0~4980.js +154 -0
- package/dist/0~5050.js +124 -113
- package/dist/{0~9512.js → 0~6090.js} +540 -3
- package/dist/0~7048.js +92 -66
- package/dist/0~7614.js +2 -1
- package/dist/0~7754.js +5653 -0
- package/dist/0~9445.js +1 -1
- package/dist/0~document-editor.js +4992 -3323
- package/dist/0~markdown-editor.js +250 -44
- package/dist/0~pdf-viewer.js +1016 -24
- package/dist/0~presentation-editor.js +179 -8
- package/dist/0~spreadsheet-editor.js +3371 -578
- package/dist/0~work-docx-export.js +6801 -658
- package/dist/0~work-docx-import.js +1388 -795
- package/dist/0~work-office-diagnostics.js +524 -30
- package/dist/0~work-pptx-export.js +2 -1
- package/dist/0~work-pptx-import.js +1 -2
- package/dist/0~work-presentation-charts.js +1 -1
- package/dist/2591.js +197 -0
- package/dist/3818.js +1090 -0
- package/dist/4104.js +970 -60
- package/dist/432.js +171 -14
- package/dist/4476.js +2008 -0
- package/dist/4560.js +674 -0
- package/dist/4650.js +70 -0
- package/dist/{1134.js → 5184.js} +183 -1
- package/dist/6489.js +18 -18
- package/dist/7060.js +132 -0
- package/dist/8715.js +2 -136
- package/dist/8928.js +16778 -0
- package/dist/9787.js +209 -0
- package/dist/core.d.ts +29 -9
- package/dist/core.js +10 -2
- package/dist/index.js +13 -3
- package/dist/internal/collaboration/office-collaboration-flat-json.d.ts +13 -0
- package/dist/internal/collaboration/office-collaboration-json.d.ts +4 -0
- package/dist/internal/collaboration/office-collaboration-presence.d.ts +86 -0
- package/dist/internal/collaboration/office-collaboration-transport.d.ts +42 -0
- package/dist/internal/collaboration/office-collaboration.d.ts +85 -0
- package/dist/internal/collaboration/office-document-collaboration-bibliography.d.ts +7 -0
- package/dist/internal/collaboration/office-document-collaboration-claims.d.ts +9 -0
- package/dist/internal/collaboration/office-document-collaboration-comments.d.ts +7 -0
- package/dist/internal/collaboration/office-document-collaboration-sidecar-utils.d.ts +27 -0
- package/dist/internal/collaboration/office-document-collaboration-sidecars.d.ts +16 -0
- package/dist/internal/collaboration/office-document-collaboration.d.ts +45 -0
- package/dist/internal/collaboration/office-markdown-collaboration.d.ts +31 -0
- package/dist/internal/collaboration/office-pdf-collaboration-claims.d.ts +4 -0
- package/dist/internal/collaboration/office-pdf-collaboration-conflicts.d.ts +2 -0
- package/dist/internal/collaboration/office-pdf-collaboration-model.d.ts +26 -0
- package/dist/internal/collaboration/office-pdf-collaboration-records.d.ts +21 -0
- package/dist/internal/collaboration/office-pdf-collaboration-types.d.ts +91 -0
- package/dist/internal/collaboration/office-pdf-collaboration-validation.d.ts +4 -0
- package/dist/internal/collaboration/office-pdf-collaboration.d.ts +35 -0
- package/dist/internal/collaboration/office-presentation-collaboration-model.d.ts +25 -0
- package/dist/internal/collaboration/office-presentation-collaboration-records.d.ts +22 -0
- package/dist/internal/collaboration/office-presentation-collaboration-validation.d.ts +4 -0
- package/dist/internal/collaboration/office-presentation-collaboration.d.ts +32 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration-cells.d.ts +13 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration-claims.d.ts +4 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration-conflicts.d.ts +2 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration-flat-json.d.ts +10 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration-model.d.ts +31 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration-records.d.ts +17 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration-validation.d.ts +4 -0
- package/dist/internal/collaboration/office-spreadsheet-collaboration.d.ts +32 -0
- package/dist/internal/design-system/primitives/navigation/tabs.d.ts +3 -1
- package/dist/internal/features/work/components/work-document-page-border.d.ts +6 -0
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +536 -0
- package/dist/internal/features/work/editors/document-editor-focus.d.ts +1 -1
- package/dist/internal/features/work/editors/document-editor-support.d.ts +7 -3
- package/dist/internal/features/work/editors/document-editor.d.ts +8 -2
- package/dist/internal/features/work/editors/document-external-content.d.ts +14 -0
- package/dist/internal/features/work/editors/document-format-clipboard.d.ts +6 -0
- package/dist/internal/features/work/editors/document-format-tools.d.ts +4 -0
- package/dist/internal/features/work/editors/document-layout-panel.d.ts +4 -1
- package/dist/internal/features/work/editors/document-page-chrome-wps-shortcuts.d.ts +2 -0
- package/dist/internal/features/work/editors/document-page-layout-ribbon.d.ts +14 -0
- package/dist/internal/features/work/editors/document-page-stack.d.ts +10 -1
- package/dist/internal/features/work/editors/document-page-thumbnail.d.ts +2 -0
- package/dist/internal/features/work/editors/document-pagination-run-coordinator.d.ts +26 -0
- package/dist/internal/features/work/editors/document-picture-properties-dialog-model.d.ts +20 -1
- package/dist/internal/features/work/editors/document-review-navigation.d.ts +9 -0
- package/dist/internal/features/work/editors/document-statistics-dialog.d.ts +7 -0
- package/dist/internal/features/work/editors/document-status-bar.d.ts +2 -1
- package/dist/internal/features/work/editors/document-table-properties-dialog-model.d.ts +4 -1
- package/dist/internal/features/work/editors/document-toolbar.d.ts +19 -42
- package/dist/internal/features/work/editors/document-wps-shortcuts.d.ts +12 -0
- package/dist/internal/features/work/editors/document-zoom.d.ts +17 -0
- package/dist/internal/features/work/editors/markdown-editor-focus.d.ts +1 -1
- package/dist/internal/features/work/editors/markdown-editor.d.ts +5 -1
- package/dist/internal/features/work/editors/markdown-toolbar.d.ts +2 -1
- package/dist/internal/features/work/editors/office-collaboration-participants.d.ts +3 -0
- package/dist/internal/features/work/editors/office-collaboration-presence-context.d.ts +17 -0
- package/dist/internal/features/work/editors/office-collaboration-presence-ui.d.ts +25 -0
- package/dist/internal/features/work/editors/office-editor-focus-handoff.d.ts +27 -0
- package/dist/internal/features/work/editors/pdf-annotation-controller.d.ts +5 -0
- package/dist/internal/features/work/editors/pdf-collaboration-presence.d.ts +3 -0
- package/dist/internal/features/work/editors/pdf-collaboration-projection.d.ts +10 -0
- package/dist/internal/features/work/editors/pdf-evidence-contract.d.ts +36 -0
- package/dist/internal/features/work/editors/pdf-evidence-overlay.d.ts +37 -0
- package/dist/internal/features/work/editors/pdf-toolbar.d.ts +2 -1
- package/dist/internal/features/work/editors/pdf-viewer-controller.d.ts +7 -1
- package/dist/internal/features/work/editors/pdf-viewer.d.ts +11 -1
- package/dist/internal/features/work/editors/presentation-collaboration-presence.d.ts +5 -0
- package/dist/internal/features/work/editors/presentation-editor-focus.d.ts +3 -2
- package/dist/internal/features/work/editors/presentation-editor-types.d.ts +3 -0
- package/dist/internal/features/work/editors/presentation-editor.d.ts +1 -1
- package/dist/internal/features/work/editors/spreadsheet-auto-filter.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-clear.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-merge.d.ts +12 -0
- package/dist/internal/features/work/editors/spreadsheet-clipboard-shortcuts.d.ts +3 -7
- package/dist/internal/features/work/editors/spreadsheet-collaboration-presence.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +464 -0
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +45 -9
- package/dist/internal/features/work/editors/spreadsheet-context-menu.d.ts +2 -0
- package/dist/internal/features/work/editors/spreadsheet-editor-ribbon.d.ts +9 -28
- package/dist/internal/features/work/editors/spreadsheet-editor.d.ts +8 -2
- package/dist/internal/features/work/editors/spreadsheet-format-painter.d.ts +27 -0
- package/dist/internal/features/work/editors/spreadsheet-freeze-panes.d.ts +14 -0
- package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +3 -2
- package/dist/internal/features/work/editors/use-document-pagination.d.ts +6 -1
- package/dist/internal/features/work/editors/use-document-review-conflicts.d.ts +28 -0
- package/dist/internal/features/work/editors/use-spreadsheet-auto-filter.d.ts +21 -0
- package/dist/internal/features/work/editors/use-spreadsheet-collaboration.d.ts +27 -0
- package/dist/internal/features/work/editors/use-spreadsheet-format-painter.d.ts +18 -0
- package/dist/internal/features/work/editors/work-office-chrome.d.ts +22 -3
- package/dist/internal/features/work/editors/work-office-ribbon-overflow.d.ts +2 -0
- package/dist/internal/features/work/work-document-bookmark-references.d.ts +37 -0
- package/dist/internal/features/work/work-document-bookmarks.d.ts +29 -0
- package/dist/internal/features/work/work-document-caption-nodes.d.ts +4 -1
- package/dist/internal/features/work/work-document-comments.d.ts +1 -1
- package/dist/internal/features/work/work-document-equations.d.ts +513 -0
- package/dist/internal/features/work/work-document-extensions.d.ts +1 -0
- package/dist/internal/features/work/work-document-field-identity.d.ts +2 -0
- package/dist/internal/features/work/work-document-field-node.d.ts +2 -2
- package/dist/internal/features/work/work-document-fields.d.ts +7 -0
- package/dist/internal/features/work/work-document-image-identity.d.ts +30 -0
- package/dist/internal/features/work/work-document-image-layout.d.ts +46 -1
- package/dist/internal/features/work/work-document-image-wrap-contour.d.ts +16 -0
- package/dist/internal/features/work/work-document-incremental-layout.d.ts +2 -2
- package/dist/internal/features/work/work-document-model-codec.d.ts +4 -1
- package/dist/internal/features/work/work-document-note-integrity.d.ts +2 -0
- package/dist/internal/features/work/work-document-page-borders.d.ts +25 -0
- package/dist/internal/features/work/work-document-page-capture.d.ts +8 -0
- package/dist/internal/features/work/work-document-page-frames.d.ts +15 -0
- package/dist/internal/features/work/work-document-page-margins.d.ts +56 -0
- package/dist/internal/features/work/work-document-page-size.d.ts +47 -0
- package/dist/internal/features/work/work-document-pagination-measurement.d.ts +1 -2
- package/dist/internal/features/work/work-document-pagination-types.d.ts +7 -2
- package/dist/internal/features/work/work-document-pagination.d.ts +2 -2
- package/dist/internal/features/work/work-document-paragraph-borders.d.ts +32 -0
- package/dist/internal/features/work/work-document-paragraph-identity.d.ts +26 -0
- package/dist/internal/features/work/work-document-paragraph-shading.d.ts +18 -0
- package/dist/internal/features/work/work-document-review-conflicts.d.ts +35 -0
- package/dist/internal/features/work/work-document-section.d.ts +4 -0
- package/dist/internal/features/work/work-document-snapshot.d.ts +19 -0
- package/dist/internal/features/work/work-document-source.d.ts +23 -0
- package/dist/internal/features/work/work-document-table-column-widths.d.ts +7 -0
- package/dist/internal/features/work/work-document-table-property-changes.d.ts +3 -0
- package/dist/internal/features/work/work-document-table-row-identity.d.ts +15 -0
- package/dist/internal/features/work/work-document-table-sizing.d.ts +3 -0
- package/dist/internal/features/work/work-document-text-layout.d.ts +3 -1
- package/dist/internal/features/work/work-document-word-line-metrics.d.ts +2 -0
- package/dist/internal/features/work/work-docx-bookmark-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-bookmark-import.d.ts +24 -0
- package/dist/internal/features/work/work-docx-bookmarks.d.ts +17 -0
- package/dist/internal/features/work/work-docx-comment-durable-id-preservation.d.ts +2 -0
- package/dist/internal/features/work/work-docx-comment-export.d.ts +3 -0
- package/dist/internal/features/work/work-docx-comment-metadata.d.ts +2 -0
- package/dist/internal/features/work/work-docx-drawing-extension-preservation.d.ts +4 -0
- package/dist/internal/features/work/work-docx-equation-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-equation-export.d.ts +14 -0
- package/dist/internal/features/work/work-docx-equation-import.d.ts +30 -0
- package/dist/internal/features/work/work-docx-equation-story.d.ts +9 -0
- package/dist/internal/features/work/work-docx-export-formatting.d.ts +3 -1
- package/dist/internal/features/work/work-docx-export-image.d.ts +5 -1
- package/dist/internal/features/work/work-docx-export.d.ts +1 -1
- package/dist/internal/features/work/work-docx-field-instructions.d.ts +8 -0
- package/dist/internal/features/work/work-docx-font-table-preservation.d.ts +3 -0
- package/dist/internal/features/work/work-docx-ignorable-extension-preservation.d.ts +15 -0
- package/dist/internal/features/work/work-docx-image-crop.d.ts +12 -0
- package/dist/internal/features/work/work-docx-image-identity.d.ts +17 -0
- package/dist/internal/features/work/work-docx-image-layer.d.ts +12 -0
- package/dist/internal/features/work/work-docx-image-layout-import.d.ts +14 -2
- package/dist/internal/features/work/work-docx-image-wrap.d.ts +15 -0
- package/dist/internal/features/work/work-docx-import.d.ts +13 -3
- package/dist/internal/features/work/work-docx-list-export.d.ts +18 -0
- package/dist/internal/features/work/work-docx-list-import.d.ts +14 -0
- package/dist/internal/features/work/work-docx-note-comment-content-control-block-preservation.d.ts +18 -0
- package/dist/internal/features/work/work-docx-note-comment-content-control-model.d.ts +47 -0
- package/dist/internal/features/work/work-docx-note-comment-content-control-preservation.d.ts +4 -0
- package/dist/internal/features/work/work-docx-note-comment-content-control-properties.d.ts +17 -0
- package/dist/internal/features/work/work-docx-note-comment-content-control-table-model.d.ts +17 -0
- package/dist/internal/features/work/work-docx-note-comment-content-control-xml.d.ts +14 -0
- package/dist/internal/features/work/work-docx-note-comment-extension-preservation.d.ts +2 -0
- package/dist/internal/features/work/work-docx-note-comment-hyperlink-content.d.ts +40 -0
- package/dist/internal/features/work/work-docx-note-comment-hyperlink-preservation.d.ts +5 -0
- package/dist/internal/features/work/work-docx-note-comment-hyperlink-relationships.d.ts +35 -0
- package/dist/internal/features/work/work-docx-note-comment-identity.d.ts +15 -0
- package/dist/internal/features/work/work-docx-note-comment-run-preservation.d.ts +4 -0
- package/dist/internal/features/work/work-docx-note-comment-run-properties.d.ts +2 -0
- package/dist/internal/features/work/work-docx-note-image-import.d.ts +12 -0
- package/dist/internal/features/work/work-docx-note-image-relationships.d.ts +1 -0
- package/dist/internal/features/work/work-docx-numbering-extension-preservation.d.ts +6 -0
- package/dist/internal/features/work/work-docx-numbering.d.ts +1 -0
- package/dist/internal/features/work/work-docx-page-borders-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-page-borders-import.d.ts +10 -0
- package/dist/internal/features/work/work-docx-page-margins-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-page-margins-import.d.ts +18 -0
- package/dist/internal/features/work/work-docx-page-size-diagnostics.d.ts +2 -0
- package/dist/internal/features/work/work-docx-page-size-import.d.ts +17 -0
- package/dist/internal/features/work/work-docx-paragraph-borders-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-paragraph-borders-export.d.ts +18 -0
- package/dist/internal/features/work/work-docx-paragraph-borders-import.d.ts +24 -0
- package/dist/internal/features/work/work-docx-paragraph-default-collapsed.d.ts +19 -0
- package/dist/internal/features/work/work-docx-paragraph-extension-preservation.d.ts +2 -0
- package/dist/internal/features/work/work-docx-paragraph-identity-import.d.ts +10 -0
- package/dist/internal/features/work/work-docx-paragraph-identity.d.ts +18 -0
- package/dist/internal/features/work/work-docx-paragraph-pagination-import.d.ts +6 -1
- package/dist/internal/features/work/work-docx-paragraph-shading-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-paragraph-shading-export.d.ts +5 -0
- package/dist/internal/features/work/work-docx-paragraph-shading-import.d.ts +18 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +3 -0
- package/dist/internal/features/work/work-docx-settings-preservation.d.ts +10 -0
- package/dist/internal/features/work/work-docx-settings-xml.d.ts +16 -0
- package/dist/internal/features/work/work-docx-style-extension-preservation.d.ts +2 -0
- package/dist/internal/features/work/work-docx-table-cell-export.d.ts +2 -1
- package/dist/internal/features/work/work-docx-table-cell-import.d.ts +3 -0
- package/dist/internal/features/work/work-docx-table-extension-preservation.d.ts +2 -0
- package/dist/internal/features/work/work-docx-table-row-import.d.ts +2 -0
- package/dist/internal/features/work/work-docx-table-sizing-import.d.ts +1 -0
- package/dist/internal/features/work/work-docx-theme-reference.d.ts +23 -0
- package/dist/internal/features/work/work-docx-theme.d.ts +4 -1
- package/dist/internal/features/work/work-docx-twips.d.ts +12 -0
- package/dist/internal/features/work/work-file-contract.d.ts +1 -0
- package/dist/internal/features/work/work-file-io.d.ts +1 -1
- package/dist/internal/features/work/work-markdown-extensions.d.ts +4 -1
- package/dist/internal/features/work/work-ooxml-package-preservation.d.ts +12 -0
- package/dist/internal/features/work/work-ooxml-package-security.d.ts +6 -0
- package/dist/internal/features/work/work-ooxml-relationship-preservation.d.ts +10 -0
- package/dist/internal/features/work/work-ooxml-xml.d.ts +2 -0
- package/dist/internal/features/work/work-pdf-export.d.ts +10 -0
- package/dist/internal/features/work/work-repository.d.ts +2 -0
- package/dist/internal/features/work/work-types.d.ts +15 -2
- package/dist/internal/kernel/office-kernel-client-types.d.ts +1 -0
- package/dist/internal/kernel/office-kernel-protocol.d.ts +7 -0
- package/dist/internal/kernel/office-kernel-version.d.ts +1 -1
- package/dist/office-kernel.wasm +0 -0
- package/dist/office-kernel.worker.js +93 -41
- package/dist/react.d.ts +18 -12
- package/dist/react.js +1 -1
- package/dist/styles.css +1367 -16
- package/dist/vue.d.ts +48 -5
- package/dist/vue.js +42 -3
- package/dist/web-component.d.ts +24 -2
- package/dist/web-component.js +101 -2
- package/docs/latest/en/browser-editor-architecture.md +262 -47
- package/package.json +29 -4
- package/dist/0~152.js +0 -94
- package/dist/0~2582.js +0 -485
- package/dist/0~4750.js +0 -939
- package/dist/0~5861.js +0 -596
- package/dist/0~work-document-extensions.js +0 -3045
- package/dist/0~work-document-model-codec.js +0 -42
- package/dist/0~work-docx-bibliography.js +0 -347
- package/dist/0~work-docx-page-color.js +0 -42
- package/dist/2881.js +0 -1455
- package/dist/8728.js +0 -723
|
@@ -1,13 +1,281 @@
|
|
|
1
1
|
import jszip from "jszip";
|
|
2
|
-
import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage, firstDescendant, descendants, directChild,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { readDocxBibliography } from "./0~work-docx-bibliography.js";
|
|
8
|
-
import { importDocxPageColor } from "./0~work-docx-page-color.js";
|
|
2
|
+
import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage, firstDescendant, descendants, directChild, attribute } from "./5184.js";
|
|
3
|
+
import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, normalizeDocumentTabStops, createDocumentImageIdentityRegistry, normalizeDocumentColumns, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, normalizeDocumentImageAlignment, normalizeDocumentParagraphId, applyDocumentImageLayerToElement, normalizeDocumentNotesHtml, normalizeDocumentBookmarkReferencesHtml, documentCitationTagsFromInstruction, applyDocumentImageWrapContourToElement, renderDocumentAutoLineHeight, applyDocumentPageGeometry, normalizeDocumentPageChrome, normalizeDocumentImageLayoutOptions, applyDocumentImageCropToElement, documentPageMarginsForLayout, createDocumentNoteElement, serializeDocumentTabStops, normalizeDocumentImageLayer, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, documentBookmarkReferenceInstruction, documentInitialSectionLayout, normalizeDocumentFieldsHtml, documentCaptionLabel, documentTableBordersFromElement, isContourImageLayout, normalizeDocumentCitationsHtml, normalizeDocumentImageIdentity, normalizeDocumentImageWrapSide, applyDocumentParagraphIdentityToElement, documentAutoLineHeight, docxDocumentFieldKind, serializeDocxThemeReference, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentParagraphShadingDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentParagraphBordersDomAttributes, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, normalizeDocumentParagraphIdentity, documentPageMarginBody, normalizeDocumentParagraphIndent, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentWordLineHeightFactor } from "./8928.js";
|
|
4
|
+
import { parseDocxPageMargins, parseDocxPageGeometry, parseDocxPageBorders, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, inspectDocxPageMarginSettings, docxTableRunPropertySources, docxParagraphPropertySources, docxCaptionSequenceKind, resolveDocxParagraphBordersForParagraph, applyImportedDocxParagraphShadingMarkers, hasImportedDocxParagraphBorderMarkers, docxCaptionBookmark, docxFieldResultText, resolveDocxParagraphStyleResolver, createDocxParagraphStyleResolver, docxEquationHtml, docxFieldOccurrences, docxTableParagraphPropertySources, resolveDocxTableStyleResolver, docxTableCellStyleLayers, markDocxParagraphBorders, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, parseDocxPaperSource, docxTablePropertySources, docxRunPropertySources, parseDirectDocxParagraphShading, markDocxParagraphShading, markDocxPackageEquations } from "./0~7754.js";
|
|
5
|
+
import { xmlAttributeLocalName, docxThemeFont, readDocxBibliography, createDocxThemeResolver, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~2805.js";
|
|
6
|
+
import { importDocxPageColor, importedDocumentNoteId } from "./0~4980.js";
|
|
9
7
|
const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
10
8
|
const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
9
|
+
const MAX_BOOKMARK_NAME_LENGTH = 40;
|
|
10
|
+
const MAX_BOOKMARK_NATIVE_ID = 0x7fffffff;
|
|
11
|
+
function markDocxBookmarks(document) {
|
|
12
|
+
const captionBookmarks = captionBookmarkStarts(document);
|
|
13
|
+
const captionNames = new Set(Array.from(captionBookmarks).map((bookmark)=>attribute(bookmark, 'name')?.trim().toLowerCase()).filter((name)=>Boolean(name)));
|
|
14
|
+
const pairs = docxBookmarkPairs(document).filter((pair)=>!captionBookmarks.has(pair.start) && '_GoBack' !== pair.sourceName);
|
|
15
|
+
const names = new Set();
|
|
16
|
+
const normalizedNames = new Map();
|
|
17
|
+
for(let index = pairs.length - 1; index >= 0; index -= 1){
|
|
18
|
+
const pair = pairs[index];
|
|
19
|
+
if (!pair) continue;
|
|
20
|
+
const base = normalizeDocumentBookmarkName(pair.sourceName) ?? safeImportedBookmarkName(pair.sourceName, index + 1);
|
|
21
|
+
const name = uniqueImportedBookmarkName(base, names);
|
|
22
|
+
names.add(name.toLowerCase());
|
|
23
|
+
normalizedNames.set(pair, name);
|
|
24
|
+
}
|
|
25
|
+
const nativeIds = new Set();
|
|
26
|
+
const internalIds = new Set();
|
|
27
|
+
const bookmarks = [];
|
|
28
|
+
for (const [index, pair] of pairs.entries()){
|
|
29
|
+
const preferredNativeId = normalizeDocumentBookmarkNativeId(pair.sourceNativeId);
|
|
30
|
+
const nativeId = null === preferredNativeId || nativeIds.has(preferredNativeId) ? nextNativeId(nativeIds) : preferredNativeId;
|
|
31
|
+
nativeIds.add(nativeId);
|
|
32
|
+
const name = normalizedNames.get(pair) ?? `Bookmark_${index + 1}`;
|
|
33
|
+
const id = uniqueImportedBookmarkId(name, nativeId, index + 1, internalIds);
|
|
34
|
+
internalIds.add(id);
|
|
35
|
+
const marker = importedBookmarkMarker(index + 1, id, name, pair.sourceName, nativeId, document.documentElement.textContent ?? '');
|
|
36
|
+
insertBoundaryMarker(document, pair.start, marker.start);
|
|
37
|
+
insertBoundaryMarker(document, pair.end, marker.end);
|
|
38
|
+
pair.start.remove();
|
|
39
|
+
pair.end.remove();
|
|
40
|
+
bookmarks.push(marker);
|
|
41
|
+
}
|
|
42
|
+
const targets = new Map();
|
|
43
|
+
for (const bookmark of bookmarks)targets.set(bookmark.sourceName.toLowerCase(), bookmark);
|
|
44
|
+
const references = docxFieldOccurrences(document).flatMap((field, index)=>{
|
|
45
|
+
const sourceTarget = docxBookmarkReferenceTarget(field.instruction);
|
|
46
|
+
const target = sourceTarget ? targets.get(sourceTarget.toLowerCase()) : null;
|
|
47
|
+
if (!sourceTarget || !target || captionNames.has(sourceTarget.toLowerCase()) || !canMarkField(field)) return [];
|
|
48
|
+
const marker = importedBookmarkReferenceMarker(index + 1, target, field.instruction, docxFieldResultText(field), document.documentElement.textContent ?? '');
|
|
49
|
+
insertFieldBoundaryMarkers(document, field, marker.start, marker.end);
|
|
50
|
+
return [
|
|
51
|
+
marker
|
|
52
|
+
];
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
bookmarks,
|
|
56
|
+
references
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function applyImportedDocxBookmarkMarkers(document, markers) {
|
|
60
|
+
for (const reference of markers.references){
|
|
61
|
+
const element = document.createElement('span');
|
|
62
|
+
element.dataset.documentCrossReference = 'true';
|
|
63
|
+
element.dataset.referenceTargetType = 'bookmark';
|
|
64
|
+
element.dataset.referenceTargetId = reference.targetId;
|
|
65
|
+
element.dataset.referenceTargetName = reference.targetName;
|
|
66
|
+
element.dataset.referenceInstruction = reference.instruction;
|
|
67
|
+
const convertedDisplay = replaceBookmarkReferenceMarkerRange(document.body, reference.start, reference.end, element);
|
|
68
|
+
const display = reference.display.trim() || convertedDisplay.trim() || reference.targetName;
|
|
69
|
+
element.dataset.referenceDisplay = display;
|
|
70
|
+
element.className = 'work-document-cross-reference';
|
|
71
|
+
element.textContent = display;
|
|
72
|
+
}
|
|
73
|
+
const targetNames = new Map();
|
|
74
|
+
for (const bookmark of markers.bookmarks){
|
|
75
|
+
targetNames.set(bookmark.sourceName.toLowerCase(), bookmark.name);
|
|
76
|
+
replaceBookmarkMarker(document.body, bookmark.start, {
|
|
77
|
+
...bookmark,
|
|
78
|
+
kind: 'start'
|
|
79
|
+
});
|
|
80
|
+
replaceBookmarkMarker(document.body, bookmark.end, {
|
|
81
|
+
...bookmark,
|
|
82
|
+
kind: 'end'
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
for (const link of document.body.querySelectorAll('a[href^="#"]')){
|
|
86
|
+
const sourceName = (link.getAttribute('href') ?? '').slice(1);
|
|
87
|
+
const name = targetNames.get(sourceName.toLowerCase());
|
|
88
|
+
if (name) link.setAttribute('href', `#${name}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function hasImportedDocxBookmarkMarkers(markers) {
|
|
92
|
+
return markers.bookmarks.length > 0 || markers.references.length > 0;
|
|
93
|
+
}
|
|
94
|
+
function docxBookmarkPairs(document) {
|
|
95
|
+
const open = new Map();
|
|
96
|
+
const pairs = [];
|
|
97
|
+
for (const element of Array.from(document.getElementsByTagName('*'))){
|
|
98
|
+
if ('bookmarkStart' === element.localName) {
|
|
99
|
+
const id = attribute(element, 'id')?.trim() ?? '';
|
|
100
|
+
const stack = open.get(id) ?? [];
|
|
101
|
+
stack.push(element);
|
|
102
|
+
open.set(id, stack);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if ('bookmarkEnd' !== element.localName) continue;
|
|
106
|
+
const id = attribute(element, 'id')?.trim() ?? '';
|
|
107
|
+
const start = open.get(id)?.pop();
|
|
108
|
+
if (start) pairs.push({
|
|
109
|
+
start,
|
|
110
|
+
end: element,
|
|
111
|
+
sourceName: attribute(start, 'name')?.trim() ?? '',
|
|
112
|
+
sourceNativeId: id
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
pairs.sort((left, right)=>{
|
|
116
|
+
const position = left.start.compareDocumentPosition(right.start);
|
|
117
|
+
if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
|
|
118
|
+
if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;
|
|
119
|
+
return 0;
|
|
120
|
+
});
|
|
121
|
+
return pairs;
|
|
122
|
+
}
|
|
123
|
+
function captionBookmarkStarts(document) {
|
|
124
|
+
const bookmarks = new Set();
|
|
125
|
+
for (const paragraph of descendants(document, 'p'))for (const field of docxFieldOccurrences(paragraph)){
|
|
126
|
+
if (!docxCaptionSequenceKind(field.instruction)) continue;
|
|
127
|
+
const bookmark = docxCaptionBookmark(paragraph, field);
|
|
128
|
+
if (bookmark) bookmarks.add(bookmark);
|
|
129
|
+
}
|
|
130
|
+
return bookmarks;
|
|
131
|
+
}
|
|
132
|
+
function importedBookmarkMarker(index, id, name, sourceName, nativeId, occupiedText) {
|
|
133
|
+
const base = `${index}_${stableHash(`${id}:${name}`)}`;
|
|
134
|
+
let suffix = base;
|
|
135
|
+
let collision = 2;
|
|
136
|
+
while(occupiedText.includes(`__A3S_WORK_BOOKMARK_START_${suffix}__`) || occupiedText.includes(`__A3S_WORK_BOOKMARK_END_${suffix}__`)){
|
|
137
|
+
suffix = `${base}_${collision}`;
|
|
138
|
+
collision += 1;
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
start: `__A3S_WORK_BOOKMARK_START_${suffix}__`,
|
|
142
|
+
end: `__A3S_WORK_BOOKMARK_END_${suffix}__`,
|
|
143
|
+
id,
|
|
144
|
+
name,
|
|
145
|
+
sourceName,
|
|
146
|
+
nativeId
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function importedBookmarkReferenceMarker(index, target, sourceInstruction, display, occupiedText) {
|
|
150
|
+
const base = `${index}_${stableHash(`${target.id}:${sourceInstruction}`)}`;
|
|
151
|
+
let suffix = base;
|
|
152
|
+
let collision = 2;
|
|
153
|
+
while(occupiedText.includes(`__A3S_WORK_BOOKMARK_REFERENCE_START_${suffix}__`) || occupiedText.includes(`__A3S_WORK_BOOKMARK_REFERENCE_END_${suffix}__`)){
|
|
154
|
+
suffix = `${base}_${collision}`;
|
|
155
|
+
collision += 1;
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
start: `__A3S_WORK_BOOKMARK_REFERENCE_START_${suffix}__`,
|
|
159
|
+
end: `__A3S_WORK_BOOKMARK_REFERENCE_END_${suffix}__`,
|
|
160
|
+
targetId: target.id,
|
|
161
|
+
targetName: target.name,
|
|
162
|
+
instruction: documentBookmarkReferenceInstruction(target.name, sourceInstruction),
|
|
163
|
+
display
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function insertBoundaryMarker(document, boundary, marker) {
|
|
167
|
+
boundary.parentNode?.insertBefore(work_docx_bookmark_import_markerRun(document, marker), boundary);
|
|
168
|
+
}
|
|
169
|
+
function insertFieldBoundaryMarkers(document, field, start, end) {
|
|
170
|
+
if ('fldChar' === field.start.localName && 'fldChar' === field.end.localName) {
|
|
171
|
+
field.start.parentNode?.insertBefore(markerText(document, start), field.start);
|
|
172
|
+
field.end.parentNode?.insertBefore(markerText(document, end), field.end.nextSibling);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
field.start.parentNode?.insertBefore(work_docx_bookmark_import_markerRun(document, start), field.start);
|
|
176
|
+
field.end.parentNode?.insertBefore(work_docx_bookmark_import_markerRun(document, end), field.end.nextSibling);
|
|
177
|
+
}
|
|
178
|
+
function work_docx_bookmark_import_markerRun(document, marker) {
|
|
179
|
+
const run = document.createElementNS(WORD_NAMESPACE, 'w:r');
|
|
180
|
+
run.append(markerText(document, marker));
|
|
181
|
+
return run;
|
|
182
|
+
}
|
|
183
|
+
function markerText(document, marker) {
|
|
184
|
+
const text = document.createElementNS(WORD_NAMESPACE, 'w:t');
|
|
185
|
+
text.setAttributeNS(XML_NAMESPACE, 'xml:space', 'preserve');
|
|
186
|
+
text.textContent = marker;
|
|
187
|
+
return text;
|
|
188
|
+
}
|
|
189
|
+
function replaceBookmarkMarker(root, marker, bookmark) {
|
|
190
|
+
const text = textNodes(root).find((node)=>node.data.includes(marker));
|
|
191
|
+
if (!text) return false;
|
|
192
|
+
const offset = text.data.indexOf(marker);
|
|
193
|
+
const element = root.ownerDocument.createElement('span');
|
|
194
|
+
element.dataset.documentBookmarkBoundary = 'true';
|
|
195
|
+
element.dataset.bookmarkKind = bookmark.kind;
|
|
196
|
+
element.dataset.bookmarkId = bookmark.id;
|
|
197
|
+
element.dataset.bookmarkName = bookmark.name;
|
|
198
|
+
element.dataset.officeBookmarkId = String(bookmark.nativeId);
|
|
199
|
+
element.className = `work-document-bookmark-boundary ${bookmark.kind}`;
|
|
200
|
+
element.contentEditable = 'false';
|
|
201
|
+
element.setAttribute('aria-hidden', 'true');
|
|
202
|
+
if ('start' === bookmark.kind) element.id = bookmark.name;
|
|
203
|
+
const before = text.data.slice(0, offset);
|
|
204
|
+
const after = text.data.slice(offset + marker.length);
|
|
205
|
+
const fragment = root.ownerDocument.createDocumentFragment();
|
|
206
|
+
if (before) fragment.append(root.ownerDocument.createTextNode(before));
|
|
207
|
+
fragment.append(element);
|
|
208
|
+
if (after) fragment.append(root.ownerDocument.createTextNode(after));
|
|
209
|
+
text.replaceWith(fragment);
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
function replaceBookmarkReferenceMarkerRange(root, start, end, replacement) {
|
|
213
|
+
const nodes = textNodes(root);
|
|
214
|
+
const startNode = nodes.find((node)=>node.data.includes(start));
|
|
215
|
+
const endNode = nodes.find((node)=>node.data.includes(end));
|
|
216
|
+
if (!startNode || !endNode) return '';
|
|
217
|
+
const range = root.ownerDocument.createRange();
|
|
218
|
+
range.setStart(startNode, startNode.data.indexOf(start));
|
|
219
|
+
range.setEnd(endNode, endNode.data.indexOf(end) + end.length);
|
|
220
|
+
const content = range.cloneContents();
|
|
221
|
+
removeMarkerText(content, start);
|
|
222
|
+
removeMarkerText(content, end);
|
|
223
|
+
const display = content.textContent ?? '';
|
|
224
|
+
range.deleteContents();
|
|
225
|
+
range.insertNode(replacement);
|
|
226
|
+
return display;
|
|
227
|
+
}
|
|
228
|
+
function removeMarkerText(root, marker) {
|
|
229
|
+
for (const node of textNodes(root))node.data = node.data.replace(marker, '');
|
|
230
|
+
}
|
|
231
|
+
function canMarkField(field) {
|
|
232
|
+
return field.start !== field.end || 'fldSimple' === field.start.localName;
|
|
233
|
+
}
|
|
234
|
+
function safeImportedBookmarkName(source, index) {
|
|
235
|
+
const characters = Array.from(source.trim()).map((character)=>/^[\p{L}\p{N}_]$/u.test(character) ? character : '_').join('');
|
|
236
|
+
const leading = /^[\p{L}_]/u.test(characters) ? characters : `Bookmark_${characters}`;
|
|
237
|
+
return Array.from(leading || `Bookmark_${index}`).slice(0, MAX_BOOKMARK_NAME_LENGTH).join('') || `Bookmark_${index}`;
|
|
238
|
+
}
|
|
239
|
+
function uniqueImportedBookmarkName(base, names) {
|
|
240
|
+
if (!names.has(base.toLowerCase())) return base;
|
|
241
|
+
let suffix = 2;
|
|
242
|
+
while(suffix <= MAX_BOOKMARK_NATIVE_ID){
|
|
243
|
+
const ending = `_${suffix}`;
|
|
244
|
+
const prefix = Array.from(base).slice(0, MAX_BOOKMARK_NAME_LENGTH - ending.length).join('');
|
|
245
|
+
const candidate = `${prefix}${ending}`;
|
|
246
|
+
if (!names.has(candidate.toLowerCase())) return candidate;
|
|
247
|
+
suffix += 1;
|
|
248
|
+
}
|
|
249
|
+
throw new Error('No unique imported Word bookmark name is available.');
|
|
250
|
+
}
|
|
251
|
+
function uniqueImportedBookmarkId(name, nativeId, index, ids) {
|
|
252
|
+
const base = `docx-bookmark-${nativeId}-${stableHash(name)}`;
|
|
253
|
+
if (!ids.has(base)) return base;
|
|
254
|
+
let suffix = index;
|
|
255
|
+
while(ids.has(`${base}-${suffix}`))suffix += 1;
|
|
256
|
+
return `${base}-${suffix}`;
|
|
257
|
+
}
|
|
258
|
+
function nextNativeId(ids) {
|
|
259
|
+
for(let id = 0; id <= MAX_BOOKMARK_NATIVE_ID; id += 1)if (!ids.has(id)) return id;
|
|
260
|
+
throw new Error('No unique imported Word bookmark identifier is available.');
|
|
261
|
+
}
|
|
262
|
+
function stableHash(source) {
|
|
263
|
+
let hash = 0x811c9dc5;
|
|
264
|
+
for(let index = 0; index < source.length; index += 1){
|
|
265
|
+
hash ^= source.charCodeAt(index);
|
|
266
|
+
hash = Math.imul(hash, 0x01000193);
|
|
267
|
+
}
|
|
268
|
+
return (hash >>> 0).toString(36);
|
|
269
|
+
}
|
|
270
|
+
function textNodes(root) {
|
|
271
|
+
const walker = root.ownerDocument?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
272
|
+
const nodes = [];
|
|
273
|
+
if (!walker) return nodes;
|
|
274
|
+
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
275
|
+
return nodes;
|
|
276
|
+
}
|
|
277
|
+
const work_docx_caption_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
278
|
+
const work_docx_caption_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
11
279
|
function markDocxCaptionFields(document) {
|
|
12
280
|
const captions = [];
|
|
13
281
|
const bookmarkTargets = new Map();
|
|
@@ -32,7 +300,7 @@ function markDocxCaptionFields(document) {
|
|
|
32
300
|
const targetId = bookmarkName ? bookmarkTargets.get(bookmarkName) : void 0;
|
|
33
301
|
if (!targetId) continue;
|
|
34
302
|
const marker = referenceMarker(references.length + 1, targetId);
|
|
35
|
-
|
|
303
|
+
work_docx_caption_import_insertFieldBoundaryMarkers(document, field, marker.start, marker.end);
|
|
36
304
|
references.push(marker);
|
|
37
305
|
}
|
|
38
306
|
return {
|
|
@@ -50,8 +318,8 @@ function applyImportedDocxCaptionMarkers(document, markers) {
|
|
|
50
318
|
for (const caption of markers.captions){
|
|
51
319
|
const block = markerBlock(document.body, caption.start, caption.end);
|
|
52
320
|
if (!block) continue;
|
|
53
|
-
|
|
54
|
-
|
|
321
|
+
work_docx_caption_import_removeMarkerText(block, caption.start);
|
|
322
|
+
work_docx_caption_import_removeMarkerText(block, caption.end);
|
|
55
323
|
removeCaptionPrefix(block, caption.kind);
|
|
56
324
|
const element = document.createElement('figcaption');
|
|
57
325
|
element.dataset.documentCaption = 'true';
|
|
@@ -93,29 +361,29 @@ function insertParagraphBoundaryMarkers(document, paragraph, start, end) {
|
|
|
93
361
|
paragraph.insertBefore(work_docx_caption_import_markerRun(document, start), firstContent ?? null);
|
|
94
362
|
paragraph.append(work_docx_caption_import_markerRun(document, end));
|
|
95
363
|
}
|
|
96
|
-
function
|
|
364
|
+
function work_docx_caption_import_insertFieldBoundaryMarkers(document, field, start, end) {
|
|
97
365
|
if ('fldChar' === field.start.localName && 'fldChar' === field.end.localName) {
|
|
98
|
-
field.start.parentNode?.insertBefore(
|
|
99
|
-
field.end.parentNode?.insertBefore(
|
|
366
|
+
field.start.parentNode?.insertBefore(work_docx_caption_import_markerText(document, start), field.start);
|
|
367
|
+
field.end.parentNode?.insertBefore(work_docx_caption_import_markerText(document, end), field.end.nextSibling);
|
|
100
368
|
return;
|
|
101
369
|
}
|
|
102
370
|
field.start.parentNode?.insertBefore(work_docx_caption_import_markerRun(document, start), field.start);
|
|
103
371
|
field.end.parentNode?.insertBefore(work_docx_caption_import_markerRun(document, end), field.end.nextSibling);
|
|
104
372
|
}
|
|
105
373
|
function work_docx_caption_import_markerRun(document, text) {
|
|
106
|
-
const run = document.createElementNS(
|
|
107
|
-
run.append(
|
|
374
|
+
const run = document.createElementNS(work_docx_caption_import_WORD_NAMESPACE, 'w:r');
|
|
375
|
+
run.append(work_docx_caption_import_markerText(document, text));
|
|
108
376
|
return run;
|
|
109
377
|
}
|
|
110
|
-
function
|
|
111
|
-
const value = document.createElementNS(
|
|
112
|
-
value.setAttributeNS(
|
|
378
|
+
function work_docx_caption_import_markerText(document, text) {
|
|
379
|
+
const value = document.createElementNS(work_docx_caption_import_WORD_NAMESPACE, 'w:t');
|
|
380
|
+
value.setAttributeNS(work_docx_caption_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
113
381
|
value.textContent = text;
|
|
114
382
|
return value;
|
|
115
383
|
}
|
|
116
384
|
function markerBlock(root, start, end) {
|
|
117
|
-
const startNode =
|
|
118
|
-
const endNode =
|
|
385
|
+
const startNode = work_docx_caption_import_textNodes(root).find((node)=>node.data.includes(start));
|
|
386
|
+
const endNode = work_docx_caption_import_textNodes(root).find((node)=>node.data.includes(end));
|
|
119
387
|
if (!startNode || !endNode) return null;
|
|
120
388
|
let current = startNode.parentElement;
|
|
121
389
|
while(current && current !== root){
|
|
@@ -125,7 +393,7 @@ function markerBlock(root, start, end) {
|
|
|
125
393
|
return null;
|
|
126
394
|
}
|
|
127
395
|
function replaceMarkerRange(root, start, end, replacement) {
|
|
128
|
-
const nodes =
|
|
396
|
+
const nodes = work_docx_caption_import_textNodes(root);
|
|
129
397
|
const startNode = nodes.find((node)=>node.data.includes(start));
|
|
130
398
|
const endNode = nodes.find((node)=>node.data.includes(end));
|
|
131
399
|
if (!startNode || !endNode) return false;
|
|
@@ -136,8 +404,8 @@ function replaceMarkerRange(root, start, end, replacement) {
|
|
|
136
404
|
range.insertNode(replacement);
|
|
137
405
|
return true;
|
|
138
406
|
}
|
|
139
|
-
function
|
|
140
|
-
for (const node of
|
|
407
|
+
function work_docx_caption_import_removeMarkerText(root, marker) {
|
|
408
|
+
for (const node of work_docx_caption_import_textNodes(root))node.data = node.data.replace(marker, '');
|
|
141
409
|
}
|
|
142
410
|
function removeCaptionPrefix(root, kind) {
|
|
143
411
|
const label = documentCaptionLabel(kind);
|
|
@@ -146,14 +414,14 @@ function removeCaptionPrefix(root, kind) {
|
|
|
146
414
|
const match = expression.exec(source);
|
|
147
415
|
if (!match || !source.trimStart().startsWith(label) && !/^(?:Figure|Fig|Table)/i.test(source.trimStart())) return;
|
|
148
416
|
let remaining = match[0].length;
|
|
149
|
-
for (const node of
|
|
417
|
+
for (const node of work_docx_caption_import_textNodes(root)){
|
|
150
418
|
if (remaining <= 0) break;
|
|
151
419
|
const removed = Math.min(remaining, node.data.length);
|
|
152
420
|
node.data = node.data.slice(removed);
|
|
153
421
|
remaining -= removed;
|
|
154
422
|
}
|
|
155
423
|
}
|
|
156
|
-
function
|
|
424
|
+
function work_docx_caption_import_textNodes(root) {
|
|
157
425
|
const walker = root.ownerDocument?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
158
426
|
const nodes = [];
|
|
159
427
|
if (!walker) return nodes;
|
|
@@ -298,7 +566,7 @@ function markDocxCitationFields(document) {
|
|
|
298
566
|
const citations = [];
|
|
299
567
|
const bibliographies = [];
|
|
300
568
|
for (const field of docxFieldOccurrences(document)){
|
|
301
|
-
if (!
|
|
569
|
+
if (!work_docx_citation_import_canMarkField(field)) continue;
|
|
302
570
|
const tags = documentCitationTagsFromInstruction(field.instruction);
|
|
303
571
|
if (tags.length) {
|
|
304
572
|
const index = citations.length + 1;
|
|
@@ -349,7 +617,7 @@ function applyImportedDocxCitationMarkers(document, markers) {
|
|
|
349
617
|
function hasImportedDocxCitationMarkers(markers) {
|
|
350
618
|
return markers.citations.length > 0 || markers.bibliographies.length > 0;
|
|
351
619
|
}
|
|
352
|
-
function
|
|
620
|
+
function work_docx_citation_import_canMarkField(field) {
|
|
353
621
|
return field.start !== field.end || 'fldSimple' === field.start.localName;
|
|
354
622
|
}
|
|
355
623
|
function work_docx_citation_import_insertFieldBoundaryMarkers(document, field, start, end) {
|
|
@@ -439,6 +707,45 @@ function work_docx_citation_import_textNodes(root) {
|
|
|
439
707
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
440
708
|
return nodes;
|
|
441
709
|
}
|
|
710
|
+
const TWIPS_PER_MILLIMETER = 1440 / 25.4;
|
|
711
|
+
function importDocxColumns(element, fallback) {
|
|
712
|
+
const columnElements = directChildren(element, 'col');
|
|
713
|
+
const sourceCount = numberAttribute(element, 'num') || columnElements.length || fallback.count;
|
|
714
|
+
const count = Math.min(6, Math.max(1, sourceCount));
|
|
715
|
+
const spacingAttribute = attribute(element, 'space');
|
|
716
|
+
const spacing = null === spacingAttribute ? fallback.spacing : twipsToMillimeters(Number(spacingAttribute), fallback.spacing);
|
|
717
|
+
const base = {
|
|
718
|
+
count,
|
|
719
|
+
spacing,
|
|
720
|
+
separator: enabledAttribute(element, 'sep')
|
|
721
|
+
};
|
|
722
|
+
if (!columnElements.length) return normalizeDocumentColumns(base);
|
|
723
|
+
return normalizeDocumentColumns({
|
|
724
|
+
...base,
|
|
725
|
+
count: Math.min(count, columnElements.length),
|
|
726
|
+
custom: columnElements.slice(0, count).map((column, index)=>{
|
|
727
|
+
const columnSpacing = attribute(column, 'space');
|
|
728
|
+
return {
|
|
729
|
+
widthPercent: Math.max(1, numberAttribute(column, 'w')),
|
|
730
|
+
spacing: index === Math.min(count, columnElements.length) - 1 ? 0 : null === columnSpacing ? spacing : twipsToMillimeters(Number(columnSpacing), spacing)
|
|
731
|
+
};
|
|
732
|
+
})
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
function numberAttribute(element, name) {
|
|
736
|
+
const value = Number(attribute(element, name));
|
|
737
|
+
return Number.isFinite(value) ? value : 0;
|
|
738
|
+
}
|
|
739
|
+
function enabledAttribute(element, name) {
|
|
740
|
+
const value = attribute(element, name)?.toLowerCase();
|
|
741
|
+
return '1' === value || 'true' === value || 'on' === value;
|
|
742
|
+
}
|
|
743
|
+
function twipsToMillimeters(value, fallback) {
|
|
744
|
+
return Number.isFinite(value) ? roundOne(Math.max(0, value) / TWIPS_PER_MILLIMETER) : fallback;
|
|
745
|
+
}
|
|
746
|
+
function roundOne(value) {
|
|
747
|
+
return Math.round(10 * value) / 10;
|
|
748
|
+
}
|
|
442
749
|
const work_docx_comment_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
443
750
|
const work_docx_comment_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
444
751
|
async function markDocxComments(document, archive) {
|
|
@@ -641,51 +948,12 @@ function work_docx_comment_import_compareDocumentOrder(left, right) {
|
|
|
641
948
|
if (left === right) return 0;
|
|
642
949
|
return left.compareDocumentPosition(right) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
|
|
643
950
|
}
|
|
644
|
-
const TWIPS_PER_MILLIMETER = 1440 / 25.4;
|
|
645
|
-
function importDocxColumns(element, fallback) {
|
|
646
|
-
const columnElements = directChildren(element, 'col');
|
|
647
|
-
const sourceCount = numberAttribute(element, 'num') || columnElements.length || fallback.count;
|
|
648
|
-
const count = Math.min(6, Math.max(1, sourceCount));
|
|
649
|
-
const spacingAttribute = attribute(element, 'space');
|
|
650
|
-
const spacing = null === spacingAttribute ? fallback.spacing : twipsToMillimeters(Number(spacingAttribute), fallback.spacing);
|
|
651
|
-
const base = {
|
|
652
|
-
count,
|
|
653
|
-
spacing,
|
|
654
|
-
separator: enabledAttribute(element, 'sep')
|
|
655
|
-
};
|
|
656
|
-
if (!columnElements.length) return normalizeDocumentColumns(base);
|
|
657
|
-
return normalizeDocumentColumns({
|
|
658
|
-
...base,
|
|
659
|
-
count: Math.min(count, columnElements.length),
|
|
660
|
-
custom: columnElements.slice(0, count).map((column, index)=>{
|
|
661
|
-
const columnSpacing = attribute(column, 'space');
|
|
662
|
-
return {
|
|
663
|
-
widthPercent: Math.max(1, numberAttribute(column, 'w')),
|
|
664
|
-
spacing: index === Math.min(count, columnElements.length) - 1 ? 0 : null === columnSpacing ? spacing : twipsToMillimeters(Number(columnSpacing), spacing)
|
|
665
|
-
};
|
|
666
|
-
})
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
function numberAttribute(element, name) {
|
|
670
|
-
const value = Number(attribute(element, name));
|
|
671
|
-
return Number.isFinite(value) ? value : 0;
|
|
672
|
-
}
|
|
673
|
-
function enabledAttribute(element, name) {
|
|
674
|
-
const value = attribute(element, name)?.toLowerCase();
|
|
675
|
-
return '1' === value || 'true' === value || 'on' === value;
|
|
676
|
-
}
|
|
677
|
-
function twipsToMillimeters(value, fallback) {
|
|
678
|
-
return Number.isFinite(value) ? roundOne(Math.max(0, value) / TWIPS_PER_MILLIMETER) : fallback;
|
|
679
|
-
}
|
|
680
|
-
function roundOne(value) {
|
|
681
|
-
return Math.round(10 * value) / 10;
|
|
682
|
-
}
|
|
683
951
|
const work_docx_field_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
684
952
|
const work_docx_field_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
685
953
|
function markDocxBodyFields(document) {
|
|
686
954
|
const fields = docxFieldOccurrences(document).flatMap((field, index)=>{
|
|
687
955
|
const kind = docxDocumentFieldKind(field.instruction);
|
|
688
|
-
if (!kind || !
|
|
956
|
+
if (!kind || !docxFieldOccurrenceIsInlineEditable(field)) return [];
|
|
689
957
|
const marker = {
|
|
690
958
|
start: `__A3S_WORK_FIELD_START_${index + 1}__`,
|
|
691
959
|
end: `__A3S_WORK_FIELD_END_${index + 1}__`,
|
|
@@ -719,9 +987,6 @@ function applyImportedDocxFieldMarkers(document, markers) {
|
|
|
719
987
|
function hasImportedDocxFieldMarkers(markers) {
|
|
720
988
|
return markers.fields.length > 0;
|
|
721
989
|
}
|
|
722
|
-
function work_docx_field_import_canMarkField(field) {
|
|
723
|
-
return field.start !== field.end || 'fldSimple' === field.start.localName;
|
|
724
|
-
}
|
|
725
990
|
function work_docx_field_import_insertFieldBoundaryMarkers(document, field, start, end) {
|
|
726
991
|
if ('fldChar' === field.start.localName && 'fldChar' === field.end.localName) {
|
|
727
992
|
field.start.parentNode?.insertBefore(work_docx_field_import_markerText(document, start), field.start);
|
|
@@ -769,68 +1034,262 @@ function work_docx_field_import_textNodes(root) {
|
|
|
769
1034
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
770
1035
|
return nodes;
|
|
771
1036
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1037
|
+
const work_docx_image_layout_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
1038
|
+
const work_docx_image_layout_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
1039
|
+
const EMUS_PER_MILLIMETER = 36000;
|
|
1040
|
+
const IMAGE_LAYOUT_MARKER_PATTERN = /__A3S_WORK_IMAGE_LAYOUT_\d+_(?:START|END)__/g;
|
|
1041
|
+
const MAX_IMPORTED_IMAGE_LAYOUTS = 4096;
|
|
1042
|
+
function createImportedDocxImageLayoutMarkerState() {
|
|
1043
|
+
return {
|
|
1044
|
+
identityRegistry: createDocumentImageIdentityRegistry(),
|
|
1045
|
+
nextMarker: 1
|
|
778
1046
|
};
|
|
779
|
-
const references = Array.from(document.body.querySelectorAll('a[href^="#footnote-"], a[href^="#endnote-"]'));
|
|
780
|
-
for (const reference of references){
|
|
781
|
-
const target = reference.getAttribute('href')?.slice(1) ?? '';
|
|
782
|
-
const kind = noteKindFromTarget(target);
|
|
783
|
-
if (!kind) continue;
|
|
784
|
-
let note = notes.get(target);
|
|
785
|
-
if (!note) {
|
|
786
|
-
counters[kind] += 1;
|
|
787
|
-
note = {
|
|
788
|
-
id: `document-${kind}-${counters[kind]}`,
|
|
789
|
-
kind,
|
|
790
|
-
number: counters[kind],
|
|
791
|
-
html: definitions.get(target) ?? '<p></p>'
|
|
792
|
-
};
|
|
793
|
-
notes.set(target, note);
|
|
794
|
-
}
|
|
795
|
-
const marker = document.createElement('sup');
|
|
796
|
-
marker.setAttribute('data-document-note-reference', 'true');
|
|
797
|
-
marker.setAttribute('data-note-kind', note.kind);
|
|
798
|
-
marker.setAttribute('data-note-id', note.id);
|
|
799
|
-
marker.setAttribute('data-note-number', String(note.number));
|
|
800
|
-
marker.textContent = String(note.number);
|
|
801
|
-
const wrapper = reference.parentElement;
|
|
802
|
-
if (wrapper?.tagName.toLowerCase() === 'sup' && 1 === wrapper.childNodes.length) wrapper.replaceWith(marker);
|
|
803
|
-
else reference.replaceWith(marker);
|
|
804
|
-
}
|
|
805
|
-
return Array.from(notes.values());
|
|
806
1047
|
}
|
|
807
|
-
function
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
(
|
|
1048
|
+
function markDocxImageLayouts(document, state = createImportedDocxImageLayoutMarkerState()) {
|
|
1049
|
+
const images = [];
|
|
1050
|
+
const markedRuns = new Set();
|
|
1051
|
+
const drawings = [
|
|
1052
|
+
...descendants(document, 'anchor'),
|
|
1053
|
+
...descendants(document, 'inline')
|
|
1054
|
+
];
|
|
1055
|
+
for (const anchor of drawings){
|
|
1056
|
+
const run = closestAncestor(anchor, 'r');
|
|
1057
|
+
if (!run || markedRuns.has(run)) continue;
|
|
1058
|
+
const crop = anchorCrop(anchor);
|
|
1059
|
+
const layout = 'inline' === anchor.localName ? 'inline' : anchorLayout(anchor);
|
|
1060
|
+
if (!layout) continue;
|
|
1061
|
+
if (state.nextMarker > MAX_IMPORTED_IMAGE_LAYOUTS) throw new Error('Imported DOCX exceeds the image-layout limit.');
|
|
1062
|
+
markedRuns.add(run);
|
|
1063
|
+
const index = state.nextMarker;
|
|
1064
|
+
state.nextMarker += 1;
|
|
1065
|
+
const startMarker = `__A3S_WORK_IMAGE_LAYOUT_${index}_START__`;
|
|
1066
|
+
const endMarker = `__A3S_WORK_IMAGE_LAYOUT_${index}_END__`;
|
|
1067
|
+
insertMarkerRun(document, run, startMarker, 'before');
|
|
1068
|
+
insertMarkerRun(document, run, endMarker, 'after');
|
|
1069
|
+
images.push({
|
|
1070
|
+
startMarker,
|
|
1071
|
+
endMarker,
|
|
1072
|
+
options: normalizeDocumentImageLayoutOptions({
|
|
1073
|
+
layout,
|
|
1074
|
+
alignment: anchorAlignment(anchor),
|
|
1075
|
+
wrapDistance: anchorWrapDistance(anchor, layout),
|
|
1076
|
+
wrapSide: anchorWrapSide(anchor, layout)
|
|
1077
|
+
}),
|
|
1078
|
+
position: anchorPosition(anchor),
|
|
1079
|
+
crop,
|
|
1080
|
+
contour: isContourImageLayout(layout) ? anchorWrapContour(anchor, layout) : null,
|
|
1081
|
+
layer: 'anchor' === anchor.localName ? anchorLayer(anchor) : null,
|
|
1082
|
+
identity: uniqueDocumentImageIdentity(drawingIdentitySource(anchor), state.identityRegistry)
|
|
1083
|
+
});
|
|
813
1084
|
}
|
|
1085
|
+
return {
|
|
1086
|
+
images
|
|
1087
|
+
};
|
|
814
1088
|
}
|
|
815
|
-
function
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
1089
|
+
function applyImportedDocxImageLayoutMarkers(document, markers) {
|
|
1090
|
+
const starts = new Map(markers.images.map((image)=>[
|
|
1091
|
+
image.startMarker,
|
|
1092
|
+
image
|
|
1093
|
+
]));
|
|
1094
|
+
const ends = new Set(markers.images.map((image)=>image.endMarker));
|
|
1095
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
|
|
1096
|
+
const nodes = [];
|
|
1097
|
+
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
1098
|
+
const state = {
|
|
1099
|
+
active: null,
|
|
1100
|
+
applied: false
|
|
1101
|
+
};
|
|
1102
|
+
for (const node of nodes){
|
|
1103
|
+
if (node instanceof Text) {
|
|
1104
|
+
node.data = node.data.replace(IMAGE_LAYOUT_MARKER_PATTERN, (marker)=>{
|
|
1105
|
+
const start = starts.get(marker);
|
|
1106
|
+
if (start) {
|
|
1107
|
+
state.active = start;
|
|
1108
|
+
state.applied = false;
|
|
1109
|
+
} else if (ends.has(marker)) {
|
|
1110
|
+
state.active = null;
|
|
1111
|
+
state.applied = false;
|
|
1112
|
+
}
|
|
1113
|
+
return '';
|
|
1114
|
+
});
|
|
1115
|
+
continue;
|
|
1116
|
+
}
|
|
1117
|
+
if (!state.applied && state.active && node instanceof HTMLImageElement) {
|
|
1118
|
+
applyImageLayout(node, state.active.options, state.active.position, state.active.crop, state.active.contour, state.active.layer, state.active.identity);
|
|
1119
|
+
state.applied = true;
|
|
1120
|
+
}
|
|
826
1121
|
}
|
|
827
|
-
|
|
1122
|
+
document.body.normalize();
|
|
828
1123
|
}
|
|
829
|
-
function
|
|
830
|
-
|
|
831
|
-
|
|
1124
|
+
function hasImportedDocxImageLayoutMarkers(markers) {
|
|
1125
|
+
return markers.images.length > 0;
|
|
1126
|
+
}
|
|
1127
|
+
function anchorLayout(anchor) {
|
|
1128
|
+
if (directChild(anchor, 'wrapNone')) return 'none';
|
|
1129
|
+
if (directChild(anchor, 'wrapTopAndBottom')) return 'topBottom';
|
|
1130
|
+
if (directChild(anchor, 'wrapSquare')) return 'square';
|
|
1131
|
+
if (directChild(anchor, 'wrapTight')) return 'tight';
|
|
1132
|
+
if (directChild(anchor, 'wrapThrough')) return 'through';
|
|
832
1133
|
return null;
|
|
833
1134
|
}
|
|
1135
|
+
function anchorAlignment(anchor) {
|
|
1136
|
+
const position = directChild(anchor, 'positionH');
|
|
1137
|
+
const alignment = position ? directChild(position, 'align') : void 0;
|
|
1138
|
+
const value = alignment?.textContent?.trim();
|
|
1139
|
+
if ('inside' === value) return 'left';
|
|
1140
|
+
if ('outside' === value) return 'right';
|
|
1141
|
+
return normalizeDocumentImageAlignment(value);
|
|
1142
|
+
}
|
|
1143
|
+
function anchorWrapDistance(anchor, layout) {
|
|
1144
|
+
const wrap = anchorWrapElement(anchor, layout);
|
|
1145
|
+
const names = 'topBottom' === layout ? [
|
|
1146
|
+
'distT',
|
|
1147
|
+
'distB'
|
|
1148
|
+
] : [
|
|
1149
|
+
'distL',
|
|
1150
|
+
'distR'
|
|
1151
|
+
];
|
|
1152
|
+
const distance = Math.max(0, ...names.flatMap((name)=>[
|
|
1153
|
+
numericAttribute(wrap, name) ?? 0,
|
|
1154
|
+
numericAttribute(anchor, name) ?? 0
|
|
1155
|
+
]));
|
|
1156
|
+
return distance / EMUS_PER_MILLIMETER;
|
|
1157
|
+
}
|
|
1158
|
+
function anchorWrapSide(anchor, layout) {
|
|
1159
|
+
return normalizeDocumentImageWrapSide(attribute(anchorWrapElement(anchor, layout) ?? anchor, 'wrapText'));
|
|
1160
|
+
}
|
|
1161
|
+
function anchorWrapElement(anchor, layout) {
|
|
1162
|
+
if ('square' === layout) return directChild(anchor, 'wrapSquare');
|
|
1163
|
+
if ('tight' === layout) return directChild(anchor, 'wrapTight');
|
|
1164
|
+
if ('through' === layout) return directChild(anchor, 'wrapThrough');
|
|
1165
|
+
if ('topBottom' === layout) return directChild(anchor, 'wrapTopAndBottom');
|
|
1166
|
+
if ('none' === layout) return directChild(anchor, 'wrapNone');
|
|
1167
|
+
}
|
|
1168
|
+
function anchorWrapContour(anchor, layout) {
|
|
1169
|
+
const wrap = anchorWrapElement(anchor, layout);
|
|
1170
|
+
const polygon = wrap ? directChild(wrap, 'wrapPolygon') : void 0;
|
|
1171
|
+
if (!polygon) return null;
|
|
1172
|
+
const vertices = directChildren(polygon);
|
|
1173
|
+
if (vertices[0]?.localName !== 'start' || vertices.slice(1).some((element)=>'lineTo' !== element.localName)) return null;
|
|
1174
|
+
return normalizeDocumentImageWrapContour({
|
|
1175
|
+
edited: attribute(polygon, 'edited'),
|
|
1176
|
+
points: vertices.map((point)=>({
|
|
1177
|
+
x: attribute(point, 'x'),
|
|
1178
|
+
y: attribute(point, 'y')
|
|
1179
|
+
}))
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
function anchorPosition(anchor) {
|
|
1183
|
+
const horizontal = directChild(anchor, 'positionH');
|
|
1184
|
+
const vertical = directChild(anchor, 'positionV');
|
|
1185
|
+
const horizontalOffset = positionOffset(horizontal);
|
|
1186
|
+
const verticalOffset = positionOffset(vertical);
|
|
1187
|
+
if (null === horizontalOffset && null === verticalOffset) return null;
|
|
1188
|
+
return normalizeDocumentImagePosition({
|
|
1189
|
+
horizontalOffset,
|
|
1190
|
+
verticalOffset,
|
|
1191
|
+
horizontalReference: horizontal ? attribute(horizontal, 'relativeFrom') : null,
|
|
1192
|
+
verticalReference: vertical ? attribute(vertical, 'relativeFrom') : null
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
function anchorCrop(anchor) {
|
|
1196
|
+
const source = descendants(anchor, 'srcRect')[0];
|
|
1197
|
+
if (!source) return null;
|
|
1198
|
+
return normalizeDocumentImageCrop({
|
|
1199
|
+
cropTop: cropPercentage(source, 't'),
|
|
1200
|
+
cropRight: cropPercentage(source, 'r'),
|
|
1201
|
+
cropBottom: cropPercentage(source, 'b'),
|
|
1202
|
+
cropLeft: cropPercentage(source, 'l')
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
function anchorLayer(anchor) {
|
|
1206
|
+
return normalizeDocumentImageLayer({
|
|
1207
|
+
relativeHeight: attribute(anchor, 'relativeHeight'),
|
|
1208
|
+
behindDocument: anchorBooleanAttribute(anchor, 'behindDoc', false),
|
|
1209
|
+
allowOverlap: anchorBooleanAttribute(anchor, 'allowOverlap', false),
|
|
1210
|
+
layoutInCell: anchorBooleanAttribute(anchor, 'layoutInCell', true),
|
|
1211
|
+
lockAnchor: anchorBooleanAttribute(anchor, 'locked', false)
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
function drawingIdentitySource(anchor) {
|
|
1215
|
+
const properties = directChild(anchor, 'docPr');
|
|
1216
|
+
return {
|
|
1217
|
+
docPropertiesId: properties ? attribute(properties, 'id') : null,
|
|
1218
|
+
anchorId: attribute(anchor, 'anchorId'),
|
|
1219
|
+
editId: attribute(anchor, 'editId')
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
function cropPercentage(source, name) {
|
|
1223
|
+
const value = attribute(source, name)?.trim() ?? '';
|
|
1224
|
+
if (!value) return 0;
|
|
1225
|
+
const number = Number(value.endsWith('%') ? value.slice(0, -1) : value);
|
|
1226
|
+
if (!Number.isFinite(number)) return 0;
|
|
1227
|
+
return value.endsWith('%') ? number : number / 1000;
|
|
1228
|
+
}
|
|
1229
|
+
function positionOffset(position) {
|
|
1230
|
+
const value = position ? directChild(position, 'posOffset') : void 0;
|
|
1231
|
+
if (!value?.textContent?.trim()) return null;
|
|
1232
|
+
const emus = Number(value.textContent);
|
|
1233
|
+
return Number.isFinite(emus) ? emus / EMUS_PER_MILLIMETER : null;
|
|
1234
|
+
}
|
|
1235
|
+
function insertMarkerRun(document, run, marker, position) {
|
|
1236
|
+
const markerRun = document.createElementNS(work_docx_image_layout_import_WORD_NAMESPACE, 'w:r');
|
|
1237
|
+
const text = document.createElementNS(work_docx_image_layout_import_WORD_NAMESPACE, 'w:t');
|
|
1238
|
+
text.setAttributeNS(work_docx_image_layout_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
1239
|
+
text.textContent = marker;
|
|
1240
|
+
markerRun.append(text);
|
|
1241
|
+
const parent = run.parentNode;
|
|
1242
|
+
if (!parent) return;
|
|
1243
|
+
parent.insertBefore(markerRun, 'before' === position ? run : run.nextSibling);
|
|
1244
|
+
}
|
|
1245
|
+
function applyImageLayout(image, options, position, crop, contour, layer, identity) {
|
|
1246
|
+
applyDocumentImageIdentityToElement(image, identity);
|
|
1247
|
+
image.dataset.officeImageLayout = options.layout;
|
|
1248
|
+
image.dataset.officeImageAlignment = options.alignment;
|
|
1249
|
+
image.dataset.officeImageWrapDistance = formatNumber(options.wrapDistance);
|
|
1250
|
+
if (wrapsBesideImage(options.layout) || 'bothSides' !== options.wrapSide) image.dataset.officeImageWrapSide = options.wrapSide;
|
|
1251
|
+
else delete image.dataset.officeImageWrapSide;
|
|
1252
|
+
image.style.setProperty('--work-document-image-wrap-distance', `${formatNumber(options.wrapDistance)}mm`);
|
|
1253
|
+
if (position) {
|
|
1254
|
+
if (null !== position.horizontalOffset) {
|
|
1255
|
+
image.dataset.officeImageHorizontalOffset = formatNumber(position.horizontalOffset);
|
|
1256
|
+
image.style.setProperty('--work-document-image-horizontal-offset', `${formatNumber(position.horizontalOffset)}mm`);
|
|
1257
|
+
}
|
|
1258
|
+
if (null !== position.verticalOffset) {
|
|
1259
|
+
image.dataset.officeImageVerticalOffset = formatNumber(position.verticalOffset);
|
|
1260
|
+
image.style.setProperty('--work-document-image-vertical-offset', `${formatNumber(position.verticalOffset)}mm`);
|
|
1261
|
+
}
|
|
1262
|
+
image.dataset.officeImageHorizontalReference = position.horizontalReference;
|
|
1263
|
+
image.dataset.officeImageVerticalReference = position.verticalReference;
|
|
1264
|
+
}
|
|
1265
|
+
applyDocumentImageCropToElement(image, crop);
|
|
1266
|
+
applyDocumentImageWrapContourToElement(image, contour);
|
|
1267
|
+
if (layer) applyDocumentImageLayerToElement(image, layer);
|
|
1268
|
+
}
|
|
1269
|
+
function anchorBooleanAttribute(element, name, fallback) {
|
|
1270
|
+
const value = attribute(element, name)?.trim().toLowerCase();
|
|
1271
|
+
if ('1' === value || 'true' === value || 'on' === value) return true;
|
|
1272
|
+
if ('0' === value || 'false' === value || 'off' === value) return false;
|
|
1273
|
+
return fallback;
|
|
1274
|
+
}
|
|
1275
|
+
function numericAttribute(element, name) {
|
|
1276
|
+
if (!element) return null;
|
|
1277
|
+
const source = attribute(element, name);
|
|
1278
|
+
if (null === source || !source.trim()) return null;
|
|
1279
|
+
const value = Number(source);
|
|
1280
|
+
return Number.isFinite(value) && value >= 0 ? value : null;
|
|
1281
|
+
}
|
|
1282
|
+
function closestAncestor(element, localName) {
|
|
1283
|
+
let current = element;
|
|
1284
|
+
while(current){
|
|
1285
|
+
if (current.localName === localName) return current;
|
|
1286
|
+
current = current.parentElement;
|
|
1287
|
+
}
|
|
1288
|
+
return null;
|
|
1289
|
+
}
|
|
1290
|
+
function formatNumber(value) {
|
|
1291
|
+
return Number(value.toFixed(2)).toString();
|
|
1292
|
+
}
|
|
834
1293
|
const work_docx_list_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
835
1294
|
const work_docx_list_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
836
1295
|
const LIST_START_MARKER_PATTERN = /__A3S_WORK_LIST_START_\d+__/g;
|
|
@@ -871,14 +1330,65 @@ function markDocxLists(document, numbering) {
|
|
|
871
1330
|
const abstractId = integerAttribute(concrete ? directChild(concrete, 'abstractNumId') : null, 'val');
|
|
872
1331
|
const abstract = null === abstractId ? void 0 : abstractNumbering.get(abstractId);
|
|
873
1332
|
const start = effectiveListStart(concrete, abstract, level);
|
|
1333
|
+
const definition = effectiveListLevel(concrete, abstract, level);
|
|
1334
|
+
const format = stringAttribute(definition ? directChild(definition, 'numFmt') : null, 'val');
|
|
1335
|
+
const text = rawStringAttribute(definition ? directChild(definition, 'lvlText') : null, 'val');
|
|
1336
|
+
const suffix = stringAttribute(definition ? directChild(definition, 'suff') : null, 'val');
|
|
1337
|
+
const alignment = stringAttribute(definition ? directChild(definition, 'lvlJc') : null, 'val');
|
|
1338
|
+
const paragraphProperties = definition ? directChild(definition, 'pPr') : void 0;
|
|
1339
|
+
const indent = paragraphProperties ? directChild(paragraphProperties, 'ind') : void 0;
|
|
1340
|
+
const indentLeft = signedIntegerAttribute(indent, 'left');
|
|
1341
|
+
const indentStart = signedIntegerAttribute(indent, 'start');
|
|
1342
|
+
const indentRight = signedIntegerAttribute(indent, 'right');
|
|
1343
|
+
const indentEnd = signedIntegerAttribute(indent, 'end');
|
|
1344
|
+
const indentHanging = integerAttribute(indent, 'hanging');
|
|
1345
|
+
const indentFirstLine = integerAttribute(indent, 'firstLine');
|
|
1346
|
+
const restartAfterLevel = integerAttribute(definition ? directChild(definition, 'lvlRestart') : null, 'val');
|
|
874
1347
|
const type = effectiveOrderedListType(concrete, abstract, level);
|
|
875
1348
|
const bulletStyle = effectiveBulletListStyle(concrete, abstract, level);
|
|
876
|
-
if (start <= 1 && !type && !bulletStyle) continue;
|
|
877
1349
|
const marker = `__A3S_WORK_LIST_START_${lists.length + 1}__`;
|
|
878
1350
|
insertParagraphMarker(document, paragraph, marker);
|
|
879
1351
|
lists.push({
|
|
880
1352
|
marker,
|
|
881
1353
|
start,
|
|
1354
|
+
numberingId: numId,
|
|
1355
|
+
...null === abstractId ? {} : {
|
|
1356
|
+
abstractNumberingId: abstractId
|
|
1357
|
+
},
|
|
1358
|
+
level,
|
|
1359
|
+
...format ? {
|
|
1360
|
+
format
|
|
1361
|
+
} : {},
|
|
1362
|
+
...text ? {
|
|
1363
|
+
text
|
|
1364
|
+
} : {},
|
|
1365
|
+
...suffix ? {
|
|
1366
|
+
suffix
|
|
1367
|
+
} : {},
|
|
1368
|
+
...alignment ? {
|
|
1369
|
+
alignment
|
|
1370
|
+
} : {},
|
|
1371
|
+
...null === indentLeft ? {} : {
|
|
1372
|
+
indentLeft
|
|
1373
|
+
},
|
|
1374
|
+
...null === indentRight ? {} : {
|
|
1375
|
+
indentRight
|
|
1376
|
+
},
|
|
1377
|
+
...null === indentStart ? {} : {
|
|
1378
|
+
indentStart
|
|
1379
|
+
},
|
|
1380
|
+
...null === indentEnd ? {} : {
|
|
1381
|
+
indentEnd
|
|
1382
|
+
},
|
|
1383
|
+
...null === indentHanging ? {} : {
|
|
1384
|
+
indentHanging
|
|
1385
|
+
},
|
|
1386
|
+
...null === indentFirstLine ? {} : {
|
|
1387
|
+
indentFirstLine
|
|
1388
|
+
},
|
|
1389
|
+
...null === restartAfterLevel ? {} : {
|
|
1390
|
+
restartAfterLevel
|
|
1391
|
+
},
|
|
882
1392
|
...type ? {
|
|
883
1393
|
type
|
|
884
1394
|
} : {},
|
|
@@ -903,6 +1413,20 @@ function applyImportedDocxListMarkers(document, markers) {
|
|
|
903
1413
|
node.data = node.data.replace(LIST_START_MARKER_PATTERN, (marker)=>{
|
|
904
1414
|
const imported = listByMarker.get(marker);
|
|
905
1415
|
if (imported && list instanceof HTMLElement) {
|
|
1416
|
+
list.dataset.officeNumberingId = String(imported.numberingId);
|
|
1417
|
+
list.dataset.officeNumberingLevel = String(imported.level);
|
|
1418
|
+
if (imported.format) list.dataset.officeNumberingFormat = imported.format;
|
|
1419
|
+
if (imported.text) list.dataset.officeNumberingText = imported.text;
|
|
1420
|
+
setOptionalDataset(list, 'officeNumberingSuffix', imported.suffix);
|
|
1421
|
+
setOptionalDataset(list, 'officeNumberingAlignment', imported.alignment);
|
|
1422
|
+
setOptionalDataset(list, 'officeNumberingIndentLeft', imported.indentLeft);
|
|
1423
|
+
setOptionalDataset(list, 'officeNumberingIndentRight', imported.indentRight);
|
|
1424
|
+
setOptionalDataset(list, 'officeNumberingIndentStart', imported.indentStart);
|
|
1425
|
+
setOptionalDataset(list, 'officeNumberingIndentEnd', imported.indentEnd);
|
|
1426
|
+
setOptionalDataset(list, 'officeNumberingIndentHanging', imported.indentHanging);
|
|
1427
|
+
setOptionalDataset(list, 'officeNumberingIndentFirstLine', imported.indentFirstLine);
|
|
1428
|
+
setOptionalDataset(list, 'officeNumberingRestartAfterLevel', imported.restartAfterLevel);
|
|
1429
|
+
if (void 0 !== imported.abstractNumberingId) list.dataset.officeAbstractNumberingId = String(imported.abstractNumberingId);
|
|
906
1430
|
if ('ol' === list.tagName.toLowerCase()) {
|
|
907
1431
|
if (imported.start > 1) list.setAttribute('start', String(imported.start));
|
|
908
1432
|
if (imported.type) list.setAttribute('type', imported.type);
|
|
@@ -967,11 +1491,25 @@ function integerAttribute(element, name) {
|
|
|
967
1491
|
const value = Number(source);
|
|
968
1492
|
return Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
969
1493
|
}
|
|
1494
|
+
function signedIntegerAttribute(element, name) {
|
|
1495
|
+
if (!element) return null;
|
|
1496
|
+
const source = attribute(element, name) ?? (name.includes(':') ? null : attribute(element, `w:${name}`));
|
|
1497
|
+
if (null === source) return null;
|
|
1498
|
+
const value = Number(source);
|
|
1499
|
+
return Number.isSafeInteger(value) ? value : null;
|
|
1500
|
+
}
|
|
1501
|
+
function setOptionalDataset(element, key, value) {
|
|
1502
|
+
if (void 0 !== value) element.dataset[key] = String(value);
|
|
1503
|
+
}
|
|
970
1504
|
function stringAttribute(element, name) {
|
|
971
1505
|
if (!element) return null;
|
|
972
1506
|
const value = attribute(element, name) ?? (name.includes(':') ? null : attribute(element, `w:${name}`));
|
|
973
1507
|
return value?.trim() || null;
|
|
974
1508
|
}
|
|
1509
|
+
function rawStringAttribute(element, name) {
|
|
1510
|
+
if (!element) return null;
|
|
1511
|
+
return attribute(element, name) ?? (name.includes(':') ? null : attribute(element, `w:${name}`));
|
|
1512
|
+
}
|
|
975
1513
|
function work_docx_list_import_textNodes(root) {
|
|
976
1514
|
const document = root.ownerDocument;
|
|
977
1515
|
const walker = document?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
@@ -980,138 +1518,107 @@ function work_docx_list_import_textNodes(root) {
|
|
|
980
1518
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
981
1519
|
return nodes;
|
|
982
1520
|
}
|
|
983
|
-
|
|
984
|
-
const
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
const
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
})
|
|
1009
|
-
}
|
|
1521
|
+
async function markDocxNoteImageLayouts(archive, state) {
|
|
1522
|
+
const markers = {
|
|
1523
|
+
images: []
|
|
1524
|
+
};
|
|
1525
|
+
const parts = [];
|
|
1526
|
+
for (const config of [
|
|
1527
|
+
{
|
|
1528
|
+
path: 'word/footnotes.xml',
|
|
1529
|
+
root: 'footnotes'
|
|
1530
|
+
},
|
|
1531
|
+
{
|
|
1532
|
+
path: 'word/endnotes.xml',
|
|
1533
|
+
root: 'endnotes'
|
|
1534
|
+
}
|
|
1535
|
+
]){
|
|
1536
|
+
if (!archive.has(config.path)) continue;
|
|
1537
|
+
const document = await archive.xml(config.path);
|
|
1538
|
+
const root = document.documentElement;
|
|
1539
|
+
if (root.localName !== config.root || !DOCX_WORDPROCESSING_NAMESPACES.has(root.namespaceURI ?? '')) continue;
|
|
1540
|
+
const partMarkers = markDocxImageLayouts(document, state);
|
|
1541
|
+
if (partMarkers.images.length) {
|
|
1542
|
+
markers.images.push(...partMarkers.images);
|
|
1543
|
+
parts.push({
|
|
1544
|
+
document,
|
|
1545
|
+
path: config.path
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1010
1548
|
}
|
|
1011
1549
|
return {
|
|
1012
|
-
|
|
1550
|
+
markers,
|
|
1551
|
+
parts
|
|
1013
1552
|
};
|
|
1014
1553
|
}
|
|
1015
|
-
function
|
|
1016
|
-
const
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
|
|
1022
|
-
const nodes = [];
|
|
1023
|
-
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
1024
|
-
const state = {
|
|
1025
|
-
active: null,
|
|
1026
|
-
applied: false
|
|
1554
|
+
function extractMammothDocumentNotes(document) {
|
|
1555
|
+
const definitions = extractDefinitions(document);
|
|
1556
|
+
const notes = new Map();
|
|
1557
|
+
const counters = {
|
|
1558
|
+
footnote: 0,
|
|
1559
|
+
endnote: 0
|
|
1027
1560
|
};
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
if (!state.applied && state.active && node instanceof HTMLImageElement) {
|
|
1044
|
-
applyImageLayout(node, state.active.options);
|
|
1045
|
-
state.applied = true;
|
|
1561
|
+
const references = Array.from(document.body.querySelectorAll('a[href^="#footnote-"], a[href^="#endnote-"]'));
|
|
1562
|
+
for (const reference of references){
|
|
1563
|
+
const target = reference.getAttribute('href')?.slice(1) ?? '';
|
|
1564
|
+
const kind = noteKindFromTarget(target);
|
|
1565
|
+
if (!kind) continue;
|
|
1566
|
+
let note = notes.get(target);
|
|
1567
|
+
if (!note) {
|
|
1568
|
+
counters[kind] += 1;
|
|
1569
|
+
note = {
|
|
1570
|
+
id: importedDocumentNoteId(kind, target) ?? `document-${kind}-${counters[kind]}`,
|
|
1571
|
+
kind,
|
|
1572
|
+
number: counters[kind],
|
|
1573
|
+
html: definitions.get(target) ?? '<p></p>'
|
|
1574
|
+
};
|
|
1575
|
+
notes.set(target, note);
|
|
1046
1576
|
}
|
|
1577
|
+
const marker = document.createElement('sup');
|
|
1578
|
+
marker.setAttribute('data-document-note-reference', 'true');
|
|
1579
|
+
marker.setAttribute('data-note-kind', note.kind);
|
|
1580
|
+
marker.setAttribute('data-note-id', note.id);
|
|
1581
|
+
marker.setAttribute('data-note-number', String(note.number));
|
|
1582
|
+
marker.textContent = String(note.number);
|
|
1583
|
+
const wrapper = reference.parentElement;
|
|
1584
|
+
if (wrapper?.tagName.toLowerCase() === 'sup' && 1 === wrapper.childNodes.length) wrapper.replaceWith(marker);
|
|
1585
|
+
else reference.replaceWith(marker);
|
|
1047
1586
|
}
|
|
1048
|
-
|
|
1049
|
-
}
|
|
1050
|
-
function hasImportedDocxImageLayoutMarkers(markers) {
|
|
1051
|
-
return markers.images.length > 0;
|
|
1052
|
-
}
|
|
1053
|
-
function anchorLayout(anchor) {
|
|
1054
|
-
if (directChild(anchor, 'wrapTopAndBottom')) return 'topBottom';
|
|
1055
|
-
if (directChild(anchor, 'wrapSquare') || directChild(anchor, 'wrapTight') || directChild(anchor, 'wrapThrough')) return 'square';
|
|
1056
|
-
return null;
|
|
1057
|
-
}
|
|
1058
|
-
function anchorAlignment(anchor) {
|
|
1059
|
-
const position = directChild(anchor, 'positionH');
|
|
1060
|
-
const alignment = position ? directChild(position, 'align') : void 0;
|
|
1061
|
-
const value = alignment?.textContent?.trim();
|
|
1062
|
-
if ('inside' === value) return 'left';
|
|
1063
|
-
if ('outside' === value) return 'right';
|
|
1064
|
-
return normalizeDocumentImageAlignment(value);
|
|
1065
|
-
}
|
|
1066
|
-
function anchorWrapDistance(anchor, layout) {
|
|
1067
|
-
const wrap = directChild(anchor, 'square' === layout ? 'wrapSquare' : 'wrapTopAndBottom') ?? ('square' === layout ? directChild(anchor, 'wrapTight') ?? directChild(anchor, 'wrapThrough') : void 0);
|
|
1068
|
-
const names = 'square' === layout ? [
|
|
1069
|
-
'distL',
|
|
1070
|
-
'distR'
|
|
1071
|
-
] : [
|
|
1072
|
-
'distT',
|
|
1073
|
-
'distB'
|
|
1074
|
-
];
|
|
1075
|
-
const distance = Math.max(0, ...names.flatMap((name)=>[
|
|
1076
|
-
numericAttribute(wrap, name) ?? 0,
|
|
1077
|
-
numericAttribute(anchor, name) ?? 0
|
|
1078
|
-
]));
|
|
1079
|
-
return distance / EMUS_PER_MILLIMETER;
|
|
1080
|
-
}
|
|
1081
|
-
function insertMarkerRun(document, run, marker, position) {
|
|
1082
|
-
const markerRun = document.createElementNS(work_docx_image_layout_import_WORD_NAMESPACE, 'w:r');
|
|
1083
|
-
const text = document.createElementNS(work_docx_image_layout_import_WORD_NAMESPACE, 'w:t');
|
|
1084
|
-
text.setAttributeNS(work_docx_image_layout_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
1085
|
-
text.textContent = marker;
|
|
1086
|
-
markerRun.append(text);
|
|
1087
|
-
const parent = run.parentNode;
|
|
1088
|
-
if (!parent) return;
|
|
1089
|
-
parent.insertBefore(markerRun, 'before' === position ? run : run.nextSibling);
|
|
1090
|
-
}
|
|
1091
|
-
function applyImageLayout(image, options) {
|
|
1092
|
-
image.dataset.officeImageLayout = options.layout;
|
|
1093
|
-
image.dataset.officeImageAlignment = options.alignment;
|
|
1094
|
-
image.dataset.officeImageWrapDistance = formatNumber(options.wrapDistance);
|
|
1095
|
-
image.style.setProperty('--work-document-image-wrap-distance', `${formatNumber(options.wrapDistance)}mm`);
|
|
1587
|
+
return Array.from(notes.values());
|
|
1096
1588
|
}
|
|
1097
|
-
function
|
|
1098
|
-
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1589
|
+
function placeMammothDocumentNotes(document, notes) {
|
|
1590
|
+
const sections = Array.from(document.body.querySelectorAll('section[data-document-section]'));
|
|
1591
|
+
for (const note of notes){
|
|
1592
|
+
const reference = Array.from(document.body.querySelectorAll('sup[data-document-note-reference]')).find((element)=>element.dataset.noteKind === note.kind && element.dataset.noteId === note.id);
|
|
1593
|
+
const target = 'footnote' === note.kind ? reference?.closest('section[data-document-section]') : sections.at(-1);
|
|
1594
|
+
(target ?? document.body).append(createDocumentNoteElement(document, note));
|
|
1595
|
+
}
|
|
1103
1596
|
}
|
|
1104
|
-
function
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1597
|
+
function extractDefinitions(document) {
|
|
1598
|
+
const definitions = new Map();
|
|
1599
|
+
const elements = Array.from(document.body.querySelectorAll('li[id^="footnote-"], li[id^="endnote-"]'));
|
|
1600
|
+
for (const element of elements){
|
|
1601
|
+
const id = element.id;
|
|
1602
|
+
const clone = element.cloneNode(true);
|
|
1603
|
+
for (const backlink of Array.from(clone.querySelectorAll('a[href^="#footnote-ref-"], a[href^="#endnote-ref-"]')))backlink.remove();
|
|
1604
|
+
definitions.set(id, clone.innerHTML.trim() || '<p></p>');
|
|
1605
|
+
const parent = element.parentElement;
|
|
1606
|
+
element.remove();
|
|
1607
|
+
if (parent && !parent.children.length) parent.remove();
|
|
1109
1608
|
}
|
|
1110
|
-
return
|
|
1609
|
+
return definitions;
|
|
1111
1610
|
}
|
|
1112
|
-
function
|
|
1113
|
-
|
|
1611
|
+
function noteKindFromTarget(target) {
|
|
1612
|
+
if (target.startsWith('footnote-')) return 'footnote';
|
|
1613
|
+
if (target.startsWith('endnote-')) return 'endnote';
|
|
1614
|
+
return null;
|
|
1114
1615
|
}
|
|
1616
|
+
const WORDPROCESSING_DRAWING_NAMESPACES = new Set([
|
|
1617
|
+
'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing',
|
|
1618
|
+
'http://purl.oclc.org/ooxml/drawingml/wordprocessingDrawing'
|
|
1619
|
+
]);
|
|
1620
|
+
const WORDPROCESSING_DRAWING_2010_NAMESPACE = 'http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing';
|
|
1621
|
+
const WORD_2010_NAMESPACE = 'http://schemas.microsoft.com/office/word/2010/wordml';
|
|
1115
1622
|
async function importSectionPageChrome(section, archive, documentRelationships, previous, oddEvenEnabled) {
|
|
1116
1623
|
const fallback = normalizeDocumentPageChrome(previous.pageChrome, previous);
|
|
1117
1624
|
const variants = await Promise.all([
|
|
@@ -1162,16 +1669,25 @@ async function importReferencedPart(section, referenceName, variant, archive, do
|
|
|
1162
1669
|
}
|
|
1163
1670
|
async function pageChromePartHtml(document, archive, partPath) {
|
|
1164
1671
|
const relationships = await archive.relationships(partPath);
|
|
1672
|
+
const themePath = archive.paths('word/theme/').find((path)=>/\/theme\d*\.xml$/i.test(path));
|
|
1673
|
+
const themeDocument = themePath ? await archive.xml(themePath) : null;
|
|
1674
|
+
const settingsDocument = archive.has('word/settings.xml') ? await archive.xml('word/settings.xml') : null;
|
|
1675
|
+
const stylesDocument = archive.has('word/styles.xml') ? await archive.xml('word/styles.xml') : null;
|
|
1676
|
+
const theme = createDocxThemeResolver(themeDocument, settingsDocument);
|
|
1677
|
+
const paragraphStyles = createDocxParagraphStyleResolver(stylesDocument);
|
|
1678
|
+
const tableStyles = createDocxTableStyleResolver(stylesDocument);
|
|
1165
1679
|
const root = document.documentElement;
|
|
1166
1680
|
const blocks = [];
|
|
1167
1681
|
for (const child of directChildren(root)){
|
|
1168
|
-
if ('p' === child.localName) blocks.push(await paragraphHtml(child, archive, relationships));
|
|
1169
|
-
if ('tbl' === child.localName) blocks.push(await tableHtml(child, archive, relationships));
|
|
1682
|
+
if ('p' === child.localName) blocks.push(await paragraphHtml(child, archive, relationships, theme, paragraphStyles, tableStyles));
|
|
1683
|
+
if ('tbl' === child.localName) blocks.push(await tableHtml(child, archive, relationships, theme, paragraphStyles, tableStyles));
|
|
1684
|
+
if (isDocxEquationLikeRoot(child)) blocks.push(`<p>${docxEquationHtml(child)}</p>`);
|
|
1170
1685
|
}
|
|
1171
1686
|
return blocks.join('');
|
|
1172
1687
|
}
|
|
1173
|
-
async function paragraphHtml(paragraph, archive, relationships) {
|
|
1174
|
-
const
|
|
1688
|
+
async function paragraphHtml(paragraph, archive, relationships, theme, paragraphStyles, tableStyles) {
|
|
1689
|
+
const properties = directChild(paragraph, 'pPr');
|
|
1690
|
+
const alignmentValue = attribute(firstDescendant(properties, 'jc') ?? paragraph, 'val');
|
|
1175
1691
|
const alignment = 'center' === alignmentValue ? 'center' : 'right' === alignmentValue || 'end' === alignmentValue ? 'right' : 'both' === alignmentValue || 'distribute' === alignmentValue ? 'justify' : 'left' === alignmentValue || 'start' === alignmentValue ? 'left' : '';
|
|
1176
1692
|
const field = {
|
|
1177
1693
|
active: false,
|
|
@@ -1181,6 +1697,10 @@ async function paragraphHtml(paragraph, archive, relationships) {
|
|
|
1181
1697
|
};
|
|
1182
1698
|
let html = '';
|
|
1183
1699
|
for (const child of directChildren(paragraph))if ('pPr' !== child.localName) {
|
|
1700
|
+
if (isDocxEquationLikeRoot(child)) {
|
|
1701
|
+
html += docxEquationHtml(child);
|
|
1702
|
+
continue;
|
|
1703
|
+
}
|
|
1184
1704
|
if ('hyperlink' === child.localName) {
|
|
1185
1705
|
const content = await containerRunsHtml(child, field, archive, relationships);
|
|
1186
1706
|
const relationship = relationships.get(attribute(child, 'r:id') ?? '');
|
|
@@ -1196,12 +1716,44 @@ async function paragraphHtml(paragraph, archive, relationships) {
|
|
|
1196
1716
|
}
|
|
1197
1717
|
html += await containerRunsHtml(child, field, archive, relationships);
|
|
1198
1718
|
}
|
|
1199
|
-
|
|
1719
|
+
const identityAttributes = paragraphIdentityAttributes(paragraph);
|
|
1720
|
+
const defaultCollapsed = properties ? parseDocxParagraphDefaultCollapsed(properties) : {
|
|
1721
|
+
status: 'absent'
|
|
1722
|
+
};
|
|
1723
|
+
const defaultCollapsedAttribute = 'valid' === defaultCollapsed.status ? ` data-office-default-collapsed="${defaultCollapsed.value}"` : '';
|
|
1724
|
+
const parsedShading = properties ? parseDirectDocxParagraphShading(properties, theme) : void 0;
|
|
1725
|
+
const shading = null === parsedShading ? {
|
|
1726
|
+
pattern: 'nil'
|
|
1727
|
+
} : parsedShading;
|
|
1728
|
+
const shadingAttributes = documentParagraphShadingDomAttributes(shading);
|
|
1729
|
+
const borders = resolveDocxParagraphBordersForParagraph(paragraph, paragraphStyles, theme, tableStyles).borders;
|
|
1730
|
+
const borderAttributes = documentParagraphBordersDomAttributes(borders);
|
|
1731
|
+
const styles = [
|
|
1732
|
+
alignment ? `text-align: ${alignment}` : '',
|
|
1733
|
+
borderAttributes.style ?? '',
|
|
1734
|
+
shadingAttributes.style ?? ''
|
|
1735
|
+
].filter(Boolean);
|
|
1736
|
+
const borderAttribute = borderAttributes['data-office-paragraph-borders'];
|
|
1737
|
+
const shadingAttribute = shadingAttributes['data-office-paragraph-shading'];
|
|
1738
|
+
return `<p${styles.length ? ` style="${escapeHtml(styles.join('; '))}"` : ''}${identityAttributes}${defaultCollapsedAttribute}${borderAttribute ? ` data-office-paragraph-borders="${escapeHtml(borderAttribute)}"` : ''}${shadingAttribute ? ` data-office-paragraph-shading="${escapeHtml(shadingAttribute)}"` : ''}>${html}</p>`;
|
|
1739
|
+
}
|
|
1740
|
+
function paragraphIdentityAttributes(paragraph) {
|
|
1741
|
+
const identity = normalizeDocumentParagraphIdentity({
|
|
1742
|
+
paragraphId: namespacedAttribute(paragraph, WORD_2010_NAMESPACE, 'paraId'),
|
|
1743
|
+
textId: namespacedAttribute(paragraph, WORD_2010_NAMESPACE, 'textId')
|
|
1744
|
+
});
|
|
1745
|
+
return identity ? ` data-office-paragraph-id="${identity.paragraphId}" data-office-paragraph-text-id="${identity.textId}"` : '';
|
|
1200
1746
|
}
|
|
1201
1747
|
async function containerRunsHtml(container, field, archive, relationships) {
|
|
1202
1748
|
if ('r' === container.localName) return runHtml(container, field, archive, relationships);
|
|
1203
1749
|
let html = '';
|
|
1204
|
-
for (const
|
|
1750
|
+
for (const child of directChildren(container)){
|
|
1751
|
+
if (isDocxEquationLikeRoot(child)) {
|
|
1752
|
+
html += docxEquationHtml(child);
|
|
1753
|
+
continue;
|
|
1754
|
+
}
|
|
1755
|
+
html += await containerRunsHtml(child, field, archive, relationships);
|
|
1756
|
+
}
|
|
1205
1757
|
return html;
|
|
1206
1758
|
}
|
|
1207
1759
|
async function runHtml(run, field, archive, relationships) {
|
|
@@ -1216,6 +1768,10 @@ async function runHtml(run, field, archive, relationships) {
|
|
|
1216
1768
|
continue;
|
|
1217
1769
|
}
|
|
1218
1770
|
if (fieldContentVisible(field)) {
|
|
1771
|
+
if (isDocxEquationLikeRoot(child)) {
|
|
1772
|
+
content += docxEquationHtml(child);
|
|
1773
|
+
continue;
|
|
1774
|
+
}
|
|
1219
1775
|
if ('t' === child.localName) content += escapeHtml(child.textContent ?? '');
|
|
1220
1776
|
if ('tab' === child.localName) content += '	';
|
|
1221
1777
|
if ('br' === child.localName || 'cr' === child.localName) content += '<br>';
|
|
@@ -1243,20 +1799,48 @@ async function drawingHtml(drawing, archive, relationships) {
|
|
|
1243
1799
|
const extent = firstDescendant(drawing, 'extent');
|
|
1244
1800
|
const width = Math.max(1, Math.round(Number(attribute(extent ?? drawing, 'cx')) / 9525));
|
|
1245
1801
|
const height = Math.max(1, Math.round(Number(attribute(extent ?? drawing, 'cy')) / 9525));
|
|
1246
|
-
|
|
1802
|
+
const identityAttributes = drawingIdentityAttributes(drawing);
|
|
1803
|
+
return `<img src="${source}" alt="Header or footer image"${width > 1 ? ` width="${width}"` : ''}${height > 1 ? ` height="${height}"` : ''}${identityAttributes}>`;
|
|
1804
|
+
}
|
|
1805
|
+
function drawingIdentityAttributes(drawing) {
|
|
1806
|
+
const anchor = Array.from(drawing.querySelectorAll('*')).find((element)=>('anchor' === element.localName || 'inline' === element.localName) && WORDPROCESSING_DRAWING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
1807
|
+
const properties = anchor ? directChildren(anchor, 'docPr').find((element)=>WORDPROCESSING_DRAWING_NAMESPACES.has(element.namespaceURI ?? '')) : void 0;
|
|
1808
|
+
const identity = normalizeDocumentImageIdentity({
|
|
1809
|
+
docPropertiesId: properties?.getAttribute('id'),
|
|
1810
|
+
anchorId: anchor ? namespacedAttribute(anchor, WORDPROCESSING_DRAWING_2010_NAMESPACE, 'anchorId') : null,
|
|
1811
|
+
editId: anchor ? namespacedAttribute(anchor, WORDPROCESSING_DRAWING_2010_NAMESPACE, 'editId') : null
|
|
1812
|
+
});
|
|
1813
|
+
if (!identity) return '';
|
|
1814
|
+
return [
|
|
1815
|
+
` data-office-image-object-id="${identity.objectId}"`,
|
|
1816
|
+
` data-office-image-doc-properties-id="${identity.docPropertiesId}"`,
|
|
1817
|
+
` data-office-image-anchor-id="${identity.anchorId}"`,
|
|
1818
|
+
` data-office-image-edit-id="${identity.editId}"`
|
|
1819
|
+
].join('');
|
|
1820
|
+
}
|
|
1821
|
+
function namespacedAttribute(element, namespace, localName) {
|
|
1822
|
+
for (const item of Array.from(element.attributes))if (xmlAttributeLocalName(item) === localName && xmlAttributeNamespace(element, item) === namespace) return item.value;
|
|
1823
|
+
return null;
|
|
1247
1824
|
}
|
|
1248
|
-
async function tableHtml(table, archive, relationships) {
|
|
1825
|
+
async function tableHtml(table, archive, relationships, theme, paragraphStyles, tableStyles) {
|
|
1249
1826
|
const rows = [];
|
|
1250
1827
|
for (const row of directChildren(table, 'tr')){
|
|
1251
1828
|
const cells = [];
|
|
1252
1829
|
for (const cell of directChildren(row, 'tc')){
|
|
1253
|
-
const paragraphs = await Promise.all(directChildren(cell, 'p').map((item)=>paragraphHtml(item, archive, relationships)));
|
|
1830
|
+
const paragraphs = await Promise.all(directChildren(cell, 'p').map((item)=>paragraphHtml(item, archive, relationships, theme, paragraphStyles, tableStyles)));
|
|
1254
1831
|
cells.push(`<td>${paragraphs.join('')}</td>`);
|
|
1255
1832
|
}
|
|
1256
|
-
rows.push(`<tr>${cells.join('')}</tr>`);
|
|
1833
|
+
rows.push(`<tr${tableRowIdentityAttributes(row)}>${cells.join('')}</tr>`);
|
|
1257
1834
|
}
|
|
1258
1835
|
return `<table><tbody>${rows.join('')}</tbody></table>`;
|
|
1259
1836
|
}
|
|
1837
|
+
function tableRowIdentityAttributes(row) {
|
|
1838
|
+
const identity = normalizeDocumentTableRowIdentity({
|
|
1839
|
+
rowId: namespacedAttribute(row, WORD_2010_NAMESPACE, 'paraId'),
|
|
1840
|
+
rowTextId: namespacedAttribute(row, WORD_2010_NAMESPACE, 'textId')
|
|
1841
|
+
});
|
|
1842
|
+
return identity ? ` ${DOCUMENT_TABLE_ROW_ID_ATTRIBUTE}="${identity.rowId}" ${DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE}="${identity.rowTextId}"` : '';
|
|
1843
|
+
}
|
|
1260
1844
|
function containsPageNumber(document) {
|
|
1261
1845
|
return descendants(document, 'instrText').some((element)=>/\bPAGE\b/i.test(element.textContent ?? '')) || descendants(document, 'fldSimple').some((element)=>/\bPAGE\b/i.test(attribute(element, 'instr') ?? ''));
|
|
1262
1846
|
}
|
|
@@ -1297,339 +1881,135 @@ function updateFieldState(field, fieldType) {
|
|
|
1297
1881
|
function fieldContentVisible(field) {
|
|
1298
1882
|
return !field.active || field.separated && !field.skipResult;
|
|
1299
1883
|
}
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
const
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
const
|
|
1311
|
-
if (
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
runProperties: directChild(style, 'rPr')
|
|
1319
|
-
};
|
|
1320
|
-
if ('paragraph' === type) styles.set(styleId, value);
|
|
1321
|
-
else characterStyles.set(styleId, value);
|
|
1322
|
-
if ('paragraph' === type && !defaultStyleId && onOffAttribute(style, 'default')) defaultStyleId = styleId;
|
|
1323
|
-
}
|
|
1324
|
-
return {
|
|
1325
|
-
defaultProperties: childPath(stylesDocument.documentElement, 'docDefaults', 'pPrDefault', 'pPr'),
|
|
1326
|
-
defaultRunProperties: childPath(stylesDocument.documentElement, 'docDefaults', 'rPrDefault', 'rPr'),
|
|
1327
|
-
defaultStyleId,
|
|
1328
|
-
styles,
|
|
1329
|
-
characterStyles
|
|
1330
|
-
};
|
|
1331
|
-
}
|
|
1332
|
-
function resolveDocxParagraphStyleResolver(source) {
|
|
1333
|
-
return source && 'styles' in source ? source : createDocxParagraphStyleResolver(source);
|
|
1334
|
-
}
|
|
1335
|
-
function docxParagraphPropertySources(directProperties, resolver, contextualProperties = []) {
|
|
1336
|
-
const sources = [];
|
|
1337
|
-
if (resolver.defaultProperties) sources.push(resolver.defaultProperties);
|
|
1338
|
-
const styleReference = directProperties ? directChild(directProperties, 'pStyle') : void 0;
|
|
1339
|
-
const styleId = (styleReference ? wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
|
|
1340
|
-
if (styleId) sources.push(...stylePropertySources(resolver.styles, styleId, 'paragraphProperties'));
|
|
1341
|
-
sources.push(...contextualProperties);
|
|
1342
|
-
if (directProperties) sources.push(directProperties);
|
|
1343
|
-
return sources;
|
|
1344
|
-
}
|
|
1345
|
-
function docxRunPropertySources(paragraphProperties, runProperties, resolver, contextualProperties = []) {
|
|
1346
|
-
const sources = [];
|
|
1347
|
-
if (resolver.defaultRunProperties) sources.push(resolver.defaultRunProperties);
|
|
1348
|
-
const paragraphStyleReference = paragraphProperties ? directChild(paragraphProperties, 'pStyle') : void 0;
|
|
1349
|
-
const paragraphStyleId = (paragraphStyleReference ? wordAttribute(paragraphStyleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
|
|
1350
|
-
if (paragraphStyleId) sources.push(...stylePropertySources(resolver.styles, paragraphStyleId, 'runProperties'));
|
|
1351
|
-
sources.push(...contextualProperties);
|
|
1352
|
-
const paragraphRunProperties = paragraphProperties ? directChild(paragraphProperties, 'rPr') : void 0;
|
|
1353
|
-
if (paragraphRunProperties) sources.push(paragraphRunProperties);
|
|
1354
|
-
const characterStyleReference = runProperties ? directChild(runProperties, 'rStyle') : void 0;
|
|
1355
|
-
const characterStyleId = characterStyleReference ? wordAttribute(characterStyleReference, 'val')?.trim() : void 0;
|
|
1356
|
-
if (characterStyleId) sources.push(...stylePropertySources(resolver.characterStyles, characterStyleId, 'runProperties'));
|
|
1357
|
-
if (runProperties) sources.push(runProperties);
|
|
1358
|
-
return sources;
|
|
1359
|
-
}
|
|
1360
|
-
function stylePropertySources(styles, styleId, property) {
|
|
1361
|
-
const inherited = [];
|
|
1362
|
-
const visited = new Set();
|
|
1363
|
-
let currentStyleId = styleId;
|
|
1364
|
-
let depth = 0;
|
|
1365
|
-
while(currentStyleId && depth < MAX_STYLE_INHERITANCE_DEPTH && !visited.has(currentStyleId)){
|
|
1366
|
-
depth += 1;
|
|
1367
|
-
visited.add(currentStyleId);
|
|
1368
|
-
const style = styles.get(currentStyleId);
|
|
1369
|
-
if (!style) break;
|
|
1370
|
-
const properties = style[property];
|
|
1371
|
-
if (properties) inherited.push(properties);
|
|
1372
|
-
currentStyleId = style.basedOn;
|
|
1373
|
-
}
|
|
1374
|
-
return inherited.reverse();
|
|
1375
|
-
}
|
|
1376
|
-
function onOffAttribute(element, name) {
|
|
1377
|
-
const value = wordAttribute(element, name)?.trim().toLowerCase();
|
|
1378
|
-
if (null == value) return false;
|
|
1379
|
-
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
1380
|
-
}
|
|
1381
|
-
function wordAttribute(element, name) {
|
|
1382
|
-
return attribute(element, name) ?? attribute(element, `w:${name}`);
|
|
1383
|
-
}
|
|
1384
|
-
const work_docx_table_styles_MAX_STYLE_INHERITANCE_DEPTH = 64;
|
|
1385
|
-
const DEFAULT_TABLE_LOOK = {
|
|
1386
|
-
firstRow: true,
|
|
1387
|
-
lastRow: false,
|
|
1388
|
-
firstColumn: true,
|
|
1389
|
-
lastColumn: false,
|
|
1390
|
-
noHorizontalBand: false,
|
|
1391
|
-
noVerticalBand: true
|
|
1392
|
-
};
|
|
1393
|
-
const TABLE_LOOK_BITS = {
|
|
1394
|
-
firstRow: 0x0020,
|
|
1395
|
-
lastRow: 0x0040,
|
|
1396
|
-
firstColumn: 0x0080,
|
|
1397
|
-
lastColumn: 0x0100,
|
|
1398
|
-
noHorizontalBand: 0x0200,
|
|
1399
|
-
noVerticalBand: 0x0400
|
|
1400
|
-
};
|
|
1401
|
-
function createDocxTableStyleResolver(stylesDocument) {
|
|
1402
|
-
if (!stylesDocument) return {
|
|
1403
|
-
tableStyles: new Map()
|
|
1404
|
-
};
|
|
1405
|
-
const tableStyles = new Map();
|
|
1406
|
-
let defaultStyleId;
|
|
1407
|
-
for (const style of descendants(stylesDocument, 'style')){
|
|
1408
|
-
if ('table' !== work_docx_table_styles_wordAttribute(style, 'type')) continue;
|
|
1409
|
-
const styleId = work_docx_table_styles_wordAttribute(style, 'styleId')?.trim();
|
|
1410
|
-
if (!styleId) continue;
|
|
1411
|
-
const basedOn = directChild(style, 'basedOn');
|
|
1412
|
-
const conditional = new Map();
|
|
1413
|
-
for (const conditionalStyle of directChildren(style, 'tblStylePr')){
|
|
1414
|
-
const type = work_docx_table_styles_wordAttribute(conditionalStyle, 'type')?.trim();
|
|
1415
|
-
if (type) conditional.set(type, styleLayer(conditionalStyle));
|
|
1416
|
-
}
|
|
1417
|
-
tableStyles.set(styleId, {
|
|
1418
|
-
...styleLayer(style),
|
|
1419
|
-
basedOn: basedOn ? work_docx_table_styles_wordAttribute(basedOn, 'val')?.trim() || void 0 : void 0,
|
|
1420
|
-
conditional
|
|
1884
|
+
const work_docx_paragraph_alignment_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
1885
|
+
const work_docx_paragraph_alignment_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
1886
|
+
const PARAGRAPH_ALIGNMENT_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_ALIGNMENT_\d+__/g;
|
|
1887
|
+
function markDocxParagraphAlignments(document, styleSource, tableStyleSource) {
|
|
1888
|
+
const paragraphs = [];
|
|
1889
|
+
const styles = resolveDocxParagraphStyleResolver(styleSource);
|
|
1890
|
+
const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
|
|
1891
|
+
for (const paragraph of descendants(document, 'p')){
|
|
1892
|
+
let properties = directChild(paragraph, 'pPr');
|
|
1893
|
+
const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
|
|
1894
|
+
const alignment = paragraphAlignment(sources);
|
|
1895
|
+
if (!alignment) continue;
|
|
1896
|
+
properties ??= insertParagraphProperties(document, paragraph);
|
|
1897
|
+
const marker = `__A3S_WORK_PARAGRAPH_ALIGNMENT_${paragraphs.length + 1}__`;
|
|
1898
|
+
work_docx_paragraph_alignment_import_insertParagraphMarker(document, paragraph, properties, marker);
|
|
1899
|
+
paragraphs.push({
|
|
1900
|
+
marker,
|
|
1901
|
+
alignment
|
|
1421
1902
|
});
|
|
1422
|
-
if (!defaultStyleId && work_docx_table_styles_onOffAttribute(style, 'default')) defaultStyleId = styleId;
|
|
1423
1903
|
}
|
|
1424
1904
|
return {
|
|
1425
|
-
|
|
1426
|
-
tableStyles
|
|
1905
|
+
paragraphs
|
|
1427
1906
|
};
|
|
1428
1907
|
}
|
|
1429
|
-
function
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
const
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
const table = work_docx_table_styles_closestAncestor(cell, 'tbl');
|
|
1442
|
-
if (!table) return [];
|
|
1443
|
-
const directTableProperties = directChild(table, 'tblPr');
|
|
1444
|
-
const styleReference = directTableProperties ? directChild(directTableProperties, 'tblStyle') : void 0;
|
|
1445
|
-
const styleId = (styleReference ? work_docx_table_styles_wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
|
|
1446
|
-
if (!styleId) return [];
|
|
1447
|
-
const styles = tableStyleChain(resolver.tableStyles, styleId);
|
|
1448
|
-
if (!styles.length) return [];
|
|
1449
|
-
const unconditionalLayers = styles.map(styleLayerFromStyle);
|
|
1450
|
-
const propertySources = unconditionalLayers.map(({ tableProperties })=>tableProperties).filter((properties)=>Boolean(properties));
|
|
1451
|
-
if (directTableProperties) propertySources.push(directTableProperties);
|
|
1452
|
-
const position = tableCellPosition(table, cell);
|
|
1453
|
-
if (!position) return unconditionalLayers;
|
|
1454
|
-
const look = resolveTableLook(propertySources);
|
|
1455
|
-
const rowBandSize = resolveBandSize(propertySources, 'tblStyleRowBandSize');
|
|
1456
|
-
const columnBandSize = resolveBandSize(propertySources, 'tblStyleColBandSize');
|
|
1457
|
-
const layers = [
|
|
1458
|
-
...unconditionalLayers
|
|
1459
|
-
];
|
|
1460
|
-
for (const condition of applicableConditions(position, look, rowBandSize, columnBandSize))for (const style of styles){
|
|
1461
|
-
const layer = style.conditional.get(condition);
|
|
1462
|
-
if (layer) layers.push(layer);
|
|
1463
|
-
}
|
|
1464
|
-
return layers;
|
|
1465
|
-
}
|
|
1466
|
-
function docxTableRunPropertySources(element, resolver) {
|
|
1467
|
-
const cell = work_docx_table_styles_closestAncestor(element, 'tc');
|
|
1468
|
-
if (!cell) return [];
|
|
1469
|
-
const sources = [];
|
|
1470
|
-
for (const layer of docxTableCellStyleLayers(cell, resolver)){
|
|
1471
|
-
const paragraphRunProperties = layer.paragraphProperties ? directChild(layer.paragraphProperties, 'rPr') : void 0;
|
|
1472
|
-
if (paragraphRunProperties) sources.push(paragraphRunProperties);
|
|
1473
|
-
if (layer.runProperties) sources.push(layer.runProperties);
|
|
1474
|
-
}
|
|
1475
|
-
return sources;
|
|
1476
|
-
}
|
|
1477
|
-
function docxTableParagraphPropertySources(element, resolver) {
|
|
1478
|
-
const cell = work_docx_table_styles_closestAncestor(element, 'tc');
|
|
1479
|
-
if (!cell) return [];
|
|
1480
|
-
return docxTableCellStyleLayers(cell, resolver).map(({ paragraphProperties })=>paragraphProperties).filter((properties)=>Boolean(properties));
|
|
1481
|
-
}
|
|
1482
|
-
function styleLayer(parent) {
|
|
1483
|
-
return {
|
|
1484
|
-
tableProperties: directChild(parent, 'tblPr'),
|
|
1485
|
-
cellProperties: directChild(parent, 'tcPr'),
|
|
1486
|
-
paragraphProperties: directChild(parent, 'pPr'),
|
|
1487
|
-
runProperties: directChild(parent, 'rPr')
|
|
1488
|
-
};
|
|
1908
|
+
function applyImportedDocxParagraphAlignmentMarkers(document, markers) {
|
|
1909
|
+
const alignmentByMarker = new Map(markers.paragraphs.map(({ marker, alignment })=>[
|
|
1910
|
+
marker,
|
|
1911
|
+
alignment
|
|
1912
|
+
]));
|
|
1913
|
+
for (const node of work_docx_paragraph_alignment_import_textNodes(document.body))if (node.data.includes('__A3S_WORK_PARAGRAPH_ALIGNMENT_')) node.data = node.data.replace(PARAGRAPH_ALIGNMENT_MARKER_PATTERN, (marker)=>{
|
|
1914
|
+
const alignment = alignmentByMarker.get(marker);
|
|
1915
|
+
const block = alignment ? closestParagraphBlock(node.parentElement, node) : null;
|
|
1916
|
+
if (block && alignment) block.style.textAlign = alignment;
|
|
1917
|
+
return '';
|
|
1918
|
+
});
|
|
1919
|
+
document.body.normalize();
|
|
1489
1920
|
}
|
|
1490
|
-
function
|
|
1491
|
-
return
|
|
1492
|
-
tableProperties: style.tableProperties,
|
|
1493
|
-
cellProperties: style.cellProperties,
|
|
1494
|
-
paragraphProperties: style.paragraphProperties,
|
|
1495
|
-
runProperties: style.runProperties
|
|
1496
|
-
};
|
|
1921
|
+
function hasImportedDocxParagraphAlignmentMarkers(markers) {
|
|
1922
|
+
return markers.paragraphs.length > 0;
|
|
1497
1923
|
}
|
|
1498
|
-
function
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
let
|
|
1502
|
-
let depth = 0;
|
|
1503
|
-
while(currentStyleId && depth < work_docx_table_styles_MAX_STYLE_INHERITANCE_DEPTH && !visited.has(currentStyleId)){
|
|
1504
|
-
depth += 1;
|
|
1505
|
-
visited.add(currentStyleId);
|
|
1506
|
-
const style = styles.get(currentStyleId);
|
|
1507
|
-
if (!style) break;
|
|
1508
|
-
inherited.push(style);
|
|
1509
|
-
currentStyleId = style.basedOn;
|
|
1510
|
-
}
|
|
1511
|
-
return inherited.reverse();
|
|
1512
|
-
}
|
|
1513
|
-
function applicableConditions(position, look, rowBandSize, columnBandSize) {
|
|
1514
|
-
const conditions = [
|
|
1515
|
-
'wholeTable'
|
|
1516
|
-
];
|
|
1517
|
-
const isFirstRow = 0 === position.rowIndex;
|
|
1518
|
-
const isLastRow = position.rowIndex === position.rowCount - 1;
|
|
1519
|
-
const isFirstColumn = 0 === position.columnStart;
|
|
1520
|
-
const isLastColumn = position.columnEnd === position.columnCount - 1;
|
|
1521
|
-
if (!look.noVerticalBand) {
|
|
1522
|
-
const offset = look.firstColumn ? 1 : 0;
|
|
1523
|
-
const bandIndex = position.columnStart - offset;
|
|
1524
|
-
if (bandIndex >= 0) conditions.push(Math.floor(bandIndex / columnBandSize) % 2 === 0 ? 'band1Vert' : 'band2Vert');
|
|
1525
|
-
}
|
|
1526
|
-
if (!look.noHorizontalBand) {
|
|
1527
|
-
const offset = look.firstRow ? 1 : 0;
|
|
1528
|
-
const bandIndex = position.rowIndex - offset;
|
|
1529
|
-
if (bandIndex >= 0) conditions.push(Math.floor(bandIndex / rowBandSize) % 2 === 0 ? 'band1Horz' : 'band2Horz');
|
|
1530
|
-
}
|
|
1531
|
-
if (look.firstColumn && isFirstColumn) conditions.push('firstCol');
|
|
1532
|
-
if (look.lastColumn && isLastColumn) conditions.push('lastCol');
|
|
1533
|
-
if (look.firstRow && isFirstRow) conditions.push('firstRow');
|
|
1534
|
-
if (look.lastRow && isLastRow) conditions.push('lastRow');
|
|
1535
|
-
if (look.firstRow && isFirstRow && look.firstColumn && isFirstColumn) conditions.push('nwCell');
|
|
1536
|
-
if (look.firstRow && isFirstRow && look.lastColumn && isLastColumn) conditions.push('neCell');
|
|
1537
|
-
if (look.lastRow && isLastRow && look.firstColumn && isFirstColumn) conditions.push('swCell');
|
|
1538
|
-
if (look.lastRow && isLastRow && look.lastColumn && isLastColumn) conditions.push('seCell');
|
|
1539
|
-
return conditions;
|
|
1540
|
-
}
|
|
1541
|
-
function resolveTableLook(propertySources) {
|
|
1542
|
-
const look = {
|
|
1543
|
-
...DEFAULT_TABLE_LOOK
|
|
1544
|
-
};
|
|
1924
|
+
function paragraphAlignment(propertySources) {
|
|
1925
|
+
let direction = 'ltr';
|
|
1926
|
+
let justification = null;
|
|
1927
|
+
let hasJustification = false;
|
|
1545
1928
|
for (const properties of propertySources){
|
|
1546
|
-
const
|
|
1547
|
-
if (
|
|
1548
|
-
const
|
|
1549
|
-
if (
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
look.lastRow = Boolean(value & TABLE_LOOK_BITS.lastRow);
|
|
1553
|
-
look.firstColumn = Boolean(value & TABLE_LOOK_BITS.firstColumn);
|
|
1554
|
-
look.lastColumn = Boolean(value & TABLE_LOOK_BITS.lastColumn);
|
|
1555
|
-
look.noHorizontalBand = Boolean(value & TABLE_LOOK_BITS.noHorizontalBand);
|
|
1556
|
-
look.noVerticalBand = Boolean(value & TABLE_LOOK_BITS.noVerticalBand);
|
|
1929
|
+
const bidi = directChild(properties, 'bidi');
|
|
1930
|
+
if (bidi) direction = onOffValue(bidi) ? 'rtl' : 'ltr';
|
|
1931
|
+
const source = directChild(properties, 'jc');
|
|
1932
|
+
if (source) {
|
|
1933
|
+
hasJustification = true;
|
|
1934
|
+
justification = wordAttribute(source, 'val')?.trim() ?? null;
|
|
1557
1935
|
}
|
|
1558
|
-
assignLookFlag(look, 'firstRow', element, 'firstRow');
|
|
1559
|
-
assignLookFlag(look, 'lastRow', element, 'lastRow');
|
|
1560
|
-
assignLookFlag(look, 'firstColumn', element, 'firstColumn');
|
|
1561
|
-
assignLookFlag(look, 'lastColumn', element, 'lastColumn');
|
|
1562
|
-
assignLookFlag(look, 'noHorizontalBand', element, 'noHBand');
|
|
1563
|
-
assignLookFlag(look, 'noVerticalBand', element, 'noVBand');
|
|
1564
1936
|
}
|
|
1565
|
-
return
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
if (
|
|
1937
|
+
if (!hasJustification || !justification) return null;
|
|
1938
|
+
if ('center' === justification) return 'center';
|
|
1939
|
+
if ('left' === justification) return 'left';
|
|
1940
|
+
if ('right' === justification) return 'right';
|
|
1941
|
+
if ('start' === justification) return 'rtl' === direction ? 'right' : 'left';
|
|
1942
|
+
if ('end' === justification) return 'rtl' === direction ? 'left' : 'right';
|
|
1943
|
+
if ('both' === justification || 'distribute' === justification || 'highKashida' === justification || 'lowKashida' === justification || 'mediumKashida' === justification || 'thaiDistribute' === justification) return 'justify';
|
|
1944
|
+
return null;
|
|
1570
1945
|
}
|
|
1571
|
-
function
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
const element = directChild(properties, propertyName);
|
|
1575
|
-
const value = Number(element ? work_docx_table_styles_wordAttribute(element, 'val') : void 0);
|
|
1576
|
-
if (Number.isInteger(value) && value > 0 && value <= 64) size = value;
|
|
1577
|
-
}
|
|
1578
|
-
return size;
|
|
1579
|
-
}
|
|
1580
|
-
function tableCellPosition(table, targetCell) {
|
|
1581
|
-
const rows = descendants(table, 'tr').filter((row)=>work_docx_table_styles_closestAncestor(row, 'tbl') === table);
|
|
1582
|
-
const targetRow = work_docx_table_styles_closestAncestor(targetCell, 'tr');
|
|
1583
|
-
if (!targetRow) return null;
|
|
1584
|
-
const rowIndex = rows.indexOf(targetRow);
|
|
1585
|
-
if (rowIndex < 0) return null;
|
|
1586
|
-
const cells = rowCells(targetRow);
|
|
1587
|
-
const cellIndex = cells.indexOf(targetCell);
|
|
1588
|
-
if (cellIndex < 0) return null;
|
|
1589
|
-
const columnStart = rowGridOffset(targetRow, 'gridBefore') + cells.slice(0, cellIndex).reduce((total, cell)=>total + cellGridSpan(cell), 0);
|
|
1590
|
-
const columnEnd = columnStart + cellGridSpan(targetCell) - 1;
|
|
1591
|
-
const columnCount = Math.max(1, ...rows.map((row)=>rowGridOffset(row, 'gridBefore') + rowCells(row).reduce((total, cell)=>total + cellGridSpan(cell), 0) + rowGridOffset(row, 'gridAfter')));
|
|
1592
|
-
return {
|
|
1593
|
-
rowIndex,
|
|
1594
|
-
rowCount: rows.length,
|
|
1595
|
-
columnStart,
|
|
1596
|
-
columnEnd,
|
|
1597
|
-
columnCount
|
|
1598
|
-
};
|
|
1946
|
+
function onOffValue(element) {
|
|
1947
|
+
const value = wordAttribute(element, 'val')?.trim().toLowerCase();
|
|
1948
|
+
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
1599
1949
|
}
|
|
1600
|
-
function
|
|
1601
|
-
return
|
|
1950
|
+
function wordAttribute(element, name) {
|
|
1951
|
+
return attribute(element, name) ?? attribute(element, `w:${name}`);
|
|
1602
1952
|
}
|
|
1603
|
-
function
|
|
1604
|
-
const
|
|
1605
|
-
const
|
|
1606
|
-
|
|
1607
|
-
|
|
1953
|
+
function work_docx_paragraph_alignment_import_insertParagraphMarker(document, paragraph, properties, marker) {
|
|
1954
|
+
const run = document.createElementNS(work_docx_paragraph_alignment_import_WORD_NAMESPACE, 'w:r');
|
|
1955
|
+
const text = document.createElementNS(work_docx_paragraph_alignment_import_WORD_NAMESPACE, 'w:t');
|
|
1956
|
+
text.setAttributeNS(work_docx_paragraph_alignment_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
1957
|
+
text.textContent = marker;
|
|
1958
|
+
run.append(text);
|
|
1959
|
+
paragraph.insertBefore(run, properties.nextSibling);
|
|
1608
1960
|
}
|
|
1609
|
-
function
|
|
1610
|
-
const properties =
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
return Number.isInteger(value) && value > 0 && value <= 256 ? value : 0;
|
|
1961
|
+
function insertParagraphProperties(document, paragraph) {
|
|
1962
|
+
const properties = document.createElementNS(work_docx_paragraph_alignment_import_WORD_NAMESPACE, 'w:pPr');
|
|
1963
|
+
paragraph.insertBefore(properties, paragraph.firstChild);
|
|
1964
|
+
return properties;
|
|
1614
1965
|
}
|
|
1615
|
-
function
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
current = current.parentElement;
|
|
1620
|
-
}
|
|
1621
|
-
return null;
|
|
1966
|
+
function closestParagraphBlock(element, markerNode) {
|
|
1967
|
+
const block = element?.closest('p, h1, h2, h3, h4, h5, h6, blockquote, li');
|
|
1968
|
+
if (!(block instanceof HTMLElement)) return null;
|
|
1969
|
+
return 'li' === block.tagName.toLowerCase() ? wrapListItemParagraph(block, markerNode) : block;
|
|
1622
1970
|
}
|
|
1623
|
-
function
|
|
1624
|
-
|
|
1971
|
+
function wrapListItemParagraph(item, markerNode) {
|
|
1972
|
+
let anchor = markerNode;
|
|
1973
|
+
while(anchor.parentNode && anchor.parentNode !== item)anchor = anchor.parentNode;
|
|
1974
|
+
const children = Array.from(item.childNodes);
|
|
1975
|
+
const anchorIndex = children.indexOf(anchor);
|
|
1976
|
+
if (anchorIndex < 0) return item;
|
|
1977
|
+
let start = anchorIndex;
|
|
1978
|
+
let end = anchorIndex;
|
|
1979
|
+
while(start > 0 && !isListItemBlock(children[start - 1]))start -= 1;
|
|
1980
|
+
while(end + 1 < children.length && !isListItemBlock(children[end + 1]))end += 1;
|
|
1981
|
+
const paragraph = item.ownerDocument.createElement('p');
|
|
1982
|
+
const grouped = children.slice(start, end + 1);
|
|
1983
|
+
item.insertBefore(paragraph, grouped[0] ?? null);
|
|
1984
|
+
paragraph.append(...grouped);
|
|
1985
|
+
return paragraph;
|
|
1625
1986
|
}
|
|
1626
|
-
function
|
|
1627
|
-
if (
|
|
1628
|
-
|
|
1629
|
-
|
|
1987
|
+
function isListItemBlock(node) {
|
|
1988
|
+
if (!(node instanceof HTMLElement)) return false;
|
|
1989
|
+
return [
|
|
1990
|
+
'blockquote',
|
|
1991
|
+
'div',
|
|
1992
|
+
'h1',
|
|
1993
|
+
'h2',
|
|
1994
|
+
'h3',
|
|
1995
|
+
'h4',
|
|
1996
|
+
'h5',
|
|
1997
|
+
'h6',
|
|
1998
|
+
'hr',
|
|
1999
|
+
'ol',
|
|
2000
|
+
'p',
|
|
2001
|
+
'pre',
|
|
2002
|
+
'table',
|
|
2003
|
+
'ul'
|
|
2004
|
+
].includes(node.tagName.toLowerCase());
|
|
1630
2005
|
}
|
|
1631
|
-
function
|
|
1632
|
-
|
|
2006
|
+
function work_docx_paragraph_alignment_import_textNodes(root) {
|
|
2007
|
+
const document = root.ownerDocument;
|
|
2008
|
+
const walker = document?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
2009
|
+
const nodes = [];
|
|
2010
|
+
if (!walker) return nodes;
|
|
2011
|
+
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
2012
|
+
return nodes;
|
|
1633
2013
|
}
|
|
1634
2014
|
const work_docx_paragraph_direction_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
1635
2015
|
const work_docx_paragraph_direction_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
@@ -1643,7 +2023,7 @@ function markDocxParagraphDirections(document, styleSource, tableStyleSource) {
|
|
|
1643
2023
|
const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
|
|
1644
2024
|
const direction = paragraphDirection(sources);
|
|
1645
2025
|
if (!direction) continue;
|
|
1646
|
-
properties ??=
|
|
2026
|
+
properties ??= work_docx_paragraph_direction_import_insertParagraphProperties(document, paragraph);
|
|
1647
2027
|
const marker = `__A3S_WORK_PARAGRAPH_DIRECTION_${paragraphs.length + 1}__`;
|
|
1648
2028
|
work_docx_paragraph_direction_import_insertParagraphMarker(document, paragraph, properties, marker);
|
|
1649
2029
|
paragraphs.push({
|
|
@@ -1662,7 +2042,7 @@ function applyImportedDocxParagraphDirectionMarkers(document, markers) {
|
|
|
1662
2042
|
]));
|
|
1663
2043
|
for (const node of work_docx_paragraph_direction_import_textNodes(document.body)){
|
|
1664
2044
|
if (!node.data.includes('__A3S_WORK_PARAGRAPH_DIRECTION_')) continue;
|
|
1665
|
-
const block =
|
|
2045
|
+
const block = work_docx_paragraph_direction_import_closestParagraphBlock(node.parentElement);
|
|
1666
2046
|
node.data = node.data.replace(PARAGRAPH_DIRECTION_MARKER_PATTERN, (marker)=>{
|
|
1667
2047
|
const direction = directionByMarker.get(marker);
|
|
1668
2048
|
if (block && direction) block.setAttribute('dir', direction);
|
|
@@ -1694,12 +2074,12 @@ function work_docx_paragraph_direction_import_insertParagraphMarker(document, pa
|
|
|
1694
2074
|
run.append(text);
|
|
1695
2075
|
paragraph.insertBefore(run, properties.nextSibling);
|
|
1696
2076
|
}
|
|
1697
|
-
function
|
|
2077
|
+
function work_docx_paragraph_direction_import_insertParagraphProperties(document, paragraph) {
|
|
1698
2078
|
const properties = document.createElementNS(work_docx_paragraph_direction_import_WORD_NAMESPACE, 'w:pPr');
|
|
1699
2079
|
paragraph.insertBefore(properties, paragraph.firstChild);
|
|
1700
2080
|
return properties;
|
|
1701
2081
|
}
|
|
1702
|
-
function
|
|
2082
|
+
function work_docx_paragraph_direction_import_closestParagraphBlock(element) {
|
|
1703
2083
|
const block = element?.closest('p, h1, h2, h3, h4, h5, h6, blockquote, li');
|
|
1704
2084
|
return block instanceof HTMLElement ? block : null;
|
|
1705
2085
|
}
|
|
@@ -1711,114 +2091,117 @@ function work_docx_paragraph_direction_import_textNodes(root) {
|
|
|
1711
2091
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
1712
2092
|
return nodes;
|
|
1713
2093
|
}
|
|
1714
|
-
const
|
|
1715
|
-
const
|
|
1716
|
-
const
|
|
1717
|
-
|
|
2094
|
+
const work_docx_paragraph_identity_import_WORD_2010_NAMESPACE = 'http://schemas.microsoft.com/office/word/2010/wordml';
|
|
2095
|
+
const work_docx_paragraph_identity_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2096
|
+
const PARAGRAPH_IDENTITY_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_IDENTITY_\d+__/g;
|
|
2097
|
+
const MAX_PARAGRAPH_IDENTITIES = 65536;
|
|
2098
|
+
function markDocxParagraphIdentities(document) {
|
|
2099
|
+
const counts = wordIdentityIdCounts(document);
|
|
2100
|
+
const candidates = descendants(document, 'p').flatMap((element)=>{
|
|
2101
|
+
if (!DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? '')) return [];
|
|
2102
|
+
const identity = wordParagraphIdentity(element);
|
|
2103
|
+
return identity ? [
|
|
2104
|
+
{
|
|
2105
|
+
element,
|
|
2106
|
+
identity
|
|
2107
|
+
}
|
|
2108
|
+
] : [];
|
|
2109
|
+
});
|
|
2110
|
+
if (candidates.length > MAX_PARAGRAPH_IDENTITIES) throw new Error('DOCX exceeds the paragraph-identity limit.');
|
|
1718
2111
|
const paragraphs = [];
|
|
1719
|
-
const
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
|
|
1724
|
-
const alignment = paragraphAlignment(sources);
|
|
1725
|
-
if (!alignment) continue;
|
|
1726
|
-
properties ??= work_docx_paragraph_alignment_import_insertParagraphProperties(document, paragraph);
|
|
1727
|
-
const marker = `__A3S_WORK_PARAGRAPH_ALIGNMENT_${paragraphs.length + 1}__`;
|
|
1728
|
-
work_docx_paragraph_alignment_import_insertParagraphMarker(document, paragraph, properties, marker);
|
|
2112
|
+
for (const candidate of candidates){
|
|
2113
|
+
if (1 !== counts.get(candidate.identity.paragraphId)) continue;
|
|
2114
|
+
const marker = `__A3S_WORK_PARAGRAPH_IDENTITY_${paragraphs.length + 1}__`;
|
|
2115
|
+
work_docx_paragraph_identity_import_insertParagraphMarker(candidate.element, marker);
|
|
1729
2116
|
paragraphs.push({
|
|
1730
2117
|
marker,
|
|
1731
|
-
|
|
2118
|
+
...candidate.identity
|
|
1732
2119
|
});
|
|
1733
2120
|
}
|
|
1734
2121
|
return {
|
|
1735
2122
|
paragraphs
|
|
1736
2123
|
};
|
|
1737
2124
|
}
|
|
1738
|
-
function
|
|
1739
|
-
const
|
|
2125
|
+
function wordIdentityIdCounts(document) {
|
|
2126
|
+
const counts = new Map();
|
|
2127
|
+
for (const localName of [
|
|
2128
|
+
'p',
|
|
2129
|
+
'tr'
|
|
2130
|
+
])for (const element of descendants(document, localName)){
|
|
2131
|
+
if (!DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? '')) continue;
|
|
2132
|
+
const paragraphId = normalizeDocumentParagraphId(word2010Attribute(element, 'paraId'));
|
|
2133
|
+
if (paragraphId) counts.set(paragraphId, (counts.get(paragraphId) ?? 0) + 1);
|
|
2134
|
+
}
|
|
2135
|
+
return counts;
|
|
2136
|
+
}
|
|
2137
|
+
function applyImportedDocxParagraphIdentityMarkers(document, markers) {
|
|
2138
|
+
const identities = new Map(markers.paragraphs.map(({ marker, paragraphId, textId })=>[
|
|
1740
2139
|
marker,
|
|
1741
|
-
|
|
2140
|
+
{
|
|
2141
|
+
paragraphId,
|
|
2142
|
+
textId
|
|
2143
|
+
}
|
|
1742
2144
|
]));
|
|
1743
|
-
for (const node of
|
|
1744
|
-
const
|
|
1745
|
-
const block =
|
|
1746
|
-
if (
|
|
2145
|
+
for (const node of work_docx_paragraph_identity_import_textNodes(document.body))if (node.data.includes('__A3S_WORK_PARAGRAPH_IDENTITY_')) node.data = node.data.replace(PARAGRAPH_IDENTITY_MARKER_PATTERN, (marker)=>{
|
|
2146
|
+
const identity = identities.get(marker);
|
|
2147
|
+
const block = identity ? work_docx_paragraph_identity_import_closestParagraphBlock(node.parentElement, node) : null;
|
|
2148
|
+
if (identity && block) applyDocumentParagraphIdentityToElement(block, identity);
|
|
1747
2149
|
return '';
|
|
1748
2150
|
});
|
|
1749
2151
|
document.body.normalize();
|
|
1750
2152
|
}
|
|
1751
|
-
function
|
|
2153
|
+
function hasImportedDocxParagraphIdentityMarkers(markers) {
|
|
1752
2154
|
return markers.paragraphs.length > 0;
|
|
1753
2155
|
}
|
|
1754
|
-
function
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
const bidi = directChild(properties, 'bidi');
|
|
1760
|
-
if (bidi) direction = work_docx_paragraph_alignment_import_onOffValue(bidi) ? 'rtl' : 'ltr';
|
|
1761
|
-
const source = directChild(properties, 'jc');
|
|
1762
|
-
if (source) {
|
|
1763
|
-
hasJustification = true;
|
|
1764
|
-
justification = work_docx_paragraph_alignment_import_wordAttribute(source, 'val')?.trim() ?? null;
|
|
1765
|
-
}
|
|
1766
|
-
}
|
|
1767
|
-
if (!hasJustification || !justification) return null;
|
|
1768
|
-
if ('center' === justification) return 'center';
|
|
1769
|
-
if ('left' === justification) return 'left';
|
|
1770
|
-
if ('right' === justification) return 'right';
|
|
1771
|
-
if ('start' === justification) return 'rtl' === direction ? 'right' : 'left';
|
|
1772
|
-
if ('end' === justification) return 'rtl' === direction ? 'left' : 'right';
|
|
1773
|
-
if ('both' === justification || 'distribute' === justification || 'highKashida' === justification || 'lowKashida' === justification || 'mediumKashida' === justification || 'thaiDistribute' === justification) return 'justify';
|
|
1774
|
-
return null;
|
|
1775
|
-
}
|
|
1776
|
-
function work_docx_paragraph_alignment_import_onOffValue(element) {
|
|
1777
|
-
const value = work_docx_paragraph_alignment_import_wordAttribute(element, 'val')?.trim().toLowerCase();
|
|
1778
|
-
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
2156
|
+
function wordParagraphIdentity(paragraph) {
|
|
2157
|
+
return normalizeDocumentParagraphIdentity({
|
|
2158
|
+
paragraphId: word2010Attribute(paragraph, 'paraId'),
|
|
2159
|
+
textId: word2010Attribute(paragraph, 'textId')
|
|
2160
|
+
});
|
|
1779
2161
|
}
|
|
1780
|
-
function
|
|
1781
|
-
return
|
|
2162
|
+
function word2010Attribute(element, localName) {
|
|
2163
|
+
return Array.from(element.attributes).find((item)=>xmlAttributeLocalName(item) === localName && xmlAttributeNamespace(element, item) === work_docx_paragraph_identity_import_WORD_2010_NAMESPACE)?.value ?? null;
|
|
1782
2164
|
}
|
|
1783
|
-
function
|
|
1784
|
-
const
|
|
1785
|
-
const
|
|
1786
|
-
|
|
2165
|
+
function work_docx_paragraph_identity_import_insertParagraphMarker(paragraph, marker) {
|
|
2166
|
+
const document = paragraph.ownerDocument;
|
|
2167
|
+
const namespace = paragraph.namespaceURI ?? '';
|
|
2168
|
+
const prefix = paragraph.prefix ? `${paragraph.prefix}:` : '';
|
|
2169
|
+
const run = document.createElementNS(namespace, `${prefix}r`);
|
|
2170
|
+
const text = document.createElementNS(namespace, `${prefix}t`);
|
|
2171
|
+
text.setAttributeNS(work_docx_paragraph_identity_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
1787
2172
|
text.textContent = marker;
|
|
1788
2173
|
run.append(text);
|
|
1789
|
-
paragraph
|
|
1790
|
-
|
|
1791
|
-
function work_docx_paragraph_alignment_import_insertParagraphProperties(document, paragraph) {
|
|
1792
|
-
const properties = document.createElementNS(work_docx_paragraph_alignment_import_WORD_NAMESPACE, 'w:pPr');
|
|
1793
|
-
paragraph.insertBefore(properties, paragraph.firstChild);
|
|
1794
|
-
return properties;
|
|
2174
|
+
const properties = directChildren(paragraph, 'pPr').find((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
2175
|
+
paragraph.insertBefore(run, properties?.nextSibling ?? paragraph.firstChild);
|
|
1795
2176
|
}
|
|
1796
|
-
function
|
|
1797
|
-
const
|
|
1798
|
-
if (
|
|
1799
|
-
|
|
2177
|
+
function work_docx_paragraph_identity_import_closestParagraphBlock(element, markerNode) {
|
|
2178
|
+
const explicit = element?.closest('p, h1, h2, h3, h4, h5, h6, figcaption');
|
|
2179
|
+
if (explicit instanceof HTMLElement) return explicit;
|
|
2180
|
+
const container = element?.closest('li, blockquote, td, th, div');
|
|
2181
|
+
return container instanceof HTMLElement ? wrapParagraphSegment(container, markerNode) : null;
|
|
1800
2182
|
}
|
|
1801
|
-
function
|
|
2183
|
+
function wrapParagraphSegment(container, markerNode) {
|
|
1802
2184
|
let anchor = markerNode;
|
|
1803
|
-
while(anchor.parentNode && anchor.parentNode !==
|
|
1804
|
-
const children = Array.from(
|
|
2185
|
+
while(anchor.parentNode && anchor.parentNode !== container)anchor = anchor.parentNode;
|
|
2186
|
+
const children = Array.from(container.childNodes);
|
|
1805
2187
|
const anchorIndex = children.indexOf(anchor);
|
|
1806
|
-
if (anchorIndex < 0) return
|
|
2188
|
+
if (anchorIndex < 0) return container;
|
|
1807
2189
|
let start = anchorIndex;
|
|
1808
2190
|
let end = anchorIndex;
|
|
1809
|
-
while(start > 0 && !
|
|
1810
|
-
while(end + 1 < children.length && !
|
|
1811
|
-
const paragraph =
|
|
2191
|
+
while(start > 0 && !isParagraphBoundary(children[start - 1]))start -= 1;
|
|
2192
|
+
while(end + 1 < children.length && !isParagraphBoundary(children[end + 1]))end += 1;
|
|
2193
|
+
const paragraph = container.ownerDocument.createElement('p');
|
|
1812
2194
|
const grouped = children.slice(start, end + 1);
|
|
1813
|
-
|
|
2195
|
+
container.insertBefore(paragraph, grouped[0] ?? null);
|
|
1814
2196
|
paragraph.append(...grouped);
|
|
1815
2197
|
return paragraph;
|
|
1816
2198
|
}
|
|
1817
|
-
function
|
|
2199
|
+
function isParagraphBoundary(node) {
|
|
1818
2200
|
if (!(node instanceof HTMLElement)) return false;
|
|
1819
2201
|
return [
|
|
1820
2202
|
'blockquote',
|
|
1821
2203
|
'div',
|
|
2204
|
+
'figcaption',
|
|
1822
2205
|
'h1',
|
|
1823
2206
|
'h2',
|
|
1824
2207
|
'h3',
|
|
@@ -1833,9 +2216,8 @@ function isListItemBlock(node) {
|
|
|
1833
2216
|
'ul'
|
|
1834
2217
|
].includes(node.tagName.toLowerCase());
|
|
1835
2218
|
}
|
|
1836
|
-
function
|
|
1837
|
-
const
|
|
1838
|
-
const walker = document?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
2219
|
+
function work_docx_paragraph_identity_import_textNodes(root) {
|
|
2220
|
+
const walker = root.ownerDocument?.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
1839
2221
|
const nodes = [];
|
|
1840
2222
|
if (!walker) return nodes;
|
|
1841
2223
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
@@ -2011,10 +2393,18 @@ function paragraphPagination(sources) {
|
|
|
2011
2393
|
const keepWithNext = directChild(properties, 'keepNext');
|
|
2012
2394
|
const pageBreakBefore = directChild(properties, 'pageBreakBefore');
|
|
2013
2395
|
const widowControl = directChild(properties, 'widowControl');
|
|
2396
|
+
const contextualSpacing = directChild(properties, 'contextualSpacing');
|
|
2397
|
+
const outlineLevel = directChild(properties, 'outlineLvl');
|
|
2398
|
+
const defaultCollapsed = parseDocxParagraphDefaultCollapsed(properties);
|
|
2014
2399
|
if (keepLines) pagination.keepLines = work_docx_paragraph_pagination_import_onOffValue(keepLines);
|
|
2015
2400
|
if (keepWithNext) pagination.keepWithNext = work_docx_paragraph_pagination_import_onOffValue(keepWithNext);
|
|
2016
2401
|
if (pageBreakBefore) pagination.pageBreakBefore = work_docx_paragraph_pagination_import_onOffValue(pageBreakBefore);
|
|
2017
2402
|
if (widowControl) pagination.widowControl = work_docx_paragraph_pagination_import_onOffValue(widowControl);
|
|
2403
|
+
if (contextualSpacing) pagination.contextualSpacing = work_docx_paragraph_pagination_import_onOffValue(contextualSpacing);
|
|
2404
|
+
const outline = integerValue(outlineLevel);
|
|
2405
|
+
if (null !== outline && outline <= 9) pagination.outlineLevel = outline;
|
|
2406
|
+
if ('valid' === defaultCollapsed.status) pagination.defaultCollapsed = defaultCollapsed.value;
|
|
2407
|
+
else if ('invalid' === defaultCollapsed.status) delete pagination.defaultCollapsed;
|
|
2018
2408
|
}
|
|
2019
2409
|
return pagination;
|
|
2020
2410
|
}
|
|
@@ -2044,6 +2434,14 @@ function applyParagraphPagination(element, pagination) {
|
|
|
2044
2434
|
setBooleanAttribute(element, 'data-office-keep-with-next', pagination.keepWithNext);
|
|
2045
2435
|
setBooleanAttribute(element, 'data-office-page-break-before', pagination.pageBreakBefore);
|
|
2046
2436
|
setBooleanAttribute(element, 'data-office-widow-control', pagination.widowControl);
|
|
2437
|
+
setBooleanAttribute(element, 'data-office-contextual-spacing', pagination.contextualSpacing);
|
|
2438
|
+
setBooleanAttribute(element, 'data-office-default-collapsed', pagination.defaultCollapsed);
|
|
2439
|
+
if (void 0 !== pagination.outlineLevel) element.dataset.officeOutlineLevel = String(pagination.outlineLevel);
|
|
2440
|
+
}
|
|
2441
|
+
function integerValue(element) {
|
|
2442
|
+
if (!element) return null;
|
|
2443
|
+
const value = Number(attribute(element, 'val') ?? attribute(element, 'w:val'));
|
|
2444
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
2047
2445
|
}
|
|
2048
2446
|
function setBooleanAttribute(element, name, value) {
|
|
2049
2447
|
if (void 0 !== value) element.setAttribute(name, String(value));
|
|
@@ -2195,93 +2593,6 @@ function work_docx_paragraph_spacing_import_textNodes(root) {
|
|
|
2195
2593
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
2196
2594
|
return nodes;
|
|
2197
2595
|
}
|
|
2198
|
-
function createDocxThemeResolver(themeDocument) {
|
|
2199
|
-
if (!themeDocument) return {
|
|
2200
|
-
colors: new Map(),
|
|
2201
|
-
fonts: new Map()
|
|
2202
|
-
};
|
|
2203
|
-
const fonts = new Map();
|
|
2204
|
-
const fontScheme = firstDescendant(themeDocument, 'fontScheme');
|
|
2205
|
-
addThemeFontFamily(fonts, 'major', fontScheme ? directChild(fontScheme, 'majorFont') : void 0);
|
|
2206
|
-
addThemeFontFamily(fonts, 'minor', fontScheme ? directChild(fontScheme, 'minorFont') : void 0);
|
|
2207
|
-
const colors = new Map();
|
|
2208
|
-
const colorScheme = firstDescendant(themeDocument, 'clrScheme');
|
|
2209
|
-
if (colorScheme) for (const entry of directChildren(colorScheme)){
|
|
2210
|
-
const color = themeColorValue(directChildren(entry)[0]);
|
|
2211
|
-
if (color) colors.set(entry.localName.toLowerCase(), color);
|
|
2212
|
-
}
|
|
2213
|
-
return {
|
|
2214
|
-
colors,
|
|
2215
|
-
fonts
|
|
2216
|
-
};
|
|
2217
|
-
}
|
|
2218
|
-
function resolveDocxThemeResolver(source) {
|
|
2219
|
-
return isDocxThemeResolver(source) ? source : createDocxThemeResolver(source);
|
|
2220
|
-
}
|
|
2221
|
-
function docxThemeFont(resolver, key) {
|
|
2222
|
-
return key ? resolver.fonts.get(key.trim().toLowerCase()) : void 0;
|
|
2223
|
-
}
|
|
2224
|
-
function docxThemeColor(resolver, key, tint, shade) {
|
|
2225
|
-
const color = key ? resolver.colors.get(key.trim().toLowerCase()) : void 0;
|
|
2226
|
-
if (!color) return;
|
|
2227
|
-
const channels = [
|
|
2228
|
-
Number.parseInt(color.slice(0, 2), 16),
|
|
2229
|
-
Number.parseInt(color.slice(2, 4), 16),
|
|
2230
|
-
Number.parseInt(color.slice(4, 6), 16)
|
|
2231
|
-
];
|
|
2232
|
-
const shadeFactor = hexFactor(shade);
|
|
2233
|
-
const tintFactor = hexFactor(tint);
|
|
2234
|
-
const transformed = channels.map((channel)=>{
|
|
2235
|
-
const shaded = void 0 === shadeFactor ? channel : channel * shadeFactor;
|
|
2236
|
-
const tinted = void 0 === tintFactor ? shaded : shaded + (255 - shaded) * tintFactor;
|
|
2237
|
-
return Math.max(0, Math.min(255, Math.round(tinted)));
|
|
2238
|
-
});
|
|
2239
|
-
return transformed.map((channel)=>channel.toString(16).padStart(2, '0')).join('');
|
|
2240
|
-
}
|
|
2241
|
-
function addThemeFontFamily(fonts, prefix, family) {
|
|
2242
|
-
if (!family) return;
|
|
2243
|
-
const latin = typeface(directChild(family, 'latin'));
|
|
2244
|
-
const eastAsia = typeface(directChild(family, 'ea')) || scriptTypeface(family, [
|
|
2245
|
-
'Hans',
|
|
2246
|
-
'Hant',
|
|
2247
|
-
'Jpan',
|
|
2248
|
-
'Hang'
|
|
2249
|
-
]) || latin;
|
|
2250
|
-
const complex = typeface(directChild(family, 'cs')) || latin;
|
|
2251
|
-
if (latin) {
|
|
2252
|
-
fonts.set(`${prefix}ascii`, latin);
|
|
2253
|
-
fonts.set(`${prefix}hansi`, latin);
|
|
2254
|
-
}
|
|
2255
|
-
if (eastAsia) fonts.set(`${prefix}eastasia`, eastAsia);
|
|
2256
|
-
if (complex) fonts.set(`${prefix}bidi`, complex);
|
|
2257
|
-
}
|
|
2258
|
-
function scriptTypeface(family, scripts) {
|
|
2259
|
-
const fonts = directChildren(family, 'font');
|
|
2260
|
-
for (const script of scripts){
|
|
2261
|
-
const font = fonts.find((candidate)=>drawingAttribute(candidate, "script") === script);
|
|
2262
|
-
const value = font ? typeface(font) : void 0;
|
|
2263
|
-
if (value) return value;
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
2266
|
-
function typeface(element) {
|
|
2267
|
-
const value = element ? drawingAttribute(element, 'typeface')?.trim() : void 0;
|
|
2268
|
-
return value || void 0;
|
|
2269
|
-
}
|
|
2270
|
-
function themeColorValue(element) {
|
|
2271
|
-
if (!element) return;
|
|
2272
|
-
const value = 'sysClr' === element.localName ? drawingAttribute(element, 'lastClr') : drawingAttribute(element, 'val');
|
|
2273
|
-
return value && /^[0-9a-f]{6}$/i.test(value) ? value.toLowerCase() : void 0;
|
|
2274
|
-
}
|
|
2275
|
-
function drawingAttribute(element, name) {
|
|
2276
|
-
return attribute(element, name) ?? attribute(element, `a:${name}`);
|
|
2277
|
-
}
|
|
2278
|
-
function hexFactor(value) {
|
|
2279
|
-
if (!value || !/^[0-9a-f]{2}$/i.test(value)) return;
|
|
2280
|
-
return Number.parseInt(value, 16) / 255;
|
|
2281
|
-
}
|
|
2282
|
-
function isDocxThemeResolver(source) {
|
|
2283
|
-
return Boolean(source && 'colors' in source && source.colors instanceof Map && 'fonts' in source && source.fonts instanceof Map);
|
|
2284
|
-
}
|
|
2285
2596
|
const work_docx_run_formatting_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2286
2597
|
const work_docx_run_formatting_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2287
2598
|
const RUN_FORMATTING_MARKER_PATTERN = /__A3S_WORK_RUN_(?:START|END)_\d+__/g;
|
|
@@ -2331,6 +2642,8 @@ function resolvedRunFormatting(propertySources, theme, runText) {
|
|
|
2331
2642
|
let complexFontSize;
|
|
2332
2643
|
let color;
|
|
2333
2644
|
let backgroundColor;
|
|
2645
|
+
let themeColor;
|
|
2646
|
+
let themeFill;
|
|
2334
2647
|
let bold;
|
|
2335
2648
|
let complexBold;
|
|
2336
2649
|
let italic;
|
|
@@ -2368,21 +2681,38 @@ function resolvedRunFormatting(propertySources, theme, runText) {
|
|
|
2368
2681
|
if (colorElement) {
|
|
2369
2682
|
const value = work_docx_run_formatting_import_wordAttribute(colorElement, 'val')?.trim();
|
|
2370
2683
|
const themed = docxThemeColor(theme, work_docx_run_formatting_import_wordAttribute(colorElement, 'themeColor'), work_docx_run_formatting_import_wordAttribute(colorElement, 'themeTint'), work_docx_run_formatting_import_wordAttribute(colorElement, 'themeShade'));
|
|
2371
|
-
if (themed)
|
|
2372
|
-
|
|
2373
|
-
|
|
2684
|
+
if (themed) {
|
|
2685
|
+
color = `#${themed}`;
|
|
2686
|
+
themeColor = themeReference(colorElement, 'themeColor', 'themeTint', 'themeShade', color);
|
|
2687
|
+
} else if (value?.toLowerCase() === 'auto') {
|
|
2688
|
+
color = 'inherit';
|
|
2689
|
+
themeColor = void 0;
|
|
2690
|
+
} else if (value && /^[0-9a-f]{6}$/i.test(value)) {
|
|
2691
|
+
color = `#${value.toLowerCase()}`;
|
|
2692
|
+
themeColor = void 0;
|
|
2693
|
+
}
|
|
2374
2694
|
}
|
|
2375
2695
|
const highlight = directChild(properties, 'highlight');
|
|
2376
2696
|
if (highlight) {
|
|
2377
2697
|
const value = work_docx_run_formatting_import_wordAttribute(highlight, 'val')?.trim().toLowerCase();
|
|
2378
|
-
if (value)
|
|
2698
|
+
if (value) {
|
|
2699
|
+
backgroundColor = wordHighlightColor(value);
|
|
2700
|
+
themeFill = void 0;
|
|
2701
|
+
}
|
|
2379
2702
|
} else {
|
|
2380
2703
|
const shading = directChild(properties, 'shd');
|
|
2381
2704
|
const fill = shading ? work_docx_run_formatting_import_wordAttribute(shading, 'fill')?.trim() : void 0;
|
|
2382
2705
|
const themed = shading ? docxThemeColor(theme, work_docx_run_formatting_import_wordAttribute(shading, 'themeFill'), work_docx_run_formatting_import_wordAttribute(shading, 'themeFillTint'), work_docx_run_formatting_import_wordAttribute(shading, 'themeFillShade')) : void 0;
|
|
2383
|
-
if (themed)
|
|
2384
|
-
|
|
2385
|
-
|
|
2706
|
+
if (themed) {
|
|
2707
|
+
backgroundColor = `#${themed}`;
|
|
2708
|
+
themeFill = themeReference(shading, 'themeFill', 'themeFillTint', 'themeFillShade', backgroundColor);
|
|
2709
|
+
} else if (fill?.toLowerCase() === 'auto') {
|
|
2710
|
+
backgroundColor = 'transparent';
|
|
2711
|
+
themeFill = void 0;
|
|
2712
|
+
} else if (fill && /^[0-9a-f]{6}$/i.test(fill)) {
|
|
2713
|
+
backgroundColor = `#${fill.toLowerCase()}`;
|
|
2714
|
+
themeFill = void 0;
|
|
2715
|
+
}
|
|
2386
2716
|
}
|
|
2387
2717
|
}
|
|
2388
2718
|
const fontSlot = true === complexScriptFormatting || true === rightToLeft ? 'complex' : docxFontSlotForText(runText, fontHint);
|
|
@@ -2426,6 +2756,12 @@ function resolvedRunFormatting(propertySources, theme, runText) {
|
|
|
2426
2756
|
} : {},
|
|
2427
2757
|
...backgroundColor ? {
|
|
2428
2758
|
backgroundColor
|
|
2759
|
+
} : {},
|
|
2760
|
+
...themeColor ? {
|
|
2761
|
+
themeColor
|
|
2762
|
+
} : {},
|
|
2763
|
+
...themeFill ? {
|
|
2764
|
+
themeFill
|
|
2429
2765
|
} : {}
|
|
2430
2766
|
};
|
|
2431
2767
|
}
|
|
@@ -2455,7 +2791,11 @@ function formattingMarkup(document, formatting) {
|
|
|
2455
2791
|
if (void 0 !== formatting.wordSnapToGrid) span.dataset.officeWordSnapToGrid = String(formatting.wordSnapToGrid);
|
|
2456
2792
|
if (void 0 !== formatting.fontSize) span.style.fontSize = `${work_docx_run_formatting_import_formatNumber(formatting.fontSize)}pt`;
|
|
2457
2793
|
if (formatting.color) span.style.color = formatting.color;
|
|
2794
|
+
const themeColor = serializeDocxThemeReference(formatting.themeColor ?? null);
|
|
2795
|
+
if (themeColor) span.dataset.officeThemeColor = themeColor;
|
|
2458
2796
|
if (formatting.backgroundColor) span.style.backgroundColor = formatting.backgroundColor;
|
|
2797
|
+
const themeFill = serializeDocxThemeReference(formatting.themeFill ?? null);
|
|
2798
|
+
if (themeFill) span.dataset.officeThemeFill = themeFill;
|
|
2459
2799
|
const html = span.outerHTML;
|
|
2460
2800
|
const tags = [
|
|
2461
2801
|
...formatting.bold ? [
|
|
@@ -2478,6 +2818,26 @@ function formattingMarkup(document, formatting) {
|
|
|
2478
2818
|
].reverse().map((tag)=>`</${tag}>`).join('')}</span>`
|
|
2479
2819
|
};
|
|
2480
2820
|
}
|
|
2821
|
+
function themeReference(element, themeName, tintName, shadeName, resolved) {
|
|
2822
|
+
const theme = work_docx_run_formatting_import_wordAttribute(element, themeName)?.trim();
|
|
2823
|
+
if (!theme) return;
|
|
2824
|
+
const tint = normalizedByteHex(work_docx_run_formatting_import_wordAttribute(element, tintName));
|
|
2825
|
+
const shade = normalizedByteHex(work_docx_run_formatting_import_wordAttribute(element, shadeName));
|
|
2826
|
+
return {
|
|
2827
|
+
theme,
|
|
2828
|
+
resolved,
|
|
2829
|
+
...tint ? {
|
|
2830
|
+
tint
|
|
2831
|
+
} : {},
|
|
2832
|
+
...shade ? {
|
|
2833
|
+
shade
|
|
2834
|
+
} : {}
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
function normalizedByteHex(value) {
|
|
2838
|
+
const normalized = value?.trim().toUpperCase();
|
|
2839
|
+
return normalized && /^[0-9A-F]{2}$/.test(normalized) ? normalized : void 0;
|
|
2840
|
+
}
|
|
2481
2841
|
function overriddenBoolean(current, next) {
|
|
2482
2842
|
return void 0 === next ? current : next;
|
|
2483
2843
|
}
|
|
@@ -2805,18 +3165,21 @@ function markDocxTableCells(document, themeSource, tableStyleSource) {
|
|
|
2805
3165
|
] : []
|
|
2806
3166
|
];
|
|
2807
3167
|
const borders = importedTableCellBorders(cell, layers, theme);
|
|
2808
|
-
const
|
|
3168
|
+
const background = importedTableCellBackgroundColor(layers, theme);
|
|
2809
3169
|
const verticalAlign = importedTableCellVerticalAlign(layers);
|
|
2810
3170
|
const margins = importedTableCellMargins(layers);
|
|
2811
|
-
if (!
|
|
3171
|
+
if (!background && !verticalAlign && !borders && !margins) continue;
|
|
2812
3172
|
const paragraph = firstTableCellParagraph(document, cell);
|
|
2813
3173
|
if (!paragraph) continue;
|
|
2814
3174
|
const marker = `__A3S_WORK_TABLE_CELL_${cells.length + 1}__`;
|
|
2815
3175
|
insertCellMarker(document, paragraph, marker);
|
|
2816
3176
|
cells.push({
|
|
2817
3177
|
marker,
|
|
2818
|
-
...
|
|
2819
|
-
backgroundColor
|
|
3178
|
+
...background ? {
|
|
3179
|
+
backgroundColor: background.color
|
|
3180
|
+
} : {},
|
|
3181
|
+
...background?.theme ? {
|
|
3182
|
+
themeFill: background.theme
|
|
2820
3183
|
} : {},
|
|
2821
3184
|
...verticalAlign ? {
|
|
2822
3185
|
verticalAlign
|
|
@@ -2857,6 +3220,8 @@ function applyCellFormat(cell, format) {
|
|
|
2857
3220
|
cell.dataset.officeCellFill = format.backgroundColor;
|
|
2858
3221
|
cell.style.backgroundColor = format.backgroundColor;
|
|
2859
3222
|
}
|
|
3223
|
+
const themeFill = serializeDocxThemeReference(format.themeFill ?? null);
|
|
3224
|
+
if (themeFill) cell.dataset.officeCellThemeFill = themeFill;
|
|
2860
3225
|
if (format.verticalAlign) {
|
|
2861
3226
|
cell.dataset.officeCellVerticalAlign = format.verticalAlign;
|
|
2862
3227
|
cell.style.verticalAlign = format.verticalAlign;
|
|
@@ -2872,6 +3237,8 @@ function applyCellFormat(cell, format) {
|
|
|
2872
3237
|
if (border) borders[edge] = {
|
|
2873
3238
|
...border
|
|
2874
3239
|
};
|
|
3240
|
+
const theme = serializeDocxThemeReference(border?.theme ?? null);
|
|
3241
|
+
if (theme) cell.dataset[`officeCellBorderTheme${capitalize(edge)}`] = theme;
|
|
2875
3242
|
}
|
|
2876
3243
|
const rendered = renderDocumentTableBorders(borders);
|
|
2877
3244
|
for (const [name, value] of Object.entries(rendered))if ('style' !== name) cell.setAttribute(name, value);
|
|
@@ -3000,7 +3367,10 @@ function parseBorder(edge, theme) {
|
|
|
3000
3367
|
return {
|
|
3001
3368
|
color,
|
|
3002
3369
|
style,
|
|
3003
|
-
width: Math.max(0.5, Math.min(6, Math.round(2 * width) / 2))
|
|
3370
|
+
width: Math.max(0.5, Math.min(6, Math.round(2 * width) / 2)),
|
|
3371
|
+
...themed ? {
|
|
3372
|
+
theme: work_docx_table_cell_import_themeReference(edge, 'themeColor', 'themeTint', 'themeShade', color)
|
|
3373
|
+
} : {}
|
|
3004
3374
|
};
|
|
3005
3375
|
}
|
|
3006
3376
|
function importedTableCellBackgroundColor(layers, theme) {
|
|
@@ -3015,7 +3385,36 @@ function importedTableCellBackgroundColor(layers, theme) {
|
|
|
3015
3385
|
}
|
|
3016
3386
|
function tableCellBackgroundColor(shading, theme) {
|
|
3017
3387
|
const themed = docxThemeColor(theme, attribute(shading, 'themeFill'), attribute(shading, 'themeFillTint'), attribute(shading, 'themeFillShade'));
|
|
3018
|
-
|
|
3388
|
+
if (themed) {
|
|
3389
|
+
const color = `#${themed}`;
|
|
3390
|
+
return {
|
|
3391
|
+
color,
|
|
3392
|
+
theme: work_docx_table_cell_import_themeReference(shading, 'themeFill', 'themeFillTint', 'themeFillShade', color)
|
|
3393
|
+
};
|
|
3394
|
+
}
|
|
3395
|
+
const color = ooxmlColor(attribute(shading, 'fill'));
|
|
3396
|
+
return color ? {
|
|
3397
|
+
color
|
|
3398
|
+
} : null;
|
|
3399
|
+
}
|
|
3400
|
+
function work_docx_table_cell_import_themeReference(element, themeName, tintName, shadeName, resolved) {
|
|
3401
|
+
const theme = attribute(element, themeName)?.trim() ?? '';
|
|
3402
|
+
const tint = work_docx_table_cell_import_normalizedByteHex(attribute(element, tintName));
|
|
3403
|
+
const shade = work_docx_table_cell_import_normalizedByteHex(attribute(element, shadeName));
|
|
3404
|
+
return {
|
|
3405
|
+
theme,
|
|
3406
|
+
resolved,
|
|
3407
|
+
...tint ? {
|
|
3408
|
+
tint
|
|
3409
|
+
} : {},
|
|
3410
|
+
...shade ? {
|
|
3411
|
+
shade
|
|
3412
|
+
} : {}
|
|
3413
|
+
};
|
|
3414
|
+
}
|
|
3415
|
+
function work_docx_table_cell_import_normalizedByteHex(value) {
|
|
3416
|
+
const normalized = value?.trim().toUpperCase();
|
|
3417
|
+
return normalized && /^[0-9A-F]{2}$/.test(normalized) ? normalized : void 0;
|
|
3019
3418
|
}
|
|
3020
3419
|
function importedTableCellVerticalAlign(layers) {
|
|
3021
3420
|
let alignment = null;
|
|
@@ -3079,20 +3478,33 @@ function work_docx_table_cell_import_textNodes(root) {
|
|
|
3079
3478
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
3080
3479
|
return nodes;
|
|
3081
3480
|
}
|
|
3481
|
+
function capitalize(value) {
|
|
3482
|
+
return `${value.slice(0, 1).toUpperCase()}${value.slice(1)}`;
|
|
3483
|
+
}
|
|
3082
3484
|
const work_docx_table_row_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
3485
|
+
const work_docx_table_row_import_WORD_2010_NAMESPACE = 'http://schemas.microsoft.com/office/word/2010/wordml';
|
|
3083
3486
|
const work_docx_table_row_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
3084
3487
|
const TABLE_ROW_MARKER_PATTERN = /__A3S_WORK_TABLE_ROW_\d+__/g;
|
|
3085
3488
|
const work_docx_table_row_import_PIXELS_PER_TWIP = 96 / 1440;
|
|
3086
3489
|
function markDocxTableRows(document) {
|
|
3490
|
+
const wordRows = descendants(document, 'tr').filter((row)=>DOCX_WORDPROCESSING_NAMESPACES.has(row.namespaceURI ?? ''));
|
|
3491
|
+
const identities = new Map();
|
|
3492
|
+
const identityCounts = work_docx_table_row_import_wordIdentityIdCounts(document);
|
|
3493
|
+
for (const row of wordRows){
|
|
3494
|
+
const identity = wordTableRowIdentity(row);
|
|
3495
|
+
if (identity) identities.set(row, identity);
|
|
3496
|
+
}
|
|
3087
3497
|
const rows = [];
|
|
3088
|
-
for (const row of
|
|
3498
|
+
for (const row of wordRows){
|
|
3089
3499
|
const properties = directChild(row, 'trPr');
|
|
3090
3500
|
const cantSplit = properties ? directChild(properties, 'cantSplit') : void 0;
|
|
3091
3501
|
const repeatHeader = properties ? directChild(properties, 'tblHeader') : void 0;
|
|
3092
3502
|
const height = properties ? directChild(properties, 'trHeight') : void 0;
|
|
3093
3503
|
const rowHeight = height ? work_docx_table_row_import_twipsToPixels(Number(attribute(height, 'val'))) : null;
|
|
3094
3504
|
const rowHeightRule = tableRowHeightRule(attribute(height ?? row, 'hRule'));
|
|
3095
|
-
|
|
3505
|
+
const rowIdentity = identities.get(row);
|
|
3506
|
+
const uniqueIdentity = rowIdentity && 1 === identityCounts.get(rowIdentity.rowId) ? rowIdentity : null;
|
|
3507
|
+
if (!cantSplit && !repeatHeader && null === rowHeight && !uniqueIdentity) continue;
|
|
3096
3508
|
const paragraph = firstTableRowParagraph(document, row);
|
|
3097
3509
|
if (!paragraph) continue;
|
|
3098
3510
|
const marker = `__A3S_WORK_TABLE_ROW_${rows.length + 1}__`;
|
|
@@ -3105,6 +3517,7 @@ function markDocxTableRows(document) {
|
|
|
3105
3517
|
...repeatHeader ? {
|
|
3106
3518
|
repeatHeader: work_docx_table_row_import_onOffValue(repeatHeader)
|
|
3107
3519
|
} : {},
|
|
3520
|
+
...uniqueIdentity ?? {},
|
|
3108
3521
|
...null !== rowHeight ? {
|
|
3109
3522
|
rowHeight
|
|
3110
3523
|
} : {},
|
|
@@ -3117,6 +3530,18 @@ function markDocxTableRows(document) {
|
|
|
3117
3530
|
rows
|
|
3118
3531
|
};
|
|
3119
3532
|
}
|
|
3533
|
+
function work_docx_table_row_import_wordIdentityIdCounts(document) {
|
|
3534
|
+
const counts = new Map();
|
|
3535
|
+
for (const localName of [
|
|
3536
|
+
'p',
|
|
3537
|
+
'tr'
|
|
3538
|
+
])for (const element of descendants(document, localName)){
|
|
3539
|
+
if (!DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? '')) continue;
|
|
3540
|
+
const paragraphId = normalizeDocumentParagraphId(work_docx_table_row_import_word2010Attribute(element, 'paraId'));
|
|
3541
|
+
if (paragraphId) counts.set(paragraphId, (counts.get(paragraphId) ?? 0) + 1);
|
|
3542
|
+
}
|
|
3543
|
+
return counts;
|
|
3544
|
+
}
|
|
3120
3545
|
function applyImportedDocxTableRowMarkers(document, markers) {
|
|
3121
3546
|
const rowByMarker = new Map(markers.rows.map((row)=>[
|
|
3122
3547
|
row.marker,
|
|
@@ -3128,6 +3553,7 @@ function applyImportedDocxTableRowMarkers(document, markers) {
|
|
|
3128
3553
|
node.data = node.data.replace(TABLE_ROW_MARKER_PATTERN, (marker)=>{
|
|
3129
3554
|
const properties = rowByMarker.get(marker);
|
|
3130
3555
|
if (row instanceof HTMLTableRowElement && properties) {
|
|
3556
|
+
applyDocumentTableRowIdentityToElement(row, properties);
|
|
3131
3557
|
work_docx_table_row_import_setBooleanAttribute(row, 'data-office-cant-split', properties.cantSplit);
|
|
3132
3558
|
work_docx_table_row_import_setBooleanAttribute(row, 'data-office-repeat-header', properties.repeatHeader);
|
|
3133
3559
|
if (void 0 !== properties.rowHeight) {
|
|
@@ -3149,19 +3575,32 @@ function firstTableRowParagraph(document, row) {
|
|
|
3149
3575
|
if (!cell) return null;
|
|
3150
3576
|
const existing = directChild(cell, 'p') ?? descendants(cell, 'p').find((paragraph)=>work_docx_table_row_import_closestAncestor(paragraph, 'tr') === row);
|
|
3151
3577
|
if (existing) return existing;
|
|
3152
|
-
const
|
|
3578
|
+
const namespace = cell.namespaceURI ?? work_docx_table_row_import_WORD_NAMESPACE;
|
|
3579
|
+
const prefix = cell.prefix ? `${cell.prefix}:` : '';
|
|
3580
|
+
const paragraph = document.createElementNS(namespace, `${prefix}p`);
|
|
3153
3581
|
cell.append(paragraph);
|
|
3154
3582
|
return paragraph;
|
|
3155
3583
|
}
|
|
3156
3584
|
function insertRowMarker(document, paragraph, marker) {
|
|
3157
|
-
const
|
|
3158
|
-
const
|
|
3585
|
+
const namespace = paragraph.namespaceURI ?? work_docx_table_row_import_WORD_NAMESPACE;
|
|
3586
|
+
const prefix = paragraph.prefix ? `${paragraph.prefix}:` : '';
|
|
3587
|
+
const run = document.createElementNS(namespace, `${prefix}r`);
|
|
3588
|
+
const text = document.createElementNS(namespace, `${prefix}t`);
|
|
3159
3589
|
text.setAttributeNS(work_docx_table_row_import_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
3160
3590
|
text.textContent = marker;
|
|
3161
3591
|
run.append(text);
|
|
3162
3592
|
const properties = directChild(paragraph, 'pPr');
|
|
3163
3593
|
paragraph.insertBefore(run, properties?.nextSibling ?? paragraph.firstChild);
|
|
3164
3594
|
}
|
|
3595
|
+
function wordTableRowIdentity(row) {
|
|
3596
|
+
return normalizeDocumentTableRowIdentity({
|
|
3597
|
+
rowId: work_docx_table_row_import_word2010Attribute(row, 'paraId'),
|
|
3598
|
+
rowTextId: work_docx_table_row_import_word2010Attribute(row, 'textId')
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
function work_docx_table_row_import_word2010Attribute(element, localName) {
|
|
3602
|
+
return Array.from(element.attributes).find((item)=>xmlAttributeLocalName(item) === localName && xmlAttributeNamespace(element, item) === work_docx_table_row_import_WORD_2010_NAMESPACE)?.value ?? null;
|
|
3603
|
+
}
|
|
3165
3604
|
function work_docx_table_row_import_onOffValue(element) {
|
|
3166
3605
|
const value = (attribute(element, 'val') ?? attribute(element, 'w:val'))?.trim().toLowerCase();
|
|
3167
3606
|
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
@@ -3210,7 +3649,8 @@ function markDocxTableSizing(document, tableStyleSource) {
|
|
|
3210
3649
|
tables.push({
|
|
3211
3650
|
marker,
|
|
3212
3651
|
geometry: importedTableGeometry(docxTablePropertySources(table, tableStyles)),
|
|
3213
|
-
columnWidths
|
|
3652
|
+
columnWidths,
|
|
3653
|
+
columnPercentages: importedColumnPercentages(table, columnWidths)
|
|
3214
3654
|
});
|
|
3215
3655
|
}
|
|
3216
3656
|
return {
|
|
@@ -3231,6 +3671,7 @@ function applyImportedDocxTableSizingMarkers(document, markers) {
|
|
|
3231
3671
|
table.dataset.officeTableImported = 'true';
|
|
3232
3672
|
applyDocumentTableGeometryToElement(table, sizing.geometry);
|
|
3233
3673
|
if (sizing.columnWidths.length) applyColumnWidths(table, sizing.columnWidths);
|
|
3674
|
+
if (sizing.columnPercentages.length) applyColumnPercentages(table, sizing.columnPercentages);
|
|
3234
3675
|
}
|
|
3235
3676
|
return '';
|
|
3236
3677
|
});
|
|
@@ -3341,9 +3782,9 @@ function percentageValue(value) {
|
|
|
3341
3782
|
}
|
|
3342
3783
|
function applyColumnWidths(table, columnWidths) {
|
|
3343
3784
|
const occupiedUntilRow = [];
|
|
3344
|
-
|
|
3785
|
+
ownedTableRows(table).forEach((row, rowIndex)=>{
|
|
3345
3786
|
let columnIndex = 0;
|
|
3346
|
-
for (const cell of
|
|
3787
|
+
for (const cell of ownedTableRowCells(row)){
|
|
3347
3788
|
while((occupiedUntilRow[columnIndex] ?? 0) > rowIndex)columnIndex += 1;
|
|
3348
3789
|
const widths = columnWidths.slice(columnIndex, columnIndex + cell.colSpan);
|
|
3349
3790
|
if (widths.length === cell.colSpan) cell.setAttribute('colwidth', widths.join(','));
|
|
@@ -3352,6 +3793,70 @@ function applyColumnWidths(table, columnWidths) {
|
|
|
3352
3793
|
}
|
|
3353
3794
|
});
|
|
3354
3795
|
}
|
|
3796
|
+
function applyColumnPercentages(table, columnPercentages) {
|
|
3797
|
+
const occupiedUntilRow = [];
|
|
3798
|
+
ownedTableRows(table).forEach((row, rowIndex)=>{
|
|
3799
|
+
let columnIndex = 0;
|
|
3800
|
+
for (const cell of ownedTableRowCells(row)){
|
|
3801
|
+
while((occupiedUntilRow[columnIndex] ?? 0) > rowIndex)columnIndex += 1;
|
|
3802
|
+
const percentages = columnPercentages.slice(columnIndex, columnIndex + cell.colSpan);
|
|
3803
|
+
if (percentages.length === cell.colSpan) cell.dataset.officeColumnWidthsPercent = percentages.join(',');
|
|
3804
|
+
if (cell.rowSpan > 1) for(let offset = 0; offset < cell.colSpan; offset += 1)occupiedUntilRow[columnIndex + offset] = rowIndex + cell.rowSpan;
|
|
3805
|
+
columnIndex += cell.colSpan;
|
|
3806
|
+
}
|
|
3807
|
+
});
|
|
3808
|
+
}
|
|
3809
|
+
function ownedTableRows(table) {
|
|
3810
|
+
return Array.from(table.rows).filter((row)=>row.closest('table') === table);
|
|
3811
|
+
}
|
|
3812
|
+
function ownedTableRowCells(row) {
|
|
3813
|
+
return Array.from(row.cells).filter((cell)=>cell.closest('tr') === row);
|
|
3814
|
+
}
|
|
3815
|
+
function importedColumnPercentages(table, columnWidths) {
|
|
3816
|
+
const columnCount = columnWidths.length || logicalTableColumnCount(table);
|
|
3817
|
+
const percentages = Array.from({
|
|
3818
|
+
length: columnCount
|
|
3819
|
+
}, ()=>null);
|
|
3820
|
+
const rows = directChildren(table, 'tr');
|
|
3821
|
+
for (const row of rows){
|
|
3822
|
+
let column = rowGridBefore(row);
|
|
3823
|
+
for (const cell of directChildren(row, 'tc')){
|
|
3824
|
+
const properties = directChild(cell, 'tcPr');
|
|
3825
|
+
const gridSpan = directChild(properties ?? cell, 'gridSpan');
|
|
3826
|
+
const span = Math.max(1, Number(gridSpan ? attribute(gridSpan, 'val') : null) || 1);
|
|
3827
|
+
const width = directChild(properties ?? cell, 'tcW');
|
|
3828
|
+
const total = width && 'pct' === attribute(width, 'type') ? percentageValue(attribute(width, 'w')) : null;
|
|
3829
|
+
if (null !== total) {
|
|
3830
|
+
const physical = columnWidths.slice(column, column + span);
|
|
3831
|
+
const physicalTotal = physical.reduce((sum, value)=>sum + value, 0);
|
|
3832
|
+
for(let offset = 0; offset < span; offset += 1){
|
|
3833
|
+
if (null !== percentages[column + offset]) continue;
|
|
3834
|
+
const share = physicalTotal > 0 ? total * ((physical[offset] ?? 0) / physicalTotal) : total / span;
|
|
3835
|
+
percentages[column + offset] = Math.round(100 * share) / 100;
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3838
|
+
column += span;
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3841
|
+
return percentages.every((value)=>null !== value && value > 0) ? percentages : [];
|
|
3842
|
+
}
|
|
3843
|
+
function logicalTableColumnCount(table) {
|
|
3844
|
+
return directChildren(table, 'tr').reduce((maximum, row)=>{
|
|
3845
|
+
const count = directChildren(row, 'tc').reduce((sum, cell)=>{
|
|
3846
|
+
const properties = directChild(cell, 'tcPr');
|
|
3847
|
+
const gridSpan = directChild(properties ?? cell, 'gridSpan');
|
|
3848
|
+
const span = Number(gridSpan ? attribute(gridSpan, 'val') : null);
|
|
3849
|
+
return sum + (Number.isSafeInteger(span) && span > 0 ? span : 1);
|
|
3850
|
+
}, rowGridBefore(row));
|
|
3851
|
+
return Math.max(maximum, count);
|
|
3852
|
+
}, 0);
|
|
3853
|
+
}
|
|
3854
|
+
function rowGridBefore(row) {
|
|
3855
|
+
const properties = directChild(row, 'trPr');
|
|
3856
|
+
const gridBefore = directChild(properties ?? row, 'gridBefore');
|
|
3857
|
+
const value = Number(gridBefore ? attribute(gridBefore, 'val') : null);
|
|
3858
|
+
return Number.isSafeInteger(value) && value > 0 ? value : 0;
|
|
3859
|
+
}
|
|
3355
3860
|
function firstTableParagraph(document, table) {
|
|
3356
3861
|
const cell = descendants(table, 'tc').find((candidate)=>work_docx_table_sizing_import_closestAncestor(candidate, 'tbl') === table);
|
|
3357
3862
|
if (!cell) return null;
|
|
@@ -3390,7 +3895,6 @@ function work_docx_table_sizing_import_textNodes(root) {
|
|
|
3390
3895
|
while(walker.nextNode())nodes.push(walker.currentNode);
|
|
3391
3896
|
return nodes;
|
|
3392
3897
|
}
|
|
3393
|
-
const work_docx_import_TWIPS_PER_MILLIMETER = 1440 / 25.4;
|
|
3394
3898
|
const work_docx_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
3395
3899
|
const work_docx_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
3396
3900
|
async function prepareDocxImport(buffer) {
|
|
@@ -3413,6 +3917,10 @@ async function prepareDocxImport(buffer) {
|
|
|
3413
3917
|
captions: [],
|
|
3414
3918
|
references: []
|
|
3415
3919
|
},
|
|
3920
|
+
bookmarkMarkers: {
|
|
3921
|
+
bookmarks: [],
|
|
3922
|
+
references: []
|
|
3923
|
+
},
|
|
3416
3924
|
changeMarkers: {
|
|
3417
3925
|
changes: []
|
|
3418
3926
|
},
|
|
@@ -3423,6 +3931,9 @@ async function prepareDocxImport(buffer) {
|
|
|
3423
3931
|
fieldMarkers: {
|
|
3424
3932
|
fields: []
|
|
3425
3933
|
},
|
|
3934
|
+
equationMarkers: {
|
|
3935
|
+
equations: []
|
|
3936
|
+
},
|
|
3426
3937
|
citationMarkers: {
|
|
3427
3938
|
citations: [],
|
|
3428
3939
|
bibliographies: []
|
|
@@ -3433,6 +3944,9 @@ async function prepareDocxImport(buffer) {
|
|
|
3433
3944
|
imageLayoutMarkers: {
|
|
3434
3945
|
images: []
|
|
3435
3946
|
},
|
|
3947
|
+
paragraphIdentityMarkers: {
|
|
3948
|
+
paragraphs: []
|
|
3949
|
+
},
|
|
3436
3950
|
paragraphAlignmentMarkers: {
|
|
3437
3951
|
paragraphs: []
|
|
3438
3952
|
},
|
|
@@ -3445,6 +3959,16 @@ async function prepareDocxImport(buffer) {
|
|
|
3445
3959
|
paragraphPaginationMarkers: {
|
|
3446
3960
|
paragraphs: []
|
|
3447
3961
|
},
|
|
3962
|
+
paragraphBorderMarkers: {
|
|
3963
|
+
paragraphs: [],
|
|
3964
|
+
invalidCount: 0,
|
|
3965
|
+
spoofedCount: 0
|
|
3966
|
+
},
|
|
3967
|
+
paragraphShadingMarkers: {
|
|
3968
|
+
paragraphs: [],
|
|
3969
|
+
invalidCount: 0,
|
|
3970
|
+
spoofedCount: 0
|
|
3971
|
+
},
|
|
3448
3972
|
paragraphSpacingMarkers: {
|
|
3449
3973
|
paragraphs: []
|
|
3450
3974
|
},
|
|
@@ -3469,14 +3993,20 @@ async function prepareDocxImport(buffer) {
|
|
|
3469
3993
|
};
|
|
3470
3994
|
const document = await archive.xml('word/document.xml');
|
|
3471
3995
|
const pageColor = importDocxPageColor(document);
|
|
3996
|
+
const paragraphIdentityMarkers = markDocxParagraphIdentities(document);
|
|
3472
3997
|
const numbering = archive.has('word/numbering.xml') ? await archive.xml('word/numbering.xml') : null;
|
|
3473
3998
|
const commentMarkers = await markDocxComments(document, archive);
|
|
3474
3999
|
const changeMarkers = markDocxTextChanges(document);
|
|
3475
4000
|
const captionMarkers = markDocxCaptionFields(document);
|
|
4001
|
+
const bookmarkMarkers = markDocxBookmarks(document);
|
|
3476
4002
|
const citationMarkers = markDocxCitationFields(document);
|
|
3477
4003
|
const fieldMarkers = markDocxBodyFields(document);
|
|
3478
4004
|
const listMarkers = markDocxLists(document, numbering);
|
|
3479
|
-
const
|
|
4005
|
+
const imageLayoutMarkerState = createImportedDocxImageLayoutMarkerState();
|
|
4006
|
+
const imageLayoutMarkers = markDocxImageLayouts(document, imageLayoutMarkerState);
|
|
4007
|
+
const noteImageMarkers = await markDocxNoteImageLayouts(archive, imageLayoutMarkerState);
|
|
4008
|
+
imageLayoutMarkers.images.push(...noteImageMarkers.markers.images);
|
|
4009
|
+
const equationMarkers = await markDocxPackageEquations(archive, document, noteImageMarkers.parts);
|
|
3480
4010
|
const paragraphStylesDocument = archive.has('word/styles.xml') ? await archive.xml('word/styles.xml') : null;
|
|
3481
4011
|
const paragraphStyles = createDocxParagraphStyleResolver(paragraphStylesDocument);
|
|
3482
4012
|
const tableStyles = createDocxTableStyleResolver(paragraphStylesDocument);
|
|
@@ -3487,16 +4017,20 @@ async function prepareDocxImport(buffer) {
|
|
|
3487
4017
|
const paragraphPaginationMarkers = markDocxParagraphPagination(document, paragraphStyles, tableStyles);
|
|
3488
4018
|
const themePath = archive.paths('word/theme/').find((path)=>/\/theme\d*\.xml$/i.test(path));
|
|
3489
4019
|
const themeDocument = themePath ? await archive.xml(themePath) : null;
|
|
3490
|
-
const
|
|
4020
|
+
const settings = archive.has('word/settings.xml') ? await archive.xml('word/settings.xml') : null;
|
|
4021
|
+
const pageMarginSettings = inspectDocxPageMarginSettings(settings);
|
|
4022
|
+
const theme = createDocxThemeResolver(themeDocument, settings);
|
|
4023
|
+
const paragraphBorderMarkers = markDocxParagraphBorders(document, paragraphStyles, theme, tableStyles);
|
|
4024
|
+
const paragraphShadingMarkers = markDocxParagraphShading(document, paragraphStyles, theme, tableStyles);
|
|
4025
|
+
const runFormattingMarkers = markDocxRunFormatting(document, paragraphStyles, theme, tableStyles);
|
|
3491
4026
|
const tabStopMarkers = markDocxParagraphTabStops(document, paragraphStyles, tableStyles);
|
|
3492
|
-
const tableCellMarkers = markDocxTableCells(document,
|
|
4027
|
+
const tableCellMarkers = markDocxTableCells(document, theme, tableStyles);
|
|
3493
4028
|
const tableRowMarkers = markDocxTableRows(document);
|
|
3494
4029
|
const tableSizingMarkers = markDocxTableSizing(document, tableStyles);
|
|
3495
|
-
const settings = archive.has('word/settings.xml') ? await archive.xml('word/settings.xml') : null;
|
|
3496
4030
|
const trackChanges = Boolean(settings && firstDescendant(settings, 'trackRevisions')) || changeMarkers.changes.length > 0;
|
|
3497
4031
|
const sectionElements = effectiveSectionProperties(document);
|
|
3498
4032
|
if (!sectionElements.length) return {
|
|
3499
|
-
conversionBuffer: hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document) : buffer,
|
|
4033
|
+
conversionBuffer: hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxBookmarkMarkers(bookmarkMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || equationMarkers.changed || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxParagraphIdentityMarkers(paragraphIdentityMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphBorderMarkers(paragraphBorderMarkers) || hasImportedDocxParagraphShadingMarkers(paragraphShadingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document, equationMarkers.parts) : buffer,
|
|
3500
4034
|
sections: [
|
|
3501
4035
|
{
|
|
3502
4036
|
id: 'document-section-1',
|
|
@@ -3505,16 +4039,21 @@ async function prepareDocxImport(buffer) {
|
|
|
3505
4039
|
],
|
|
3506
4040
|
pageColor,
|
|
3507
4041
|
captionMarkers,
|
|
4042
|
+
bookmarkMarkers,
|
|
3508
4043
|
changeMarkers,
|
|
3509
4044
|
commentMarkers,
|
|
3510
4045
|
fieldMarkers,
|
|
4046
|
+
equationMarkers: equationMarkers.markers,
|
|
3511
4047
|
citationMarkers,
|
|
3512
4048
|
listMarkers,
|
|
3513
4049
|
imageLayoutMarkers,
|
|
4050
|
+
paragraphIdentityMarkers,
|
|
3514
4051
|
paragraphAlignmentMarkers,
|
|
3515
4052
|
paragraphDirectionMarkers,
|
|
3516
4053
|
paragraphIndentMarkers,
|
|
3517
4054
|
paragraphPaginationMarkers,
|
|
4055
|
+
paragraphBorderMarkers,
|
|
4056
|
+
paragraphShadingMarkers,
|
|
3518
4057
|
paragraphSpacingMarkers,
|
|
3519
4058
|
runFormattingMarkers,
|
|
3520
4059
|
tabStopMarkers,
|
|
@@ -3529,7 +4068,7 @@ async function prepareDocxImport(buffer) {
|
|
|
3529
4068
|
const sections = [];
|
|
3530
4069
|
let previous = fallback;
|
|
3531
4070
|
for (const [index, element] of sectionElements.entries()){
|
|
3532
|
-
const layout = await parseSectionLayout(element, archive, relationships, previous, oddEvenPageChrome);
|
|
4071
|
+
const layout = await parseSectionLayout(element, archive, relationships, previous, oddEvenPageChrome, theme, pageMarginSettings);
|
|
3533
4072
|
sections.push({
|
|
3534
4073
|
id: `document-section-${index + 1}`,
|
|
3535
4074
|
layout
|
|
@@ -3538,20 +4077,25 @@ async function prepareDocxImport(buffer) {
|
|
|
3538
4077
|
}
|
|
3539
4078
|
if (sections.length > 1) addSectionMarkers(document, sectionElements);
|
|
3540
4079
|
return {
|
|
3541
|
-
conversionBuffer: sections.length > 1 || hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document) : buffer,
|
|
4080
|
+
conversionBuffer: sections.length > 1 || hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxBookmarkMarkers(bookmarkMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || equationMarkers.changed || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxParagraphIdentityMarkers(paragraphIdentityMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphBorderMarkers(paragraphBorderMarkers) || hasImportedDocxParagraphShadingMarkers(paragraphShadingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document, equationMarkers.parts) : buffer,
|
|
3542
4081
|
sections,
|
|
3543
4082
|
pageColor,
|
|
3544
4083
|
captionMarkers,
|
|
4084
|
+
bookmarkMarkers,
|
|
3545
4085
|
changeMarkers,
|
|
3546
4086
|
commentMarkers,
|
|
3547
4087
|
fieldMarkers,
|
|
4088
|
+
equationMarkers: equationMarkers.markers,
|
|
3548
4089
|
citationMarkers,
|
|
3549
4090
|
listMarkers,
|
|
3550
4091
|
imageLayoutMarkers,
|
|
4092
|
+
paragraphIdentityMarkers,
|
|
3551
4093
|
paragraphAlignmentMarkers,
|
|
3552
4094
|
paragraphDirectionMarkers,
|
|
3553
4095
|
paragraphIndentMarkers,
|
|
3554
4096
|
paragraphPaginationMarkers,
|
|
4097
|
+
paragraphBorderMarkers,
|
|
4098
|
+
paragraphShadingMarkers,
|
|
3555
4099
|
paragraphSpacingMarkers,
|
|
3556
4100
|
runFormattingMarkers,
|
|
3557
4101
|
tabStopMarkers,
|
|
@@ -3565,6 +4109,9 @@ async function prepareDocxImport(buffer) {
|
|
|
3565
4109
|
function applyDocxSectionsToHtml(html, sections, captionMarkers = {
|
|
3566
4110
|
captions: [],
|
|
3567
4111
|
references: []
|
|
4112
|
+
}, bookmarkMarkers = {
|
|
4113
|
+
bookmarks: [],
|
|
4114
|
+
references: []
|
|
3568
4115
|
}, changeMarkers = {
|
|
3569
4116
|
changes: []
|
|
3570
4117
|
}, commentMarkers = {
|
|
@@ -3572,6 +4119,8 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
|
|
|
3572
4119
|
ranges: []
|
|
3573
4120
|
}, fieldMarkers = {
|
|
3574
4121
|
fields: []
|
|
4122
|
+
}, equationMarkers = {
|
|
4123
|
+
equations: []
|
|
3575
4124
|
}, citationMarkers = {
|
|
3576
4125
|
citations: [],
|
|
3577
4126
|
bibliographies: []
|
|
@@ -3579,6 +4128,8 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
|
|
|
3579
4128
|
lists: []
|
|
3580
4129
|
}, imageLayoutMarkers = {
|
|
3581
4130
|
images: []
|
|
4131
|
+
}, paragraphIdentityMarkers = {
|
|
4132
|
+
paragraphs: []
|
|
3582
4133
|
}, paragraphAlignmentMarkers = {
|
|
3583
4134
|
paragraphs: []
|
|
3584
4135
|
}, runFormattingMarkers = {
|
|
@@ -3589,6 +4140,14 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
|
|
|
3589
4140
|
paragraphs: []
|
|
3590
4141
|
}, paragraphSpacingMarkers = {
|
|
3591
4142
|
paragraphs: []
|
|
4143
|
+
}, paragraphBorderMarkers = {
|
|
4144
|
+
paragraphs: [],
|
|
4145
|
+
invalidCount: 0,
|
|
4146
|
+
spoofedCount: 0
|
|
4147
|
+
}, paragraphShadingMarkers = {
|
|
4148
|
+
paragraphs: [],
|
|
4149
|
+
invalidCount: 0,
|
|
4150
|
+
spoofedCount: 0
|
|
3592
4151
|
}, paragraphPaginationMarkers = {
|
|
3593
4152
|
paragraphs: []
|
|
3594
4153
|
}, bibliography, tabStopMarkers = {
|
|
@@ -3603,14 +4162,18 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
|
|
|
3603
4162
|
}) {
|
|
3604
4163
|
const document = new DOMParser().parseFromString(html, 'text/html');
|
|
3605
4164
|
applyImportedDocxRunFormattingMarkers(document, runFormattingMarkers);
|
|
4165
|
+
applyImportedDocxBookmarkMarkers(document, bookmarkMarkers);
|
|
3606
4166
|
applyImportedDocxCaptionMarkers(document, captionMarkers);
|
|
3607
4167
|
applyImportedDocxCitationMarkers(document, citationMarkers);
|
|
3608
4168
|
applyImportedDocxFieldMarkers(document, fieldMarkers);
|
|
4169
|
+
applyImportedDocxEquationMarkers(document, equationMarkers);
|
|
3609
4170
|
applyImportedDocxListMarkers(document, listMarkers);
|
|
3610
4171
|
applyImportedDocxImageLayoutMarkers(document, imageLayoutMarkers);
|
|
3611
4172
|
applyImportedDocxParagraphDirectionMarkers(document, paragraphDirectionMarkers);
|
|
3612
4173
|
applyImportedDocxParagraphIndentMarkers(document, paragraphIndentMarkers);
|
|
3613
4174
|
applyImportedDocxParagraphSpacingMarkers(document, paragraphSpacingMarkers);
|
|
4175
|
+
applyImportedDocxParagraphBorderMarkers(document, paragraphBorderMarkers);
|
|
4176
|
+
applyImportedDocxParagraphShadingMarkers(document, paragraphShadingMarkers);
|
|
3614
4177
|
applyImportedDocxParagraphPaginationMarkers(document, paragraphPaginationMarkers);
|
|
3615
4178
|
applyImportedDocxParagraphTabStopMarkers(document, tabStopMarkers);
|
|
3616
4179
|
applyImportedDocxParagraphAlignmentMarkers(document, paragraphAlignmentMarkers);
|
|
@@ -3619,6 +4182,7 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
|
|
|
3619
4182
|
applyImportedDocxTableRowMarkers(document, tableRowMarkers);
|
|
3620
4183
|
applyImportedDocxChangeMarkers(document, changeMarkers);
|
|
3621
4184
|
applyImportedDocxCommentMarkers(document, commentMarkers);
|
|
4185
|
+
applyImportedDocxParagraphIdentityMarkers(document, paragraphIdentityMarkers);
|
|
3622
4186
|
const notes = extractMammothDocumentNotes(document);
|
|
3623
4187
|
const sourceNodes = Array.from(document.body.childNodes);
|
|
3624
4188
|
document.body.replaceChildren();
|
|
@@ -3643,7 +4207,7 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
|
|
|
3643
4207
|
document.body.append(missing);
|
|
3644
4208
|
}
|
|
3645
4209
|
placeMammothDocumentNotes(document, notes);
|
|
3646
|
-
return normalizeDocumentCitationsHtml(normalizeDocumentFieldsHtml(normalizeDocumentCaptionsHtml(normalizeDocumentNotesHtml(document.body.innerHTML))), bibliography);
|
|
4210
|
+
return normalizeDocumentBookmarkReferencesHtml(normalizeDocumentBookmarksHtml(normalizeDocumentCitationsHtml(normalizeDocumentFieldsHtml(normalizeDocumentCaptionsHtml(normalizeDocumentNotesHtml(document.body.innerHTML))), bibliography)));
|
|
3647
4211
|
}
|
|
3648
4212
|
async function readDocxLayout(buffer) {
|
|
3649
4213
|
const prepared = await prepareDocxImport(buffer);
|
|
@@ -3654,24 +4218,22 @@ async function readDocxLayout(buffer) {
|
|
|
3654
4218
|
} : {}
|
|
3655
4219
|
};
|
|
3656
4220
|
}
|
|
3657
|
-
async function parseSectionLayout(section, archive, relationships, previous, oddEvenPageChrome) {
|
|
3658
|
-
const
|
|
3659
|
-
const
|
|
3660
|
-
const
|
|
3661
|
-
const
|
|
3662
|
-
const shortEdge = Math.min(width || 11906, height || 16838);
|
|
3663
|
-
const size = pageSize ? Math.abs(shortEdge - 12240) < Math.abs(shortEdge - 11906) ? 'letter' : 'a4' : previous.pageSize;
|
|
3664
|
-
const marginsElement = firstDescendant(section, 'pgMar');
|
|
4221
|
+
async function parseSectionLayout(section, archive, relationships, previous, oddEvenPageChrome, theme, pageMarginSettings) {
|
|
4222
|
+
const parsedPageGeometry = parseDocxPageGeometry(section, previous.pageGeometry);
|
|
4223
|
+
const pageGeometry = null === parsedPageGeometry ? previous.pageGeometry : parsedPageGeometry;
|
|
4224
|
+
const parsedPaperSource = parseDocxPaperSource(section, previous.paperSource);
|
|
4225
|
+
const paperSource = null === parsedPaperSource ? previous.paperSource : parsedPaperSource;
|
|
3665
4226
|
const columnsElement = firstDescendant(section, 'cols');
|
|
3666
4227
|
const documentGridElement = directChild(section, 'docGrid');
|
|
4228
|
+
const pageBorders = parseDocxPageBorders(section, theme);
|
|
4229
|
+
const parsedPageMargins = parseDocxPageMargins(section, pageMarginSettings, documentPageMarginsForLayout(previous));
|
|
4230
|
+
const pageMargins = null === parsedPageMargins ? documentPageMarginsForLayout(previous) : parsedPageMargins;
|
|
3667
4231
|
const pageChrome = await importSectionPageChrome(section, archive, relationships, previous, oddEvenPageChrome);
|
|
3668
4232
|
const pageNumberStart = work_docx_import_numberAttribute(firstDescendant(section, 'pgNumType'), 'start');
|
|
3669
|
-
|
|
3670
|
-
pageSize:
|
|
3671
|
-
orientation,
|
|
3672
|
-
margins:
|
|
3673
|
-
...previous.margins
|
|
3674
|
-
},
|
|
4233
|
+
const layout = {
|
|
4234
|
+
pageSize: previous.pageSize,
|
|
4235
|
+
orientation: previous.orientation,
|
|
4236
|
+
margins: documentPageMarginBody(pageMargins, previous.margins),
|
|
3675
4237
|
columns: columnsElement ? importDocxColumns(columnsElement, previous.columns) : {
|
|
3676
4238
|
...previous.columns
|
|
3677
4239
|
},
|
|
@@ -3682,10 +4244,23 @@ async function parseSectionLayout(section, archive, relationships, previous, odd
|
|
|
3682
4244
|
...previous.documentGrid
|
|
3683
4245
|
}
|
|
3684
4246
|
} : {},
|
|
4247
|
+
...pageBorders ? {
|
|
4248
|
+
pageBorders
|
|
4249
|
+
} : {},
|
|
4250
|
+
...pageMargins ? {
|
|
4251
|
+
pageMargins
|
|
4252
|
+
} : {},
|
|
4253
|
+
...pageGeometry ? {
|
|
4254
|
+
pageGeometry
|
|
4255
|
+
} : {},
|
|
4256
|
+
...paperSource ? {
|
|
4257
|
+
paperSource
|
|
4258
|
+
} : {},
|
|
3685
4259
|
breakAfter: parseSectionBreak(firstDescendant(section, 'type')),
|
|
3686
4260
|
...pageChrome,
|
|
3687
4261
|
pageNumberStart: pageNumberStart > 0 ? pageNumberStart : void 0
|
|
3688
4262
|
};
|
|
4263
|
+
return pageGeometry ? applyDocumentPageGeometry(layout, pageGeometry) : layout;
|
|
3689
4264
|
}
|
|
3690
4265
|
function parseDocumentGrid(element) {
|
|
3691
4266
|
const sourceType = attribute(element, 'type');
|
|
@@ -3710,13 +4285,43 @@ function addSectionMarkers(document, sectionElements) {
|
|
|
3710
4285
|
paragraph.parentNode.insertBefore(marker, paragraph.nextSibling);
|
|
3711
4286
|
}
|
|
3712
4287
|
}
|
|
3713
|
-
async function writeDocumentXml(buffer, document) {
|
|
4288
|
+
async function writeDocumentXml(buffer, document, additionalParts = []) {
|
|
3714
4289
|
const zip = await jszip.loadAsync(buffer);
|
|
3715
|
-
zip.file('word/document.xml',
|
|
4290
|
+
zip.file('word/document.xml', serializeDocxConversionXml(document));
|
|
4291
|
+
for (const part of additionalParts)zip.file(part.path, serializeDocxConversionXml(part.document));
|
|
3716
4292
|
return zip.generateAsync({
|
|
3717
4293
|
type: 'arraybuffer'
|
|
3718
4294
|
});
|
|
3719
4295
|
}
|
|
4296
|
+
function serializeDocxConversionXml(document) {
|
|
4297
|
+
const dialects = new Map([
|
|
4298
|
+
[
|
|
4299
|
+
'http://purl.oclc.org/ooxml/wordprocessingml/main',
|
|
4300
|
+
'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
|
|
4301
|
+
],
|
|
4302
|
+
[
|
|
4303
|
+
'http://purl.oclc.org/ooxml/officeDocument/math',
|
|
4304
|
+
'http://schemas.openxmlformats.org/officeDocument/2006/math'
|
|
4305
|
+
],
|
|
4306
|
+
[
|
|
4307
|
+
'http://purl.oclc.org/ooxml/officeDocument/relationships',
|
|
4308
|
+
'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
|
|
4309
|
+
],
|
|
4310
|
+
[
|
|
4311
|
+
'http://purl.oclc.org/ooxml/drawingml/wordprocessingDrawing',
|
|
4312
|
+
'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'
|
|
4313
|
+
],
|
|
4314
|
+
[
|
|
4315
|
+
'http://purl.oclc.org/ooxml/drawingml/main',
|
|
4316
|
+
'http://schemas.openxmlformats.org/drawingml/2006/main'
|
|
4317
|
+
],
|
|
4318
|
+
[
|
|
4319
|
+
'http://purl.oclc.org/ooxml/drawingml/picture',
|
|
4320
|
+
'http://schemas.openxmlformats.org/drawingml/2006/picture'
|
|
4321
|
+
]
|
|
4322
|
+
]);
|
|
4323
|
+
return new XMLSerializer().serializeToString(document).replace(/(\sxmlns(?::[A-Za-z_][A-Za-z0-9_.-]*)?\s*=\s*)(["'])([^"']+)\2/g, (_declaration, assignment, quote, namespace)=>`${assignment}${quote}${dialects.get(namespace) ?? namespace}${quote}`);
|
|
4324
|
+
}
|
|
3720
4325
|
function effectiveSectionProperties(document) {
|
|
3721
4326
|
return descendants(document, 'sectPr').filter((element)=>!work_docx_import_closestAncestor(element, 'sectPrChange'));
|
|
3722
4327
|
}
|
|
@@ -3741,14 +4346,6 @@ function isSectionMarker(node, index) {
|
|
|
3741
4346
|
function sectionMarker(index) {
|
|
3742
4347
|
return `__A3S_WORK_DOCUMENT_SECTION_${index + 1}__`;
|
|
3743
4348
|
}
|
|
3744
|
-
function parseMargins(element, fallback) {
|
|
3745
|
-
return {
|
|
3746
|
-
top: work_docx_import_twipsToMillimeters(work_docx_import_numberAttribute(element, 'top'), fallback.top),
|
|
3747
|
-
right: work_docx_import_twipsToMillimeters(work_docx_import_numberAttribute(element, 'right'), fallback.right),
|
|
3748
|
-
bottom: work_docx_import_twipsToMillimeters(work_docx_import_numberAttribute(element, 'bottom'), fallback.bottom),
|
|
3749
|
-
left: work_docx_import_twipsToMillimeters(work_docx_import_numberAttribute(element, 'left'), fallback.left)
|
|
3750
|
-
};
|
|
3751
|
-
}
|
|
3752
4349
|
function parseSectionBreak(element) {
|
|
3753
4350
|
if (!element) return 'nextPage';
|
|
3754
4351
|
const value = attribute(element, 'val');
|
|
@@ -3768,8 +4365,4 @@ function work_docx_import_closestAncestor(element, localName) {
|
|
|
3768
4365
|
}
|
|
3769
4366
|
return null;
|
|
3770
4367
|
}
|
|
3771
|
-
function work_docx_import_twipsToMillimeters(value, fallback) {
|
|
3772
|
-
if (value <= 0) return fallback;
|
|
3773
|
-
return Math.round(value / work_docx_import_TWIPS_PER_MILLIMETER * 10) / 10;
|
|
3774
|
-
}
|
|
3775
4368
|
export { applyDocxSectionsToHtml, prepareDocxImport, readDocxLayout };
|