@a3s-lab/office 0.25.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.
- package/README.md +76 -2
- package/dist/0~4595.js +16 -2
- package/dist/0~5093.js +463 -201
- package/dist/0~6090.js +77 -77
- package/dist/{0~2805.js → 0~7043.js} +305 -2
- package/dist/0~document-editor.js +2451 -985
- package/dist/0~spreadsheet-editor.js +22113 -20117
- package/dist/0~work-docx-export.js +492 -10
- package/dist/0~work-docx-import.js +171 -98
- package/dist/0~work-office-diagnostics.js +198 -4
- package/dist/{164.js → 1544.js} +1412 -1055
- package/dist/4104.js +145 -29
- package/dist/6282.js +1920 -544
- package/dist/9424.js +16 -0
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +102 -0
- package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +83 -0
- package/dist/internal/features/work/editors/document-font-dialog-script-font-model.d.ts +18 -0
- package/dist/internal/features/work/editors/document-font-dialog.d.ts +9 -0
- package/dist/internal/features/work/editors/document-home-ribbon.d.ts +2 -1
- package/dist/internal/features/work/editors/document-page-chrome-editor.d.ts +6 -0
- package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +2 -1
- package/dist/internal/features/work/editors/document-strike-ribbon.d.ts +7 -0
- package/dist/internal/features/work/editors/document-text-case-ribbon.d.ts +4 -0
- package/dist/internal/features/work/editors/document-toolbar.d.ts +3 -1
- package/dist/internal/features/work/editors/document-underline-ribbon.d.ts +9 -0
- package/dist/internal/features/work/editors/document-wps-shortcuts.d.ts +1 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-fill-format.d.ts +11 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-format.d.ts +2 -1
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +18 -9
- package/dist/internal/features/work/editors/spreadsheet-format-cells-dialog-model.d.ts +13 -2
- package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-panel.d.ts +13 -0
- package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-preview.d.ts +6 -0
- package/dist/internal/features/work/editors/spreadsheet-format-painter.d.ts +1 -1
- package/dist/internal/features/work/editors/spreadsheet-operation-projection.d.ts +6 -0
- package/dist/internal/features/work/editors/spreadsheet-rich-text-dom-selection.d.ts +11 -0
- package/dist/internal/features/work/editors/spreadsheet-rich-text-paste.d.ts +22 -0
- package/dist/internal/features/work/editors/spreadsheet-rich-text-selection-controller.d.ts +38 -0
- package/dist/internal/features/work/editors/spreadsheet-rich-text-selection-format.d.ts +26 -0
- package/dist/internal/features/work/editors/work-office-chrome.d.ts +9 -1
- package/dist/internal/features/work/work-css-color.d.ts +1 -0
- package/dist/internal/features/work/work-document-character-formatting.d.ts +16 -1
- package/dist/internal/features/work/work-document-character-position.d.ts +9 -0
- package/dist/internal/features/work/work-document-character-scale.d.ts +8 -0
- package/dist/internal/features/work/work-document-character-spacing.d.ts +8 -0
- package/dist/internal/features/work/work-document-emphasis.d.ts +7 -0
- package/dist/internal/features/work/work-document-equations.d.ts +2 -1
- package/dist/internal/features/work/work-document-format-changes.d.ts +16 -2
- package/dist/internal/features/work/work-document-hidden-text.d.ts +5 -0
- package/dist/internal/features/work/work-document-kerning.d.ts +10 -0
- package/dist/internal/features/work/work-document-paragraph-shading.d.ts +1 -1
- package/dist/internal/features/work/work-document-script-font-extension.d.ts +2 -0
- package/dist/internal/features/work/work-document-script-fonts.d.ts +51 -0
- package/dist/internal/features/work/work-document-strike.d.ts +21 -0
- package/dist/internal/features/work/work-document-text-case.d.ts +10 -0
- package/dist/internal/features/work/work-document-underline.d.ts +37 -0
- package/dist/internal/features/work/work-document-word-line-metrics.d.ts +12 -0
- package/dist/internal/features/work/work-docx-character-position.d.ts +2 -0
- package/dist/internal/features/work/work-docx-character-scale.d.ts +2 -0
- package/dist/internal/features/work/work-docx-character-spacing.d.ts +4 -0
- package/dist/internal/features/work/work-docx-emphasis-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-emphasis.d.ts +14 -0
- package/dist/internal/features/work/work-docx-hidden-text-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-hidden-text-export.d.ts +16 -0
- package/dist/internal/features/work/work-docx-hidden-text.d.ts +11 -0
- package/dist/internal/features/work/work-docx-kerning-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-kerning.d.ts +14 -0
- package/dist/internal/features/work/work-docx-run-fonts-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-run-fonts-export.d.ts +14 -0
- package/dist/internal/features/work/work-docx-run-fonts.d.ts +13 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +23 -2
- package/dist/internal/features/work/work-docx-run-script-font-import.d.ts +9 -0
- package/dist/internal/features/work/work-docx-strike.d.ts +8 -0
- package/dist/internal/features/work/work-docx-theme-reference.d.ts +1 -1
- package/dist/internal/features/work/work-docx-twips.d.ts +6 -0
- package/dist/internal/features/work/work-docx-underline.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-gradient-fill-canvas.d.ts +10 -0
- package/dist/internal/features/work/work-spreadsheet-native-fill-canvas.d.ts +8 -0
- package/dist/internal/features/work/work-spreadsheet-pattern-fill-canvas.d.ts +8 -0
- package/dist/internal/features/work/work-xlsx-cell-style-origin.d.ts +2 -1
- package/dist/internal/features/work/work-xlsx-cell-style-writer.d.ts +3 -0
- package/dist/internal/features/work/work-xlsx-cell-styles.d.ts +4 -0
- package/dist/internal/features/work/work-xlsx-gradient-fill.d.ts +31 -0
- package/dist/internal/features/work/work-xlsx-native-fill.d.ts +17 -0
- package/dist/internal/features/work/work-xlsx-pattern-fill.d.ts +21 -0
- package/dist/internal/features/work/work-xlsx-rich-text-edit.d.ts +28 -0
- package/dist/internal/features/work/work-xlsx-rich-text-model.d.ts +40 -0
- package/dist/internal/features/work/work-xlsx-rich-text.d.ts +4 -18
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +770 -80
- package/docs/latest/en/browser-editor-architecture.md +37 -0
- package/package.json +32 -1
package/dist/0~6090.js
CHANGED
|
@@ -696,6 +696,83 @@ function adjacentDocumentTabStop(current, direction, excludedRoot) {
|
|
|
696
696
|
const index = tabStops.indexOf(current);
|
|
697
697
|
return index < 0 ? null : tabStops[index + direction] ?? null;
|
|
698
698
|
}
|
|
699
|
+
const OFFICE_MENU_NAVIGATION_KEYS = [
|
|
700
|
+
'ArrowDown',
|
|
701
|
+
'ArrowUp',
|
|
702
|
+
'Home',
|
|
703
|
+
'End'
|
|
704
|
+
];
|
|
705
|
+
const OFFICE_GRID_MENU_NAVIGATION_KEYS = [
|
|
706
|
+
...OFFICE_MENU_NAVIGATION_KEYS,
|
|
707
|
+
'ArrowLeft',
|
|
708
|
+
'ArrowRight'
|
|
709
|
+
];
|
|
710
|
+
const OFFICE_MENU_BUTTON_SELECTOR = 'button[role="menuitem"]:not(:disabled), button[role="menuitemradio"]:not(:disabled), button[role="menuitemcheckbox"]:not(:disabled)';
|
|
711
|
+
function moveOfficeMenuFocus(event) {
|
|
712
|
+
if (!OFFICE_MENU_NAVIGATION_KEYS.includes(event.key)) return false;
|
|
713
|
+
const buttons = officeMenuButtons(event.currentTarget);
|
|
714
|
+
if (!buttons.length) return false;
|
|
715
|
+
event.preventDefault();
|
|
716
|
+
const current = buttons.indexOf(document.activeElement);
|
|
717
|
+
const next = 'Home' === event.key ? 0 : 'End' === event.key ? buttons.length - 1 : 'ArrowDown' === event.key ? (current + 1 + buttons.length) % buttons.length : (current - 1 + buttons.length) % buttons.length;
|
|
718
|
+
buttons[next]?.focus();
|
|
719
|
+
return true;
|
|
720
|
+
}
|
|
721
|
+
function moveOfficeGridMenuFocus(event, columns) {
|
|
722
|
+
if (!OFFICE_GRID_MENU_NAVIGATION_KEYS.includes(event.key)) return false;
|
|
723
|
+
const buttons = officeMenuButtons(event.currentTarget);
|
|
724
|
+
if (!buttons.length) return false;
|
|
725
|
+
event.preventDefault();
|
|
726
|
+
const currentButton = document.activeElement;
|
|
727
|
+
const current = Math.max(0, buttons.indexOf(currentButton));
|
|
728
|
+
if ('Home' === event.key || 'End' === event.key) {
|
|
729
|
+
buttons['Home' === event.key ? 0 : buttons.length - 1]?.focus();
|
|
730
|
+
return true;
|
|
731
|
+
}
|
|
732
|
+
if ('ArrowLeft' === event.key || 'ArrowRight' === event.key) {
|
|
733
|
+
const delta = 'ArrowRight' === event.key ? 1 : -1;
|
|
734
|
+
buttons[(current + delta + buttons.length) % buttons.length]?.focus();
|
|
735
|
+
return true;
|
|
736
|
+
}
|
|
737
|
+
const groups = [
|
|
738
|
+
...event.currentTarget.querySelectorAll('[data-office-menu-grid]')
|
|
739
|
+
];
|
|
740
|
+
const groupIndex = groups.findIndex((group)=>group.contains(currentButton));
|
|
741
|
+
if (groupIndex < 0) {
|
|
742
|
+
const delta = 'ArrowDown' === event.key ? columns : -columns;
|
|
743
|
+
buttons[(current + delta + buttons.length) % buttons.length]?.focus();
|
|
744
|
+
return true;
|
|
745
|
+
}
|
|
746
|
+
const groupButtons = officeMenuButtons(groups[groupIndex]);
|
|
747
|
+
const localIndex = Math.max(0, groupButtons.indexOf(currentButton));
|
|
748
|
+
const column = localIndex % columns;
|
|
749
|
+
if ('ArrowDown' === event.key) {
|
|
750
|
+
const nextRow = localIndex - column + columns;
|
|
751
|
+
if (nextRow < groupButtons.length) {
|
|
752
|
+
groupButtons[Math.min(nextRow + column, groupButtons.length - 1)]?.focus();
|
|
753
|
+
return true;
|
|
754
|
+
}
|
|
755
|
+
const nextGroup = groups[(groupIndex + 1) % groups.length];
|
|
756
|
+
const nextButtons = officeMenuButtons(nextGroup);
|
|
757
|
+
nextButtons[Math.min(column, nextButtons.length - 1)]?.focus();
|
|
758
|
+
return true;
|
|
759
|
+
}
|
|
760
|
+
const previousRow = localIndex - column - columns;
|
|
761
|
+
if (previousRow >= 0) {
|
|
762
|
+
groupButtons[previousRow + column]?.focus();
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
765
|
+
const previousGroup = groups[(groupIndex - 1 + groups.length) % groups.length];
|
|
766
|
+
const previousButtons = officeMenuButtons(previousGroup);
|
|
767
|
+
const previousRowStart = Math.floor((previousButtons.length - 1) / columns) * columns;
|
|
768
|
+
previousButtons[Math.min(previousRowStart + column, previousButtons.length - 1)]?.focus();
|
|
769
|
+
return true;
|
|
770
|
+
}
|
|
771
|
+
function officeMenuButtons(root) {
|
|
772
|
+
return [
|
|
773
|
+
...root.querySelectorAll(OFFICE_MENU_BUTTON_SELECTOR)
|
|
774
|
+
];
|
|
775
|
+
}
|
|
699
776
|
const PRESENCE_COLORS = [
|
|
700
777
|
'#1d4ed8',
|
|
701
778
|
'#6d28d9',
|
|
@@ -1230,83 +1307,6 @@ function presenceLocationLabel(participant) {
|
|
|
1230
1307
|
return `第 ${location.pageIndex + 1} 页`;
|
|
1231
1308
|
}
|
|
1232
1309
|
}
|
|
1233
|
-
const OFFICE_MENU_NAVIGATION_KEYS = [
|
|
1234
|
-
'ArrowDown',
|
|
1235
|
-
'ArrowUp',
|
|
1236
|
-
'Home',
|
|
1237
|
-
'End'
|
|
1238
|
-
];
|
|
1239
|
-
const OFFICE_GRID_MENU_NAVIGATION_KEYS = [
|
|
1240
|
-
...OFFICE_MENU_NAVIGATION_KEYS,
|
|
1241
|
-
'ArrowLeft',
|
|
1242
|
-
'ArrowRight'
|
|
1243
|
-
];
|
|
1244
|
-
const OFFICE_MENU_BUTTON_SELECTOR = 'button[role="menuitem"]:not(:disabled), button[role="menuitemradio"]:not(:disabled), button[role="menuitemcheckbox"]:not(:disabled)';
|
|
1245
|
-
function moveOfficeMenuFocus(event) {
|
|
1246
|
-
if (!OFFICE_MENU_NAVIGATION_KEYS.includes(event.key)) return false;
|
|
1247
|
-
const buttons = officeMenuButtons(event.currentTarget);
|
|
1248
|
-
if (!buttons.length) return false;
|
|
1249
|
-
event.preventDefault();
|
|
1250
|
-
const current = buttons.indexOf(document.activeElement);
|
|
1251
|
-
const next = 'Home' === event.key ? 0 : 'End' === event.key ? buttons.length - 1 : 'ArrowDown' === event.key ? (current + 1 + buttons.length) % buttons.length : (current - 1 + buttons.length) % buttons.length;
|
|
1252
|
-
buttons[next]?.focus();
|
|
1253
|
-
return true;
|
|
1254
|
-
}
|
|
1255
|
-
function moveOfficeGridMenuFocus(event, columns) {
|
|
1256
|
-
if (!OFFICE_GRID_MENU_NAVIGATION_KEYS.includes(event.key)) return false;
|
|
1257
|
-
const buttons = officeMenuButtons(event.currentTarget);
|
|
1258
|
-
if (!buttons.length) return false;
|
|
1259
|
-
event.preventDefault();
|
|
1260
|
-
const currentButton = document.activeElement;
|
|
1261
|
-
const current = Math.max(0, buttons.indexOf(currentButton));
|
|
1262
|
-
if ('Home' === event.key || 'End' === event.key) {
|
|
1263
|
-
buttons['Home' === event.key ? 0 : buttons.length - 1]?.focus();
|
|
1264
|
-
return true;
|
|
1265
|
-
}
|
|
1266
|
-
if ('ArrowLeft' === event.key || 'ArrowRight' === event.key) {
|
|
1267
|
-
const delta = 'ArrowRight' === event.key ? 1 : -1;
|
|
1268
|
-
buttons[(current + delta + buttons.length) % buttons.length]?.focus();
|
|
1269
|
-
return true;
|
|
1270
|
-
}
|
|
1271
|
-
const groups = [
|
|
1272
|
-
...event.currentTarget.querySelectorAll('[data-office-menu-grid]')
|
|
1273
|
-
];
|
|
1274
|
-
const groupIndex = groups.findIndex((group)=>group.contains(currentButton));
|
|
1275
|
-
if (groupIndex < 0) {
|
|
1276
|
-
const delta = 'ArrowDown' === event.key ? columns : -columns;
|
|
1277
|
-
buttons[(current + delta + buttons.length) % buttons.length]?.focus();
|
|
1278
|
-
return true;
|
|
1279
|
-
}
|
|
1280
|
-
const groupButtons = officeMenuButtons(groups[groupIndex]);
|
|
1281
|
-
const localIndex = Math.max(0, groupButtons.indexOf(currentButton));
|
|
1282
|
-
const column = localIndex % columns;
|
|
1283
|
-
if ('ArrowDown' === event.key) {
|
|
1284
|
-
const nextRow = localIndex - column + columns;
|
|
1285
|
-
if (nextRow < groupButtons.length) {
|
|
1286
|
-
groupButtons[Math.min(nextRow + column, groupButtons.length - 1)]?.focus();
|
|
1287
|
-
return true;
|
|
1288
|
-
}
|
|
1289
|
-
const nextGroup = groups[(groupIndex + 1) % groups.length];
|
|
1290
|
-
const nextButtons = officeMenuButtons(nextGroup);
|
|
1291
|
-
nextButtons[Math.min(column, nextButtons.length - 1)]?.focus();
|
|
1292
|
-
return true;
|
|
1293
|
-
}
|
|
1294
|
-
const previousRow = localIndex - column - columns;
|
|
1295
|
-
if (previousRow >= 0) {
|
|
1296
|
-
groupButtons[previousRow + column]?.focus();
|
|
1297
|
-
return true;
|
|
1298
|
-
}
|
|
1299
|
-
const previousGroup = groups[(groupIndex - 1 + groups.length) % groups.length];
|
|
1300
|
-
const previousButtons = officeMenuButtons(previousGroup);
|
|
1301
|
-
const previousRowStart = Math.floor((previousButtons.length - 1) / columns) * columns;
|
|
1302
|
-
previousButtons[Math.min(previousRowStart + column, previousButtons.length - 1)]?.focus();
|
|
1303
|
-
return true;
|
|
1304
|
-
}
|
|
1305
|
-
function officeMenuButtons(root) {
|
|
1306
|
-
return [
|
|
1307
|
-
...root.querySelectorAll(OFFICE_MENU_BUTTON_SELECTOR)
|
|
1308
|
-
];
|
|
1309
|
-
}
|
|
1310
1310
|
function stepOfficeZoom(zoom, direction, { minimum = 50, maximum = 200, step = 10 } = {}) {
|
|
1311
1311
|
const delta = 'in' === direction ? step : -step;
|
|
1312
1312
|
return Math.min(maximum, Math.max(minimum, Math.round(zoom + delta)));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import jszip from "jszip";
|
|
2
2
|
import { serializeUtf8Xml, directChildren, xmlNamespacePrefix, parseXml, firstDescendant, decodeXmlBytes, directChild, descendants, attribute as work_ooxml_package_attribute } from "./5184.js";
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeDocumentEmphasisMark, normalizeDocumentCharacterScalePercent, documentCitationStyle, normalizeDocumentKerningThresholdHalfPoints, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentCharacterSpacingTwips, normalizeDocumentTabStops, createDocumentBibliography, documentCitationStyleDetails } from "./6282.js";
|
|
4
4
|
const BIBLIOGRAPHY_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/bibliography';
|
|
5
5
|
const CUSTOM_XML_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/customXml';
|
|
6
6
|
const OFFICE_RELATIONSHIPS_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
|
|
@@ -708,6 +708,309 @@ function isAllowedExtensionNamespace(namespace, context) {
|
|
|
708
708
|
function isNamespacePrefix(value) {
|
|
709
709
|
return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) && 'xml' !== value;
|
|
710
710
|
}
|
|
711
|
+
const STRICT_WORDPROCESSING_NAMESPACE = 'http://purl.oclc.org/ooxml/wordprocessingml/main';
|
|
712
|
+
const UNIVERSAL_TWIP_RATIOS = {
|
|
713
|
+
mm: [
|
|
714
|
+
7200n,
|
|
715
|
+
127n
|
|
716
|
+
],
|
|
717
|
+
cm: [
|
|
718
|
+
72000n,
|
|
719
|
+
127n
|
|
720
|
+
],
|
|
721
|
+
in: [
|
|
722
|
+
1440n,
|
|
723
|
+
1n
|
|
724
|
+
],
|
|
725
|
+
pt: [
|
|
726
|
+
20n,
|
|
727
|
+
1n
|
|
728
|
+
],
|
|
729
|
+
pc: [
|
|
730
|
+
240n,
|
|
731
|
+
1n
|
|
732
|
+
],
|
|
733
|
+
pi: [
|
|
734
|
+
240n,
|
|
735
|
+
1n
|
|
736
|
+
]
|
|
737
|
+
};
|
|
738
|
+
const UNIVERSAL_HALF_POINT_RATIOS = {
|
|
739
|
+
mm: [
|
|
740
|
+
720n,
|
|
741
|
+
127n
|
|
742
|
+
],
|
|
743
|
+
cm: [
|
|
744
|
+
7200n,
|
|
745
|
+
127n
|
|
746
|
+
],
|
|
747
|
+
in: [
|
|
748
|
+
144n,
|
|
749
|
+
1n
|
|
750
|
+
],
|
|
751
|
+
pt: [
|
|
752
|
+
2n,
|
|
753
|
+
1n
|
|
754
|
+
],
|
|
755
|
+
pc: [
|
|
756
|
+
24n,
|
|
757
|
+
1n
|
|
758
|
+
],
|
|
759
|
+
pi: [
|
|
760
|
+
24n,
|
|
761
|
+
1n
|
|
762
|
+
]
|
|
763
|
+
};
|
|
764
|
+
function parseDocxTwipsMeasure(source, options) {
|
|
765
|
+
const integer = parseBoundedDocxInteger(source, {
|
|
766
|
+
minimum: options.minimum,
|
|
767
|
+
maximum: options.maximum,
|
|
768
|
+
signed: options.signed
|
|
769
|
+
});
|
|
770
|
+
if (null !== integer) return integer;
|
|
771
|
+
return options.strict ? parseStrictUniversalMeasure(source, UNIVERSAL_TWIP_RATIOS, options) : null;
|
|
772
|
+
}
|
|
773
|
+
function parseDocxHalfPointsMeasure(source, options) {
|
|
774
|
+
const integer = parseBoundedDocxInteger(source, {
|
|
775
|
+
minimum: options.minimum,
|
|
776
|
+
maximum: options.maximum,
|
|
777
|
+
signed: options.signed
|
|
778
|
+
});
|
|
779
|
+
if (null !== integer) return integer;
|
|
780
|
+
return options.strict ? parseStrictUniversalMeasure(source, UNIVERSAL_HALF_POINT_RATIOS, options) : null;
|
|
781
|
+
}
|
|
782
|
+
function parseBoundedDocxInteger(source, options) {
|
|
783
|
+
if (source.length > 32) return null;
|
|
784
|
+
const pattern = options.signed ? /^[+-]?\d+$/u : /^\+?\d+$/u;
|
|
785
|
+
if (!pattern.test(source)) return null;
|
|
786
|
+
const value = Number(source);
|
|
787
|
+
return Number.isSafeInteger(value) && value >= options.minimum && value <= options.maximum ? Object.is(value, -0) ? 0 : value : null;
|
|
788
|
+
}
|
|
789
|
+
function parseStrictUniversalMeasure(source, conversions, options) {
|
|
790
|
+
if (source.length > 64) return null;
|
|
791
|
+
const match = /^(-?)(\d+)(?:\.(\d+))?(mm|cm|in|pt|pc|pi)$/u.exec(source);
|
|
792
|
+
if (!match) return null;
|
|
793
|
+
const [, sign, whole = '', fraction = '', unit = ''] = match;
|
|
794
|
+
if (!options.signed && sign) return null;
|
|
795
|
+
const conversion = conversions[unit];
|
|
796
|
+
if (!conversion) return null;
|
|
797
|
+
const denominator = 10n ** BigInt(fraction.length) * conversion[1];
|
|
798
|
+
const numerator = BigInt(`${whole}${fraction}`) * conversion[0] * (sign ? -1n : 1n);
|
|
799
|
+
if (numerator % denominator !== 0n) return null;
|
|
800
|
+
const units = numerator / denominator;
|
|
801
|
+
if (units < BigInt(options.minimum) || units > BigInt(options.maximum)) return null;
|
|
802
|
+
return Number(units);
|
|
803
|
+
}
|
|
804
|
+
function docxCharacterScaleValue(value) {
|
|
805
|
+
return normalizeDocumentCharacterScalePercent(value) ?? void 0;
|
|
806
|
+
}
|
|
807
|
+
function docxCharacterScalePercentFromProperties(properties) {
|
|
808
|
+
if (!properties) return;
|
|
809
|
+
const localMatches = directChildren(properties, 'w');
|
|
810
|
+
const scales = localMatches.filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
811
|
+
if (1 !== localMatches.length || 1 !== scales.length) return;
|
|
812
|
+
const scale = scales[0];
|
|
813
|
+
if (directChildren(scale).length || Array.from(scale.childNodes).some((node)=>(node.nodeType === Node.TEXT_NODE || node.nodeType === Node.CDATA_SECTION_NODE) && Boolean(node.textContent?.trim()))) return;
|
|
814
|
+
const attributes = Array.from(scale.attributes).filter((attribute)=>xmlAttributeNamespace(scale, attribute) !== XMLNS_NAMESPACE && 'xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:'));
|
|
815
|
+
if (!attributes.length) return 100;
|
|
816
|
+
if (1 !== attributes.length || 'val' !== xmlAttributeLocalName(attributes[0]) || !DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(scale, attributes[0]) ?? '')) return;
|
|
817
|
+
return parseBoundedDocxInteger(attributes[0].value.trim(), {
|
|
818
|
+
minimum: 1,
|
|
819
|
+
maximum: 600,
|
|
820
|
+
signed: false
|
|
821
|
+
}) ?? void 0;
|
|
822
|
+
}
|
|
823
|
+
function docxCharacterPositionValue(value) {
|
|
824
|
+
const position = normalizeDocumentCharacterPositionHalfPoints(value);
|
|
825
|
+
return null === position ? void 0 : String(position);
|
|
826
|
+
}
|
|
827
|
+
function docxCharacterPositionHalfPointsFromProperties(properties) {
|
|
828
|
+
if (!properties) return;
|
|
829
|
+
const localMatches = directChildren(properties, 'position');
|
|
830
|
+
const positions = localMatches.filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
831
|
+
if (1 !== localMatches.length || 1 !== positions.length) return;
|
|
832
|
+
const position = positions[0];
|
|
833
|
+
if (directChildren(position).length || Array.from(position.childNodes).some((node)=>(node.nodeType === Node.TEXT_NODE || node.nodeType === Node.CDATA_SECTION_NODE) && Boolean(node.textContent?.trim()))) return;
|
|
834
|
+
const attributes = Array.from(position.attributes).filter((attribute)=>xmlAttributeNamespace(position, attribute) !== XMLNS_NAMESPACE && 'xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:'));
|
|
835
|
+
if (1 !== attributes.length || 'val' !== xmlAttributeLocalName(attributes[0]) || !DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(position, attributes[0]) ?? '')) return;
|
|
836
|
+
return parseDocxHalfPointsMeasure(attributes[0].value.trim(), {
|
|
837
|
+
minimum: -3168,
|
|
838
|
+
maximum: 3168,
|
|
839
|
+
signed: true,
|
|
840
|
+
strict: position.namespaceURI === STRICT_WORDPROCESSING_NAMESPACE
|
|
841
|
+
}) ?? void 0;
|
|
842
|
+
}
|
|
843
|
+
const DOCX_EXPLICIT_ZERO_CHARACTER_SPACING_SENTINEL = 31681;
|
|
844
|
+
const CHARACTER_SPACING_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
|
|
845
|
+
function docxCharacterSpacingValue(value) {
|
|
846
|
+
const spacing = normalizeDocumentCharacterSpacingTwips(value);
|
|
847
|
+
if (null === spacing) return;
|
|
848
|
+
return 0 === spacing ? DOCX_EXPLICIT_ZERO_CHARACTER_SPACING_SENTINEL : spacing;
|
|
849
|
+
}
|
|
850
|
+
function docxCharacterSpacingTwipsFromProperties(properties) {
|
|
851
|
+
if (!properties) return;
|
|
852
|
+
const spacing = directChildren(properties, 'spacing').filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
853
|
+
if (1 !== spacing.length) return;
|
|
854
|
+
return normalizeDocumentCharacterSpacingTwips(wordValue(spacing[0])) ?? void 0;
|
|
855
|
+
}
|
|
856
|
+
async function patchDocxExplicitZeroCharacterSpacing(buffer) {
|
|
857
|
+
const archive = await jszip.loadAsync(buffer);
|
|
858
|
+
let replacements = 0;
|
|
859
|
+
for (const entry of Object.values(archive.files)){
|
|
860
|
+
if (entry.dir || !CHARACTER_SPACING_PART_PATTERN.test(entry.name)) continue;
|
|
861
|
+
const document = parseXml(decodeXmlBytes(await entry.async('uint8array'), `generated DOCX ${entry.name}`), `generated DOCX ${entry.name}`);
|
|
862
|
+
let changed = false;
|
|
863
|
+
for (const spacing of descendants(document, 'spacing'))if (DOCX_WORDPROCESSING_NAMESPACES.has(spacing.namespaceURI ?? '') && wordValue(spacing) === String(DOCX_EXPLICIT_ZERO_CHARACTER_SPACING_SENTINEL)) {
|
|
864
|
+
setWordValue(spacing, '0');
|
|
865
|
+
replacements += 1;
|
|
866
|
+
changed = true;
|
|
867
|
+
}
|
|
868
|
+
if (changed) archive.file(entry.name, serializeUtf8Xml(document));
|
|
869
|
+
}
|
|
870
|
+
if (!replacements) throw new Error('Generated DOCX explicit-zero character spacing was not emitted.');
|
|
871
|
+
return archive.generateAsync({
|
|
872
|
+
type: 'arraybuffer'
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
function wordValue(element) {
|
|
876
|
+
const values = Array.from(element.attributes).filter((item)=>'val' === xmlAttributeLocalName(item) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, item) ?? ''));
|
|
877
|
+
return 1 === values.length ? values[0].value : null;
|
|
878
|
+
}
|
|
879
|
+
function setWordValue(element, value) {
|
|
880
|
+
const existing = Array.from(element.attributes).find((candidate)=>'val' === candidate.localName && DOCX_WORDPROCESSING_NAMESPACES.has(candidate.namespaceURI ?? ''));
|
|
881
|
+
const namespace = element.namespaceURI ?? '';
|
|
882
|
+
const prefix = element.prefix || 'w';
|
|
883
|
+
if (existing) element.setAttributeNS(existing.namespaceURI, existing.name, value);
|
|
884
|
+
else element.setAttributeNS(namespace, `${prefix}:val`, value);
|
|
885
|
+
}
|
|
886
|
+
const DOCX_EXPLICIT_ZERO_KERNING_THRESHOLD_SENTINEL = 3278;
|
|
887
|
+
const KERNING_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
|
|
888
|
+
function docxKerningThresholdValue(value) {
|
|
889
|
+
const threshold = normalizeDocumentKerningThresholdHalfPoints(value);
|
|
890
|
+
if (null === threshold) return;
|
|
891
|
+
return 0 === threshold ? DOCX_EXPLICIT_ZERO_KERNING_THRESHOLD_SENTINEL : threshold;
|
|
892
|
+
}
|
|
893
|
+
function docxKerningThresholdHalfPointsFromProperties(properties) {
|
|
894
|
+
const inspection = inspectDocxKerningThresholdHalfPoints(properties);
|
|
895
|
+
return 'valid' === inspection.status ? inspection.value : void 0;
|
|
896
|
+
}
|
|
897
|
+
function resolveDocxKerningThresholdHalfPoints(propertySources) {
|
|
898
|
+
let threshold;
|
|
899
|
+
for (const properties of propertySources){
|
|
900
|
+
const candidate = docxKerningThresholdHalfPointsFromProperties(properties);
|
|
901
|
+
if (void 0 !== candidate) threshold = candidate;
|
|
902
|
+
}
|
|
903
|
+
return threshold;
|
|
904
|
+
}
|
|
905
|
+
function inspectDocxKerningThresholdHalfPoints(properties) {
|
|
906
|
+
if (!properties) return {
|
|
907
|
+
status: 'absent'
|
|
908
|
+
};
|
|
909
|
+
const localMatches = directChildren(properties, 'kern');
|
|
910
|
+
if (!localMatches.length) return {
|
|
911
|
+
status: 'absent'
|
|
912
|
+
};
|
|
913
|
+
const nativeMatches = localMatches.filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
914
|
+
if (1 !== localMatches.length || 1 !== nativeMatches.length) return {
|
|
915
|
+
status: 'invalid'
|
|
916
|
+
};
|
|
917
|
+
const kerning = nativeMatches[0];
|
|
918
|
+
if (directChildren(kerning).length || Array.from(kerning.childNodes).some((node)=>(node.nodeType === Node.TEXT_NODE || node.nodeType === Node.CDATA_SECTION_NODE) && Boolean(node.textContent?.trim()))) return {
|
|
919
|
+
status: 'invalid'
|
|
920
|
+
};
|
|
921
|
+
const attributes = Array.from(kerning.attributes).filter((attribute)=>xmlAttributeNamespace(kerning, attribute) !== XMLNS_NAMESPACE && 'xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:'));
|
|
922
|
+
if (1 !== attributes.length || 'val' !== xmlAttributeLocalName(attributes[0]) || !DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(kerning, attributes[0]) ?? '')) return {
|
|
923
|
+
status: 'invalid'
|
|
924
|
+
};
|
|
925
|
+
const value = parseBoundedDocxInteger(attributes[0].value.trim(), {
|
|
926
|
+
minimum: 0,
|
|
927
|
+
maximum: 3277,
|
|
928
|
+
signed: false
|
|
929
|
+
});
|
|
930
|
+
return null === value ? {
|
|
931
|
+
status: 'invalid'
|
|
932
|
+
} : {
|
|
933
|
+
status: 'valid',
|
|
934
|
+
value
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
async function patchDocxExplicitZeroKerningThresholds(buffer) {
|
|
938
|
+
const archive = await jszip.loadAsync(buffer);
|
|
939
|
+
let replacements = 0;
|
|
940
|
+
for (const entry of Object.values(archive.files)){
|
|
941
|
+
if (entry.dir || !KERNING_PART_PATTERN.test(entry.name)) continue;
|
|
942
|
+
const document = parseXml(decodeXmlBytes(await entry.async('uint8array'), `generated DOCX ${entry.name}`), `generated DOCX ${entry.name}`);
|
|
943
|
+
let changed = false;
|
|
944
|
+
for (const kerning of descendants(document, 'kern'))if (DOCX_WORDPROCESSING_NAMESPACES.has(kerning.namespaceURI ?? '') && work_docx_kerning_wordValue(kerning) === String(DOCX_EXPLICIT_ZERO_KERNING_THRESHOLD_SENTINEL)) {
|
|
945
|
+
work_docx_kerning_setWordValue(kerning, '0');
|
|
946
|
+
replacements += 1;
|
|
947
|
+
changed = true;
|
|
948
|
+
}
|
|
949
|
+
if (changed) archive.file(entry.name, serializeUtf8Xml(document));
|
|
950
|
+
}
|
|
951
|
+
if (!replacements) throw new Error('Generated DOCX explicit-zero kerning was not emitted.');
|
|
952
|
+
return archive.generateAsync({
|
|
953
|
+
type: 'arraybuffer'
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
function work_docx_kerning_wordValue(element) {
|
|
957
|
+
const values = Array.from(element.attributes).filter((attribute)=>'val' === xmlAttributeLocalName(attribute) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, attribute) ?? ''));
|
|
958
|
+
return 1 === values.length ? values[0].value : null;
|
|
959
|
+
}
|
|
960
|
+
function work_docx_kerning_setWordValue(element, value) {
|
|
961
|
+
const existing = Array.from(element.attributes).find((attribute)=>'val' === xmlAttributeLocalName(attribute) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, attribute) ?? ''));
|
|
962
|
+
const namespace = element.namespaceURI ?? '';
|
|
963
|
+
const prefix = element.prefix || 'w';
|
|
964
|
+
if (existing) existing.value = value;
|
|
965
|
+
else element.setAttributeNS(namespace, `${prefix}:val`, value);
|
|
966
|
+
}
|
|
967
|
+
function docxEmphasisMarkFromProperties(properties) {
|
|
968
|
+
const inspection = inspectDocxEmphasisMark(properties);
|
|
969
|
+
return 'valid' === inspection.status ? inspection.value : void 0;
|
|
970
|
+
}
|
|
971
|
+
function resolveDocxEmphasisMark(propertySources) {
|
|
972
|
+
let emphasisMark;
|
|
973
|
+
for (const properties of propertySources){
|
|
974
|
+
const candidate = docxEmphasisMarkFromProperties(properties);
|
|
975
|
+
if (void 0 !== candidate) emphasisMark = candidate;
|
|
976
|
+
}
|
|
977
|
+
return emphasisMark;
|
|
978
|
+
}
|
|
979
|
+
function inspectDocxEmphasisMark(properties) {
|
|
980
|
+
if (!properties) return {
|
|
981
|
+
status: 'absent'
|
|
982
|
+
};
|
|
983
|
+
const localMatches = directChildren(properties, 'em');
|
|
984
|
+
if (!localMatches.length) return {
|
|
985
|
+
status: 'absent'
|
|
986
|
+
};
|
|
987
|
+
const nativeMatches = localMatches.filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
|
|
988
|
+
if (1 !== localMatches.length || 1 !== nativeMatches.length) return {
|
|
989
|
+
status: 'invalid'
|
|
990
|
+
};
|
|
991
|
+
const emphasis = nativeMatches[0];
|
|
992
|
+
if (directChildren(emphasis).length || Array.from(emphasis.childNodes).some((node)=>(node.nodeType === Node.TEXT_NODE || node.nodeType === Node.CDATA_SECTION_NODE) && Boolean(node.textContent?.trim()))) return {
|
|
993
|
+
status: 'invalid'
|
|
994
|
+
};
|
|
995
|
+
const attributes = Array.from(emphasis.attributes).filter((attribute)=>xmlAttributeNamespace(emphasis, attribute) !== XMLNS_NAMESPACE && 'xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:'));
|
|
996
|
+
if (1 !== attributes.length || 'val' !== xmlAttributeLocalName(attributes[0]) || !DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(emphasis, attributes[0]) ?? '')) return {
|
|
997
|
+
status: 'invalid'
|
|
998
|
+
};
|
|
999
|
+
const value = normalizeDocumentEmphasisMark(attributes[0].value);
|
|
1000
|
+
return null === value ? {
|
|
1001
|
+
status: 'invalid'
|
|
1002
|
+
} : {
|
|
1003
|
+
status: 'valid',
|
|
1004
|
+
value
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
function docxEmphasisMarkRunOptions(value) {
|
|
1008
|
+
const emphasisMark = normalizeDocumentEmphasisMark(value);
|
|
1009
|
+
if (!emphasisMark) return;
|
|
1010
|
+
return {
|
|
1011
|
+
type: emphasisMark
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
711
1014
|
function paragraphAlignment(element, docx) {
|
|
712
1015
|
const alignment = element.style.textAlign;
|
|
713
1016
|
if ('center' === alignment) return docx.AlignmentType.CENTER;
|
|
@@ -1276,4 +1579,4 @@ function hexFactor(value) {
|
|
|
1276
1579
|
function isDocxThemeResolver(source) {
|
|
1277
1580
|
return Boolean(source && 'colors' in source && source.colors instanceof Map && 'fonts' in source && source.fonts instanceof Map);
|
|
1278
1581
|
}
|
|
1279
|
-
export { DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DocxParagraphDefaultCollapsedPatchCollector, XMLNS_NAMESPACE, XML_NAMESPACE, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, docxThemeColor, docxThemeFont, domDirection, hasNonWhitespaceXmlText, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, patchDocxBibliography, patchDocxParagraphDefaultCollapsed, readDocxBibliography, resolveDocxThemeResolver, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };
|
|
1582
|
+
export { DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DocxParagraphDefaultCollapsedPatchCollector, STRICT_WORDPROCESSING_NAMESPACE, XMLNS_NAMESPACE, XML_NAMESPACE, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, docxCharacterPositionHalfPointsFromProperties, docxCharacterPositionValue, docxCharacterScalePercentFromProperties, docxCharacterScaleValue, docxCharacterSpacingTwipsFromProperties, docxCharacterSpacingValue, docxEmphasisMarkRunOptions, docxKerningThresholdValue, docxThemeColor, docxThemeFont, domDirection, hasNonWhitespaceXmlText, inspectDocxEmphasisMark, inspectDocxKerningThresholdHalfPoints, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseBoundedDocxInteger, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, parseDocxTwipsMeasure, patchDocxBibliography, patchDocxExplicitZeroCharacterSpacing, patchDocxExplicitZeroKerningThresholds, patchDocxParagraphDefaultCollapsed, readDocxBibliography, resolveDocxEmphasisMark, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };
|