@a3s-lab/office 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +75 -2
  2. package/dist/0~4595.js +16 -2
  3. package/dist/0~5093.js +463 -201
  4. package/dist/0~6090.js +77 -77
  5. package/dist/{0~2805.js → 0~7043.js} +305 -2
  6. package/dist/0~document-editor.js +2451 -985
  7. package/dist/0~spreadsheet-editor.js +1324 -378
  8. package/dist/0~work-docx-export.js +492 -10
  9. package/dist/0~work-docx-import.js +171 -98
  10. package/dist/0~work-office-diagnostics.js +198 -4
  11. package/dist/{164.js → 1544.js} +1083 -785
  12. package/dist/4104.js +145 -29
  13. package/dist/6282.js +1774 -384
  14. package/dist/core.js +1 -1
  15. package/dist/index.js +1 -1
  16. package/dist/internal/features/work/editors/document-command-catalog.d.ts +102 -0
  17. package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +83 -0
  18. package/dist/internal/features/work/editors/document-font-dialog-script-font-model.d.ts +18 -0
  19. package/dist/internal/features/work/editors/document-font-dialog.d.ts +9 -0
  20. package/dist/internal/features/work/editors/document-home-ribbon.d.ts +2 -1
  21. package/dist/internal/features/work/editors/document-page-chrome-editor.d.ts +6 -0
  22. package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +2 -1
  23. package/dist/internal/features/work/editors/document-strike-ribbon.d.ts +7 -0
  24. package/dist/internal/features/work/editors/document-text-case-ribbon.d.ts +4 -0
  25. package/dist/internal/features/work/editors/document-toolbar.d.ts +3 -1
  26. package/dist/internal/features/work/editors/document-underline-ribbon.d.ts +9 -0
  27. package/dist/internal/features/work/editors/document-wps-shortcuts.d.ts +1 -0
  28. package/dist/internal/features/work/editors/spreadsheet-cell-fill-format.d.ts +11 -0
  29. package/dist/internal/features/work/editors/spreadsheet-cell-format.d.ts +2 -1
  30. package/dist/internal/features/work/editors/spreadsheet-format-cells-dialog-model.d.ts +13 -2
  31. package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-panel.d.ts +13 -0
  32. package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-preview.d.ts +6 -0
  33. package/dist/internal/features/work/editors/spreadsheet-format-painter.d.ts +1 -1
  34. package/dist/internal/features/work/editors/work-office-chrome.d.ts +9 -1
  35. package/dist/internal/features/work/work-document-character-formatting.d.ts +16 -1
  36. package/dist/internal/features/work/work-document-character-position.d.ts +9 -0
  37. package/dist/internal/features/work/work-document-character-scale.d.ts +8 -0
  38. package/dist/internal/features/work/work-document-character-spacing.d.ts +8 -0
  39. package/dist/internal/features/work/work-document-emphasis.d.ts +7 -0
  40. package/dist/internal/features/work/work-document-equations.d.ts +2 -1
  41. package/dist/internal/features/work/work-document-format-changes.d.ts +16 -2
  42. package/dist/internal/features/work/work-document-hidden-text.d.ts +5 -0
  43. package/dist/internal/features/work/work-document-kerning.d.ts +10 -0
  44. package/dist/internal/features/work/work-document-script-font-extension.d.ts +2 -0
  45. package/dist/internal/features/work/work-document-script-fonts.d.ts +51 -0
  46. package/dist/internal/features/work/work-document-strike.d.ts +21 -0
  47. package/dist/internal/features/work/work-document-text-case.d.ts +10 -0
  48. package/dist/internal/features/work/work-document-underline.d.ts +37 -0
  49. package/dist/internal/features/work/work-document-word-line-metrics.d.ts +12 -0
  50. package/dist/internal/features/work/work-docx-character-position.d.ts +2 -0
  51. package/dist/internal/features/work/work-docx-character-scale.d.ts +2 -0
  52. package/dist/internal/features/work/work-docx-character-spacing.d.ts +4 -0
  53. package/dist/internal/features/work/work-docx-emphasis-diagnostics.d.ts +3 -0
  54. package/dist/internal/features/work/work-docx-emphasis.d.ts +14 -0
  55. package/dist/internal/features/work/work-docx-hidden-text-diagnostics.d.ts +3 -0
  56. package/dist/internal/features/work/work-docx-hidden-text-export.d.ts +16 -0
  57. package/dist/internal/features/work/work-docx-hidden-text.d.ts +11 -0
  58. package/dist/internal/features/work/work-docx-kerning-diagnostics.d.ts +3 -0
  59. package/dist/internal/features/work/work-docx-kerning.d.ts +14 -0
  60. package/dist/internal/features/work/work-docx-run-fonts-diagnostics.d.ts +3 -0
  61. package/dist/internal/features/work/work-docx-run-fonts-export.d.ts +14 -0
  62. package/dist/internal/features/work/work-docx-run-fonts.d.ts +13 -0
  63. package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +23 -2
  64. package/dist/internal/features/work/work-docx-run-script-font-import.d.ts +9 -0
  65. package/dist/internal/features/work/work-docx-strike.d.ts +8 -0
  66. package/dist/internal/features/work/work-docx-theme-reference.d.ts +1 -1
  67. package/dist/internal/features/work/work-docx-twips.d.ts +6 -0
  68. package/dist/internal/features/work/work-docx-underline.d.ts +3 -0
  69. package/dist/internal/features/work/work-spreadsheet-gradient-fill-canvas.d.ts +10 -0
  70. package/dist/internal/features/work/work-spreadsheet-native-fill-canvas.d.ts +8 -0
  71. package/dist/internal/features/work/work-spreadsheet-pattern-fill-canvas.d.ts +8 -0
  72. package/dist/internal/features/work/work-xlsx-cell-style-origin.d.ts +2 -1
  73. package/dist/internal/features/work/work-xlsx-cell-style-writer.d.ts +3 -0
  74. package/dist/internal/features/work/work-xlsx-cell-styles.d.ts +4 -0
  75. package/dist/internal/features/work/work-xlsx-gradient-fill.d.ts +31 -0
  76. package/dist/internal/features/work/work-xlsx-native-fill.d.ts +17 -0
  77. package/dist/internal/features/work/work-xlsx-pattern-fill.d.ts +21 -0
  78. package/dist/office-kernel.wasm +0 -0
  79. package/dist/styles.css +770 -80
  80. package/docs/latest/en/browser-editor-architecture.md +10 -0
  81. package/package.json +32 -1
