@a3s-lab/office 0.48.1 → 0.50.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.
@@ -4128,6 +4128,131 @@ function directListItemContentRoot(item) {
4128
4128
  for (const child of item.childNodes)if (!(child instanceof HTMLElement) || 'ol' !== child.tagName.toLowerCase() && 'ul' !== child.tagName.toLowerCase()) root.append(child.cloneNode(true));
4129
4129
  return root;
4130
4130
  }
4131
+ const work_docx_move_revision_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
4132
+ const work_docx_move_revision_export_STORY_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
4133
+ const MAX_MOVE_REVISION_PATCHES = 65536;
4134
+ const MAX_MOVE_TEXT_LENGTH = 1000000;
4135
+ class DocxMoveRevisionPatchCollector {
4136
+ patches = [];
4137
+ registrations = new WeakMap();
4138
+ nextWireId = -1;
4139
+ register(element, id, revisionDate = work_docx_move_revision_export_normalizedRevisionDate(element.dataset.changeDate)) {
4140
+ if (!element.hasAttribute('data-document-change') || 'move' !== element.dataset.changeKind) return null;
4141
+ const existing = this.registrations.get(element);
4142
+ if (existing) return existing;
4143
+ const role = moveRole(element.dataset.changeMoveRole);
4144
+ const author = element.dataset.changeAuthor?.trim() ?? '';
4145
+ const date = revisionDate;
4146
+ const key = element.dataset.changeId?.trim() ?? '';
4147
+ const text = element.textContent ?? '';
4148
+ if (!role || !key || key.length > 255 || /[\u0000-\u001f\u007f]/.test(key) || !Number.isSafeInteger(id) || id < 0 || !author || author.length > 255 || /[\u0000-\u001f\u007f]/.test(author) || !text || text.length > MAX_MOVE_TEXT_LENGTH || element.querySelector('[data-document-change]') || element.querySelector('[data-document-equation], [data-document-field], [data-document-note-reference], [data-document-content-control], img, br')) throw new Error('Document contains an invalid move revision.');
4149
+ if (this.patches.length >= MAX_MOVE_REVISION_PATCHES) throw new Error('Document exceeds the move revision limit.');
4150
+ const wireId = this.nextWireId;
4151
+ this.nextWireId -= 1;
4152
+ const registration = {
4153
+ kind: 'from' === role ? 'move-from' : 'move-to',
4154
+ wireId,
4155
+ id,
4156
+ author,
4157
+ date
4158
+ };
4159
+ this.registrations.set(element, registration);
4160
+ this.patches.push({
4161
+ wireId,
4162
+ id,
4163
+ role,
4164
+ author,
4165
+ date
4166
+ });
4167
+ return registration;
4168
+ }
4169
+ }
4170
+ async function patchDocxMoveRevisions(buffer, patches) {
4171
+ if (!patches.length) return buffer;
4172
+ if (patches.length > MAX_MOVE_REVISION_PATCHES) throw new Error('Document exceeds the move revision limit.');
4173
+ const archive = await jszip.loadAsync(buffer);
4174
+ const byWireId = new Map();
4175
+ const logicalSides = new Map();
4176
+ for (const patch of patches){
4177
+ if (byWireId.has(patch.wireId)) throw new Error('Generated DOCX move revision wire IDs are duplicated.');
4178
+ byWireId.set(patch.wireId, patch);
4179
+ const logicalKey = `${patch.id}\u0000${patch.author}\u0000${patch.date}`;
4180
+ const sides = logicalSides.get(logicalKey) ?? {
4181
+ from: [],
4182
+ to: []
4183
+ };
4184
+ sides[patch.role].push(patch);
4185
+ logicalSides.set(logicalKey, sides);
4186
+ }
4187
+ for (const sides of logicalSides.values())if (!sides.from.length || !sides.to.length) throw new Error('A DOCX move revision must contain both moveFrom and moveTo sides.');
4188
+ const applied = new Map();
4189
+ const emittedText = new Map();
4190
+ for (const entry of Object.values(archive.files)){
4191
+ if (entry.dir || !work_docx_move_revision_export_STORY_PATTERN.test(entry.name)) continue;
4192
+ const document = parseXml(decodeXmlBytes(await entry.async('uint8array'), `generated DOCX ${entry.name}`), `generated DOCX ${entry.name}`);
4193
+ let changed = false;
4194
+ const wrappers = [
4195
+ ...descendants(document, 'ins'),
4196
+ ...descendants(document, 'del')
4197
+ ];
4198
+ for (const wrapper of wrappers){
4199
+ if (!wrapper.parentNode) continue;
4200
+ if (!DOCX_WORDPROCESSING_NAMESPACES.has(wrapper.namespaceURI ?? '')) continue;
4201
+ const wireId = numericWordAttribute(wrapper, 'id');
4202
+ if (null === wireId) continue;
4203
+ const patch = byWireId.get(wireId);
4204
+ if (!patch) continue;
4205
+ const expectedName = 'from' === patch.role ? 'del' : 'ins';
4206
+ if (wrapper.localName !== expectedName) throw new Error(`Generated DOCX move revision ${patch.wireId} has the wrong wrapper kind.`);
4207
+ const replacement = document.createElementNS(wrapper.namespaceURI, `${xmlNamespacePrefix(wrapper, wrapper.namespaceURI) ?? 'w'}:${'from' === patch.role ? 'moveFrom' : 'moveTo'}`);
4208
+ for (const child of Array.from(wrapper.attributes)){
4209
+ const namespace = xmlAttributeNamespace(wrapper, child);
4210
+ if (namespace) replacement.setAttributeNS(namespace, child.name, child.value);
4211
+ else replacement.setAttribute(child.name, child.value);
4212
+ }
4213
+ work_docx_move_revision_export_setWordAttribute(replacement, 'id', String(patch.id));
4214
+ work_docx_move_revision_export_setWordAttribute(replacement, 'author', patch.author);
4215
+ work_docx_move_revision_export_setWordAttribute(replacement, 'date', patch.date);
4216
+ const text = Array.from(wrapper.querySelectorAll('*')).filter((element)=>'from' === patch.role ? 'delText' === element.localName : 't' === element.localName).map((element)=>element.textContent ?? '').join('');
4217
+ emittedText.set(patch.wireId, `${emittedText.get(patch.wireId) ?? ''}${text}`);
4218
+ while(wrapper.firstChild)replacement.append(wrapper.firstChild);
4219
+ wrapper.replaceWith(replacement);
4220
+ applied.set(patch.wireId, (applied.get(patch.wireId) ?? 0) + 1);
4221
+ changed = true;
4222
+ }
4223
+ if (changed) archive.file(entry.name, serializeUtf8Xml(document));
4224
+ }
4225
+ const missing = patches.filter((patch)=>!applied.has(patch.wireId));
4226
+ if (missing.length) throw new Error(`DOCX move revision markers were not emitted: ${missing.map((patch)=>patch.wireId).join(', ')}.`);
4227
+ for (const sides of logicalSides.values()){
4228
+ const from = sides.from.map((patch)=>emittedText.get(patch.wireId) ?? '').join('');
4229
+ const to = sides.to.map((patch)=>emittedText.get(patch.wireId) ?? '').join('');
4230
+ if (!from || !to || from !== to) throw new Error('A DOCX move revision source and destination must contain the same text.');
4231
+ }
4232
+ return archive.generateAsync({
4233
+ type: 'arraybuffer'
4234
+ });
4235
+ }
4236
+ function moveRole(value) {
4237
+ return 'from' === value || 'to' === value ? value : null;
4238
+ }
4239
+ function numericWordAttribute(element, localName) {
4240
+ const namespace = element.namespaceURI;
4241
+ if (!namespace) return null;
4242
+ const attributes = Array.from(element.attributes).filter((candidate)=>xmlAttributeLocalName(candidate) === localName && xmlAttributeNamespace(element, candidate) === namespace);
4243
+ if (1 !== attributes.length) return null;
4244
+ const value = Number(attributes[0]?.value);
4245
+ return Number.isSafeInteger(value) ? value : null;
4246
+ }
4247
+ function work_docx_move_revision_export_setWordAttribute(element, localName, value) {
4248
+ const namespace = element.namespaceURI ?? work_docx_move_revision_export_WORD_NAMESPACE;
4249
+ const prefix = xmlNamespacePrefix(element, namespace) ?? element.prefix ?? 'w';
4250
+ element.setAttributeNS(namespace, `${prefix}:${localName}`, value);
4251
+ }
4252
+ function work_docx_move_revision_export_normalizedRevisionDate(value) {
4253
+ const time = Date.parse(value ?? '');
4254
+ return Number.isFinite(time) ? new Date(time).toISOString() : new Date().toISOString();
4255
+ }
4131
4256
  const DRAWINGML_NAMESPACES = new Set([
4132
4257
  'http://schemas.openxmlformats.org/drawingml/2006/main',
4133
4258
  'http://purl.oclc.org/ooxml/drawingml/main'
@@ -8526,6 +8651,8 @@ async function createDocxBlob(content, sourcePackage) {
8526
8651
  usedOpenTypeMarkers: new Set(),
8527
8652
  paragraphFormattingChangePatches: new DocxParagraphFormattingChangePatchCollector(),
8528
8653
  numberingChangePatches: new DocxNumberingChangePatchCollector(),
8654
+ moveRevisionPatches: new DocxMoveRevisionPatchCollector(),
8655
+ moveRevisionDefaultDate: new Date().toISOString(),
8529
8656
  tableOfContentsPatches: new DocxTableOfContentsPatchCollector(),
8530
8657
  indexPatches: new DocxIndexPatchCollector(),
8531
8658
  hasExplicitZeroCharacterSpacing: false,
@@ -8606,7 +8733,8 @@ async function createDocxBlob(content, sourcePackage) {
8606
8733
  const indexPatched = await patchDocxIndexes(tableOfContentsPatched, noteContext.indexPatches.patches);
8607
8734
  const paragraphFormattingChangesPatched = await patchDocxParagraphFormattingChanges(indexPatched, noteContext.paragraphFormattingChangePatches.patches);
8608
8735
  const numberingChangesPatched = await patchDocxNumberingChanges(paragraphFormattingChangesPatched, noteContext.numberingChangePatches.patches);
8609
- const equationPatched = await patchDocxEquations(numberingChangesPatched, noteContext.equationPatches.patches);
8736
+ const moveRevisionsPatched = await patchDocxMoveRevisions(numberingChangesPatched, noteContext.moveRevisionPatches.patches);
8737
+ const equationPatched = await patchDocxEquations(moveRevisionsPatched, noteContext.equationPatches.patches);
8610
8738
  const patched = await patchDocxPageColor(equationPatched, normalizedContent.pageColor);
8611
8739
  const contentControlsPatched = await patchDocxContentControls(patched, noteContext.contentControlPatches.patches);
8612
8740
  const preserved = sourcePackage ? await preserveDocxSourcePackage(contentControlsPatched, sourcePackage, {
@@ -8987,19 +9115,19 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8987
9115
  markDocxRunStyleMarkersUsed(inherited.style, noteContext);
8988
9116
  markDocxRunBorderUsed(inherited.border, noteContext);
8989
9117
  markDocxRunShadingUsed(inherited.shading, noteContext);
8990
- if (revision?.kind === 'insertion') return [
9118
+ if (revision?.kind === 'insertion' || revision?.kind === 'move-to') return [
8991
9119
  new docx.InsertedTextRun({
8992
9120
  ...inherited,
8993
- id: revision.id,
9121
+ id: revision.wireId ?? revision.id,
8994
9122
  author: revision.author,
8995
9123
  date: revision.date,
8996
9124
  text: node.textContent
8997
9125
  })
8998
9126
  ];
8999
- if (revision?.kind === 'deletion') return [
9127
+ if (revision?.kind === 'deletion' || revision?.kind === 'move-from') return [
9000
9128
  new docx.DeletedTextRun({
9001
9129
  ...inherited,
9002
- id: revision.id,
9130
+ id: revision.wireId ?? revision.id,
9003
9131
  author: revision.author,
9004
9132
  date: revision.date,
9005
9133
  text: node.textContent
@@ -9050,7 +9178,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
9050
9178
  for (const child of node.childNodes)children.push(...await visit(child, inherited, revision));
9051
9179
  return docxContentControlRuns(node, docx, noteContext.contentControlPatches, children);
9052
9180
  }
9053
- const textRevisionKind = 'del' === tag ? 'deletion' : 'ins' === tag ? 'insertion' : null;
9181
+ const textRevisionKind = 'del' === tag ? 'move' === node.dataset.changeKind ? 'move-from' : 'deletion' : 'ins' === tag ? 'move' === node.dataset.changeKind ? 'move-to' : 'insertion' : null;
9054
9182
  const change = node.hasAttribute('data-document-change') && textRevisionKind ? docxTextRevision(node, textRevisionKind, noteContext) : revision;
9055
9183
  const formattingChange = node.hasAttribute('data-document-change') && 'formatting' === node.dataset.changeKind ? noteContext.formattingChangePatches.register(node, docxRevisionId(node, noteContext)) : null;
9056
9184
  const commentBoundary = node.hasAttribute('data-document-comment') ? nextDocxCommentBoundary(node.dataset.commentId, noteContext) : null;
@@ -9273,12 +9401,18 @@ function docxTextRevision(element, kind, context) {
9273
9401
  const id = docxRevisionId(element, context);
9274
9402
  const sourceDate = element.dataset.changeDate?.trim() ?? '';
9275
9403
  const time = Date.parse(sourceDate);
9276
- return {
9404
+ const revision = {
9277
9405
  kind,
9278
9406
  id,
9279
9407
  author: element.dataset.changeAuthor?.trim() || 'A3S Work',
9280
- date: Number.isFinite(time) ? new Date(time).toISOString() : new Date().toISOString()
9408
+ date: Number.isFinite(time) ? new Date(time).toISOString() : 'move-from' === kind || 'move-to' === kind ? context.moveRevisionDefaultDate : new Date().toISOString()
9281
9409
  };
9410
+ if ('move-from' === kind || 'move-to' === kind) {
9411
+ const registration = context.moveRevisionPatches.register(element, id, revision.date);
9412
+ if (!registration) throw new Error('Document contains an invalid move revision.');
9413
+ revision.wireId = registration.wireId;
9414
+ }
9415
+ return revision;
9282
9416
  }
9283
9417
  function docxRevisionId(element, context, suffix) {
9284
9418
  const baseKey = element.dataset.changeId?.trim() || `change-${context.nextChangeId}`;
@@ -9293,7 +9427,7 @@ function docxRevisionId(element, context, suffix) {
9293
9427
  }
9294
9428
  function documentHasTrackedChanges(html) {
9295
9429
  const document = new DOMParser().parseFromString(html, 'text/html');
9296
- return Boolean(document.body.querySelector('ins[data-document-change], del[data-document-change], span[data-document-change][data-change-kind="formatting"], [data-document-change][data-change-kind="paragraph-formatting"], [data-document-change][data-change-kind="numbering"]'));
9430
+ return Boolean(document.body.querySelector('ins[data-document-change], del[data-document-change], span[data-document-change][data-change-kind="formatting"], [data-document-change][data-change-kind="paragraph-formatting"], [data-document-change][data-change-kind="numbering"], [data-document-change][data-change-kind="move"]'));
9297
9431
  }
9298
9432
  function anchoredDocumentComments(content) {
9299
9433
  const document = new DOMParser().parseFromString(content.html, 'text/html');
@@ -1,7 +1,7 @@
1
1
  import jszip from "jszip";
2
2
  import { documentRunBorderDomAttributes, contentTypeForPart, bytesToDataUrl, OoxmlPackage, normalizeDocumentIndexesHtml, firstDescendant, normalizeDocumentParagraphId, applyDocumentParagraphIdentityToElement, descendants, documentHighlightDomAttributes, attribute as work_ooxml_package_attribute, documentHighlightFromDocxValue, serializeDocxThemeReference, normalizeDocumentTableOfContentsHtml, directChildren, documentParagraphShadingDomAttributes, documentProofingDomAttributes, documentParagraphBordersDomAttributes, directChild, documentScriptFontSegments, normalizeDocumentParagraphIdentity, documentRunShadingDomAttributes } from "./6968.js";
3
3
  import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, documentCharacterPositionDomAttributes, createDocumentImageIdentityRegistry, normalizeDocumentColumns, documentStrikeDomAttributes, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, documentCharacterSpacingDomAttributes, normalizeDocumentImageAlignment, applyDocumentImageLayerToElement, normalizeDocumentNotesHtml, normalizeDocumentBookmarkReferencesHtml, documentCitationTagsFromInstruction, applyDocumentImageWrapContourToElement, documentUnderlineDomAttributes, documentHiddenTextDomAttributes, normalizeDocumentPageChrome, normalizeDocumentImageLayoutOptions, applyDocumentImageCropToElement, documentPageMarginsForLayout, applyDocumentPageGeometry, createDocumentNoteElement, normalizeDocumentImageLayer, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, documentBookmarkReferenceInstruction, applyDocumentImageTransformToElement, documentInitialSectionLayout, normalizeDocumentFieldsHtml, documentCaptionLabel, documentTableBordersFromElement, isContourImageLayout, normalizeDocumentCitationsHtml, normalizeDocumentImageIdentity, normalizeDocumentImageWrapSide, supportedDocxDocumentFieldInstruction, documentKerningDomAttributes, docxDocumentFieldKind, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentCharacterScaleDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, documentPageMarginBody, documentLegacyTextEffectsDomAttributes, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, documentOpenTypeDomAttributes, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentEmphasisMarkDomAttributes, docxDocumentFieldTarget } from "./4174.js";
4
- import { hasImportedDocxIndexMarkers, markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxTextBoxMarkers, applyImportedDocxNumberingChangeMarkers, applyImportedDocxParagraphShadingMarkers, markDocxParagraphSpacing, docxCaptionBookmark, docxFieldResultText, applyImportedDocxContentControlMarkers, createDocxParagraphStyleResolver, markDocxTextBoxes, docxTableCellStyleLayers, createImportedDocxRunFormattingMarkerState, markDocxContentControls, parseDocxPaperSource, resolveDocxLegacyTextEffects, markDocxTablesOfContents, applyImportedDocxIndexMarkers, docxTablePropertySources, applyImportedDocxTableOfContentsMarkers, markDocxIndexes, parseDirectDocxParagraphShading, markDocxPackageEquations, hasImportedDocxParagraphSpacingMarkers, markDocxParagraphIndents, parseDocxPageMargins, resolveDocxRunBorder, parseDocxPageGeometry, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, hasImportedDocxParagraphPaginationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, importedDocxStrike, docxTableRunPropertySources, hasImportedDocxNumberingChangeMarkers, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, hasImportedDocxTableOfContentsMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxContentControlMarkers, hasImportedDocxParagraphTabStopMarkers, resolveDocxRunShading, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, resolveDocxTableStyleResolver, applyImportedDocxParagraphAlignmentMarkers, hasImportedDocxTextBoxMarkers, markDocxNumberingChanges, importedDocxUnderline, markDocxParagraphBorders, applyImportedDocxParagraphDirectionMarkers, markDocxParagraphPagination, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, applyImportedDocxParagraphPaginationMarkers, applyImportedDocxParagraphTabStopMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~3320.js";
4
+ import { hasImportedDocxIndexMarkers, markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxTextBoxMarkers, applyImportedDocxNumberingChangeMarkers, applyImportedDocxParagraphShadingMarkers, applyImportedDocxChangeMarkers, markDocxParagraphSpacing, docxCaptionBookmark, docxFieldResultText, applyImportedDocxContentControlMarkers, createDocxParagraphStyleResolver, markDocxTextBoxes, docxTableCellStyleLayers, markDocxTextChanges, markDocxContentControls, createImportedDocxRunFormattingMarkerState, parseDocxPaperSource, resolveDocxLegacyTextEffects, markDocxTablesOfContents, applyImportedDocxIndexMarkers, docxTablePropertySources, applyImportedDocxTableOfContentsMarkers, markDocxIndexes, parseDirectDocxParagraphShading, markDocxPackageEquations, hasImportedDocxParagraphSpacingMarkers, markDocxParagraphIndents, parseDocxPageMargins, resolveDocxRunBorder, parseDocxPageGeometry, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, hasImportedDocxParagraphPaginationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, importedDocxStrike, docxTableRunPropertySources, hasImportedDocxNumberingChangeMarkers, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, hasImportedDocxTableOfContentsMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxContentControlMarkers, hasImportedDocxParagraphTabStopMarkers, resolveDocxRunShading, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, applyImportedDocxParagraphDirectionMarkers, applyImportedDocxParagraphAlignmentMarkers, resolveDocxTableStyleResolver, hasImportedDocxTextBoxMarkers, importedDocxUnderline, markDocxParagraphBorders, markDocxNumberingChanges, markDocxParagraphPagination, hasImportedDocxChangeMarkers, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, applyImportedDocxParagraphPaginationMarkers, applyImportedDocxParagraphTabStopMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~5600.js";
5
5
  import { readDocxBibliography, resolveDocxProofing, XMLNS_NAMESPACE, docxCharacterScalePercentFromProperties, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, resolveDocxOpenTypeFeatures, xmlAttributeLocalName, resolveDocxEmphasisMark, createDocxThemeResolver, docxCharacterPositionHalfPointsFromProperties, readDocxImageTransform, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~3534.js";
6
6
  import { importDocxPageColor, importedDocumentNoteId } from "./0~4980.js";
7
7
  const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
@@ -428,121 +428,6 @@ function work_docx_caption_import_textNodes(root) {
428
428
  while(walker.nextNode())nodes.push(walker.currentNode);
429
429
  return nodes;
430
430
  }
431
- const work_docx_change_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
432
- const work_docx_change_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
433
- function markDocxTextChanges(document) {
434
- const changes = [];
435
- const revisions = [
436
- ...descendants(document, 'ins'),
437
- ...descendants(document, 'del')
438
- ].sort(compareDocumentOrder);
439
- for (const revision of revisions){
440
- if (!revision.parentNode || closestRevision(revision.parentElement)) continue;
441
- const kind = 'del' === revision.localName ? 'deletion' : 'insertion';
442
- if (!revisionText(revision, kind)) continue;
443
- if ('deletion' === kind) convertDeletedText(document, revision);
444
- const index = changes.length + 1;
445
- const sourceId = work_ooxml_package_attribute(revision, 'id')?.trim() ?? '';
446
- const id = uniqueChangeId(sourceId ? `docx-change-${sourceId}` : `docx-change-${index}`, changes);
447
- const marker = {
448
- id,
449
- kind,
450
- author: work_ooxml_package_attribute(revision, 'author')?.trim() || '未知审阅者',
451
- date: normalizeDate(work_ooxml_package_attribute(revision, 'date')),
452
- start: `__A3S_WORK_CHANGE_START_${index}__`,
453
- end: `__A3S_WORK_CHANGE_END_${index}__`
454
- };
455
- unwrapRevision(document, revision, marker.start, marker.end);
456
- changes.push(marker);
457
- }
458
- return {
459
- changes
460
- };
461
- }
462
- function applyImportedDocxChangeMarkers(document, markers) {
463
- for (const marker of markers.changes){
464
- const element = document.createElement('deletion' === marker.kind ? 'del' : 'ins');
465
- element.dataset.documentChange = 'true';
466
- element.dataset.changeKind = marker.kind;
467
- element.dataset.changeId = marker.id;
468
- element.dataset.changeAuthor = marker.author;
469
- element.dataset.changeDate = marker.date;
470
- wrapMarkerRange(document.body, marker.start, marker.end, element);
471
- }
472
- }
473
- function hasImportedDocxChangeMarkers(markers) {
474
- return markers.changes.length > 0;
475
- }
476
- function revisionText(revision, kind) {
477
- const names = 'deletion' === kind ? [
478
- 'delText',
479
- 't'
480
- ] : [
481
- 't'
482
- ];
483
- return names.flatMap((name)=>descendants(revision, name)).map((element)=>element.textContent ?? '').join('');
484
- }
485
- function convertDeletedText(document, revision) {
486
- for (const deleted of descendants(revision, 'delText')){
487
- const text = document.createElementNS(work_docx_change_import_WORD_NAMESPACE, 'w:t');
488
- const preserve = deleted.getAttributeNS(work_docx_change_import_XML_NAMESPACE, 'space') ?? deleted.getAttribute('xml:space');
489
- if (preserve) text.setAttributeNS(work_docx_change_import_XML_NAMESPACE, 'xml:space', preserve);
490
- text.textContent = deleted.textContent;
491
- deleted.replaceWith(text);
492
- }
493
- }
494
- function unwrapRevision(document, revision, start, end) {
495
- const parent = revision.parentNode;
496
- if (!parent) return;
497
- parent.insertBefore(work_docx_change_import_markerRun(document, start), revision);
498
- while(revision.firstChild)parent.insertBefore(revision.firstChild, revision);
499
- parent.insertBefore(work_docx_change_import_markerRun(document, end), revision);
500
- revision.remove();
501
- }
502
- function work_docx_change_import_markerRun(document, value) {
503
- const run = document.createElementNS(work_docx_change_import_WORD_NAMESPACE, 'w:r');
504
- const text = document.createElementNS(work_docx_change_import_WORD_NAMESPACE, 'w:t');
505
- text.setAttributeNS(work_docx_change_import_XML_NAMESPACE, 'xml:space', 'preserve');
506
- text.textContent = value;
507
- run.append(text);
508
- return run;
509
- }
510
- function wrapMarkerRange(root, start, end, wrapper) {
511
- const html = root.innerHTML;
512
- const startIndex = html.indexOf(start);
513
- const endIndex = html.indexOf(end, startIndex + start.length);
514
- if (startIndex < 0 || endIndex < 0) return false;
515
- const closingTag = `</${wrapper.localName}>`;
516
- const serializedWrapper = wrapper.outerHTML;
517
- if (!serializedWrapper.endsWith(closingTag)) return false;
518
- const openingTag = serializedWrapper.slice(0, -closingTag.length);
519
- root.innerHTML = `${html.slice(0, startIndex)}${openingTag}${html.slice(startIndex + start.length, endIndex)}${closingTag}${html.slice(endIndex + end.length)}`;
520
- return true;
521
- }
522
- function closestRevision(element) {
523
- let current = element;
524
- while(current){
525
- if ('ins' === current.localName || 'del' === current.localName) return current;
526
- current = current.parentElement;
527
- }
528
- return null;
529
- }
530
- function uniqueChangeId(base, changes) {
531
- const ids = new Set(changes.map((change)=>change.id));
532
- if (!ids.has(base)) return base;
533
- let suffix = 2;
534
- while(ids.has(`${base}-${suffix}`))suffix += 1;
535
- return `${base}-${suffix}`;
536
- }
537
- function normalizeDate(value) {
538
- if (!value) return '';
539
- const time = Date.parse(value);
540
- return Number.isFinite(time) ? new Date(time).toISOString() : '';
541
- }
542
- function compareDocumentOrder(left, right) {
543
- if (left === right) return 0;
544
- return left.compareDocumentPosition(right) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
545
- }
546
431
  const work_docx_citation_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
547
432
  const work_docx_citation_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
548
433
  function markDocxCitationFields(document) {
@@ -744,7 +629,7 @@ async function markDocxComments(document, archive) {
744
629
  const workIds = new Map();
745
630
  const ranges = [];
746
631
  const comments = [];
747
- const starts = descendants(document, 'commentRangeStart').sort(work_docx_comment_import_compareDocumentOrder);
632
+ const starts = descendants(document, 'commentRangeStart').sort(compareDocumentOrder);
748
633
  for (const start of starts){
749
634
  const sourceId = work_ooxml_package_attribute(start, 'id')?.trim() ?? '';
750
635
  if (!sourceId) continue;
@@ -794,7 +679,7 @@ async function readCommentDefinitions(archive) {
794
679
  return {
795
680
  sourceId: work_ooxml_package_attribute(comment, 'id')?.trim() ?? '',
796
681
  author: work_ooxml_package_attribute(comment, 'author')?.trim() || '未知审阅者',
797
- date: work_docx_comment_import_normalizeDate(work_ooxml_package_attribute(comment, 'date')),
682
+ date: normalizeDate(work_ooxml_package_attribute(comment, 'date')),
798
683
  text: commentText(comment),
799
684
  paraId,
800
685
  parentParaId: metadata?.parentParaId ?? '',
@@ -922,12 +807,12 @@ function uniqueWorkCommentId(base, comments) {
922
807
  while(ids.has(`${base}-${suffix}`))suffix += 1;
923
808
  return `${base}-${suffix}`;
924
809
  }
925
- function work_docx_comment_import_normalizeDate(value) {
810
+ function normalizeDate(value) {
926
811
  if (!value) return '';
927
812
  const time = Date.parse(value);
928
813
  return Number.isFinite(time) ? new Date(time).toISOString() : '';
929
814
  }
930
- function work_docx_comment_import_compareDocumentOrder(left, right) {
815
+ function compareDocumentOrder(left, right) {
931
816
  if (left === right) return 0;
932
817
  return left.compareDocumentPosition(right) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
933
818
  }
@@ -1,7 +1,7 @@
1
1
  import { __webpack_require__ } from "./0~rslib-runtime.js";
2
2
  import { contentTypeForPart, directChildren, OoxmlPackage, parseXml, firstDescendant, isDocumentParagraphArtBorderStyle, descendants, directChild, xmlContainsAnyElement, attribute, documentRunBorderIsVisible } from "./6968.js";
3
3
  import { normalizeDocumentBookmarkName, docxBookmarkReferenceTarget, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, normalizeDocumentBookmarkNativeId, supportedDocxDocumentFieldInstruction, supportedDocxBookmarkReferenceInstruction, documentCitationTagsFromInstruction, docxDocumentFieldKind, docxDocumentFieldTarget } from "./4174.js";
4
- import { isSupportedDocxEquationPlacement, inspectDocxPageSize, inspectDocxContentControls, hasInvalidDocxFieldStructure, createDocxTableStyleResolver, inspectDocxRunBorder, inspectDocxEquation, inspectDocxPageMarginSettings, inspectDocxRunShading, supportedDocxIndexField, docxCaptionSequenceKind, inspectDocxPageBorders, docxCaptionBookmark, inspectDocxLegacyTextEffects, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, inspectDocxRunFonts, supportedDocxTableOfContentsField, docxFieldOccurrences, supportedDocxIndexEntryField, inspectDocxTextBoxes, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, inspectDocxHiddenText, isSupportedDocxRunFormattingChange, isSupportedDocxNumberingChange, markDocxParagraphShading, docxFieldInstructions } from "./0~3320.js";
4
+ import { isSupportedDocxEquationPlacement, inspectDocxPageSize, inspectDocxContentControls, hasInvalidDocxFieldStructure, createDocxTableStyleResolver, inspectDocxRunBorder, inspectDocxEquation, inspectDocxPageMarginSettings, inspectDocxRunShading, supportedDocxMovePairCount, supportedDocxIndexField, docxCaptionSequenceKind, inspectDocxPageBorders, isSupportedDocxMoveChange, docxCaptionBookmark, inspectDocxLegacyTextEffects, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, inspectDocxRunFonts, supportedDocxTableOfContentsField, docxFieldOccurrences, supportedDocxIndexEntryField, inspectDocxTextBoxes, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, inspectDocxHiddenText, isSupportedDocxRunFormattingChange, isSupportedDocxNumberingChange, markDocxParagraphShading, docxFieldInstructions } from "./0~5600.js";
5
5
  import { normalizeDocumentHref } from "./0~work-document-links.js";
6
6
  import { xmlAttributeLocalName, resolveDocxOpenTypeFeatures, inspectDocxProofingLanguages, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, DOCX_WORD_2010_NAMESPACE, inspectDocxNoProof, parseDocxParagraphDefaultCollapsed, readDocxImageTransform, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~3534.js";
7
7
  import { updateSpreadsheetWorksheetCompatibilitySummary, inspectXlsxPivotTables, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, xlsxChartNodeUsesStackedGrouping, isSupportedXlsxChartSeriesFormatting, readXlsxFormulaFeaturesFromPackage, inspectXlsxHeaderFooterText, emptySpreadsheetWorksheetCompatibilitySummary, isSupportedXlsxWorksheetImageContentType, MAX_XLSX_WORKSHEET_IMAGE_BYTES, xlsxChartSeriesFormattingShapeProperties, diagnoseXlsxProtection, isEditableXlsxPaperSizeCode, isSupportedXlsxCombinationChartNodes } from "./4166.js";
@@ -2223,6 +2223,14 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
2223
2223
  ...descendants(document, 'ins'),
2224
2224
  ...descendants(document, 'del')
2225
2225
  ];
2226
+ const moveFromRevisions = descendants(document, 'moveFrom');
2227
+ const moveToRevisions = descendants(document, 'moveTo');
2228
+ const moveRevisionCount = moveFromRevisions.length + moveToRevisions.length;
2229
+ const supportedMovePairCount = supportedDocxMovePairCount(document);
2230
+ const supportedMoveRevisionCount = [
2231
+ ...moveFromRevisions,
2232
+ ...moveToRevisions
2233
+ ].filter(isSupportedDocxMoveChange).length;
2226
2234
  const runFormattingRevisions = descendants(document, 'rPrChange');
2227
2235
  const paragraphFormattingRevisions = descendants(document, 'pPrChange');
2228
2236
  const numberingRevisions = descendants(document, 'numberingChange');
@@ -2233,14 +2241,17 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
2233
2241
  if (supportedRunFormattingRevisionCount) issues.push(work_office_diagnostics_issue('docx.revisions.formatting', 'Character-formatting revisions', `${supportedRunFormattingRevisionCount} bounded character-formatting revision(s) preserve author, date, current formatting, and prior bold, italic, underline, strike, text case, hidden text, outline, shadow, emboss, imprint, subscript, superscript, font, size, color, highlight, character borders, character shading, character scale, spacing, kerning threshold, emphasis mark, baseline position, grid state, proofing languages, and explicit proofing state. They remain reviewable in Work and round-trip as native w:rPrChange records.`, 'info'));
2234
2242
  if (supportedParagraphFormattingRevisionCount) issues.push(work_office_diagnostics_issue('docx.revisions.paragraph-formatting', 'Paragraph-formatting revisions', `${supportedParagraphFormattingRevisionCount} bounded paragraph-formatting revision(s) preserve author, date, current formatting, and prior alignment, direction, indentation, spacing, pagination, outline, tab-stop, border, shading, and collapsed state. They remain reviewable in Work and round-trip as native w:pPrChange records.`, 'info'));
2235
2243
  if (supportedNumberingRevisionCount) issues.push(work_office_diagnostics_issue('docx.revisions.numbering', 'Numbering revisions', `${supportedNumberingRevisionCount} bounded ordered-list numbering revision(s) preserve author, date, prior start, and common decimal, letter, or Roman formats. Contiguous list-item records remain reviewable as one Work change and round-trip as native w:numberingChange records.`, 'info'));
2236
- if (textRevisions.some((revision)=>!descendants(revision, 't').length && !descendants(revision, 'delText').length) || supportedRunFormattingRevisionCount !== runFormattingRevisions.length || supportedParagraphFormattingRevisionCount !== paragraphFormattingRevisions.length || supportedNumberingRevisionCount !== numberingRevisions.length || [
2237
- 'moveFrom',
2238
- 'moveTo',
2244
+ if (supportedMovePairCount) issues.push(work_office_diagnostics_issue('docx.revisions.move', 'Move revisions', `${supportedMovePairCount} bounded text move revision(s) preserve author, date, source and destination text, remain reviewable as one atomic Work change, and round-trip as native w:moveFrom and w:moveTo records. Rich content, range markers, and relationship-bound moves remain on the compatibility path.`, 'info'));
2245
+ if (textRevisions.some((revision)=>!descendants(revision, 't').length && !descendants(revision, 'delText').length) || supportedRunFormattingRevisionCount !== runFormattingRevisions.length || supportedParagraphFormattingRevisionCount !== paragraphFormattingRevisions.length || supportedNumberingRevisionCount !== numberingRevisions.length || supportedMoveRevisionCount !== moveRevisionCount || supportedMoveRevisionCount !== 2 * supportedMovePairCount || [
2246
+ 'moveFromRangeStart',
2247
+ 'moveFromRangeEnd',
2248
+ 'moveToRangeStart',
2249
+ 'moveToRangeEnd',
2239
2250
  'tblPrChange',
2240
2251
  'trPrChange',
2241
2252
  'tcPrChange',
2242
2253
  'sectPrChange'
2243
- ].some((name)=>descendants(document, name).length)) issues.push(work_office_diagnostics_issue('docx.revisions.structural', 'Structural revisions', 'Moved content plus unsupported character formatting, paragraph formatting, numbering, section, row, cell, and table-property revisions may be normalized; Work currently reviews body-text insertions/deletions and bounded character-, paragraph-, and ordered-list-numbering subsets.'));
2254
+ ].some((name)=>descendants(document, name).length)) issues.push(work_office_diagnostics_issue('docx.revisions.structural', 'Structural revisions', 'Moved content plus unsupported character formatting, paragraph formatting, numbering, section, row, cell, and table-property revisions may be normalized; Work currently reviews body-text insertions/deletions and bounded text moves, character-, paragraph-, and ordered-list-numbering subsets.'));
2244
2255
  if (captionDiagnostics.hasUnsupportedFields) issues.push(work_office_diagnostics_issue('docx.fields', 'Fields', 'Fields beyond supported body fields, citations, bibliographies, caption SEQ fields, and bookmark or caption REF fields are converted to their current displayed value.'));
2245
2256
  const sectionProperties = descendants(document, 'sectPr');
2246
2257
  const columnProperties = descendants(document, 'cols');