@a3s-lab/office 0.11.0 → 0.13.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 (122) hide show
  1. package/README.md +121 -6
  2. package/dist/0~1403.js +20 -12
  3. package/dist/0~2805.js +241 -241
  4. package/dist/0~4980.js +1 -1
  5. package/dist/0~5050.js +1 -20
  6. package/dist/0~5093.js +547 -547
  7. package/dist/0~7048.js +31 -29
  8. package/dist/0~document-editor.js +694 -90
  9. package/dist/0~pdf-viewer.js +41 -10
  10. package/dist/0~presentation-editor.js +8 -6
  11. package/dist/0~spreadsheet-editor.js +4272 -2753
  12. package/dist/0~work-document-import-worker-client.js +237 -0
  13. package/dist/0~work-docx-export.js +1 -1
  14. package/dist/0~work-docx-import.js +3 -3
  15. package/dist/0~work-docx-large-document-import.js +559 -0
  16. package/dist/0~work-office-diagnostics.js +51 -35
  17. package/dist/0~work-pptx-import.js +2 -2
  18. package/dist/4104.js +4127 -3037
  19. package/dist/432.js +51 -7
  20. package/dist/4476.js +280 -69
  21. package/dist/5184.js +24 -2
  22. package/dist/{8928.js → 6282.js} +2338 -93
  23. package/dist/8715.js +1201 -1156
  24. package/dist/9356.js +128 -8
  25. package/dist/core.d.ts +1 -0
  26. package/dist/core.js +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/internal/features/work/editors/document-editor-support.d.ts +1 -9
  29. package/dist/internal/features/work/editors/document-external-content.d.ts +1 -1
  30. package/dist/internal/features/work/editors/presentation-slide-canvas.d.ts +3 -1
  31. package/dist/internal/features/work/editors/presentation-slide-thumbnail.d.ts +3 -2
  32. package/dist/internal/features/work/editors/presentation-thumbnail-rail.d.ts +2 -1
  33. package/dist/internal/features/work/editors/presentation-workspace.d.ts +2 -1
  34. package/dist/internal/features/work/editors/spreadsheet-border-ribbon.d.ts +5 -0
  35. package/dist/internal/features/work/editors/spreadsheet-calculation-projection.d.ts +10 -0
  36. package/dist/internal/features/work/editors/spreadsheet-cell-border-command.d.ts +3 -0
  37. package/dist/internal/features/work/editors/spreadsheet-cell-border.d.ts +14 -0
  38. package/dist/internal/features/work/editors/spreadsheet-cell-fill-command.d.ts +3 -0
  39. package/dist/internal/features/work/editors/spreadsheet-cell-fill.d.ts +12 -0
  40. package/dist/internal/features/work/editors/spreadsheet-cell-range.d.ts +14 -0
  41. package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +159 -0
  42. package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +8 -4
  43. package/dist/internal/features/work/editors/spreadsheet-editor-support.d.ts +8 -1
  44. package/dist/internal/features/work/editors/spreadsheet-home-format-ribbon.d.ts +10 -0
  45. package/dist/internal/features/work/editors/spreadsheet-in-place-workbook-sync.d.ts +10 -0
  46. package/dist/internal/features/work/editors/spreadsheet-operation-projection.d.ts +14 -0
  47. package/dist/internal/features/work/editors/spreadsheet-structure-selection.d.ts +7 -0
  48. package/dist/internal/features/work/editors/use-document-pagination.d.ts +5 -0
  49. package/dist/internal/features/work/editors/use-presentation-design-commands.d.ts +2 -1
  50. package/dist/internal/features/work/editors/use-spreadsheet-collaboration.d.ts +2 -1
  51. package/dist/internal/features/work/editors/use-spreadsheet-workbook-sync.d.ts +2 -1
  52. package/dist/internal/features/work/spreadsheet-history-value.d.ts +1 -0
  53. package/dist/internal/features/work/spreadsheet-sparse.d.ts +10 -0
  54. package/dist/internal/features/work/work-document-chunk-geometry.d.ts +28 -0
  55. package/dist/internal/features/work/work-document-chunk-node.d.ts +23 -0
  56. package/dist/internal/features/work/work-document-extensions.d.ts +1 -0
  57. package/dist/internal/features/work/work-document-file-io.d.ts +2 -1
  58. package/dist/internal/features/work/work-document-html-fingerprint.d.ts +15 -0
  59. package/dist/internal/features/work/work-document-import-worker-client.d.ts +13 -0
  60. package/dist/internal/features/work/work-document-import-worker-protocol.d.ts +36 -0
  61. package/dist/internal/features/work/work-document-import.worker.d.ts +1 -0
  62. package/dist/internal/features/work/work-document-incremental-layout.d.ts +1 -1
  63. package/dist/internal/features/work/work-document-integrity-index.d.ts +14 -0
  64. package/dist/internal/features/work/work-document-lazy-block.d.ts +3 -0
  65. package/dist/internal/features/work/work-document-lazy-html.d.ts +21 -0
  66. package/dist/internal/features/work/work-document-lazy-model.d.ts +29 -0
  67. package/dist/internal/features/work/work-document-lazy-pagination-measurement.d.ts +3 -0
  68. package/dist/internal/features/work/work-document-lazy-preview.d.ts +21 -0
  69. package/dist/internal/features/work/work-document-lazy-update.d.ts +14 -0
  70. package/dist/internal/features/work/work-document-model.d.ts +18 -2
  71. package/dist/internal/features/work/work-document-page-surface-registry.d.ts +16 -0
  72. package/dist/internal/features/work/work-document-pagination-dom.d.ts +1 -0
  73. package/dist/internal/features/work/work-document-pagination-types.d.ts +1 -0
  74. package/dist/internal/features/work/work-document-pagination.d.ts +1 -1
  75. package/dist/internal/features/work/work-document-text-statistics.d.ts +25 -0
  76. package/dist/internal/features/work/work-document-windowing.d.ts +23 -0
  77. package/dist/internal/features/work/work-docx-import.d.ts +2 -1
  78. package/dist/internal/features/work/work-docx-large-document-import.d.ts +35 -0
  79. package/dist/internal/features/work/work-docx-large-document-parser.d.ts +29 -0
  80. package/dist/internal/features/work/work-file-data.d.ts +7 -1
  81. package/dist/internal/features/work/work-file-import.d.ts +33 -0
  82. package/dist/internal/features/work/work-file-io.d.ts +5 -4
  83. package/dist/internal/features/work/work-file-kind.d.ts +5 -0
  84. package/dist/internal/features/work/work-markdown-file-io.d.ts +2 -1
  85. package/dist/internal/features/work/work-office-diagnostics.d.ts +12 -2
  86. package/dist/internal/features/work/work-ooxml-package.d.ts +8 -0
  87. package/dist/internal/features/work/work-pptx-import.d.ts +1 -1
  88. package/dist/internal/features/work/work-presentation-file-io.d.ts +2 -1
  89. package/dist/internal/features/work/work-presentation-layouts.d.ts +7 -1
  90. package/dist/internal/features/work/work-repository.d.ts +1 -0
  91. package/dist/internal/features/work/work-spreadsheet-compatibility-summary.d.ts +10 -0
  92. package/dist/internal/features/work/work-spreadsheet-file-export.d.ts +2 -0
  93. package/dist/internal/features/work/work-spreadsheet-file-import.d.ts +3 -0
  94. package/dist/internal/features/work/work-spreadsheet-import-diagnostics.d.ts +2 -0
  95. package/dist/internal/features/work/work-spreadsheet-import-worker-client.d.ts +6 -0
  96. package/dist/internal/features/work/work-spreadsheet-import-worker-protocol.d.ts +32 -0
  97. package/dist/internal/features/work/work-spreadsheet-import.worker.d.ts +1 -0
  98. package/dist/internal/features/work/work-spreadsheet-matrix-profile.d.ts +64 -0
  99. package/dist/internal/features/work/work-spreadsheet-package-scan-worker-client.d.ts +6 -0
  100. package/dist/internal/features/work/work-spreadsheet-package-scan-worker-protocol.d.ts +49 -0
  101. package/dist/internal/features/work/work-spreadsheet-package-scan.worker.d.ts +1 -0
  102. package/dist/internal/features/work/work-spreadsheet-protection.d.ts +2 -0
  103. package/dist/internal/features/work/work-types.d.ts +22 -0
  104. package/dist/internal/features/work/work-xlsx-formula-diagnostics.d.ts +3 -1
  105. package/dist/internal/features/work/work-xlsx-formulas.d.ts +2 -1
  106. package/dist/internal/features/work/work-xlsx-interop.d.ts +8 -17
  107. package/dist/internal/features/work/work-xlsx-pivot-diagnostics.d.ts +2 -1
  108. package/dist/internal/features/work/work-xlsx-plain-fast-path.d.ts +54 -0
  109. package/dist/internal/features/work/work-xlsx-style-gate.d.ts +1 -0
  110. package/dist/internal/features/work/work-xlsx-worksheet-scan.d.ts +12 -0
  111. package/dist/internal/features/work/work-xlsx-worksheet.d.ts +12 -0
  112. package/dist/office-kernel.wasm +0 -0
  113. package/dist/office-kernel.worker.js +31 -29
  114. package/dist/react.d.ts +7 -1
  115. package/dist/styles.css +440 -3
  116. package/dist/work-document-import.worker.js +558 -0
  117. package/dist/work-spreadsheet-import.worker.js +24745 -0
  118. package/dist/work-spreadsheet-import.worker.js.LICENSE.txt +3 -0
  119. package/dist/work-spreadsheet-package-scan.worker.js +4157 -0
  120. package/dist/work-spreadsheet-package-scan.worker.js.LICENSE.txt +11 -0
  121. package/docs/latest/en/browser-editor-architecture.md +351 -15
  122. package/package.json +26 -4