@@ -1,11 +1,11 @@
1
1
  import { __webpack_require__ } from "./0~rslib-runtime.js";
2
2
  import { contentTypeForPart, directChildren, OoxmlPackage, parseXml, firstDescendant, descendants, directChild, xmlContainsAnyElement, attribute } from "./5184.js";
3
3
  import { normalizeDocumentBookmarkName, docxBookmarkReferenceTarget, normalizeDocumentBookmarkNativeId, isDocumentParagraphArtBorderStyle, supportedDocxBookmarkReferenceInstruction, documentCitationTagsFromInstruction, docxDocumentFieldKind } from "./6282.js";
4
- import { markDocxParagraphShading, inspectDocxPageSize, docxCaptionBookmark, hasInvalidDocxFieldStructure, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, createDocxTableStyleResolver, docxFieldOccurrences, inspectDocxEquation, inspectDocxPageMarginSettings, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, docxCaptionSequenceKind, inspectDocxPageBorders, isSupportedDocxRunFormattingChange, docxFieldInstructions, isSupportedDocxEquationPlacement } from "./0~5093.js";
4
+ import { markDocxParagraphShading, inspectDocxPageSize, docxCaptionBookmark, hasInvalidDocxFieldStructure, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, createDocxTableStyleResolver, inspectDocxRunFonts, docxFieldOccurrences, inspectDocxEquation, inspectDocxPageMarginSettings, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, inspectDocxHiddenText, docxCaptionSequenceKind, inspectDocxPageBorders, isSupportedDocxRunFormattingChange, docxFieldInstructions, isSupportedDocxEquationPlacement } from "./0~5093.js";
5
5
  import { normalizeDocumentHref } from "./0~work-document-links.js";
