@syncfusion/ej2-docx 0.0.0-stage → 35.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -2
- package/core.js +4 -0
- package/dist/ej2-docx.umd.min.js +2 -0
- package/dist/ej2-docx.umd.min.js.map +1 -0
- package/dist/es6/ej2-docx.es2015.js +66697 -0
- package/dist/es6/ej2-docx.es2015.js.map +1 -0
- package/dist/es6/ej2-docx.es5.js +77568 -0
- package/dist/es6/ej2-docx.es5.js.map +1 -0
- package/dist/global/ej2-docx.min.js +2 -0
- package/dist/global/ej2-docx.min.js.map +1 -0
- package/dist/global/index.d.ts +5 -0
- package/features.js +4 -0
- package/index.js +4 -0
- package/license +10 -0
- package/package.json +31 -4
- package/src/all.d.ts +50 -0
- package/src/all.js +147 -0
- package/src/core/compat/base64.d.ts +13 -0
- package/src/core/compat/base64.js +90 -0
- package/src/core/compat/object-compat.d.ts +30 -0
- package/src/core/compat/object-compat.js +40 -0
- package/src/core/compat/sha256.d.ts +9 -0
- package/src/core/compat/sha256.js +98 -0
- package/src/core/errors/docx-error.d.ts +89 -0
- package/src/core/errors/docx-error.js +138 -0
- package/src/core/errors/error-codes.d.ts +8 -0
- package/src/core/errors/error-codes.js +0 -0
- package/src/core/errors/index.d.ts +10 -0
- package/src/core/errors/index.js +9 -0
- package/src/core/index.d.ts +12 -0
- package/src/core/index.js +12 -0
- package/src/core/mc/alternate-content.d.ts +7 -0
- package/src/core/mc/alternate-content.js +67 -0
- package/src/core/mc/attributes.d.ts +24 -0
- package/src/core/mc/attributes.js +82 -0
- package/src/core/mc/index.d.ts +7 -0
- package/src/core/mc/index.js +5 -0
- package/src/core/mc/inspect.d.ts +16 -0
- package/src/core/mc/inspect.js +148 -0
- package/src/core/mc/namespaces.d.ts +4 -0
- package/src/core/mc/namespaces.js +4 -0
- package/src/core/mc/scope.d.ts +6 -0
- package/src/core/mc/scope.js +47 -0
- package/src/core/opc/content-types.d.ts +34 -0
- package/src/core/opc/content-types.js +162 -0
- package/src/core/opc/index.d.ts +8 -0
- package/src/core/opc/index.js +4 -0
- package/src/core/opc/package.d.ts +49 -0
- package/src/core/opc/package.js +324 -0
- package/src/core/opc/part-name.d.ts +47 -0
- package/src/core/opc/part-name.js +205 -0
- package/src/core/opc/relationships.d.ts +46 -0
- package/src/core/opc/relationships.js +212 -0
- package/src/core/preservation/index.d.ts +2 -0
- package/src/core/preservation/index.js +1 -0
- package/src/core/preservation/opaque-body.d.ts +16 -0
- package/src/core/preservation/opaque-body.js +69 -0
- package/src/core/registry/block-handlers.d.ts +30 -0
- package/src/core/registry/block-handlers.js +36 -0
- package/src/core/registry/create-defaults.d.ts +39 -0
- package/src/core/registry/create-defaults.js +42 -0
- package/src/core/registry/feature-registry.d.ts +20 -0
- package/src/core/registry/feature-registry.js +29 -0
- package/src/core/registry/index.d.ts +9 -0
- package/src/core/registry/index.js +8 -0
- package/src/core/registry/inline-handlers.d.ts +20 -0
- package/src/core/registry/inline-handlers.js +30 -0
- package/src/core/registry/materialize-handlers.d.ts +35 -0
- package/src/core/registry/materialize-handlers.js +75 -0
- package/src/core/registry/multi-part-handlers.d.ts +37 -0
- package/src/core/registry/multi-part-handlers.js +206 -0
- package/src/core/registry/package-part-handlers.d.ts +28 -0
- package/src/core/registry/package-part-handlers.js +190 -0
- package/src/core/registry/part-handlers.d.ts +24 -0
- package/src/core/registry/part-handlers.js +172 -0
- package/src/core/registry/run-leaf-handlers.d.ts +26 -0
- package/src/core/registry/run-leaf-handlers.js +72 -0
- package/src/core/security/limits.d.ts +40 -0
- package/src/core/security/limits.js +26 -0
- package/src/core/xml/index.d.ts +7 -0
- package/src/core/xml/index.js +3 -0
- package/src/core/xml/model.d.ts +66 -0
- package/src/core/xml/model.js +17 -0
- package/src/core/xml/parse.d.ts +12 -0
- package/src/core/xml/parse.js +382 -0
- package/src/core/xml/serialize.d.ts +6 -0
- package/src/core/xml/serialize.js +93 -0
- package/src/core/zip/crc32.d.ts +2 -0
- package/src/core/zip/crc32.js +25 -0
- package/src/core/zip/deflate.d.ts +6 -0
- package/src/core/zip/deflate.js +6 -0
- package/src/core/zip/index.d.ts +10 -0
- package/src/core/zip/index.js +4 -0
- package/src/core/zip/inflate-raw.d.ts +17 -0
- package/src/core/zip/inflate-raw.js +450 -0
- package/src/core/zip/names.d.ts +6 -0
- package/src/core/zip/names.js +52 -0
- package/src/core/zip/read.d.ts +8 -0
- package/src/core/zip/read.js +262 -0
- package/src/core/zip/write.d.ts +7 -0
- package/src/core/zip/write.js +189 -0
- package/src/core/zip/zip-entry.d.ts +4 -0
- package/src/core/zip/zip-entry.js +0 -0
- package/src/features/bibliography/index.d.ts +100 -0
- package/src/features/bibliography/index.js +290 -0
- package/src/features/bookmarks/index.d.ts +331 -0
- package/src/features/bookmarks/index.js +1009 -0
- package/src/features/comments/comment-extensions.d.ts +157 -0
- package/src/features/comments/comment-extensions.js +356 -0
- package/src/features/comments/index.d.ts +579 -0
- package/src/features/comments/index.js +1727 -0
- package/src/features/content-controls/index.d.ts +821 -0
- package/src/features/content-controls/index.js +2857 -0
- package/src/features/custom-xml/index.d.ts +236 -0
- package/src/features/custom-xml/index.js +661 -0
- package/src/features/document/alignment.d.ts +23 -0
- package/src/features/document/alignment.js +36 -0
- package/src/features/document/alt-chunk.d.ts +103 -0
- package/src/features/document/alt-chunk.js +221 -0
- package/src/features/document/assert-never.d.ts +1 -0
- package/src/features/document/assert-never.js +4 -0
- package/src/features/document/augmentations.d.ts +578 -0
- package/src/features/document/augmentations.js +0 -0
- package/src/features/document/body-always-on.d.ts +36 -0
- package/src/features/document/body-always-on.js +66 -0
- package/src/features/document/body-blocks.d.ts +7 -0
- package/src/features/document/body-blocks.js +78 -0
- package/src/features/document/body-item-adapters.d.ts +62 -0
- package/src/features/document/body-item-adapters.js +97 -0
- package/src/features/document/body-item-collection.d.ts +151 -0
- package/src/features/document/body-item-collection.js +440 -0
- package/src/features/document/body-item.d.ts +35 -0
- package/src/features/document/body-item.js +8 -0
- package/src/features/document/body.d.ts +150 -0
- package/src/features/document/body.js +263 -0
- package/src/features/document/character-format.d.ts +413 -0
- package/src/features/document/character-format.js +2054 -0
- package/src/features/document/color.d.ts +178 -0
- package/src/features/document/color.js +495 -0
- package/src/features/document/document.d.ts +410 -0
- package/src/features/document/document.js +1049 -0
- package/src/features/document/element-type.d.ts +68 -0
- package/src/features/document/element-type.js +133 -0
- package/src/features/document/entity-type.d.ts +92 -0
- package/src/features/document/entity-type.js +93 -0
- package/src/features/document/feature-block.d.ts +16 -0
- package/src/features/document/feature-block.js +0 -0
- package/src/features/document/feature-inline.d.ts +13 -0
- package/src/features/document/feature-inline.js +0 -0
- package/src/features/document/feature-multi-package-part.d.ts +19 -0
- package/src/features/document/feature-multi-package-part.js +8 -0
- package/src/features/document/feature-package-level-part.d.ts +18 -0
- package/src/features/document/feature-package-level-part.js +8 -0
- package/src/features/document/feature-package-part.d.ts +14 -0
- package/src/features/document/feature-package-part.js +0 -0
- package/src/features/document/feature-run-leaf.d.ts +9 -0
- package/src/features/document/feature-run-leaf.js +0 -0
- package/src/features/document/headers-footers.d.ts +206 -0
- package/src/features/document/headers-footers.js +384 -0
- package/src/features/document/index.d.ts +41 -0
- package/src/features/document/index.js +34 -0
- package/src/features/document/length.d.ts +152 -0
- package/src/features/document/length.js +245 -0
- package/src/features/document/load-options.d.ts +14 -0
- package/src/features/document/load-options.js +0 -0
- package/src/features/document/locale-ids.d.ts +227 -0
- package/src/features/document/locale-ids.js +485 -0
- package/src/features/document/on-off.d.ts +9 -0
- package/src/features/document/on-off.js +27 -0
- package/src/features/document/page-setup.d.ts +339 -0
- package/src/features/document/page-setup.js +244 -0
- package/src/features/document/paragraph-format.d.ts +880 -0
- package/src/features/document/paragraph-format.js +2807 -0
- package/src/features/document/paragraph-item-collection.d.ts +162 -0
- package/src/features/document/paragraph-item-collection.js +363 -0
- package/src/features/document/paragraph-item.d.ts +83 -0
- package/src/features/document/paragraph-item.js +103 -0
- package/src/features/document/paragraph.d.ts +435 -0
- package/src/features/document/paragraph.js +888 -0
- package/src/features/document/run.d.ts +1 -0
- package/src/features/document/run.js +768 -0
- package/src/features/document/section-partition-flatten.d.ts +124 -0
- package/src/features/document/section-partition-flatten.js +217 -0
- package/src/features/document/section-properties-model.d.ts +13 -0
- package/src/features/document/section-properties-model.js +0 -0
- package/src/features/document/section.d.ts +93 -0
- package/src/features/document/section.js +178 -0
- package/src/features/document/sections.d.ts +103 -0
- package/src/features/document/sections.js +217 -0
- package/src/features/document/sub-super-script.d.ts +23 -0
- package/src/features/document/sub-super-script.js +43 -0
- package/src/features/document/text-range.d.ts +445 -0
- package/src/features/document/text-range.js +1156 -0
- package/src/features/document/typed-body-collections.d.ts +162 -0
- package/src/features/document/typed-body-collections.js +371 -0
- package/src/features/document/underline-style.d.ts +38 -0
- package/src/features/document/underline-style.js +126 -0
- package/src/features/document/units.d.ts +8 -0
- package/src/features/document/units.js +7 -0
- package/src/features/document/wml.d.ts +16 -0
- package/src/features/document/wml.js +67 -0
- package/src/features/drawing/authoring.d.ts +27 -0
- package/src/features/drawing/authoring.js +271 -0
- package/src/features/drawing/body-pr.d.ts +271 -0
- package/src/features/drawing/body-pr.js +663 -0
- package/src/features/drawing/drawing-shape.d.ts +1192 -0
- package/src/features/drawing/drawing-shape.js +3239 -0
- package/src/features/drawing/encode-builders.d.ts +176 -0
- package/src/features/drawing/encode-builders.js +390 -0
- package/src/features/drawing/fill-format.d.ts +52 -0
- package/src/features/drawing/fill-format.js +124 -0
- package/src/features/drawing/host-codec.d.ts +632 -0
- package/src/features/drawing/host-codec.js +2595 -0
- package/src/features/drawing/index.d.ts +13 -0
- package/src/features/drawing/index.js +33 -0
- package/src/features/drawing/line-format.d.ts +76 -0
- package/src/features/drawing/line-format.js +343 -0
- package/src/features/drawing/parse-register.d.ts +50 -0
- package/src/features/drawing/parse-register.js +257 -0
- package/src/features/drawing/residual-utils.d.ts +47 -0
- package/src/features/drawing/residual-utils.js +290 -0
- package/src/features/drawing/shape-types.d.ts +433 -0
- package/src/features/drawing/shape-types.js +437 -0
- package/src/features/drawing/sp-pr.d.ts +396 -0
- package/src/features/drawing/sp-pr.js +610 -0
- package/src/features/drawing/text-frame.d.ts +90 -0
- package/src/features/drawing/text-frame.js +152 -0
- package/src/features/drawing/types.d.ts +352 -0
- package/src/features/drawing/types.js +60 -0
- package/src/features/drawing/wrap-format.d.ts +62 -0
- package/src/features/drawing/wrap-format.js +114 -0
- package/src/features/editable-ranges/index.d.ts +494 -0
- package/src/features/editable-ranges/index.js +1348 -0
- package/src/features/fields/index.d.ts +428 -0
- package/src/features/fields/index.js +2148 -0
- package/src/features/fields/paragraph-field.d.ts +187 -0
- package/src/features/fields/paragraph-field.js +692 -0
- package/src/features/font-table/font-substitution-table.d.ts +75 -0
- package/src/features/font-table/font-substitution-table.js +257 -0
- package/src/features/font-table/font-table-entry.d.ts +255 -0
- package/src/features/font-table/font-table-entry.js +823 -0
- package/src/features/font-table/font-table.d.ts +128 -0
- package/src/features/font-table/font-table.js +313 -0
- package/src/features/font-table/index.d.ts +27 -0
- package/src/features/font-table/index.js +48 -0
- package/src/features/glossary/index.d.ts +97 -0
- package/src/features/glossary/index.js +286 -0
- package/src/features/headers-footers/index.d.ts +506 -0
- package/src/features/headers-footers/index.js +1666 -0
- package/src/features/hyperlinks/index.d.ts +230 -0
- package/src/features/hyperlinks/index.js +685 -0
- package/src/features/images/caption-authoring-api.d.ts +33 -0
- package/src/features/images/caption-authoring-api.js +33 -0
- package/src/features/images/caption-enums.d.ts +52 -0
- package/src/features/images/caption-enums.js +141 -0
- package/src/features/images/caption-host.d.ts +10 -0
- package/src/features/images/caption-host.js +21 -0
- package/src/features/images/captions.d.ts +13 -0
- package/src/features/images/captions.js +142 -0
- package/src/features/images/host-codec.d.ts +103 -0
- package/src/features/images/host-codec.js +720 -0
- package/src/features/images/image-sniff.d.ts +21 -0
- package/src/features/images/image-sniff.js +71 -0
- package/src/features/images/index.d.ts +506 -0
- package/src/features/images/index.js +1429 -0
- package/src/features/images/layout-types.d.ts +232 -0
- package/src/features/images/layout-types.js +294 -0
- package/src/features/images/public-entry.d.ts +9 -0
- package/src/features/images/public-entry.js +9 -0
- package/src/features/index.d.ts +35 -0
- package/src/features/index.js +36 -0
- package/src/features/mail-merge/index.d.ts +113 -0
- package/src/features/mail-merge/index.js +315 -0
- package/src/features/notes/index.d.ts +573 -0
- package/src/features/notes/index.js +1725 -0
- package/src/features/numbering/abstract-numbering.d.ts +90 -0
- package/src/features/numbering/abstract-numbering.js +292 -0
- package/src/features/numbering/index.d.ts +182 -0
- package/src/features/numbering/index.js +668 -0
- package/src/features/numbering/list-format.d.ts +158 -0
- package/src/features/numbering/list-format.js +590 -0
- package/src/features/numbering/list-string.d.ts +7 -0
- package/src/features/numbering/list-string.js +423 -0
- package/src/features/numbering/list-style.d.ts +204 -0
- package/src/features/numbering/list-style.js +1084 -0
- package/src/features/numbering/numbering-instance.d.ts +101 -0
- package/src/features/numbering/numbering-instance.js +329 -0
- package/src/features/numbering/numbering-level.d.ts +118 -0
- package/src/features/numbering/numbering-level.js +501 -0
- package/src/features/numbering/picture-bullet.d.ts +34 -0
- package/src/features/numbering/picture-bullet.js +88 -0
- package/src/features/ole-object/catalog.d.ts +300 -0
- package/src/features/ole-object/catalog.js +908 -0
- package/src/features/ole-object/index.d.ts +526 -0
- package/src/features/ole-object/index.js +1421 -0
- package/src/features/ole-object/relationship.d.ts +27 -0
- package/src/features/ole-object/relationship.js +27 -0
- package/src/features/ole-object/typed-dom.d.ts +186 -0
- package/src/features/ole-object/typed-dom.js +595 -0
- package/src/features/properties/index.d.ts +205 -0
- package/src/features/properties/index.js +549 -0
- package/src/features/revisions/index.d.ts +204 -0
- package/src/features/revisions/index.js +695 -0
- package/src/features/sections/column-collection.d.ts +119 -0
- package/src/features/sections/column-collection.js +478 -0
- package/src/features/sections/column.d.ts +15 -0
- package/src/features/sections/column.js +37 -0
- package/src/features/sections/index.d.ts +91 -0
- package/src/features/sections/index.js +1096 -0
- package/src/features/sections/margins.d.ts +40 -0
- package/src/features/sections/margins.js +105 -0
- package/src/features/sections/page-number-style.d.ts +21 -0
- package/src/features/sections/page-number-style.js +62 -0
- package/src/features/sections/page-orientation.d.ts +10 -0
- package/src/features/sections/page-orientation.js +10 -0
- package/src/features/sections/page-setup.d.ts +435 -0
- package/src/features/sections/page-setup.js +1479 -0
- package/src/features/sections/page-size.d.ts +59 -0
- package/src/features/sections/page-size.js +68 -0
- package/src/features/sections/section-break-code.d.ts +27 -0
- package/src/features/sections/section-break-code.js +60 -0
- package/src/features/sections/section-document-association.d.ts +18 -0
- package/src/features/sections/section-document-association.js +31 -0
- package/src/features/sections/section-validation.d.ts +43 -0
- package/src/features/sections/section-validation.js +97 -0
- package/src/features/settings/attached-template.d.ts +35 -0
- package/src/features/settings/attached-template.js +98 -0
- package/src/features/settings/compat-settings.d.ts +216 -0
- package/src/features/settings/compat-settings.js +508 -0
- package/src/features/settings/document-background.d.ts +59 -0
- package/src/features/settings/document-background.js +131 -0
- package/src/features/settings/document-protection.d.ts +65 -0
- package/src/features/settings/document-protection.js +157 -0
- package/src/features/settings/document-settings-facades.d.ts +108 -0
- package/src/features/settings/document-settings-facades.js +312 -0
- package/src/features/settings/document-settings-values.d.ts +43 -0
- package/src/features/settings/document-settings-values.js +60 -0
- package/src/features/settings/footnote-properties.d.ts +211 -0
- package/src/features/settings/footnote-properties.js +591 -0
- package/src/features/settings/index.d.ts +356 -0
- package/src/features/settings/index.js +829 -0
- package/src/features/settings/settings-children.d.ts +151 -0
- package/src/features/settings/settings-children.js +505 -0
- package/src/features/settings/web-settings.d.ts +88 -0
- package/src/features/settings/web-settings.js +227 -0
- package/src/features/settings/zoom.d.ts +79 -0
- package/src/features/settings/zoom.js +147 -0
- package/src/features/styles/builtin-catalog.d.ts +159 -0
- package/src/features/styles/builtin-catalog.js +963 -0
- package/src/features/styles/builtin-resolver.d.ts +49 -0
- package/src/features/styles/builtin-resolver.js +165 -0
- package/src/features/styles/default-styles.d.ts +37 -0
- package/src/features/styles/default-styles.js +186 -0
- package/src/features/styles/default-theme.d.ts +13 -0
- package/src/features/styles/default-theme.js +13 -0
- package/src/features/styles/doc-defaults.d.ts +58 -0
- package/src/features/styles/doc-defaults.js +178 -0
- package/src/features/styles/formatting-resolver.d.ts +27 -0
- package/src/features/styles/formatting-resolver.js +72 -0
- package/src/features/styles/index.d.ts +256 -0
- package/src/features/styles/index.js +1325 -0
- package/src/features/styles/latent-styles.d.ts +68 -0
- package/src/features/styles/latent-styles.js +305 -0
- package/src/features/styles/paragraph-properties.d.ts +71 -0
- package/src/features/styles/paragraph-properties.js +237 -0
- package/src/features/styles/run-properties.d.ts +93 -0
- package/src/features/styles/run-properties.js +516 -0
- package/src/features/styles/style-base.d.ts +402 -0
- package/src/features/styles/style-base.js +1026 -0
- package/src/features/styles/style-collection.d.ts +264 -0
- package/src/features/styles/style-collection.js +714 -0
- package/src/features/styles/style-format-bridge.d.ts +64 -0
- package/src/features/styles/style-format-bridge.js +100 -0
- package/src/features/styles/style.d.ts +84 -0
- package/src/features/styles/style.js +375 -0
- package/src/features/styles/styles-with-effects.d.ts +71 -0
- package/src/features/styles/styles-with-effects.js +180 -0
- package/src/features/styles/table-style.d.ts +272 -0
- package/src/features/styles/table-style.js +1226 -0
- package/src/features/styles/theme.d.ts +126 -0
- package/src/features/styles/theme.js +377 -0
- package/src/features/tables/border-style-map.d.ts +24 -0
- package/src/features/tables/border-style-map.js +81 -0
- package/src/features/tables/borders.d.ts +126 -0
- package/src/features/tables/borders.js +527 -0
- package/src/features/tables/collections.d.ts +113 -0
- package/src/features/tables/collections.js +261 -0
- package/src/features/tables/format.d.ts +208 -0
- package/src/features/tables/format.js +716 -0
- package/src/features/tables/index.d.ts +597 -0
- package/src/features/tables/index.js +2386 -0
- package/src/features/tables/paddings.d.ts +41 -0
- package/src/features/tables/paddings.js +97 -0
- package/src/features/tables/tbl-pr-positioning.d.ts +27 -0
- package/src/features/tables/tbl-pr-positioning.js +178 -0
- package/src/features/tables/tbl-pr.d.ts +528 -0
- package/src/features/tables/tbl-pr.js +1208 -0
- package/src/features/tables/tc-pr.d.ts +168 -0
- package/src/features/tables/tc-pr.js +553 -0
- package/src/features/tables/tr-pr.d.ts +60 -0
- package/src/features/tables/tr-pr.js +215 -0
- package/src/features/watermark/detect.d.ts +76 -0
- package/src/features/watermark/detect.js +219 -0
- package/src/features/watermark/index.d.ts +28 -0
- package/src/features/watermark/index.js +91 -0
- package/src/features/watermark/logical-store.d.ts +29 -0
- package/src/features/watermark/logical-store.js +31 -0
- package/src/features/watermark/model.d.ts +285 -0
- package/src/features/watermark/model.js +597 -0
- package/src/features/watermark/parse.d.ts +84 -0
- package/src/features/watermark/parse.js +815 -0
- package/src/features/watermark/serialize.d.ts +98 -0
- package/src/features/watermark/serialize.js +1517 -0
- package/src/global.js +1 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
|
@@ -0,0 +1,1348 @@
|
|
|
1
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
2
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
3
|
+
if (!m) return o;
|
|
4
|
+
var i = m.call(o), r, ar = [], e;
|
|
5
|
+
try {
|
|
6
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
7
|
+
}
|
|
8
|
+
catch (error) { e = { error: error }; }
|
|
9
|
+
finally {
|
|
10
|
+
try {
|
|
11
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
12
|
+
}
|
|
13
|
+
finally { if (e) throw e.error; }
|
|
14
|
+
}
|
|
15
|
+
return ar;
|
|
16
|
+
};
|
|
17
|
+
var __spread = (this && this.__spread) || function () {
|
|
18
|
+
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
|
|
19
|
+
return ar;
|
|
20
|
+
};
|
|
21
|
+
var __values = (this && this.__values) || function (o) {
|
|
22
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
|
23
|
+
if (m) return m.call(o);
|
|
24
|
+
return {
|
|
25
|
+
next: function () {
|
|
26
|
+
if (o && i >= o.length) o = void 0;
|
|
27
|
+
return { value: o && o[i++], done: !o };
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
import { Paragraph } from '../document/paragraph';
|
|
32
|
+
import { FeatureInlineParagraphItem, } from '../document/text-range';
|
|
33
|
+
import { isWml, wmlAttr, wmlElement } from '../document/wml';
|
|
34
|
+
import { objectValues } from '../../core/compat/object-compat';
|
|
35
|
+
import { DetachedObjectError, DocxError } from '../../core/errors/docx-error';
|
|
36
|
+
import { featureId, registerFeature, registerFeatureBlockHandler, registerFeatureInlineHandler, registerFeatureMaterializeHandler, visitParagraphsInDocumentOrder, } from '../../core/registry/index';
|
|
37
|
+
var EDITABLE_RANGES = featureId('editable-ranges');
|
|
38
|
+
/**
|
|
39
|
+
* Editor group for an editable range (`ST_EdGrp`, ECMA-376-1 §17.18.21).
|
|
40
|
+
*
|
|
41
|
+
* `w:edGrp` on the start marker names the set of users who may edit the range.
|
|
42
|
+
* ECMA note: `w:ed` (a single editor) takes precedence over the group when both
|
|
43
|
+
* are present; the library stores both without resolving precedence.
|
|
44
|
+
*
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
export var EditableRangeEditorGroup = {
|
|
48
|
+
None: 'none',
|
|
49
|
+
Everyone: 'everyone',
|
|
50
|
+
Administrators: 'administrators',
|
|
51
|
+
Contributors: 'contributors',
|
|
52
|
+
Editors: 'editors',
|
|
53
|
+
Owners: 'owners',
|
|
54
|
+
Current: 'current',
|
|
55
|
+
};
|
|
56
|
+
var EDITOR_GROUPS = objectValues(EditableRangeEditorGroup);
|
|
57
|
+
var DISPLACED_VALUES = ['next', 'prev'];
|
|
58
|
+
/**
|
|
59
|
+
* Attributes the editable-range model consumes; everything else is residual.
|
|
60
|
+
*
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
var MODELED_ATTRIBUTE_LOCAL_NAMES = [
|
|
64
|
+
'id',
|
|
65
|
+
'edGrp',
|
|
66
|
+
'ed',
|
|
67
|
+
'colFirst',
|
|
68
|
+
'colLast',
|
|
69
|
+
'displacedByCustomXml',
|
|
70
|
+
];
|
|
71
|
+
function wmlAttribute(el, localName) {
|
|
72
|
+
var __ts33_0;
|
|
73
|
+
return ((__ts33_0 = el.attributes.find(function (a) { return a.localName === localName && (a.namespaceUri === '' || a.prefix === 'w'); })), __ts33_0 == null ? undefined : __ts33_0.value);
|
|
74
|
+
}
|
|
75
|
+
function isWmlAttribute(a) {
|
|
76
|
+
return a.prefix === 'w' || a.namespaceUri === '' || a.namespaceUri.indexOf('wordprocessingml') >= 0;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Residual attributes for lossless serialize.
|
|
80
|
+
*
|
|
81
|
+
* Modeled local names are omitted only when their values were successfully
|
|
82
|
+
* consumed. Invalid modeled values (unknown `edGrp`, non-decimal columns, bad
|
|
83
|
+
* displacement) stay in the residual bag so they round-trip unchanged.
|
|
84
|
+
*
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
function residualAttributesOf(el, consumedLocalNames) {
|
|
88
|
+
return el.attributes.filter(function (a) {
|
|
89
|
+
if (a.localName === 'space' && a.prefix === 'xml') {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (isWmlAttribute(a) && MODELED_ATTRIBUTE_LOCAL_NAMES.indexOf(a.localName) !== -1) {
|
|
93
|
+
return !consumedLocalNames.has(a.localName);
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function parseDecimalId(raw) {
|
|
99
|
+
if (raw === undefined || !/^\d+$/.test(raw)) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
return Number.parseInt(raw, 10);
|
|
103
|
+
}
|
|
104
|
+
function parseDisplaced(raw) {
|
|
105
|
+
if (raw === undefined) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
return DISPLACED_VALUES.find(function (value) { return value === raw; });
|
|
109
|
+
}
|
|
110
|
+
function parseEditorGroup(raw) {
|
|
111
|
+
if (raw === undefined) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
return EDITOR_GROUPS.find(function (value) { return value === raw; });
|
|
115
|
+
}
|
|
116
|
+
function parseColumn(raw) {
|
|
117
|
+
return parseDecimalId(raw);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Editable-range start marker (`w:permStart`, ECMA-376-1 §17.13.7.2).
|
|
121
|
+
*
|
|
122
|
+
* Paired with an {@link EditableRangeEnd} by matching {@link EditableRangeStart.rangeId}
|
|
123
|
+
* (`w:id`). Markers are first-class DOM nodes occupying an exact slot among
|
|
124
|
+
* paragraph inlines (or body blocks for run-level markers between paragraphs),
|
|
125
|
+
* so relative order versus runs, bookmarks, fields, and other content is stable.
|
|
126
|
+
*
|
|
127
|
+
* @remarks
|
|
128
|
+
* - `rangeId` maps `w:id` (non-negative after save materialization; a negative
|
|
129
|
+
* pending id is allocated on author and remapped before save).
|
|
130
|
+
* - `editorGroup` maps `w:edGrp` (`ST_EdGrp`); `editor` maps `w:ed`.
|
|
131
|
+
* - `columnFirst` / `columnLast` map `w:colFirst` / `w:colLast` (zero-based
|
|
132
|
+
* table column span).
|
|
133
|
+
* - Attributes outside the modeled set are preserved verbatim and re-emitted on
|
|
134
|
+
* serialization (lossless round-trip).
|
|
135
|
+
* - `undefined` means the attribute is absent on serialize; assigning a value
|
|
136
|
+
* emits it; assigning `undefined` removes it.
|
|
137
|
+
*
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
var EditableRangeStart = /** @class */ (function () {
|
|
141
|
+
/**
|
|
142
|
+
* @private
|
|
143
|
+
*/
|
|
144
|
+
function EditableRangeStart(rangeId, options) {
|
|
145
|
+
this.rangeIdValue = rangeId;
|
|
146
|
+
this.editorGroupValue = options == null ? undefined : options.editorGroup;
|
|
147
|
+
this.editorValue = options == null ? undefined : options.editor;
|
|
148
|
+
this.columnFirstValue = options == null ? undefined : options.columnFirst;
|
|
149
|
+
this.columnLastValue = options == null ? undefined : options.columnLast;
|
|
150
|
+
this.displacedByCustomXmlValue = options == null ? undefined : options.displacedByCustomXml;
|
|
151
|
+
this.residual = (options == null ? undefined : options.residualAttributes) !== undefined ? __spread(options.residualAttributes) : [];
|
|
152
|
+
}
|
|
153
|
+
Object.defineProperty(EditableRangeStart.prototype, "rangeId", {
|
|
154
|
+
/**
|
|
155
|
+
* Editable-range identifier shared with the paired end marker (`w:id`).
|
|
156
|
+
*/
|
|
157
|
+
get: function () {
|
|
158
|
+
return this.rangeIdValue;
|
|
159
|
+
},
|
|
160
|
+
enumerable: true,
|
|
161
|
+
configurable: true
|
|
162
|
+
});
|
|
163
|
+
/**
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
166
|
+
EditableRangeStart.prototype.setRangeId = function (rangeId) {
|
|
167
|
+
this.rangeIdValue = rangeId;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* @private
|
|
171
|
+
*/
|
|
172
|
+
EditableRangeStart.prototype.isPendingRangeId = function () {
|
|
173
|
+
return this.rangeIdValue < 0;
|
|
174
|
+
};
|
|
175
|
+
Object.defineProperty(EditableRangeStart.prototype, "editorGroup", {
|
|
176
|
+
/**
|
|
177
|
+
* Editor group allowed to edit the range (`w:edGrp`, `ST_EdGrp`).
|
|
178
|
+
*/
|
|
179
|
+
get: function () {
|
|
180
|
+
return this.editorGroupValue;
|
|
181
|
+
},
|
|
182
|
+
set: function (value) {
|
|
183
|
+
this.editorGroupValue = value;
|
|
184
|
+
},
|
|
185
|
+
enumerable: true,
|
|
186
|
+
configurable: true
|
|
187
|
+
});
|
|
188
|
+
Object.defineProperty(EditableRangeStart.prototype, "editor", {
|
|
189
|
+
/**
|
|
190
|
+
* Single editor allowed to edit the range (`w:ed`) — `DOMAIN\user`,
|
|
191
|
+
* `user@domain`, or a machine-local `user` form.
|
|
192
|
+
*/
|
|
193
|
+
get: function () {
|
|
194
|
+
return this.editorValue;
|
|
195
|
+
},
|
|
196
|
+
set: function (value) {
|
|
197
|
+
this.editorValue = value;
|
|
198
|
+
},
|
|
199
|
+
enumerable: true,
|
|
200
|
+
configurable: true
|
|
201
|
+
});
|
|
202
|
+
Object.defineProperty(EditableRangeStart.prototype, "columnFirst", {
|
|
203
|
+
/**
|
|
204
|
+
* Zero-based first table column of the range (`w:colFirst`).
|
|
205
|
+
*/
|
|
206
|
+
get: function () {
|
|
207
|
+
return this.columnFirstValue;
|
|
208
|
+
},
|
|
209
|
+
set: function (value) {
|
|
210
|
+
this.columnFirstValue = value;
|
|
211
|
+
},
|
|
212
|
+
enumerable: true,
|
|
213
|
+
configurable: true
|
|
214
|
+
});
|
|
215
|
+
Object.defineProperty(EditableRangeStart.prototype, "columnLast", {
|
|
216
|
+
/**
|
|
217
|
+
* Zero-based last table column of the range (`w:colLast`).
|
|
218
|
+
*/
|
|
219
|
+
get: function () {
|
|
220
|
+
return this.columnLastValue;
|
|
221
|
+
},
|
|
222
|
+
set: function (value) {
|
|
223
|
+
this.columnLastValue = value;
|
|
224
|
+
},
|
|
225
|
+
enumerable: true,
|
|
226
|
+
configurable: true
|
|
227
|
+
});
|
|
228
|
+
Object.defineProperty(EditableRangeStart.prototype, "displacedByCustomXml", {
|
|
229
|
+
/**
|
|
230
|
+
* Displacement relative to a custom XML markup element
|
|
231
|
+
* (`w:displacedByCustomXml`).
|
|
232
|
+
*/
|
|
233
|
+
get: function () {
|
|
234
|
+
return this.displacedByCustomXmlValue;
|
|
235
|
+
},
|
|
236
|
+
set: function (value) {
|
|
237
|
+
this.displacedByCustomXmlValue = value;
|
|
238
|
+
},
|
|
239
|
+
enumerable: true,
|
|
240
|
+
configurable: true
|
|
241
|
+
});
|
|
242
|
+
/**
|
|
243
|
+
* @private
|
|
244
|
+
* Residual attributes preserved for lossless serialization. */
|
|
245
|
+
EditableRangeStart.prototype.residualAttributes = function () {
|
|
246
|
+
return this.residual;
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* @private
|
|
250
|
+
*/
|
|
251
|
+
EditableRangeStart.prototype.releaseContent = function () {
|
|
252
|
+
return;
|
|
253
|
+
};
|
|
254
|
+
EditableRangeStart.prototype.toOpenXml = function () {
|
|
255
|
+
var attributes = [wmlAttr('id', String(this.rangeIdValue))];
|
|
256
|
+
if (this.editorGroupValue !== undefined) {
|
|
257
|
+
attributes.push(wmlAttr('edGrp', this.editorGroupValue));
|
|
258
|
+
}
|
|
259
|
+
if (this.editorValue !== undefined) {
|
|
260
|
+
attributes.push(wmlAttr('ed', this.editorValue));
|
|
261
|
+
}
|
|
262
|
+
if (this.columnFirstValue !== undefined) {
|
|
263
|
+
attributes.push(wmlAttr('colFirst', String(this.columnFirstValue)));
|
|
264
|
+
}
|
|
265
|
+
if (this.columnLastValue !== undefined) {
|
|
266
|
+
attributes.push(wmlAttr('colLast', String(this.columnLastValue)));
|
|
267
|
+
}
|
|
268
|
+
if (this.displacedByCustomXmlValue !== undefined) {
|
|
269
|
+
attributes.push(wmlAttr('displacedByCustomXml', this.displacedByCustomXmlValue));
|
|
270
|
+
}
|
|
271
|
+
attributes.push.apply(attributes, __spread(this.residual));
|
|
272
|
+
return wmlElement('permStart', { attributes: attributes });
|
|
273
|
+
};
|
|
274
|
+
return EditableRangeStart;
|
|
275
|
+
}());
|
|
276
|
+
export { EditableRangeStart };
|
|
277
|
+
/**
|
|
278
|
+
* Editable-range end marker (`w:permEnd`, ECMA-376-1 §17.13.7.1).
|
|
279
|
+
*
|
|
280
|
+
* Paired with an {@link EditableRangeStart} by matching `w:id`. The end marker
|
|
281
|
+
* carries only the identifier, optional displacement, and residual attributes.
|
|
282
|
+
*
|
|
283
|
+
* @private
|
|
284
|
+
*/
|
|
285
|
+
var EditableRangeEnd = /** @class */ (function () {
|
|
286
|
+
/**
|
|
287
|
+
* @private
|
|
288
|
+
*/
|
|
289
|
+
function EditableRangeEnd(rangeId, options) {
|
|
290
|
+
this.rangeIdValue = rangeId;
|
|
291
|
+
this.displacedByCustomXmlValue = options == null ? undefined : options.displacedByCustomXml;
|
|
292
|
+
this.residual = (options == null ? undefined : options.residualAttributes) !== undefined ? __spread(options.residualAttributes) : [];
|
|
293
|
+
}
|
|
294
|
+
Object.defineProperty(EditableRangeEnd.prototype, "rangeId", {
|
|
295
|
+
/**
|
|
296
|
+
* Editable-range identifier shared with the paired start marker (`w:id`).
|
|
297
|
+
*/
|
|
298
|
+
get: function () {
|
|
299
|
+
return this.rangeIdValue;
|
|
300
|
+
},
|
|
301
|
+
enumerable: true,
|
|
302
|
+
configurable: true
|
|
303
|
+
});
|
|
304
|
+
/**
|
|
305
|
+
* @private
|
|
306
|
+
*/
|
|
307
|
+
EditableRangeEnd.prototype.setRangeId = function (rangeId) {
|
|
308
|
+
this.rangeIdValue = rangeId;
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* @private
|
|
312
|
+
*/
|
|
313
|
+
EditableRangeEnd.prototype.isPendingRangeId = function () {
|
|
314
|
+
return this.rangeIdValue < 0;
|
|
315
|
+
};
|
|
316
|
+
Object.defineProperty(EditableRangeEnd.prototype, "displacedByCustomXml", {
|
|
317
|
+
/**
|
|
318
|
+
* Displacement relative to a custom XML markup element
|
|
319
|
+
* (`w:displacedByCustomXml`).
|
|
320
|
+
*/
|
|
321
|
+
get: function () {
|
|
322
|
+
return this.displacedByCustomXmlValue;
|
|
323
|
+
},
|
|
324
|
+
set: function (value) {
|
|
325
|
+
this.displacedByCustomXmlValue = value;
|
|
326
|
+
},
|
|
327
|
+
enumerable: true,
|
|
328
|
+
configurable: true
|
|
329
|
+
});
|
|
330
|
+
/**
|
|
331
|
+
* @private
|
|
332
|
+
* Residual attributes preserved for lossless serialization. */
|
|
333
|
+
EditableRangeEnd.prototype.residualAttributes = function () {
|
|
334
|
+
return this.residual;
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* @private
|
|
338
|
+
*/
|
|
339
|
+
EditableRangeEnd.prototype.releaseContent = function () {
|
|
340
|
+
return;
|
|
341
|
+
};
|
|
342
|
+
EditableRangeEnd.prototype.toOpenXml = function () {
|
|
343
|
+
var attributes = [wmlAttr('id', String(this.rangeIdValue))];
|
|
344
|
+
if (this.displacedByCustomXmlValue !== undefined) {
|
|
345
|
+
attributes.push(wmlAttr('displacedByCustomXml', this.displacedByCustomXmlValue));
|
|
346
|
+
}
|
|
347
|
+
attributes.push.apply(attributes, __spread(this.residual));
|
|
348
|
+
return wmlElement('permEnd', { attributes: attributes });
|
|
349
|
+
};
|
|
350
|
+
return EditableRangeEnd;
|
|
351
|
+
}());
|
|
352
|
+
export { EditableRangeEnd };
|
|
353
|
+
/**
|
|
354
|
+
* Live query view over a paired start/end marker pair, resolved by `w:id`.
|
|
355
|
+
*
|
|
356
|
+
* The view does not own markup: {@link EditableRangeStart} and
|
|
357
|
+
* {@link EditableRangeEnd} remain in their host containers (which may be
|
|
358
|
+
* different paragraphs), and property reads write through to the live start
|
|
359
|
+
* marker.
|
|
360
|
+
*
|
|
361
|
+
* @private
|
|
362
|
+
*/
|
|
363
|
+
var EditableRange = /** @class */ (function () {
|
|
364
|
+
/**
|
|
365
|
+
* @private
|
|
366
|
+
*/
|
|
367
|
+
function EditableRange(start, end) {
|
|
368
|
+
this.startMarkerValue = start;
|
|
369
|
+
this.endMarkerValue = end;
|
|
370
|
+
}
|
|
371
|
+
Object.defineProperty(EditableRange.prototype, "rangeId", {
|
|
372
|
+
/**
|
|
373
|
+
* Identifier shared by the paired markers (`w:id`).
|
|
374
|
+
*/
|
|
375
|
+
get: function () {
|
|
376
|
+
return this.startMarkerValue.rangeId;
|
|
377
|
+
},
|
|
378
|
+
enumerable: true,
|
|
379
|
+
configurable: true
|
|
380
|
+
});
|
|
381
|
+
Object.defineProperty(EditableRange.prototype, "startMarker", {
|
|
382
|
+
/**
|
|
383
|
+
* Start marker (`w:permStart`).
|
|
384
|
+
*/
|
|
385
|
+
get: function () {
|
|
386
|
+
return this.startMarkerValue;
|
|
387
|
+
},
|
|
388
|
+
enumerable: true,
|
|
389
|
+
configurable: true
|
|
390
|
+
});
|
|
391
|
+
Object.defineProperty(EditableRange.prototype, "endMarker", {
|
|
392
|
+
/**
|
|
393
|
+
* End marker (`w:permEnd`).
|
|
394
|
+
*/
|
|
395
|
+
get: function () {
|
|
396
|
+
return this.endMarkerValue;
|
|
397
|
+
},
|
|
398
|
+
enumerable: true,
|
|
399
|
+
configurable: true
|
|
400
|
+
});
|
|
401
|
+
Object.defineProperty(EditableRange.prototype, "editorGroup", {
|
|
402
|
+
/**
|
|
403
|
+
* Editor group allowed to edit the range (`w:edGrp` on the start marker).
|
|
404
|
+
* Assignment writes through to {@link EditableRangeStart.editorGroup}.
|
|
405
|
+
*/
|
|
406
|
+
get: function () {
|
|
407
|
+
return this.startMarkerValue.editorGroup;
|
|
408
|
+
},
|
|
409
|
+
set: function (value) {
|
|
410
|
+
this.startMarkerValue.editorGroup = value;
|
|
411
|
+
},
|
|
412
|
+
enumerable: true,
|
|
413
|
+
configurable: true
|
|
414
|
+
});
|
|
415
|
+
Object.defineProperty(EditableRange.prototype, "editor", {
|
|
416
|
+
/**
|
|
417
|
+
* Single editor allowed to edit the range (`w:ed` on the start marker).
|
|
418
|
+
* Assignment writes through to {@link EditableRangeStart.editor}.
|
|
419
|
+
*/
|
|
420
|
+
get: function () {
|
|
421
|
+
return this.startMarkerValue.editor;
|
|
422
|
+
},
|
|
423
|
+
set: function (value) {
|
|
424
|
+
this.startMarkerValue.editor = value;
|
|
425
|
+
},
|
|
426
|
+
enumerable: true,
|
|
427
|
+
configurable: true
|
|
428
|
+
});
|
|
429
|
+
Object.defineProperty(EditableRange.prototype, "columnFirst", {
|
|
430
|
+
/**
|
|
431
|
+
* Zero-based first table column of the range (`w:colFirst`).
|
|
432
|
+
*/
|
|
433
|
+
get: function () {
|
|
434
|
+
return this.startMarkerValue.columnFirst;
|
|
435
|
+
},
|
|
436
|
+
enumerable: true,
|
|
437
|
+
configurable: true
|
|
438
|
+
});
|
|
439
|
+
Object.defineProperty(EditableRange.prototype, "columnLast", {
|
|
440
|
+
/**
|
|
441
|
+
* Zero-based last table column of the range (`w:colLast`).
|
|
442
|
+
*/
|
|
443
|
+
get: function () {
|
|
444
|
+
return this.startMarkerValue.columnLast;
|
|
445
|
+
},
|
|
446
|
+
enumerable: true,
|
|
447
|
+
configurable: true
|
|
448
|
+
});
|
|
449
|
+
/**
|
|
450
|
+
* Whether both markers are paragraph inlines of the same paragraph.
|
|
451
|
+
*
|
|
452
|
+
* Requires a document walk; pass the owning document via
|
|
453
|
+
* {@link editableRangeMarkersShareParagraph}.
|
|
454
|
+
*
|
|
455
|
+
* @deprecated Prefer {@link editableRangeMarkersShareParagraph}.
|
|
456
|
+
* @private
|
|
457
|
+
*/
|
|
458
|
+
EditableRange.prototype.markersShareParagraph = function (document) {
|
|
459
|
+
return editableRangeMarkersShareParagraph(document, this);
|
|
460
|
+
};
|
|
461
|
+
return EditableRange;
|
|
462
|
+
}());
|
|
463
|
+
export { EditableRange };
|
|
464
|
+
/**
|
|
465
|
+
* Whether both markers of a paired range are inlines of the same paragraph.
|
|
466
|
+
*
|
|
467
|
+
* @private
|
|
468
|
+
*/
|
|
469
|
+
export function editableRangeMarkersShareParagraph(document, range) {
|
|
470
|
+
var startLoc = locateMarker(document, range.startMarker);
|
|
471
|
+
var endLoc = locateMarker(document, range.endMarker);
|
|
472
|
+
// TS 3.3 does not narrow unions through `(x == null ? undefined : x.kind)`.
|
|
473
|
+
return (startLoc !== undefined &&
|
|
474
|
+
endLoc !== undefined &&
|
|
475
|
+
startLoc.kind === 'inline' &&
|
|
476
|
+
endLoc.kind === 'inline' &&
|
|
477
|
+
startLoc.paragraph === endLoc.paragraph);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Locate a marker among document body blocks and paragraph inlines.
|
|
481
|
+
*
|
|
482
|
+
* @private
|
|
483
|
+
*/
|
|
484
|
+
function locateMarker(document, marker) {
|
|
485
|
+
var blocks = document.listBlocks();
|
|
486
|
+
for (var i = 0; i < blocks.length; i += 1) {
|
|
487
|
+
var block = blocks[i];
|
|
488
|
+
if (block === undefined) {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
if (block.type === 'feature' && block.value === marker) {
|
|
492
|
+
return { kind: 'block', document: document, index: i };
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
var found;
|
|
496
|
+
visitParagraphsInDocumentOrder(document, function (paragraph) {
|
|
497
|
+
if (found !== undefined) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
var content = paragraph.items.toArray();
|
|
501
|
+
for (var i = 0; i < content.length; i += 1) {
|
|
502
|
+
var inline = content[i];
|
|
503
|
+
// TS 3.3 does not narrow InlineContent through `(x == null ? undefined : x.type)`.
|
|
504
|
+
if (inline !== undefined &&
|
|
505
|
+
inline instanceof FeatureInlineParagraphItem &&
|
|
506
|
+
inline.value === marker) {
|
|
507
|
+
found = { kind: 'inline', paragraph: paragraph, index: i };
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
return found;
|
|
513
|
+
}
|
|
514
|
+
function removeMarkerAt(location, marker) {
|
|
515
|
+
if (location.kind === 'inline') {
|
|
516
|
+
location.paragraph.removeFeatureInline(marker);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
var block = location.document.listBlocks()[location.index];
|
|
520
|
+
if (block === undefined || block.type !== 'feature' || block.value !== marker) {
|
|
521
|
+
throw new DetachedObjectError('Editable-range marker is no longer in this document');
|
|
522
|
+
}
|
|
523
|
+
location.document.removeBlockAt(location.index);
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Deep-clone a start marker, optionally overriding `rangeId`.
|
|
527
|
+
*
|
|
528
|
+
* Residual attributes are copied. Used by paragraph/content clone helpers that
|
|
529
|
+
* re-insert ranges without sharing live marker instances.
|
|
530
|
+
*
|
|
531
|
+
* @private
|
|
532
|
+
*/
|
|
533
|
+
export function cloneEditableRangeStart(source, options) {
|
|
534
|
+
var __ts33_1;
|
|
535
|
+
return new EditableRangeStart(((__ts33_1 = options == null ? undefined : options.rangeId), __ts33_1 != null ? __ts33_1 : source.rangeId), {
|
|
536
|
+
editorGroup: source.editorGroup,
|
|
537
|
+
editor: source.editor,
|
|
538
|
+
columnFirst: source.columnFirst,
|
|
539
|
+
columnLast: source.columnLast,
|
|
540
|
+
displacedByCustomXml: source.displacedByCustomXml,
|
|
541
|
+
residualAttributes: source.residualAttributes(),
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Deep-clone an end marker, optionally overriding `rangeId`.
|
|
546
|
+
*
|
|
547
|
+
* @private
|
|
548
|
+
*/
|
|
549
|
+
export function cloneEditableRangeEnd(source, options) {
|
|
550
|
+
var __ts33_2;
|
|
551
|
+
return new EditableRangeEnd(((__ts33_2 = options == null ? undefined : options.rangeId), __ts33_2 != null ? __ts33_2 : source.rangeId), {
|
|
552
|
+
displacedByCustomXml: source.displacedByCustomXml,
|
|
553
|
+
residualAttributes: source.residualAttributes(),
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Clone a paired range’s markers onto a target document with a fresh pending id.
|
|
558
|
+
*
|
|
559
|
+
* Returns detached start/end clones (not inserted). Callers insert them into
|
|
560
|
+
* the desired hosts. Both clones share the same pending id so they pair after
|
|
561
|
+
* insertion. Does not mutate the source markers.
|
|
562
|
+
*
|
|
563
|
+
* @private
|
|
564
|
+
*/
|
|
565
|
+
export function cloneEditableRangeForInsert(document, range) {
|
|
566
|
+
var pendingId = allocatePendingEditableRangeId(document);
|
|
567
|
+
return {
|
|
568
|
+
start: cloneEditableRangeStart(range.startMarker, { rangeId: pendingId }),
|
|
569
|
+
end: cloneEditableRangeEnd(range.endMarker, { rangeId: pendingId }),
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Remove both markers of a paired editable range; enclosed content is kept.
|
|
574
|
+
*
|
|
575
|
+
* Markers may be paragraph inlines and/or body-level feature blocks. After
|
|
576
|
+
* removal the pair is gone from query APIs; orphan policy does not apply
|
|
577
|
+
* because both ends are deleted together.
|
|
578
|
+
*
|
|
579
|
+
* @param document - Owning document (used for body-level marker removal)
|
|
580
|
+
* @param range - Pair view from a query or authoring API
|
|
581
|
+
* @returns Nothing
|
|
582
|
+
* @throws {@link DocxError} `content/unknown-editable-range` when either marker
|
|
583
|
+
* is not found in the document.
|
|
584
|
+
* @example
|
|
585
|
+
* ```ts
|
|
586
|
+
* const [range] = editableRangesInDocument(doc);
|
|
587
|
+
* if (range) removeEditableRange(doc, range);
|
|
588
|
+
* ```
|
|
589
|
+
* @private
|
|
590
|
+
*/
|
|
591
|
+
export function removeEditableRange(document, range) {
|
|
592
|
+
var startLoc = locateMarker(document, range.startMarker);
|
|
593
|
+
var endLoc = locateMarker(document, range.endMarker);
|
|
594
|
+
if (startLoc === undefined || endLoc === undefined) {
|
|
595
|
+
throw new DocxError('content/unknown-editable-range', 'Editable range markers are not in this document');
|
|
596
|
+
}
|
|
597
|
+
// Remove higher document-order index first so lower indices stay valid.
|
|
598
|
+
var startOrder = markerDocumentOrderKey(startLoc);
|
|
599
|
+
var endOrder = markerDocumentOrderKey(endLoc);
|
|
600
|
+
if (startOrder > endOrder) {
|
|
601
|
+
removeMarkerAt(startLoc, range.startMarker);
|
|
602
|
+
// Re-locate end after start removal if both were body blocks with shifting indices.
|
|
603
|
+
var endReloc = locateMarker(document, range.endMarker);
|
|
604
|
+
if (endReloc === undefined) {
|
|
605
|
+
throw new DocxError('content/unknown-editable-range', 'Editable range end marker is not in this document');
|
|
606
|
+
}
|
|
607
|
+
removeMarkerAt(endReloc, range.endMarker);
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
removeMarkerAt(endLoc, range.endMarker);
|
|
611
|
+
var startReloc = locateMarker(document, range.startMarker);
|
|
612
|
+
if (startReloc === undefined) {
|
|
613
|
+
throw new DocxError('content/unknown-editable-range', 'Editable range start marker is not in this document');
|
|
614
|
+
}
|
|
615
|
+
removeMarkerAt(startReloc, range.startMarker);
|
|
616
|
+
}
|
|
617
|
+
rangeByStart.delete(range.startMarker);
|
|
618
|
+
}
|
|
619
|
+
function markerDocumentOrderKey(location) {
|
|
620
|
+
if (location.kind === 'block') {
|
|
621
|
+
// Body blocks ordered by block index; scale so they interleave roughly with
|
|
622
|
+
// paragraph walks (block index * large stride).
|
|
623
|
+
return location.index * 1000000;
|
|
624
|
+
}
|
|
625
|
+
// Prefer end-before-start removal within the same paragraph via content index.
|
|
626
|
+
var blocks = location.paragraph.owningDocument().listBlocks();
|
|
627
|
+
var blockIndex = 0;
|
|
628
|
+
for (var i = 0; i < blocks.length; i += 1) {
|
|
629
|
+
var b = blocks[i];
|
|
630
|
+
// TS 3.3 does not narrow BodyItem through `(x == null ? undefined : x.type)`.
|
|
631
|
+
if (b !== undefined && b.type === 'paragraph' && b.paragraph === location.paragraph) {
|
|
632
|
+
blockIndex = i;
|
|
633
|
+
break;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
return blockIndex * 1000000 + location.index;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Move a single modeled marker from one paragraph content slot to another.
|
|
640
|
+
*
|
|
641
|
+
* Used for same-document reorder tests; does not change `rangeId`. When the
|
|
642
|
+
* marker is a body-level feature block, it is removed from the body and
|
|
643
|
+
* inserted as an inline in the target paragraph.
|
|
644
|
+
*
|
|
645
|
+
* @private
|
|
646
|
+
*/
|
|
647
|
+
export function moveEditableRangeMarkerToParagraph(document, marker, targetParagraph, inlineIndex) {
|
|
648
|
+
var location = locateMarker(document, marker);
|
|
649
|
+
if (location === undefined) {
|
|
650
|
+
throw new DocxError('content/unknown-editable-range', 'Editable-range marker is not in this document');
|
|
651
|
+
}
|
|
652
|
+
if (targetParagraph.owningDocument() !== document) {
|
|
653
|
+
throw new DocxError('content/invalid-editable-range', 'Target paragraph is not in this document');
|
|
654
|
+
}
|
|
655
|
+
removeMarkerAt(location, marker);
|
|
656
|
+
var insertAt = inlineIndex;
|
|
657
|
+
if (location.kind === 'inline' && location.paragraph === targetParagraph) {
|
|
658
|
+
// After removal, indices after the old slot shift left by one.
|
|
659
|
+
if (inlineIndex > location.index) {
|
|
660
|
+
insertAt = inlineIndex - 1;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (insertAt < 0 || insertAt > targetParagraph.items.length) {
|
|
664
|
+
throw new RangeError("Feature inline index " + String(insertAt) + " is out of range");
|
|
665
|
+
}
|
|
666
|
+
targetParagraph.insertFeatureInlineAt(insertAt, EDITABLE_RANGES, marker);
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Remap every editable-range marker in a paragraph to fresh pending ids, pairing
|
|
670
|
+
* starts with ends that share the previous id within the paragraph only.
|
|
671
|
+
*
|
|
672
|
+
* Intended for “clone paragraph then insert” flows so positive ids are not
|
|
673
|
+
* duplicated in the document. Cross-paragraph half-clones keep unpaired markers
|
|
674
|
+
* with new pending ids (one id per marker).
|
|
675
|
+
*
|
|
676
|
+
* @private
|
|
677
|
+
*/
|
|
678
|
+
export function remapEditableRangeIdsInParagraphToPending(paragraph) {
|
|
679
|
+
var e_1, _a, e_2, _b;
|
|
680
|
+
var document = paragraph.owningDocument();
|
|
681
|
+
var content = paragraph.items.toArray();
|
|
682
|
+
var oldToPending = new Map();
|
|
683
|
+
var usedIds = new Set();
|
|
684
|
+
collectEditableRangeIds(document, function (id) {
|
|
685
|
+
usedIds.add(id);
|
|
686
|
+
});
|
|
687
|
+
var allocPending = function () {
|
|
688
|
+
var candidate = -1;
|
|
689
|
+
while (usedIds.has(candidate)) {
|
|
690
|
+
candidate -= 1;
|
|
691
|
+
}
|
|
692
|
+
usedIds.add(candidate);
|
|
693
|
+
return candidate;
|
|
694
|
+
};
|
|
695
|
+
try {
|
|
696
|
+
for (var content_1 = __values(content), content_1_1 = content_1.next(); !content_1_1.done; content_1_1 = content_1.next()) {
|
|
697
|
+
var inline = content_1_1.value;
|
|
698
|
+
if (!(inline instanceof FeatureInlineParagraphItem)) {
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
701
|
+
if (inline.value instanceof EditableRangeStart || inline.value instanceof EditableRangeEnd) {
|
|
702
|
+
var oldId = inline.value.rangeId;
|
|
703
|
+
if (!oldToPending.has(oldId)) {
|
|
704
|
+
oldToPending.set(oldId, allocPending());
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
710
|
+
finally {
|
|
711
|
+
try {
|
|
712
|
+
if (content_1_1 && !content_1_1.done && (_a = content_1.return)) _a.call(content_1);
|
|
713
|
+
}
|
|
714
|
+
finally { if (e_1) throw e_1.error; }
|
|
715
|
+
}
|
|
716
|
+
try {
|
|
717
|
+
for (var content_2 = __values(content), content_2_1 = content_2.next(); !content_2_1.done; content_2_1 = content_2.next()) {
|
|
718
|
+
var inline = content_2_1.value;
|
|
719
|
+
if (!(inline instanceof FeatureInlineParagraphItem)) {
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
if (inline.value instanceof EditableRangeStart || inline.value instanceof EditableRangeEnd) {
|
|
723
|
+
var pending_1 = oldToPending.get(inline.value.rangeId);
|
|
724
|
+
if (pending_1 !== undefined) {
|
|
725
|
+
inline.value.setRangeId(pending_1);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
731
|
+
finally {
|
|
732
|
+
try {
|
|
733
|
+
if (content_2_1 && !content_2_1.done && (_b = content_2.return)) _b.call(content_2);
|
|
734
|
+
}
|
|
735
|
+
finally { if (e_2) throw e_2.error; }
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Clone all editable-range markers found as paragraph inlines, preserving local
|
|
740
|
+
* pairing by assigning one fresh pending id per former id shared by start/end
|
|
741
|
+
* in this paragraph.
|
|
742
|
+
*
|
|
743
|
+
* Returns new marker instances (not inserted). Non-range inlines are ignored —
|
|
744
|
+
* callers building a full paragraph clone still need core paragraph clone support.
|
|
745
|
+
*
|
|
746
|
+
* @private
|
|
747
|
+
*/
|
|
748
|
+
export function cloneEditableRangeMarkersFromParagraph(document, sourceParagraph) {
|
|
749
|
+
var e_3, _a;
|
|
750
|
+
var oldToPending = new Map();
|
|
751
|
+
var usedPending = new Set();
|
|
752
|
+
collectEditableRangeIds(document, function (id) {
|
|
753
|
+
usedPending.add(id);
|
|
754
|
+
});
|
|
755
|
+
var allocPending = function () {
|
|
756
|
+
var candidate = -1;
|
|
757
|
+
while (usedPending.has(candidate)) {
|
|
758
|
+
candidate -= 1;
|
|
759
|
+
}
|
|
760
|
+
usedPending.add(candidate);
|
|
761
|
+
return candidate;
|
|
762
|
+
};
|
|
763
|
+
var content = sourceParagraph.items.toArray();
|
|
764
|
+
try {
|
|
765
|
+
for (var content_3 = __values(content), content_3_1 = content_3.next(); !content_3_1.done; content_3_1 = content_3.next()) {
|
|
766
|
+
var inline = content_3_1.value;
|
|
767
|
+
if (!(inline instanceof FeatureInlineParagraphItem)) {
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
if (inline.value instanceof EditableRangeStart || inline.value instanceof EditableRangeEnd) {
|
|
771
|
+
if (!oldToPending.has(inline.value.rangeId)) {
|
|
772
|
+
oldToPending.set(inline.value.rangeId, allocPending());
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
778
|
+
finally {
|
|
779
|
+
try {
|
|
780
|
+
if (content_3_1 && !content_3_1.done && (_a = content_3.return)) _a.call(content_3);
|
|
781
|
+
}
|
|
782
|
+
finally { if (e_3) throw e_3.error; }
|
|
783
|
+
}
|
|
784
|
+
var markers = [];
|
|
785
|
+
for (var i = 0; i < content.length; i += 1) {
|
|
786
|
+
// TS 3.3 does not narrow InlineContent through `(x == null ? undefined : x.type)`.
|
|
787
|
+
var inline = content[i];
|
|
788
|
+
if (inline === undefined || !(inline instanceof FeatureInlineParagraphItem)) {
|
|
789
|
+
continue;
|
|
790
|
+
}
|
|
791
|
+
var pending_2 = oldToPending.get(inline.value instanceof EditableRangeStart || inline.value instanceof EditableRangeEnd
|
|
792
|
+
? inline.value.rangeId
|
|
793
|
+
: Number.NaN);
|
|
794
|
+
if (pending_2 === undefined) {
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
if (inline.value instanceof EditableRangeStart) {
|
|
798
|
+
markers.push({
|
|
799
|
+
index: i,
|
|
800
|
+
marker: cloneEditableRangeStart(inline.value, { rangeId: pending_2 }),
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
else if (inline.value instanceof EditableRangeEnd) {
|
|
804
|
+
markers.push({
|
|
805
|
+
index: i,
|
|
806
|
+
marker: cloneEditableRangeEnd(inline.value, { rangeId: pending_2 }),
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return { markers: markers };
|
|
811
|
+
}
|
|
812
|
+
function parseEditableRangeStart(element) {
|
|
813
|
+
if (!isWml(element, 'permStart')) {
|
|
814
|
+
return undefined;
|
|
815
|
+
}
|
|
816
|
+
var rangeId = parseDecimalId(wmlAttribute(element, 'id'));
|
|
817
|
+
if (rangeId === undefined) {
|
|
818
|
+
// Non-decimal or missing w:id — stay opaque so bytes are preserved verbatim.
|
|
819
|
+
return undefined;
|
|
820
|
+
}
|
|
821
|
+
var consumed = new Set(['id']);
|
|
822
|
+
var editorGroupRaw = wmlAttribute(element, 'edGrp');
|
|
823
|
+
var editorGroup = parseEditorGroup(editorGroupRaw);
|
|
824
|
+
if (editorGroupRaw !== undefined && editorGroup !== undefined) {
|
|
825
|
+
consumed.add('edGrp');
|
|
826
|
+
}
|
|
827
|
+
var editor = wmlAttribute(element, 'ed');
|
|
828
|
+
if (editor !== undefined) {
|
|
829
|
+
consumed.add('ed');
|
|
830
|
+
}
|
|
831
|
+
var columnFirstRaw = wmlAttribute(element, 'colFirst');
|
|
832
|
+
var columnFirst = parseColumn(columnFirstRaw);
|
|
833
|
+
if (columnFirstRaw !== undefined && columnFirst !== undefined) {
|
|
834
|
+
consumed.add('colFirst');
|
|
835
|
+
}
|
|
836
|
+
var columnLastRaw = wmlAttribute(element, 'colLast');
|
|
837
|
+
var columnLast = parseColumn(columnLastRaw);
|
|
838
|
+
if (columnLastRaw !== undefined && columnLast !== undefined) {
|
|
839
|
+
consumed.add('colLast');
|
|
840
|
+
}
|
|
841
|
+
var displacedRaw = wmlAttribute(element, 'displacedByCustomXml');
|
|
842
|
+
var displacedByCustomXml = parseDisplaced(displacedRaw);
|
|
843
|
+
if (displacedRaw !== undefined && displacedByCustomXml !== undefined) {
|
|
844
|
+
consumed.add('displacedByCustomXml');
|
|
845
|
+
}
|
|
846
|
+
return new EditableRangeStart(rangeId, {
|
|
847
|
+
editorGroup: editorGroup,
|
|
848
|
+
editor: editor,
|
|
849
|
+
columnFirst: columnFirst,
|
|
850
|
+
columnLast: columnLast,
|
|
851
|
+
displacedByCustomXml: displacedByCustomXml,
|
|
852
|
+
residualAttributes: residualAttributesOf(element, consumed),
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
function parseEditableRangeEnd(element) {
|
|
856
|
+
if (!isWml(element, 'permEnd')) {
|
|
857
|
+
return undefined;
|
|
858
|
+
}
|
|
859
|
+
var rangeId = parseDecimalId(wmlAttribute(element, 'id'));
|
|
860
|
+
if (rangeId === undefined) {
|
|
861
|
+
return undefined;
|
|
862
|
+
}
|
|
863
|
+
var consumed = new Set(['id']);
|
|
864
|
+
var displacedRaw = wmlAttribute(element, 'displacedByCustomXml');
|
|
865
|
+
var displacedByCustomXml = parseDisplaced(displacedRaw);
|
|
866
|
+
if (displacedRaw !== undefined && displacedByCustomXml !== undefined) {
|
|
867
|
+
consumed.add('displacedByCustomXml');
|
|
868
|
+
}
|
|
869
|
+
return new EditableRangeEnd(rangeId, {
|
|
870
|
+
displacedByCustomXml: displacedByCustomXml,
|
|
871
|
+
residualAttributes: residualAttributesOf(element, consumed),
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* WordDocument-order walk of modeled editable-range markers.
|
|
876
|
+
*
|
|
877
|
+
* Visits:
|
|
878
|
+
* - body-level feature blocks that are start/end markers
|
|
879
|
+
* - inline markers inside every paragraph reachable via
|
|
880
|
+
* {@link visitParagraphsInDocumentOrder} (main body and nested feature
|
|
881
|
+
* paragraphs such as table cells)
|
|
882
|
+
*
|
|
883
|
+
* Body-level markers that sit between paragraphs are emitted when their
|
|
884
|
+
* owning block is visited, before subsequent paragraphs. Nested table-cell
|
|
885
|
+
* body-level markers that are not paragraph inlines are only visible when
|
|
886
|
+
* hosted as paragraph inlines (common Word placement).
|
|
887
|
+
*
|
|
888
|
+
* @private
|
|
889
|
+
*/
|
|
890
|
+
function collectEditableRangeMarkersInDocumentOrder(document) {
|
|
891
|
+
var e_4, _a;
|
|
892
|
+
var markers = [];
|
|
893
|
+
var seen = new Set();
|
|
894
|
+
var push = function (marker) {
|
|
895
|
+
if (seen.has(marker)) {
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
seen.add(marker);
|
|
899
|
+
markers.push(marker);
|
|
900
|
+
};
|
|
901
|
+
var visitParagraphInlines = function (paragraph) {
|
|
902
|
+
var e_5, _a;
|
|
903
|
+
try {
|
|
904
|
+
for (var _b = __values(paragraph.items), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
905
|
+
var inline = _c.value;
|
|
906
|
+
if (!(inline instanceof FeatureInlineParagraphItem)) {
|
|
907
|
+
continue;
|
|
908
|
+
}
|
|
909
|
+
if (inline.value instanceof EditableRangeStart || inline.value instanceof EditableRangeEnd) {
|
|
910
|
+
push(inline.value);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
915
|
+
finally {
|
|
916
|
+
try {
|
|
917
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
918
|
+
}
|
|
919
|
+
finally { if (e_5) throw e_5.error; }
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
// Interleave body-level markers with paragraphs in listBlocks order.
|
|
923
|
+
// For nested feature paragraphs (tables), fall back to the registry walker
|
|
924
|
+
// after finishing the top-level block stream so cell inlines are included
|
|
925
|
+
// once, without double-counting top-level paragraphs already visited.
|
|
926
|
+
var topLevelParagraphs = new Set();
|
|
927
|
+
try {
|
|
928
|
+
for (var _b = __values(document.listBlocks()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
929
|
+
var block = _c.value;
|
|
930
|
+
if (block.type === 'paragraph') {
|
|
931
|
+
topLevelParagraphs.add(block.paragraph);
|
|
932
|
+
visitParagraphInlines(block.paragraph);
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
if (block.type === 'feature') {
|
|
936
|
+
if (block.value instanceof EditableRangeStart || block.value instanceof EditableRangeEnd) {
|
|
937
|
+
push(block.value);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
943
|
+
finally {
|
|
944
|
+
try {
|
|
945
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
946
|
+
}
|
|
947
|
+
finally { if (e_4) throw e_4.error; }
|
|
948
|
+
}
|
|
949
|
+
visitParagraphsInDocumentOrder(document, function (paragraph) {
|
|
950
|
+
if (topLevelParagraphs.has(paragraph)) {
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
visitParagraphInlines(paragraph);
|
|
954
|
+
});
|
|
955
|
+
return markers;
|
|
956
|
+
}
|
|
957
|
+
function forEachEditableRangeMarker(document, visit) {
|
|
958
|
+
var e_6, _a;
|
|
959
|
+
try {
|
|
960
|
+
for (var _b = __values(collectEditableRangeMarkersInDocumentOrder(document)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
961
|
+
var marker = _c.value;
|
|
962
|
+
visit(marker);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
966
|
+
finally {
|
|
967
|
+
try {
|
|
968
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
969
|
+
}
|
|
970
|
+
finally { if (e_6) throw e_6.error; }
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
function collectEditableRangeIds(document, visit) {
|
|
974
|
+
forEachEditableRangeMarker(document, function (marker) {
|
|
975
|
+
visit(marker.rangeId);
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Pair starts to ends in document order (ECMA one-start/one-end by id).
|
|
980
|
+
*
|
|
981
|
+
* For each start, the matching end is the first subsequent unpaired end with
|
|
982
|
+
* the same id. Duplicate starts before an end: first start pairs; later starts
|
|
983
|
+
* remain unpaired. Orphan ends remain unpaired. All markers stay in the DOM.
|
|
984
|
+
*
|
|
985
|
+
* @private
|
|
986
|
+
*/
|
|
987
|
+
/** Stable EditableRange identity for a start marker while its paired end is unchanged. */
|
|
988
|
+
var rangeByStart = new WeakMap();
|
|
989
|
+
function pairViewForMarkers(start, end) {
|
|
990
|
+
var range = rangeByStart.get(start);
|
|
991
|
+
if (range === undefined || range.endMarker !== end) {
|
|
992
|
+
range = new EditableRange(start, end);
|
|
993
|
+
rangeByStart.set(start, range);
|
|
994
|
+
}
|
|
995
|
+
return range;
|
|
996
|
+
}
|
|
997
|
+
function pairEditableRanges(markers) {
|
|
998
|
+
var pairedEnd = new Set();
|
|
999
|
+
var ranges = [];
|
|
1000
|
+
for (var i = 0; i < markers.length; i += 1) {
|
|
1001
|
+
var marker = markers[i];
|
|
1002
|
+
if (!(marker instanceof EditableRangeStart)) {
|
|
1003
|
+
continue;
|
|
1004
|
+
}
|
|
1005
|
+
var start = marker;
|
|
1006
|
+
for (var j = i + 1; j < markers.length; j += 1) {
|
|
1007
|
+
var candidate = markers[j];
|
|
1008
|
+
if (!(candidate instanceof EditableRangeEnd)) {
|
|
1009
|
+
continue;
|
|
1010
|
+
}
|
|
1011
|
+
if (candidate.rangeId !== start.rangeId) {
|
|
1012
|
+
continue;
|
|
1013
|
+
}
|
|
1014
|
+
if (pairedEnd.has(candidate)) {
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1017
|
+
pairedEnd.add(candidate);
|
|
1018
|
+
var range = rangeByStart.get(start);
|
|
1019
|
+
if (range === undefined || range.endMarker !== candidate) {
|
|
1020
|
+
range = new EditableRange(start, candidate);
|
|
1021
|
+
rangeByStart.set(start, range);
|
|
1022
|
+
}
|
|
1023
|
+
ranges.push(range);
|
|
1024
|
+
break;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
return ranges;
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* All paired editable ranges in document order of their start markers.
|
|
1031
|
+
*
|
|
1032
|
+
* Walks body-level markers and paragraph inlines (including nested feature
|
|
1033
|
+
* paragraphs such as table cells). Unpaired start/end markers are omitted from
|
|
1034
|
+
* the list but remain in the DOM and continue to serialize.
|
|
1035
|
+
*
|
|
1036
|
+
* @param document - WordDocument whose body is walked
|
|
1037
|
+
* @returns Stable pair views (same start marker → same `EditableRange` object)
|
|
1038
|
+
* @example
|
|
1039
|
+
* ```ts
|
|
1040
|
+
* for (const range of editableRangesInDocument(doc)) {
|
|
1041
|
+
* console.log(range.rangeId, range.editorGroup);
|
|
1042
|
+
* }
|
|
1043
|
+
* ```
|
|
1044
|
+
* @private
|
|
1045
|
+
*/
|
|
1046
|
+
export function editableRangesInDocument(document) {
|
|
1047
|
+
return pairEditableRanges(collectEditableRangeMarkersInDocumentOrder(document));
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Paired editable ranges whose start marker lies in this paragraph.
|
|
1051
|
+
*
|
|
1052
|
+
* The matching end may be in the same paragraph, a later paragraph, or a
|
|
1053
|
+
* body-level feature block. Unpaired starts in the paragraph are omitted.
|
|
1054
|
+
*
|
|
1055
|
+
* @param paragraph - Paragraph that may host start markers
|
|
1056
|
+
* @returns Subset of {@link editableRangesInDocument} for this paragraph
|
|
1057
|
+
* @example
|
|
1058
|
+
* ```ts
|
|
1059
|
+
* const starts = editableRangesStartingInParagraph(doc.body.paragraphs[0]!);
|
|
1060
|
+
* ```
|
|
1061
|
+
* @private
|
|
1062
|
+
*/
|
|
1063
|
+
export function editableRangesStartingInParagraph(paragraph) {
|
|
1064
|
+
// Pair against the full document stream so cross-paragraph ends resolve.
|
|
1065
|
+
var owner = paragraph.owningDocument();
|
|
1066
|
+
var all = editableRangesInDocument(owner);
|
|
1067
|
+
return all.filter(function (range) {
|
|
1068
|
+
var e_7, _a;
|
|
1069
|
+
try {
|
|
1070
|
+
for (var _b = __values(paragraph.items), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1071
|
+
var inline = _c.value;
|
|
1072
|
+
if (inline instanceof FeatureInlineParagraphItem && inline.value === range.startMarker) {
|
|
1073
|
+
return true;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
1078
|
+
finally {
|
|
1079
|
+
try {
|
|
1080
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1081
|
+
}
|
|
1082
|
+
finally { if (e_7) throw e_7.error; }
|
|
1083
|
+
}
|
|
1084
|
+
return false;
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* First paired editable range with this range identifier, if any.
|
|
1089
|
+
*
|
|
1090
|
+
* When duplicate starts share an id, the first start in document order that
|
|
1091
|
+
* successfully pairs wins (see pairing algorithm).
|
|
1092
|
+
*
|
|
1093
|
+
* @param document - WordDocument to search
|
|
1094
|
+
* @param rangeId - `w:id` value (`EditableRange.rangeId`)
|
|
1095
|
+
* @returns First matching pair, or `undefined`
|
|
1096
|
+
* @example
|
|
1097
|
+
* ```ts
|
|
1098
|
+
* const range = editableRangeById(doc, 0);
|
|
1099
|
+
* ```
|
|
1100
|
+
* @private
|
|
1101
|
+
*/
|
|
1102
|
+
export function editableRangeById(document, rangeId) {
|
|
1103
|
+
var e_8, _a;
|
|
1104
|
+
try {
|
|
1105
|
+
for (var _b = __values(editableRangesInDocument(document)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1106
|
+
var range = _c.value;
|
|
1107
|
+
if (range.rangeId === rangeId) {
|
|
1108
|
+
return range;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
1113
|
+
finally {
|
|
1114
|
+
try {
|
|
1115
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1116
|
+
}
|
|
1117
|
+
finally { if (e_8) throw e_8.error; }
|
|
1118
|
+
}
|
|
1119
|
+
return undefined;
|
|
1120
|
+
}
|
|
1121
|
+
/**
|
|
1122
|
+
* Modeled editable-range markers in document order (paired and unpaired).
|
|
1123
|
+
*
|
|
1124
|
+
* Useful for diagnostics and tests; public authoring stays on pair views.
|
|
1125
|
+
*
|
|
1126
|
+
* @param document - WordDocument whose markers are listed
|
|
1127
|
+
* @returns Start and end markers in document order
|
|
1128
|
+
* @private
|
|
1129
|
+
*/
|
|
1130
|
+
export function editableRangeMarkersInDocument(document) {
|
|
1131
|
+
return collectEditableRangeMarkersInDocumentOrder(document);
|
|
1132
|
+
}
|
|
1133
|
+
function materializeEditableRangeIds(document) {
|
|
1134
|
+
var remap = new Map();
|
|
1135
|
+
var nextId = 0;
|
|
1136
|
+
collectEditableRangeIds(document, function (rangeId) {
|
|
1137
|
+
if (rangeId >= 0 && rangeId >= nextId) {
|
|
1138
|
+
nextId = rangeId + 1;
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
forEachEditableRangeMarker(document, function (marker) {
|
|
1142
|
+
if (!marker.isPendingRangeId()) {
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1145
|
+
var pendingId = marker.rangeId;
|
|
1146
|
+
var resolved = remap.get(pendingId);
|
|
1147
|
+
if (resolved === undefined) {
|
|
1148
|
+
resolved = nextId;
|
|
1149
|
+
nextId += 1;
|
|
1150
|
+
remap.set(pendingId, resolved);
|
|
1151
|
+
}
|
|
1152
|
+
marker.setRangeId(resolved);
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* @private
|
|
1157
|
+
* Allocate a pending (negative) id unique among editable-range markers. */
|
|
1158
|
+
export function allocatePendingEditableRangeId(document) {
|
|
1159
|
+
var used = new Set();
|
|
1160
|
+
collectEditableRangeIds(document, function (rangeId) {
|
|
1161
|
+
used.add(rangeId);
|
|
1162
|
+
});
|
|
1163
|
+
var candidate = -1;
|
|
1164
|
+
while (used.has(candidate)) {
|
|
1165
|
+
candidate -= 1;
|
|
1166
|
+
}
|
|
1167
|
+
return candidate;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Next free non-negative editable-range id for the document (max existing + 1).
|
|
1171
|
+
*
|
|
1172
|
+
* Does not allocate or mutate markers; save-time materialization still remaps
|
|
1173
|
+
* pending negative ids independently.
|
|
1174
|
+
*
|
|
1175
|
+
* @param document - WordDocument to scan
|
|
1176
|
+
* @returns Smallest non-negative id not used by any marker
|
|
1177
|
+
* @private
|
|
1178
|
+
*/
|
|
1179
|
+
export function nextEditableRangeId(document) {
|
|
1180
|
+
var nextId = 0;
|
|
1181
|
+
collectEditableRangeIds(document, function (rangeId) {
|
|
1182
|
+
if (rangeId >= 0 && rangeId >= nextId) {
|
|
1183
|
+
nextId = rangeId + 1;
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
return nextId;
|
|
1187
|
+
}
|
|
1188
|
+
var registered = false;
|
|
1189
|
+
/**
|
|
1190
|
+
* @private
|
|
1191
|
+
* Test hook */
|
|
1192
|
+
export function resetEditableRangesFeatureForTests() {
|
|
1193
|
+
registered = false;
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Register the editable-ranges feature handlers. Idempotent.
|
|
1197
|
+
*
|
|
1198
|
+
* Registers inline handlers (`w:permStart` / `w:permEnd` inside paragraphs),
|
|
1199
|
+
* the matching body block handlers (run-level markers between paragraphs), and
|
|
1200
|
+
* the save-time materialization pass that remaps pending negative identifiers
|
|
1201
|
+
* to the next free non-negative `w:id`. When this module is not imported,
|
|
1202
|
+
* editable-range markup stays opaque and is preserved byte-for-byte.
|
|
1203
|
+
*
|
|
1204
|
+
* @returns Nothing
|
|
1205
|
+
* @example
|
|
1206
|
+
* ```ts
|
|
1207
|
+
* import { registerEditableRangesFeature } from '@syncfusion/ej2-docx/editable-ranges';
|
|
1208
|
+
* registerEditableRangesFeature();
|
|
1209
|
+
* ```
|
|
1210
|
+
* @private
|
|
1211
|
+
*/
|
|
1212
|
+
export function registerEditableRangesFeature() {
|
|
1213
|
+
if (registered) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
registered = true;
|
|
1217
|
+
registerFeature({ id: EDITABLE_RANGES });
|
|
1218
|
+
registerFeatureInlineHandler({
|
|
1219
|
+
featureId: EDITABLE_RANGES,
|
|
1220
|
+
wmlLocalName: 'permStart',
|
|
1221
|
+
tryParse: function (element) {
|
|
1222
|
+
return parseEditableRangeStart(element);
|
|
1223
|
+
},
|
|
1224
|
+
});
|
|
1225
|
+
registerFeatureInlineHandler({
|
|
1226
|
+
featureId: EDITABLE_RANGES,
|
|
1227
|
+
wmlLocalName: 'permEnd',
|
|
1228
|
+
tryParse: function (element) {
|
|
1229
|
+
return parseEditableRangeEnd(element);
|
|
1230
|
+
},
|
|
1231
|
+
});
|
|
1232
|
+
registerFeatureBlockHandler({
|
|
1233
|
+
featureId: EDITABLE_RANGES,
|
|
1234
|
+
wmlLocalName: 'permStart',
|
|
1235
|
+
tryParse: function (element) {
|
|
1236
|
+
return parseEditableRangeStart(element);
|
|
1237
|
+
},
|
|
1238
|
+
});
|
|
1239
|
+
registerFeatureBlockHandler({
|
|
1240
|
+
featureId: EDITABLE_RANGES,
|
|
1241
|
+
wmlLocalName: 'permEnd',
|
|
1242
|
+
tryParse: function (element) {
|
|
1243
|
+
return parseEditableRangeEnd(element);
|
|
1244
|
+
},
|
|
1245
|
+
});
|
|
1246
|
+
registerFeatureMaterializeHandler({
|
|
1247
|
+
featureId: EDITABLE_RANGES,
|
|
1248
|
+
materialize: function (document) {
|
|
1249
|
+
materializeEditableRangeIds(document);
|
|
1250
|
+
},
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Whether paragraph inline content is a modeled editable-range start marker
|
|
1255
|
+
* (`w:permStart`) from this module.
|
|
1256
|
+
*
|
|
1257
|
+
* @private
|
|
1258
|
+
*/
|
|
1259
|
+
export function isEditableRangeStartInline(inline) {
|
|
1260
|
+
return (inline instanceof FeatureInlineParagraphItem &&
|
|
1261
|
+
inline.featureId === EDITABLE_RANGES &&
|
|
1262
|
+
inline.value instanceof EditableRangeStart);
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* Whether paragraph inline content is a modeled editable-range end marker
|
|
1266
|
+
* (`w:permEnd`) from this module.
|
|
1267
|
+
*
|
|
1268
|
+
* @private
|
|
1269
|
+
*/
|
|
1270
|
+
export function isEditableRangeEndInline(inline) {
|
|
1271
|
+
return (inline instanceof FeatureInlineParagraphItem &&
|
|
1272
|
+
inline.featureId === EDITABLE_RANGES &&
|
|
1273
|
+
inline.value instanceof EditableRangeEnd);
|
|
1274
|
+
}
|
|
1275
|
+
function assertEditableRangeIndices(paragraph, startInlineIndex, endInlineIndex) {
|
|
1276
|
+
var length = paragraph.items.length;
|
|
1277
|
+
if (!Number.isInteger(startInlineIndex) ||
|
|
1278
|
+
!Number.isInteger(endInlineIndex) ||
|
|
1279
|
+
startInlineIndex < 0 ||
|
|
1280
|
+
endInlineIndex < startInlineIndex ||
|
|
1281
|
+
endInlineIndex > length) {
|
|
1282
|
+
throw new DocxError('content/invalid-editable-range', "Editable range indices out of range: start=" + String(startInlineIndex) + " end=" + String(endInlineIndex) + " length=" + String(length));
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* Wrap an existing same-paragraph content slice in a new editable range.
|
|
1287
|
+
*
|
|
1288
|
+
* Indices refer to the current `paragraph.content` array **before** insertion:
|
|
1289
|
+
* the start marker is inserted at `startInlineIndex`, and the end marker is
|
|
1290
|
+
* inserted so that it follows the original slice
|
|
1291
|
+
* (`endInlineIndex + 1` after the start push). Enclosed content is not copied
|
|
1292
|
+
* or moved. Cross-paragraph authoring is not supported — use load/preserve for
|
|
1293
|
+
* multi-paragraph ranges.
|
|
1294
|
+
*
|
|
1295
|
+
* @param paragraph - Paragraph that owns the inlines to wrap
|
|
1296
|
+
* @param options - Inclusive/exclusive indices and optional editor metadata
|
|
1297
|
+
* @returns Live pair view for the new markers (pending id until save)
|
|
1298
|
+
* @example
|
|
1299
|
+
* ```ts
|
|
1300
|
+
* insertEditableRangeAt(paragraph, {
|
|
1301
|
+
* startInlineIndex: 1,
|
|
1302
|
+
* endInlineIndex: 2,
|
|
1303
|
+
* editorGroup: 'editors',
|
|
1304
|
+
* });
|
|
1305
|
+
* ```
|
|
1306
|
+
* @private
|
|
1307
|
+
*/
|
|
1308
|
+
export function insertEditableRangeAt(paragraph, options) {
|
|
1309
|
+
assertEditableRangeIndices(paragraph, options.startInlineIndex, options.endInlineIndex);
|
|
1310
|
+
var document = paragraph.owningDocument();
|
|
1311
|
+
var rangeId = allocatePendingEditableRangeId(document);
|
|
1312
|
+
var start = new EditableRangeStart(rangeId, {
|
|
1313
|
+
editorGroup: options.editorGroup,
|
|
1314
|
+
editor: options.editor,
|
|
1315
|
+
columnFirst: options.columnFirst,
|
|
1316
|
+
columnLast: options.columnLast,
|
|
1317
|
+
});
|
|
1318
|
+
var end = new EditableRangeEnd(rangeId);
|
|
1319
|
+
paragraph.insertFeatureInlineAt(options.startInlineIndex, EDITABLE_RANGES, start);
|
|
1320
|
+
// After inserting start, original exclusive end shifts by +1.
|
|
1321
|
+
paragraph.insertFeatureInlineAt(options.endInlineIndex + 1, EDITABLE_RANGES, end);
|
|
1322
|
+
return pairViewForMarkers(start, end);
|
|
1323
|
+
}
|
|
1324
|
+
Paragraph.prototype.appendEditableRange = function (text, options) {
|
|
1325
|
+
if (options === void 0) { options = {}; }
|
|
1326
|
+
var document = this.owningDocument();
|
|
1327
|
+
var rangeId = allocatePendingEditableRangeId(document);
|
|
1328
|
+
var start = new EditableRangeStart(rangeId, {
|
|
1329
|
+
editorGroup: options.editorGroup,
|
|
1330
|
+
editor: options.editor,
|
|
1331
|
+
columnFirst: options.columnFirst,
|
|
1332
|
+
columnLast: options.columnLast,
|
|
1333
|
+
});
|
|
1334
|
+
this.appendFeatureInline(EDITABLE_RANGES, start);
|
|
1335
|
+
this.appendText(text);
|
|
1336
|
+
var end = new EditableRangeEnd(rangeId);
|
|
1337
|
+
this.appendFeatureInline(EDITABLE_RANGES, end);
|
|
1338
|
+
return pairViewForMarkers(start, end);
|
|
1339
|
+
};
|
|
1340
|
+
Paragraph.prototype.insertEditableRangeAt = function (options) {
|
|
1341
|
+
return insertEditableRangeAt(this, options);
|
|
1342
|
+
};
|
|
1343
|
+
/**
|
|
1344
|
+
* Feature id string for editable-range markers (`editable-ranges`).
|
|
1345
|
+
* @private
|
|
1346
|
+
*/
|
|
1347
|
+
export var EDITABLE_RANGES_FEATURE_ID = EDITABLE_RANGES;
|
|
1348
|
+
registerEditableRangesFeature();
|