package/dist/432.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Suspense, createContext, lazy, useCallback, useContext, useEffect, useMemo, useRef } from "react";
3
- import { LoaderCircle } from "lucide-react";
4
3
  import { OfficeCollaborationError as WorkOfficeCollaborationError } from "./9787.js";
5
4
  function StateView({ icon, title, description, descriptionTitle, actions, children, tone = 'neutral', size = 'standard', role, className = '' }) {
6
5
  return /*#__PURE__*/ jsxs("div", {
@@ -34,13 +33,36 @@ function WorkEditorLoadingState({ title }) {
34
33
  className: "work-editor-loading",
35
34
  size: "compact",
36
35
  role: "status",
37
- icon: /*#__PURE__*/ jsx(LoaderCircle, {
38
- className: "spin",
39
- size: 20
40
- }),
36
+ tone: "info",
37
+ icon: /*#__PURE__*/ jsx(EditorLoadingVisual, {}),
41
38
  title: title
42
39
  });
43
40
  }
41
+ function EditorLoadingVisual() {
42
+ return /*#__PURE__*/ jsxs("span", {
43
+ className: "work-editor-loading-visual",
44
+ "aria-hidden": "true",
45
+ children: [
46
+ /*#__PURE__*/ jsx("span", {
47
+ className: "work-editor-loading-focus"
48
+ }),
49
+ /*#__PURE__*/ jsxs("span", {
50
+ className: "work-editor-loading-page",
51
+ children: [
52
+ /*#__PURE__*/ jsx("span", {
53
+ className: "work-editor-loading-line work-editor-loading-line--accent"
54
+ }),
55
+ /*#__PURE__*/ jsx("span", {
56
+ className: "work-editor-loading-line"
57
+ }),
58
+ /*#__PURE__*/ jsx("span", {
59
+ className: "work-editor-loading-line work-editor-loading-line--short"
60
+ })
61
+ ]
62
+ })
63
+ ]
64
+ });
65
+ }
44
66
  const OfficeCollaborationPresenceContext = /*#__PURE__*/ createContext(null);
45
67
  function OfficeCollaborationPresenceProvider({ children, presence }) {
46
68
  const navigatorRef = useRef(null);
@@ -218,8 +240,30 @@ const officeEditorLoaders = {
218
240
  presentation: loadPresentationEditor,
219
241
  pdf: loadPdfViewer
220
242
  };
221
- async function preloadOfficeEditor(kind) {
222
- await officeEditorLoaders[kind]();
243
+ const officeRuntimeAssetPreloads = new Map();
244
+ async function preloadOfficeEditor(kind, options = {}) {
245
+ const editor = officeEditorLoaders[kind]();
246
+ if ('pdf' !== kind || true !== options.preloadRuntimeAssets) return void await editor;
247
+ await Promise.all([
248
+ editor,
249
+ preloadOfficeRuntimeAsset(options.pdfWasmUrl ?? defaultPdfiumWasmUrl)
250
+ ]);
251
+ }
252
+ async function preloadOfficeRuntimeAsset(url) {
253
+ if ("u" < typeof document || 'function' != typeof fetch) return;
254
+ const cached = officeRuntimeAssetPreloads.get(url);
255
+ if (cached) return cached;
256
+ const preload = Promise.resolve().then(()=>fetch(url, {
257
+ cache: 'force-cache',
258
+ credentials: 'same-origin'
259
+ })).then(async (response)=>{
260
+ if (!response.ok) throw new Error(`Unable to preload the Office runtime asset: ${url}`);
261
+ await response.arrayBuffer();
262
+ }).catch(()=>{
263
+ officeRuntimeAssetPreloads.delete(url);
264
+ });
265
+ officeRuntimeAssetPreloads.set(url, preload);
266
+ await preload;
223
267
  }
224
268
  const defaultPdfiumWasmUrl = new URL('./pdfium.wasm', import.meta.url).href;
225
269
  const defaultOfficeKernelWasmUrl = new URL('./office-kernel.wasm', import.meta.url).href;
package/dist/4476.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { initializeWorkOfficeCollaborationMetadata, assertWorkOfficeCollaborationEditable, OfficeCollaborationError as WorkOfficeCollaborationError, readOfficeCollaborationMetadata as readWorkOfficeCollaborationMetadata, registerWorkOfficeCollaborationInitializer, markWorkOfficeCollaborationInitialized, assertWorkOfficeCollaborationOrigin } from "./9787.js";
2
2
  import { OFFICE_KERNEL_SPREADSHEET_MAX_ROWS } from "./5184.js";
3
3
  import { workOfficeCollaborationJsonEqual, canonicalWorkOfficeCollaborationJson, isWorkOfficeCollaborationRecord, cloneWorkOfficeCollaborationJson } from "./4650.js";
4
+ import { sparseMatrixColumnCount, cloneSparseMatrix, sparseArrayEntries as spreadsheet_sparse_sparseArrayEntries, sparseArrayIndexes, formatSpreadsheetCellRanges, parseSpreadsheetCellRanges as work_spreadsheet_ranges_parseSpreadsheetCellRanges } from "./8715.js";
4
5
  import { patchWorkOfficeCollaborationFlatJsonMap, readWorkOfficeCollaborationFlatJsonMap } from "./7060.js";
5
- import { formatSpreadsheetCellRanges, parseSpreadsheetCellRanges } from "./8715.js";
6
6
  import * as __rspack_external_yjs from "yjs";
7
7
  const MAX_POPULATED_CELLS = 1000000;
8
8
  const MAX_DENSE_MATRIX_CELLS = 1000000;
@@ -421,7 +421,7 @@ function assertCompatibleValue(previous, next, shared, label) {
421
421
  function spreadsheetCells(sheet) {
422
422
  const result = new Map();
423
423
  if (void 0 !== sheet.data) {
424
- for (const [row, values] of sheet.data.entries())for (const [column, cell] of values.entries())if (null !== cell) result.set(`${row}:${column}`, cell);
424
+ for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(sheet.data))for (const [column, cell] of spreadsheet_sparse_sparseArrayEntries(values))if (null !== cell) result.set(`${row}:${column}`, cell);
425
425
  return result;
426
426
  }
427
427
  for (const entry of sheet.celldata ?? [])if (null !== entry.v) result.set(`${entry.r}:${entry.c}`, entry.v);
@@ -531,7 +531,7 @@ function spreadsheetCellEntries(sheet) {
531
531
  if (!sheet) return [];
532
532
  const entries = [];
533
533
  if (void 0 !== sheet.data) {
534
- for (const [row, values] of sheet.data.entries())for (const [column, cell] of values.entries())if (null !== cell) entries.push({
534
+ for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(sheet.data))for (const [column, cell] of spreadsheet_sparse_sparseArrayEntries(values))if (null !== cell) entries.push({
535
535
  cell,
536
536
  column,
537
537
  coordinate: encodedCoordinate(row, column),
@@ -1284,6 +1284,195 @@ function assertInitializedSpreadsheetSession(session) {
1284
1284
  if (metadata?.initialized) return;
1285
1285
  throw new WorkOfficeCollaborationError('office.collaboration.not_initialized', 'The Spreadsheet collaboration session has not been initialized.');
1286
1286
  }
1287
+ const spreadsheetFormulaHistoryIgnoredKeys = new Set([
1288
+ 'ct',
1289
+ 'm',
1290
+ 'v'
1291
+ ]);
1292
+ function sameSpreadsheetHistoryValue(left, right) {
1293
+ if (left === right) return true;
1294
+ if (null === left || null === right || typeof left !== typeof right) return false;
1295
+ const leftFormulaCell = spreadsheetFormulaCell(left);
1296
+ const rightFormulaCell = spreadsheetFormulaCell(right);
1297
+ if (leftFormulaCell || rightFormulaCell) return Boolean(leftFormulaCell && rightFormulaCell && sameSpreadsheetFormulaHistoryCell(leftFormulaCell, rightFormulaCell));
1298
+ if (Array.isArray(left) || Array.isArray(right)) {
1299
+ if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;
1300
+ const leftKeys = Object.keys(left).filter((key)=>void 0 !== left[Number(key)]);
1301
+ const rightKeys = Object.keys(right).filter((key)=>void 0 !== right[Number(key)]);
1302
+ return leftKeys.length === rightKeys.length && leftKeys.every((key)=>Object.hasOwn(right, key) && sameSpreadsheetHistoryValue(left[Number(key)], right[Number(key)]));
1303
+ }
1304
+ if ('object' != typeof left || 'object' != typeof right) return false;
1305
+ const leftRecord = left;
1306
+ const rightRecord = right;
1307
+ const leftKeys = Object.keys(leftRecord).filter((key)=>void 0 !== leftRecord[key]);
1308
+ const rightKeys = Object.keys(rightRecord).filter((key)=>void 0 !== rightRecord[key]);
1309
+ return leftKeys.length === rightKeys.length && leftKeys.every((key)=>sameSpreadsheetHistoryValue(leftRecord[key], rightRecord[key]));
1310
+ }
1311
+ function spreadsheetFormulaCell(value) {
1312
+ return value && 'object' == typeof value && 'string' == typeof value.f ? value : null;
1313
+ }
1314
+ function sameSpreadsheetFormulaHistoryCell(left, right) {
1315
+ const leftRecord = left;
1316
+ const rightRecord = right;
1317
+ const leftKeys = Object.keys(leftRecord).filter((key)=>!spreadsheetFormulaHistoryIgnoredKeys.has(key) && void 0 !== leftRecord[key]);
1318
+ const rightKeys = Object.keys(rightRecord).filter((key)=>!spreadsheetFormulaHistoryIgnoredKeys.has(key) && void 0 !== rightRecord[key]);
1319
+ return leftKeys.length === rightKeys.length && leftKeys.every((key)=>sameSpreadsheetHistoryValue(leftRecord[key], rightRecord[key])) && sameSpreadsheetHistoryValue(spreadsheetFormulaHistoryCellType(left.ct), spreadsheetFormulaHistoryCellType(right.ct));
1320
+ }
1321
+ function spreadsheetFormulaHistoryCellType(cellType) {
1322
+ if (!cellType) return;
1323
+ const { fa, t: _type, ...retainedCellType } = cellType;
1324
+ const normalized = {
1325
+ ...retainedCellType,
1326
+ ...fa && 'General' !== fa ? {
1327
+ fa
1328
+ } : {}
1329
+ };
1330
+ return Object.keys(normalized).length ? normalized : void 0;
1331
+ }
1332
+ const SPREADSHEET_SHOWN_COMMENT_CELLS_PROPERTY = '__a3sShownCommentCells';
1333
+ const spreadsheetMatrixProfiles = new WeakMap();
1334
+ function freezeImportedSpreadsheetCell(cell) {
1335
+ freezeObject(cell.mc);
1336
+ freezeObject(cell.ct?.s);
1337
+ freezeObject(cell.ct);
1338
+ freezeObject(cell.ps);
1339
+ freezeObject(cell.hl);
1340
+ freezeObject(cell.spl);
1341
+ return Object.freeze(cell);
1342
+ }
1343
+ function registerImportedSpreadsheetMatrix(data, options) {
1344
+ data.length = Math.max(data.length, options.rowCount);
1345
+ data[0] ??= [];
1346
+ for (const rowIndex of sparseArrayIndexes(data)){
1347
+ const row = data[rowIndex];
1348
+ if (row) {
1349
+ row.length = Math.max(row.length, options.columnCount);
1350
+ Object.freeze(row);
1351
+ }
1352
+ }
1353
+ registerSpreadsheetMatrixProfile(data, options);
1354
+ }
1355
+ function registerDerivedSpreadsheetMatrix(data, source, changes) {
1356
+ const sourceProfile = spreadsheetMatrixProfiles.get(source);
1357
+ if (!sourceProfile?.fortuneReady) return false;
1358
+ const formulaCells = new Map(sourceProfile.formulaCells.map(({ column, row })=>[
1359
+ spreadsheetCoordinateKey(row, column),
1360
+ {
1361
+ column,
1362
+ row
1363
+ }
1364
+ ]));
1365
+ const shownCommentCells = new Map(sourceProfile.shownCommentCells.map(({ c, r })=>[
1366
+ spreadsheetCoordinateKey(r, c),
1367
+ {
1368
+ c,
1369
+ r
1370
+ }
1371
+ ]));
1372
+ let populatedCellCount = sourceProfile.populatedCellCount;
1373
+ let protectionCellKey = sourceProfile.protectionCellKey;
1374
+ let protectionCells;
1375
+ for (const { column, current, previous, row } of changes){
1376
+ const coordinateKey = spreadsheetCoordinateKey(row, column);
1377
+ if (null == previous && null != current) populatedCellCount += 1;
1378
+ if (null != previous && null == current) populatedCellCount -= 1;
1379
+ if (current?.f) formulaCells.set(coordinateKey, {
1380
+ column,
1381
+ row
1382
+ });
1383
+ else formulaCells.delete(coordinateKey);
1384
+ if (current?.ps?.isShow) shownCommentCells.set(coordinateKey, {
1385
+ c: column,
1386
+ r: row
1387
+ });
1388
+ else shownCommentCells.delete(coordinateKey);
1389
+ if (spreadsheetProtectionSignature(previous) !== spreadsheetProtectionSignature(current)) {
1390
+ protectionCells ??= spreadsheetProtectionCells(protectionCellKey);
1391
+ const signature = spreadsheetProtectionSignature(current);
1392
+ if (null === signature) protectionCells.delete(coordinateKey);
1393
+ else protectionCells.set(coordinateKey, signature);
1394
+ }
1395
+ const changedRow = data[row];
1396
+ if (changedRow && !Object.isFrozen(changedRow)) Object.freeze(changedRow);
1397
+ }
1398
+ if (protectionCells) protectionCellKey = Array.from(protectionCells, ([coordinate, value])=>({
1399
+ coordinate,
1400
+ value
1401
+ })).sort((left, right)=>compareSpreadsheetCoordinates(left.coordinate, right.coordinate)).map(({ coordinate, value })=>`${coordinate}:${value}`).join(',');
1402
+ registerSpreadsheetMatrixProfile(data, {
1403
+ columnCount: Math.max(sourceProfile.columnCount, ...changes.map(({ column, row })=>Math.max(column + 1, data[row]?.length ?? 0))),
1404
+ formulaCells: Array.from(formulaCells.values()).sort(compareSpreadsheetCells),
1405
+ fortuneReady: true,
1406
+ populatedCellCount: Math.max(0, populatedCellCount),
1407
+ protectionCellKey,
1408
+ rowCount: Math.max(sourceProfile.rowCount, data.length, ...changes.map(({ row })=>row + 1)),
1409
+ shownCommentCells: Array.from(shownCommentCells.values()).sort((left, right)=>left.r - right.r || left.c - right.c)
1410
+ }, {
1411
+ historyRoot: sourceProfile.historyRoot,
1412
+ historyState: changes.some(({ current, previous })=>!sameSpreadsheetHistoryValue(current, previous)) ? Object.freeze({}) : sourceProfile.historyState
1413
+ });
1414
+ return true;
1415
+ }
1416
+ function spreadsheetMatrixProfile(data) {
1417
+ return data ? spreadsheetMatrixProfiles.get(data) : void 0;
1418
+ }
1419
+ function attachSpreadsheetShownCommentCells(data, cells) {
1420
+ Object.defineProperty(data, SPREADSHEET_SHOWN_COMMENT_CELLS_PROPERTY, {
1421
+ configurable: false,
1422
+ enumerable: false,
1423
+ value: cells,
1424
+ writable: false
1425
+ });
1426
+ }
1427
+ function registerSpreadsheetMatrixProfile(data, options, history) {
1428
+ const initialHistoryState = Object.freeze({});
1429
+ const profile = Object.freeze({
1430
+ columnCount: options.columnCount,
1431
+ formulaCells: Object.freeze(options.formulaCells.map((cell)=>Object.freeze({
1432
+ ...cell
1433
+ }))),
1434
+ fortuneReady: options.fortuneReady,
1435
+ historyRoot: history?.historyRoot ?? initialHistoryState,
1436
+ historyState: history?.historyState ?? initialHistoryState,
1437
+ populatedCellCount: options.populatedCellCount,
1438
+ protectionCellKey: options.protectionCellKey,
1439
+ rowCount: options.rowCount,
1440
+ shownCommentCells: Object.freeze(options.shownCommentCells.map((cell)=>Object.freeze({
1441
+ ...cell
1442
+ })))
1443
+ });
1444
+ attachSpreadsheetShownCommentCells(data, profile.shownCommentCells);
1445
+ Object.freeze(data);
1446
+ spreadsheetMatrixProfiles.set(data, profile);
1447
+ }
1448
+ function spreadsheetProtectionCells(value) {
1449
+ const cells = new Map();
1450
+ for (const entry of value.split(',')){
1451
+ if (!entry) continue;
1452
+ const separator = entry.indexOf(':');
1453
+ if (!(separator <= 0)) cells.set(entry.slice(0, separator), entry.slice(separator + 1));
1454
+ }
1455
+ return cells;
1456
+ }
1457
+ function spreadsheetProtectionSignature(cell) {
1458
+ const hidden = cell?.hi;
1459
+ if (cell?.lo === void 0 && void 0 === hidden) return null;
1460
+ return `${cell?.lo ?? ''}:${hidden ?? ''}`;
1461
+ }
1462
+ function spreadsheetCoordinateKey(row, column) {
1463
+ return `${row}_${column}`;
1464
+ }
1465
+ function compareSpreadsheetCoordinates(left, right) {
1466
+ const [leftRow = 0, leftColumn = 0] = left.split('_').map(Number);
1467
+ const [rightRow = 0, rightColumn = 0] = right.split('_').map(Number);
1468
+ return leftRow - rightRow || leftColumn - rightColumn;
1469
+ }
1470
+ function compareSpreadsheetCells(left, right) {
1471
+ return left.row - right.row || left.column - right.column;
1472
+ }
1473
+ function freezeObject(value) {
1474
+ if (value && 'object' == typeof value) Object.freeze(value);
1475
+ }
1287
1476
  const DEFAULT_PROTECTION_HINT = '此工作表已受保护。若要更改锁定的单元格,请先取消工作表保护。';
1288
1477
  function defaultSheetProtectionAuthority(enabled = false) {
1289
1478
  return {
@@ -1305,7 +1494,8 @@ function defaultSheetProtectionAuthority(enabled = false) {
1305
1494
  editScenarios: 0,
1306
1495
  hintText: '',
1307
1496
  defaultSheetHintText: DEFAULT_PROTECTION_HINT,
1308
- allowRangeList: []
1497
+ allowRangeList: [],
1498
+ cellProtectionRanges: []
1309
1499
  };
1310
1500
  }
1311
1501
  function sheetProtectionAuthority(sheet) {
@@ -1335,9 +1525,23 @@ function normalizeSheetProtectionAuthority(source) {
1335
1525
  hintText: stringValue(authority.hintText),
1336
1526
  defaultSheetHintText: stringValue(authority.defaultSheetHintText) || DEFAULT_PROTECTION_HINT,
1337
1527
  allowRangeList: editableRangeList(authority.allowRangeList),
1528
+ cellProtectionRanges: cellProtectionRangeList(authority.cellProtectionRanges),
1338
1529
  xlsxAttributes: stringRecord(authority.xlsxAttributes)
1339
1530
  };
1340
1531
  }
1532
+ function importedSheetProtectionAuthority(authority, cellProtectionRanges) {
1533
+ if (!authority && !cellProtectionRanges.length) return;
1534
+ const normalized = normalizeSheetProtectionAuthority(authority);
1535
+ normalized.cellProtectionRanges = [
1536
+ ...cellProtectionRanges,
1537
+ ...normalized.allowRangeList.filter((range)=>!editableRangeRequiresCredentials(range)).flatMap((range)=>work_spreadsheet_ranges_parseSpreadsheetCellRanges(range.sqref) ?? []).map((range)=>({
1538
+ range,
1539
+ locked: false,
1540
+ hidden: false
1541
+ }))
1542
+ ];
1543
+ return normalized;
1544
+ }
1341
1545
  function withSheetProtection(sheet, enabled) {
1342
1546
  const authority = sheetProtectionAuthority(sheet);
1343
1547
  authority.sheet = enabled ? 1 : 0;
@@ -1359,73 +1563,56 @@ function withEditableRange(sheet, index, editableRange) {
1359
1563
  };
1360
1564
  if (null !== index && authority.allowRangeList[index]) authority.allowRangeList[index] = nextRange;
1361
1565
  else authority.allowRangeList.push(nextRange);
1362
- const ranges = parseSpreadsheetCellRanges(nextRange.sqref) ?? [];
1363
- return withAuthority(withCellProtection(sheet, ranges, false), authority);
1566
+ const ranges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(nextRange.sqref) ?? [];
1567
+ const next = withCellProtection(sheet, ranges, false);
1568
+ const nextAuthority = sheetProtectionAuthority(next);
1569
+ nextAuthority.allowRangeList = authority.allowRangeList;
1570
+ return withAuthority(next, nextAuthority);
1364
1571
  }
1365
1572
  function withoutEditableRange(sheet, index) {
1366
1573
  const authority = sheetProtectionAuthority(sheet);
1367
1574
  const removed = authority.allowRangeList[index];
1368
1575
  if (!removed) return sheet;
1369
1576
  authority.allowRangeList.splice(index, 1);
1370
- const removedRanges = parseSpreadsheetCellRanges(removed.sqref) ?? [];
1577
+ const removedRanges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(removed.sqref) ?? [];
1371
1578
  let next = withCellProtection(sheet, removedRanges, true);
1372
- for (const editableRange of authority.allowRangeList)if (!editableRangeRequiresCredentials(editableRange)) next = withCellProtection(next, parseSpreadsheetCellRanges(editableRange.sqref) ?? [], false);
1373
- return withAuthority(next, authority);
1579
+ for (const editableRange of authority.allowRangeList)if (!editableRangeRequiresCredentials(editableRange)) next = withCellProtection(next, work_spreadsheet_ranges_parseSpreadsheetCellRanges(editableRange.sqref) ?? [], false);
1580
+ const nextAuthority = sheetProtectionAuthority(next);
1581
+ nextAuthority.allowRangeList = authority.allowRangeList;
1582
+ return withAuthority(next, nextAuthority);
1374
1583
  }
1375
1584
  function withCellProtection(sheet, ranges, locked, hidden = false) {
1376
1585
  if (!ranges.length) return sheet;
1377
- const data = cloneMatrix(sheet.data);
1586
+ const data = cloneSparseMatrix(sheet.data);
1378
1587
  let rowCount = Math.max(sheet.row ?? 0, data.length);
1379
- let columnCount = Math.max(sheet.column ?? 0, ...data.map((row)=>row.length));
1588
+ let columnCount = Math.max(sheet.column ?? 0, sparseMatrixColumnCount(data));
1380
1589
  for (const range of ranges){
1381
1590
  rowCount = Math.max(rowCount, range.row[1] + 1);
1382
1591
  columnCount = Math.max(columnCount, range.column[1] + 1);
1383
- for(let row = range.row[0]; row <= range.row[1]; row += 1){
1384
- data[row] ??= [];
1385
- for(let column = range.column[0]; column <= range.column[1]; column += 1){
1386
- const cell = {
1387
- ...data[row][column] ?? {}
1388
- };
1389
- cell.lo = locked ? 1 : 0;
1390
- if (hidden) cell.hi = 1;
1391
- else if (void 0 !== cell.hi) delete cell.hi;
1392
- data[row][column] = cell;
1393
- }
1592
+ for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(data))if (!(row < range.row[0]) && !(row > range.row[1])) for (const [column, source] of spreadsheet_sparse_sparseArrayEntries(values)){
1593
+ if (column < range.column[0] || column > range.column[1]) continue;
1594
+ const cell = {
1595
+ ...source ?? {}
1596
+ };
1597
+ cell.lo = locked ? 1 : 0;
1598
+ if (hidden) cell.hi = 1;
1599
+ else if (void 0 !== cell.hi) delete cell.hi;
1600
+ data[row][column] = cell;
1394
1601
  }
1395
1602
  }
1396
1603
  normalizeMatrix(data, rowCount, columnCount);
1397
- return {
1604
+ const authority = sheetProtectionAuthority(sheet);
1605
+ authority.cellProtectionRanges.push(...ranges.map((range)=>({
1606
+ range,
1607
+ locked,
1608
+ hidden
1609
+ })));
1610
+ return withAuthority({
1398
1611
  ...sheet,
1399
1612
  row: rowCount,
1400
1613
  column: columnCount,
1401
1614
  data
1402
- };
1403
- }
1404
- function applySpreadsheetCellProtectionRanges(data, ranges, rowCount, columnCount) {
1405
- for (const item of ranges){
1406
- const lastRow = Math.min(item.range.row[1], rowCount - 1);
1407
- const lastColumn = Math.min(item.range.column[1], columnCount - 1);
1408
- for(let row = Math.max(0, item.range.row[0]); row <= lastRow; row += 1){
1409
- data[row] ??= [];
1410
- for(let column = Math.max(0, item.range.column[0]); column <= lastColumn; column += 1){
1411
- const cell = {
1412
- ...data[row][column] ?? {}
1413
- };
1414
- cell.lo = item.locked ? 1 : 0;
1415
- if (item.hidden) cell.hi = 1;
1416
- else if (void 0 !== cell.hi) delete cell.hi;
1417
- data[row][column] = cell;
1418
- }
1419
- }
1420
- }
1421
- }
1422
- function applyPasswordlessEditableRanges(data, ranges, rowCount, columnCount) {
1423
- const protectionRanges = ranges.filter((range)=>!editableRangeRequiresCredentials(range)).flatMap((range)=>parseSpreadsheetCellRanges(range.sqref) ?? []).map((range)=>({
1424
- range,
1425
- locked: false,
1426
- hidden: false
1427
- }));
1428
- applySpreadsheetCellProtectionRanges(data, protectionRanges, rowCount, columnCount);
1615
+ }, authority);
1429
1616
  }
1430
1617
  function editableRangeRequiresCredentials(range) {
1431
1618
  const attributes = range.xlsxAttributes ?? {};
@@ -1445,12 +1632,17 @@ function unlockedCellCount(sheet) {
1445
1632
  function spreadsheetProtectionKey(sheets) {
1446
1633
  return sheets.map((sheet)=>{
1447
1634
  const authority = sheetProtectionAuthority(sheet);
1448
- const cells = [];
1449
- for (const [row, values] of (sheet.data ?? []).entries())for (const [column, cell] of values.entries()){
1450
- const hidden = cell?.hi;
1451
- if (cell?.lo !== void 0 || void 0 !== hidden) cells.push(`${row}_${column}:${cell?.lo ?? ''}:${hidden ?? ''}`);
1635
+ const profile = spreadsheetMatrixProfile(sheet.data);
1636
+ let protectionCellKey = profile?.protectionCellKey;
1637
+ if (void 0 === protectionCellKey) {
1638
+ const cells = [];
1639
+ for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(sheet.data))for (const [column, cell] of spreadsheet_sparse_sparseArrayEntries(values)){
1640
+ const hidden = cell?.hi;
1641
+ if (cell?.lo !== void 0 || void 0 !== hidden) cells.push(`${row}_${column}:${cell?.lo ?? ''}:${hidden ?? ''}`);
1642
+ }
1643
+ protectionCellKey = cells.join(',');
1452
1644
  }
1453
- return `${sheet.id ?? sheet.name}:${JSON.stringify(authority)}:${cells.join(',')}`;
1645
+ return `${sheet.id ?? sheet.name}:${JSON.stringify(authority)}:${protectionCellKey}`;
1454
1646
  }).join('|');
1455
1647
  }
1456
1648
  function editableRangeCellCount(ranges) {
@@ -1471,7 +1663,7 @@ function editableRangeList(value) {
1471
1663
  if (!item || 'object' != typeof item) return [];
1472
1664
  const range = item;
1473
1665
  const sqref = stringValue(range.sqref);
1474
- if (!sqref || !parseSpreadsheetCellRanges(sqref)) return [];
1666
+ if (!sqref || !work_spreadsheet_ranges_parseSpreadsheetCellRanges(sqref)) return [];
1475
1667
  return [
1476
1668
  {
1477
1669
  name: stringValue(range.name) || `Range ${index + 1}`,
@@ -1483,21 +1675,40 @@ function editableRangeList(value) {
1483
1675
  });
1484
1676
  }
1485
1677
  function canonicalRangeReference(value) {
1486
- const ranges = parseSpreadsheetCellRanges(value);
1678
+ const ranges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(value);
1487
1679
  return ranges ? formatSpreadsheetCellRanges(ranges) : value.trim();
1488
1680
  }
1489
- function cloneMatrix(source) {
1490
- return (source ?? []).map((row)=>[
1491
- ...row
1492
- ]);
1493
- }
1494
1681
  function normalizeMatrix(data, rows, columns) {
1495
- while(data.length < rows)data.push([]);
1496
- for(let index = 0; index < data.length; index += 1){
1497
- const row = data[index] ?? [];
1498
- data[index] = row;
1499
- while(row.length < columns)row.push(null);
1500
- }
1682
+ data.length = Math.max(data.length, rows);
1683
+ for (const [, row] of spreadsheet_sparse_sparseArrayEntries(data))row.length = Math.max(row.length, columns);
1684
+ }
1685
+ function cellProtectionRangeList(value) {
1686
+ if (!Array.isArray(value)) return [];
1687
+ return value.flatMap((item)=>{
1688
+ if (!item || 'object' != typeof item) return [];
1689
+ const candidate = item;
1690
+ const range = candidate.range;
1691
+ if (!range || !Array.isArray(range.row) || !Array.isArray(range.column) || range.row.length < 2 || range.column.length < 2 || ![
1692
+ ...range.row,
1693
+ ...range.column
1694
+ ].every((index)=>Number.isSafeInteger(index) && index >= 0)) return [];
1695
+ return [
1696
+ {
1697
+ range: {
1698
+ row: [
1699
+ Math.min(range.row[0], range.row[1]),
1700
+ Math.max(range.row[0], range.row[1])
1701
+ ],
1702
+ column: [
1703
+ Math.min(range.column[0], range.column[1]),
1704
+ Math.max(range.column[0], range.column[1])
1705
+ ]
1706
+ },
1707
+ locked: false !== candidate.locked,
1708
+ hidden: true === candidate.hidden
1709
+ }
1710
+ ];
1711
+ });
1501
1712
  }
1502
1713
  function flag(value, fallback) {
1503
1714
  if (1 === value || true === value || '1' === value) return 1;
@@ -2005,4 +2216,4 @@ function boundedInteger(value, minimum, maximum, fallback) {
2005
2216
  function boundedNumber(value, minimum, maximum, fallback) {
2006
2217
  return 'number' == typeof value && Number.isFinite(value) && value >= minimum && value <= maximum ? value : fallback;
2007
2218
  }
2008
- export { DEFAULT_PROTECTION_HINT, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, SPREADSHEET_CONDITIONAL_ICON_SETS, applyPasswordlessEditableRanges, applySpreadsheetCellProtectionRanges, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, defaultSpreadsheetColorScaleThresholds, defaultSpreadsheetConditionalIconThresholds, defaultSpreadsheetDataBarOptions, drawSpreadsheetConditionalIcon, editableRangeCellCount, editableRangeRequiresCredentials, effectiveSpreadsheetPageSetup, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isSpreadsheetConditionalComparisonOperator, isSpreadsheetConditionalIconSetName, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetPaperSize, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sheetHasProtectionState, sheetProtectionAuthority, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetProtectionKey, unlockedCellCount, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withoutEditableRange };
2219
+ export { DEFAULT_PROTECTION_HINT, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, SPREADSHEET_CONDITIONAL_ICON_SETS, attachSpreadsheetShownCommentCells, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, defaultSpreadsheetColorScaleThresholds, defaultSpreadsheetConditionalIconThresholds, defaultSpreadsheetDataBarOptions, drawSpreadsheetConditionalIcon, editableRangeCellCount, editableRangeRequiresCredentials, effectiveSpreadsheetPageSetup, freezeImportedSpreadsheetCell, importedSheetProtectionAuthority, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isSpreadsheetConditionalComparisonOperator, isSpreadsheetConditionalIconSetName, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetPaperSize, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, registerDerivedSpreadsheetMatrix, registerImportedSpreadsheetMatrix, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sameSpreadsheetHistoryValue, sheetHasProtectionState, sheetProtectionAuthority, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetMatrixProfile, spreadsheetProtectionKey, unlockedCellCount, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withoutEditableRange };
package/dist/5184.js CHANGED
@@ -470,6 +470,7 @@ function serializeUtf8Xml(document) {
470
470
  }
471
471
  class OoxmlPackage {
472
472
  zip;
473
+ textCache = new Map();
473
474
  constructor(zip){
474
475
  this.zip = zip;
475
476
  }
@@ -483,9 +484,18 @@ class OoxmlPackage {
483
484
  return Object.keys(this.zip.files).filter((path)=>path.startsWith(prefix) && !this.zip.files[path]?.dir);
484
485
  }
485
486
  async text(partPath) {
487
+ const cached = this.textCache.get(partPath);
488
+ if (cached) return cached;
486
489
  const entry = this.zip.file(partPath);
487
490
  if (!entry) throw new Error(`Office package part is missing: ${partPath}`);
488
- return decodeXmlBytes(await entry.async('uint8array'), partPath);
491
+ const pending = entry.async('uint8array').then((bytes)=>decodeXmlBytes(bytes, partPath));
492
+ this.textCache.set(partPath, pending);
493
+ try {
494
+ return await pending;
495
+ } catch (error) {
496
+ this.textCache.delete(partPath);
497
+ throw error;
498
+ }
489
499
  }
490
500
  async xml(partPath) {
491
501
  return parseXml(await this.text(partPath), partPath);
@@ -519,6 +529,18 @@ function parseXml(source, label = 'Office XML') {
519
529
  if (error) throw new Error(`${label} is not valid XML: ${error.textContent?.trim() || 'parse error'}`);
520
530
  return document;
521
531
  }
532
+ const xmlElementPatterns = new Map();
533
+ function xmlContainsAnyElement(source, localNames) {
534
+ if (!source || !localNames.length) return false;
535
+ const key = localNames.join('\u0000');
536
+ let pattern = xmlElementPatterns.get(key);
537
+ if (!pattern) {
538
+ const alternatives = localNames.map((name)=>name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
539
+ pattern = new RegExp(`<(?:[A-Za-z_][\\w.-]*:)?(?:${alternatives})(?=[\\s/>])`);
540
+ xmlElementPatterns.set(key, pattern);
541
+ }
542
+ return pattern.test(source);
543
+ }
522
544
  function attribute(element, name) {
523
545
  const direct = element.getAttribute(name);
524
546
  if (null !== direct) return direct;
@@ -624,4 +646,4 @@ new TextEncoder();
624
646
  function isOfficeKernelSpreadsheetError(value) {
625
647
  return 'string' == typeof value && spreadsheetErrors.has(value);
626
648
  }
627
- export { OFFICE_KERNEL_SPREADSHEET_MAX_ROWS, OoxmlPackage, WORK_TEMPLATES as officeTemplates, attribute, bytesToDataUrl, childPath, contentTypeForPart, createWorkArtifact as createArtifact, createWorkId as createOfficeId, decodeXmlBytes, descendants, directChild, directChildren, firstDescendant, isOfficeKernelSpreadsheetError, parseXml, resolvePartTarget, serializeUtf8Xml, xmlNamespacePrefix };
649
+ export { OFFICE_KERNEL_SPREADSHEET_MAX_ROWS, OoxmlPackage, WORK_TEMPLATES as officeTemplates, attribute, bytesToDataUrl, childPath, contentTypeForPart, createWorkArtifact as createArtifact, createWorkId as createOfficeId, decodeXmlBytes, descendants, directChild, directChildren, firstDescendant, isOfficeKernelSpreadsheetError, parseXml, resolvePartTarget, serializeUtf8Xml, xmlContainsAnyElement, xmlNamespacePrefix };