6
- import { xmlAttributeLocalName, parseDocxParagraphDefaultCollapsed, readDocxBibliography, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, createDocxThemeResolver } from "./0~2805.js";
6
+ import { xmlAttributeLocalName, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, parseDocxParagraphDefaultCollapsed, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~7043.js";
7
7
  import { updateSpreadsheetWorksheetCompatibilitySummary, inspectXlsxPivotTables, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, xlsxChartNodeUsesStackedGrouping, isSupportedXlsxChartSeriesFormatting, readXlsxFormulaFeaturesFromPackage, inspectXlsxHeaderFooterText, emptySpreadsheetWorksheetCompatibilitySummary, isSupportedXlsxWorksheetImageContentType, MAX_XLSX_WORKSHEET_IMAGE_BYTES, xlsxChartSeriesFormattingShapeProperties, diagnoseXlsxProtection, isEditableXlsxPaperSizeCode, isSupportedXlsxCombinationChartNodes } from "./4104.js";
8
- import { spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconSetCount, xlsxWorksheetCellEntries } from "./164.js";
8
+ import { spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconSetCount, xlsxWorksheetCellEntries } from "./1544.js";
9
9
  import { formulaHasStructuredReference, formulaHasExternalReference, parseSpreadsheetPrintTitles, volatileSpreadsheetFormulaFunctions, stripSpreadsheetSheetQualifier } from "./8715.js";
10
10
  import { unsupportedSpreadsheetFormulaFunctions } from "./0~work-spreadsheet-formula-support.js";
11
11
  var work_office_diagnostics_namespaceObject = {};
@@ -269,6 +269,137 @@ function equationIssue(code, message, severity = 'warning') {
269
269
  severity
270
270
  };
271
271
  }
272
+ const EMPHASIS_DIAGNOSTIC_PART_PATTERN = /^word\/(?:document|styles|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
273
+ async function diagnoseDocxEmphasisMarks(archive, document) {
274
+ const parts = [
275
+ {
276
+ path: 'word/document.xml',
277
+ document
278
+ }
279
+ ];
280
+ for (const path of archive.paths('word/'))if ('word/document.xml' !== path.toLowerCase() && EMPHASIS_DIAGNOSTIC_PART_PATTERN.test(path)) parts.push({
281
+ path,
282
+ document: await archive.xml(path)
283
+ });
284
+ let validCount = 0;
285
+ let explicitNoneCount = 0;
286
+ let underDotCount = 0;
287
+ let invalidCount = 0;
288
+ for (const part of parts){
289
+ const propertySets = descendants(part.document, 'rPr').filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
290
+ for (const properties of propertySets){
291
+ if (!directChildren(properties, 'em').length) continue;
292
+ const inspection = inspectDocxEmphasisMark(properties);
293
+ if ('valid' === inspection.status) {
294
+ validCount += 1;
295
+ if ('none' === inspection.value) explicitNoneCount += 1;
296
+ if ('underDot' === inspection.value) underDotCount += 1;
297
+ } else if ('invalid' === inspection.status) invalidCount += 1;
298
+ }
299
+ invalidCount += descendants(part.document, 'em').filter((element)=>{
300
+ const parent = element.parentElement;
301
+ return !parent || 'rPr' !== parent.localName || !DOCX_WORDPROCESSING_NAMESPACES.has(parent.namespaceURI ?? '');
302
+ }).length;
303
+ }
304
+ const issues = [];
305
+ if (validCount) issues.push({
306
+ code: 'docx.emphasis-mark',
307
+ severity: 'info',
308
+ feature: 'East Asian emphasis marks',
309
+ message: `${validCount} native emphasis mark(s), including ${explicitNoneCount} explicit none reset(s) and ${underDotCount} below-text dot(s), preserve all five w:em values through style inheritance, body and page-chrome editing, formatting revisions, CSS projection, and DOCX export. Runs with visible marks use browser line measurement so their out-of-line glyph extents are not approximated by the Worker/WASM shaper.`
310
+ });
311
+ if (invalidCount) issues.push({
312
+ code: 'docx.emphasis-mark.invalid',
313
+ severity: 'warning',
314
+ feature: 'East Asian emphasis marks',
315
+ message: `${invalidCount} malformed, duplicated, misplaced, namespace-spoofed, text-bearing, or unknown emphasis property set(s) are ignored instead of enabling untrusted typography.`
316
+ });
317
+ return issues;
318
+ }
319
+ const HIDDEN_TEXT_DIAGNOSTIC_PART_PATTERN = /^word\/(?:document|styles|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
320
+ async function diagnoseDocxHiddenText(archive, document) {
321
+ const parts = [
322
+ document
323
+ ];
324
+ for (const path of archive.paths('word/'))if ('word/document.xml' !== path.toLowerCase() && HIDDEN_TEXT_DIAGNOSTIC_PART_PATTERN.test(path)) parts.push(await archive.xml(path));
325
+ let hiddenCount = 0;
326
+ let visibleResetCount = 0;
327
+ let invalidCount = 0;
328
+ for (const part of parts){
329
+ const propertySets = descendants(part, 'rPr').filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
330
+ for (const properties of propertySets){
331
+ if (!directChildren(properties, 'vanish').length) continue;
332
+ const inspection = inspectDocxHiddenText(properties);
333
+ if ('valid' === inspection.status) if (inspection.value) hiddenCount += 1;
334
+ else visibleResetCount += 1;
335
+ else if ('invalid' === inspection.status) invalidCount += 1;
336
+ }
337
+ invalidCount += descendants(part, 'vanish').filter((element)=>{
338
+ const parent = element.parentElement;
339
+ return !parent || 'rPr' !== parent.localName || !DOCX_WORDPROCESSING_NAMESPACES.has(parent.namespaceURI ?? '');
340
+ }).length;
341
+ }
342
+ const issues = [];
343
+ const validCount = hiddenCount + visibleResetCount;
344
+ if (validCount) issues.push({
345
+ code: 'docx.hidden-text',
346
+ severity: 'info',
347
+ feature: 'Hidden text',
348
+ message: `${validCount} native hidden-text value(s), including ${hiddenCount} hidden value(s) and ${visibleResetCount} explicit visible reset(s), were detected across document defaults, character and paragraph styles, body, headers, footers, notes, comments, and formatting revisions. Editable Writer stories preserve w:vanish through the Font dialog, the show-hidden-text editing view, and exact DOCX export; unchanged comment XML remains source-preserved rather than becoming a rich comment-editing claim. Preview and PDF output keep hidden text suppressed, while affected paragraphs use browser-authoritative line measurement.`
349
+ });
350
+ if (invalidCount) issues.push({
351
+ code: 'docx.hidden-text.invalid',
352
+ severity: 'warning',
353
+ feature: 'Hidden text',
354
+ message: `${invalidCount} malformed, duplicated, misplaced, namespace-spoofed, text-bearing, child-bearing, extra-attribute, or unknown hidden-text property set(s) are ignored instead of hiding untrusted content.`
355
+ });
356
+ return issues;
357
+ }
358
+ const KERNING_DIAGNOSTIC_PART_PATTERN = /^word\/(?:document|styles|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
359
+ async function diagnoseDocxKerning(archive, document) {
360
+ const parts = [
361
+ {
362
+ path: 'word/document.xml',
363
+ document
364
+ }
365
+ ];
366
+ for (const path of archive.paths('word/'))if ('word/document.xml' !== path.toLowerCase() && KERNING_DIAGNOSTIC_PART_PATTERN.test(path)) parts.push({
367
+ path,
368
+ document: await archive.xml(path)
369
+ });
370
+ let validCount = 0;
371
+ let explicitZeroCount = 0;
372
+ let invalidCount = 0;
373
+ for (const part of parts){
374
+ const propertySets = descendants(part.document, 'rPr').filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
375
+ for (const properties of propertySets){
376
+ if (!directChildren(properties, 'kern').length) continue;
377
+ const inspection = inspectDocxKerningThresholdHalfPoints(properties);
378
+ if ('valid' === inspection.status) {
379
+ validCount += 1;
380
+ if (0 === inspection.value) explicitZeroCount += 1;
381
+ } else if ('invalid' === inspection.status) invalidCount += 1;
382
+ }
383
+ invalidCount += descendants(part.document, 'kern').filter((element)=>{
384
+ const parent = element.parentElement;
385
+ return !parent || 'rPr' !== parent.localName || !DOCX_WORDPROCESSING_NAMESPACES.has(parent.namespaceURI ?? '');
386
+ }).length;
387
+ }
388
+ const issues = [];
389
+ if (validCount) issues.push({
390
+ code: 'docx.kerning',
391
+ severity: 'info',
392
+ feature: 'Character kerning',
393
+ message: `${validCount} native kerning threshold(s), including ${explicitZeroCount} explicit all-font-size value(s), preserve exact half-points through style inheritance, body and page-chrome editing, effective font-size rendering, formatting revisions, and DOCX export. Pair kerning applies when the effective w:sz value meets or exceeds w:kern; absence throughout the hierarchy keeps kerning disabled.`
394
+ });
395
+ if (invalidCount) issues.push({
396
+ code: 'docx.kerning.invalid',
397
+ severity: 'warning',
398
+ feature: 'Character kerning',
399
+ message: `${invalidCount} malformed, duplicated, misplaced, namespace-spoofed, text-bearing, or out-of-range kerning property set(s) are ignored instead of enabling untrusted typography.`
400
+ });
401
+ return issues;
402
+ }
272
403
  const WORDPROCESSINGML_NAMESPACES = new Set([
273
404
  'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
274
405
  'http://purl.oclc.org/ooxml/wordprocessingml/main'
@@ -665,6 +796,63 @@ async function diagnoseDocxParagraphShading(archive, document) {
665
796
  });
666
797
  return issues;
667
798
  }
799
+ const RUN_FONT_DIAGNOSTIC_PART_PATTERN = /^word\/(?:document|styles|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
800
+ async function diagnoseDocxRunFonts(archive, document) {
801
+ const parts = [
802
+ {
803
+ path: 'word/document.xml',
804
+ document
805
+ }
806
+ ];
807
+ for (const path of archive.paths('word/'))if ('word/document.xml' !== path.toLowerCase() && RUN_FONT_DIAGNOSTIC_PART_PATTERN.test(path)) parts.push({
808
+ path,
809
+ document: await archive.xml(path)
810
+ });
811
+ let validCount = 0;
812
+ let directSlotCount = 0;
813
+ let themeSlotCount = 0;
814
+ let hintCount = 0;
815
+ let invalidCount = 0;
816
+ for (const part of parts){
817
+ const propertySets = descendants(part.document, 'rPr').filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
818
+ for (const properties of propertySets){
819
+ if (!directChildren(properties, 'rFonts').length) continue;
820
+ const inspection = inspectDocxRunFonts(properties);
821
+ if ('valid' === inspection.status) {
822
+ validCount += 1;
823
+ if (!inspection.value) continue;
824
+ for (const slot of [
825
+ inspection.value.ascii,
826
+ inspection.value.highAnsi,
827
+ inspection.value.eastAsia,
828
+ inspection.value.complexScript
829
+ ]){
830
+ if (slot?.name) directSlotCount += 1;
831
+ if (slot?.theme) themeSlotCount += 1;
832
+ }
833
+ if (inspection.value.hint) hintCount += 1;
834
+ } else if ('invalid' === inspection.status) invalidCount += 1;
835
+ }
836
+ invalidCount += descendants(part.document, 'rFonts').filter((element)=>{
837
+ const parent = element.parentElement;
838
+ return !parent || 'rPr' !== parent.localName || !DOCX_WORDPROCESSING_NAMESPACES.has(parent.namespaceURI ?? '');
839
+ }).length;
840
+ }
841
+ const issues = [];
842
+ if (validCount) issues.push({
843
+ code: "docx.script-fonts",
844
+ severity: 'info',
845
+ feature: 'Script-specific run fonts',
846
+ message: `${validCount} native run-font property set(s), containing ${directSlotCount} direct slot value(s), ${themeSlotCount} theme slot reference(s), and ${hintCount} script hint(s), preserve the independent ASCII, high ANSI, East Asian, and complex-script identities through style inheritance, mixed-script browser rendering, body and page-chrome editing, formatting revisions, and DOCX export. Browser-resolved families remain separate from native source identity so font substitution does not rewrite untouched theme references.`
847
+ });
848
+ if (invalidCount) issues.push({
849
+ code: "docx.script-fonts.invalid",
850
+ severity: 'warning',
851
+ feature: 'Script-specific run fonts',
852
+ message: `${invalidCount} malformed, duplicated, misplaced, namespace-spoofed, child-bearing, text-bearing, unknown, or oversized run-font property set(s) are ignored instead of applying untrusted font metadata.`
853
+ });
854
+ return issues;
855
+ }
668
856
  const SUPPORTED_CHART_ELEMENTS = new Set([
669
857
  'barChart',
670
858
  'lineChart',
@@ -1687,6 +1875,12 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
1687
1875
  }
1688
1876
  issues.push(...await diagnoseDocxNotes(archive, document));
1689
1877
  issues.push(...await diagnoseDocxEquations(archive, document));
1878
+ if (document) {
1879
+ issues.push(...await diagnoseDocxKerning(archive, document));
1880
+ issues.push(...await diagnoseDocxEmphasisMarks(archive, document));
1881
+ issues.push(...await diagnoseDocxHiddenText(archive, document));
1882
+ issues.push(...await diagnoseDocxRunFonts(archive, document));
1883
+ }
1690
1884
  issues.push(...await diagnoseDocxPageChrome(archive));
1691
1885
  if (archive.paths('word/embeddings/').length) issues.push(work_office_diagnostics_issue('docx.embedded', 'Embedded objects', 'Embedded Office and OLE payload parts plus safe relationships are retained in source-backed exports, but Work does not render or edit their object anchors; placement inside regenerated document XML may normalize.'));
1692
1886
  if (document) {
@@ -1716,7 +1910,7 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
1716
1910
  const supportedRunFormattingRevisionCount = runFormattingRevisions.filter(isSupportedDocxRunFormattingChange).length;
1717
1911
  const supportedParagraphFormattingRevisionCount = paragraphFormattingRevisions.filter(isSupportedDocxParagraphFormattingChange).length;
1718
1912
  if (textRevisions.some((revision)=>descendants(revision, 't').length || descendants(revision, 'delText').length)) issues.push(work_office_diagnostics_issue('docx.revisions', 'Tracked changes', 'Body-text insertions and deletions preserve their author and date, remain reviewable in Work, and round-trip as native DOCX revisions.', 'info'));
1719
- 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, subscript, superscript, font, size, color, highlight, and grid state. They remain reviewable in Work and round-trip as native w:rPrChange records.`, 'info'));
1913
+ 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, subscript, superscript, font, size, color, highlight, character scale, spacing, kerning threshold, emphasis mark, baseline position, and grid state. They remain reviewable in Work and round-trip as native w:rPrChange records.`, 'info'));
1720
1914
  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'));
1721
1915
  if (textRevisions.some((revision)=>!descendants(revision, 't').length && !descendants(revision, 'delText').length) || supportedRunFormattingRevisionCount !== runFormattingRevisions.length || supportedParagraphFormattingRevisionCount !== paragraphFormattingRevisions.length || [
1722
1916
  'moveFrom',