@a3s-lab/office 0.37.0 → 0.37.2

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 (59) hide show
  1. package/README.md +282 -1544
  2. package/dist/0~3557.js +2 -1
  3. package/dist/0~3635.js +4 -1
  4. package/dist/0~9073.js +9 -4
  5. package/dist/0~controlled-editor-composition.js +54 -0
  6. package/dist/0~document-editor.js +60 -10
  7. package/dist/0~markdown-editor.js +62 -21
  8. package/dist/0~presentation-editor.js +83 -21
  9. package/dist/0~spreadsheet-editor.js +17010 -13958
  10. package/dist/{3266.js → 5416.js} +1139 -15
  11. package/dist/9333.js +1 -1
  12. package/dist/core.d.ts +1 -0
  13. package/dist/core.js +112 -26
  14. package/dist/index.js +1 -1
  15. package/dist/internal/features/work/editors/controlled-editor-composition.d.ts +20 -0
  16. package/dist/internal/features/work/editors/office-shortcuts.d.ts +1 -0
  17. package/dist/internal/features/work/editors/spreadsheet-auto-filter-command.d.ts +3 -0
  18. package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog-model.d.ts +27 -0
  19. package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog.d.ts +17 -0
  20. package/dist/internal/features/work/editors/spreadsheet-auto-filter-menu.d.ts +10 -0
  21. package/dist/internal/features/work/editors/spreadsheet-auto-filter.d.ts +16 -4
  22. package/dist/internal/features/work/editors/spreadsheet-cell-range.d.ts +1 -0
  23. package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +9 -0
  24. package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +13 -1
  25. package/dist/internal/features/work/editors/spreadsheet-current-region.d.ts +12 -0
  26. package/dist/internal/features/work/editors/spreadsheet-editor-support.d.ts +1 -0
  27. package/dist/internal/features/work/editors/spreadsheet-editor.d.ts +5 -1
  28. package/dist/internal/features/work/editors/spreadsheet-sort-appearance.d.ts +45 -0
  29. package/dist/internal/features/work/editors/spreadsheet-sort-collation.d.ts +8 -0
  30. package/dist/internal/features/work/editors/spreadsheet-sort-command.d.ts +3 -0
  31. package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-editor.d.ts +8 -0
  32. package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-store.d.ts +13 -0
  33. package/dist/internal/features/work/editors/spreadsheet-sort-custom-list.d.ts +26 -0
  34. package/dist/internal/features/work/editors/spreadsheet-sort-dialog.d.ts +9 -0
  35. package/dist/internal/features/work/editors/spreadsheet-sort-matrix.d.ts +4 -0
  36. package/dist/internal/features/work/editors/spreadsheet-sort-options-dialog.d.ts +7 -0
  37. package/dist/internal/features/work/editors/spreadsheet-sort-order-controls.d.ts +16 -0
  38. package/dist/internal/features/work/editors/spreadsheet-sort-range-dialog.d.ts +7 -0
  39. package/dist/internal/features/work/editors/spreadsheet-sort.d.ts +138 -0
  40. package/dist/internal/features/work/editors/use-document-review-conflicts.d.ts +3 -1
  41. package/dist/internal/features/work/editors/use-spreadsheet-auto-filter.d.ts +12 -3
  42. package/dist/internal/features/work/editors/use-spreadsheet-sort.d.ts +26 -0
  43. package/dist/internal/features/work/editors/work-office-chrome.d.ts +3 -0
  44. package/dist/internal/features/work/work-spreadsheet-auto-filter.d.ts +14 -0
  45. package/dist/internal/features/work/work-spreadsheet-dynamic-filter.d.ts +7 -0
  46. package/dist/internal/features/work/work-spreadsheet-filter-contract.d.ts +3 -0
  47. package/dist/internal/features/work/work-spreadsheet-wildcard.d.ts +7 -0
  48. package/dist/internal/features/work/work-types.d.ts +31 -7
  49. package/dist/internal/features/work/work-xlsx-interop.d.ts +2 -1
  50. package/dist/internal/features/work/work-xlsx-table-filters.d.ts +3 -1
  51. package/dist/office-kernel.wasm +0 -0
  52. package/dist/styles.css +544 -20
  53. package/dist/vue.d.ts +3 -1
  54. package/dist/vue.js +2 -0
  55. package/dist/web-component.d.ts +3 -1
  56. package/dist/web-component.js +9 -0
  57. package/dist/work-spreadsheet-package-scan.worker.js +2 -1
  58. package/docs/latest/en/browser-editor-architecture.md +144 -0
  59. package/package.json +22 -1
@@ -3985,6 +3985,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
3985
3985
  }
3986
3986
  const IMPORTED_WORKSHEET_ELEMENTS = new Set([
3987
3987
  'pane',
3988
+ 'autoFilter',
3988
3989
  'dataValidation',
3989
3990
  'conditionalFormatting',
3990
3991
  'sheetProtection',
@@ -4012,7 +4013,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
4012
4013
  'rowBreaks',
4013
4014
  'colBreaks'
4014
4015
  ]);
4015
- const WORKSHEET_SCAN_PATTERN = /<(?:[A-Za-z_][\w.-]*:)?(?:(cols|f|pane|dataValidation|conditionalFormatting|sheetProtection|protectedRange|rowBreaks|colBreaks|pageSetup|pageMargins|printOptions|headerFooter|pageSetUpPr|drawing|tableParts)(?=[\s/>])|(row)(?=[\s/>])[^>]*\s(?:collapsed|customFormat|customHeight|hidden|ht|outlineLevel|thickBot|thickTop)\s*=|(c)(?=[\s/>])[^>]*\ss\s*=|(r)(?=[\s/>]))/g;
4016
+ const WORKSHEET_SCAN_PATTERN = /<(?:[A-Za-z_][\w.-]*:)?(?:(cols|f|pane|autoFilter|dataValidation|conditionalFormatting|sheetProtection|protectedRange|rowBreaks|colBreaks|pageSetup|pageMargins|printOptions|headerFooter|pageSetUpPr|drawing|tableParts)(?=[\s/>])|(row)(?=[\s/>])[^>]*\s(?:collapsed|customFormat|customHeight|hidden|ht|outlineLevel|thickBot|thickTop)\s*=|(c)(?=[\s/>])[^>]*\ss\s*=|(r)(?=[\s/>]))/g;
4016
4017
  function scanXlsxWorksheetXml(source) {
4017
4018
  let hasDirectCellStyles = false;
4018
4019
  let hasDiagnosticFeatures = false;
@@ -644,6 +644,22 @@ The shell never searches visible labels, scrapes rendered text, or synthesizes
644
644
  clicks to infer product intent. This keeps localized UI copy independent from
645
645
  behavior and gives Worker/WASM operations a stable request contract.
646
646
 
647
+ ## Controlled rich-text IME boundary
648
+
649
+ Document body text, visual Markdown, and Presentation text share one internal
650
+ composition coordinator. `compositionstart` blocks host publication and
651
+ controlled-value reconciliation. `compositionend` schedules settlement after
652
+ the current task so ProseMirror can flush WebKit's pending DOM observer records;
653
+ bounded 20 ms retries cover runtimes that briefly retain `view.composing`.
654
+ Only the settled canonical value is published, and an authoritative host value
655
+ received during composition is reconciled afterward.
656
+
657
+ The coordinator creates no timers or extra renders for ordinary keyboard input.
658
+ Focused component tests cover controlled echo and mid-composition host
659
+ replacement. A dedicated Playwright WebKit gate exercises the browser event
660
+ ordering, asserts zero publications for Pinyin pre-edit text, one publication
661
+ for the committed Chinese value, and the same value after a controlled reopen.
662
+
647
663
  ## Markdown editing flow
648
664
 
649
665
  ```text
@@ -1439,6 +1455,134 @@ changes, and table renames; and `totalsRowFunction`, `totalsRowLabel`, and
1439
1455
  protected, overlapping, AutoFilter, unsafe, external, and over-budget targets
1440
1456
  fail closed. Slicers and external/query tables remain open gates.
1441
1457
 
1458
+ Value-based multi-key Custom Sort is now owned by a separate
1459
+ `spreadsheetSort` editor extension rather than the row/column structure
1460
+ extension. The command freezes one continuous selection, derives a header
1461
+ candidate, and validates up to 64 unique keys before cloning and stably sorting
1462
+ complete cell rows or columns. A nested Traditional Office-compatible Sort Options dialog
1463
+ selects top-to-bottom column keys or left-to-right row keys; the latter disables
1464
+ header retention because every selected column moves. The same normalized
1465
+ options select Simplified Chinese pinyin or stroke collation and optional case
1466
+ sensitivity. A key is a closed union
1467
+ of ascending/descending value order, an explicit custom sequence, or an
1468
+ effective cell-color, font-color, or conditional-icon target with axis-aware
1469
+ first/last placement. The
1470
+ `spreadsheet-sort-custom-list` model owns
1471
+ normalization, duplicate and size guards, seven immutable month/weekday lists,
1472
+ and rank matching; the validated request clones custom entries so command
1473
+ execution has no dependency on mutable UI state. The browser adapters own a
1474
+ bounded user-list registry and never writes preferences into controlled
1475
+ workbook content. Without a store it remains scoped to the mounted session.
1476
+ The optional typed `SpreadsheetSortCustomListStore` synchronously loads and
1477
+ saves canonical lists through a host-selected local backend. The provided
1478
+ `LocalStorageSpreadsheetSortCustomListStore` accepts an injected Storage
1479
+ object, uses a versioned key, and validates, deduplicates, and caps reads at 32
1480
+ lists. Corrupt reads fail closed; a rejected write visibly downgrades the new
1481
+ list to session scope. A stored list precedes an identical request-carried
1482
+ session copy so persistence identity remains stable. The separate
1483
+ `spreadsheet-sort-appearance` model snapshots direct native styles plus
1484
+ calculated conditional-format output, preserves no-fill/automatic identities,
1485
+ and declines to flatten native patterns or gradients into one color. The
1486
+ command reconstructs that snapshot from controlled sheet state and the live
1487
+ range immediately before execution, then validates its shape and target
1488
+ identities. The `spreadsheet-sort-collation` boundary compiles one local
1489
+ `Intl.Collator` per request, keeps numeric text lexical, behavior-probes the
1490
+ requested order instead of trusting runtime-specific resolved labels, and fails
1491
+ closed when that order is unavailable. A direction-neutral matrix engine transposes only its bounded item
1492
+ view, then uses one stable comparator for both orientations. Relative formula
1493
+ references are translated along the moved row or column axis with the same
1494
+ bounded reference engine used by Paste Special, while absolute references stay
1495
+ fixed.
1496
+ One accepted operation crosses the Fortune boundary as one range write and one
1497
+ controlled Undo record. Table, worksheet-AutoFilter, hyperlink-map,
1498
+ imported-formula-metadata, and border-sidecar intersections fail closed because
1499
+ those models still own coordinates outside the cell matrix. Moving large sorts,
1500
+ large aggregate/rank scans, remaining advanced filter predicates, full custom-list preference
1501
+ management, and structural sidecar reconciliation into the Worker/WASM kernel
1502
+ remains Stage 3 work.
1503
+ Direct host focus of the native grid now enters the same bounded focus observer
1504
+ used by ribbon commands. If a controlled workbook update replaces the focused
1505
+ Fortune overlay, focus transfers to its connected replacement; deliberate
1506
+ pointer, Tab, or active text-editor movement still cancels restoration.
1507
+
1508
+ Worksheet AutoFilter conditions now have a separate A3S-owned model and typed
1509
+ `spreadsheetAutoFilter` command extension. A versioned condition payload lives
1510
+ inside each Fortune filter column only as the grid projection; the controlled
1511
+ sheet, absolute header column, exact filter range, and editable state are
1512
+ reauthenticated before mutation. The pure evaluator reads dense or sparse cells
1513
+ and derives one hidden-row set per column. Their union drives Fortune row
1514
+ visibility, while an explicit overlap marker keeps independently hidden rows
1515
+ separate when a criterion is replaced or removed. This gives one source of
1516
+ truth for multi-column ownership instead of inferring provenance from the
1517
+ combined `config.rowhidden` map.
1518
+
1519
+ Same-column custom conditions use a separate fixed pair inside the closed
1520
+ filter union. Each item is a nonrecursive single-value predicate and the pair
1521
+ has one explicit AND/OR discriminator. The evaluator composes exactly two
1522
+ matchers, collaboration validation rejects any nested or differently sized
1523
+ condition array, and the dialog cannot attach a second condition to range,
1524
+ blank, Top/Bottom, or dynamic families.
1525
+
1526
+ Wildcard expressions are two additional nonrecursive custom-condition
1527
+ variants, so existing equality and other text operands remain literal. A pure
1528
+ compiler tokenizes `*`, `?`, and `~` once per criterion, normalizes literal
1529
+ segments and cell text with NFKC plus the existing locale-pinned lowercase
1530
+ folding, and evaluates the token sequence without executing or interpolating
1531
+ user text. The same 32,767-character operand ceiling is enforced by the dialog,
1532
+ model, command, and collaboration boundaries. Literal-only spans use ordered
1533
+ substring search; long fixed-width candidate scans switch to a bounded bitset
1534
+ matcher instead of quadratically rescanning late mismatches.
1535
+
1536
+ Top/Bottom criteria take a separate aggregate path before the per-cell matcher.
1537
+ The evaluator gathers finite numeric values from the filter column, converts a
1538
+ percentage to `ceil(n * percent / 100)` items, sorts in the requested direction,
1539
+ and uses the selected boundary as a comparison threshold. Every equal boundary
1540
+ value remains visible, while text, Boolean, blank, and nonfinite cells do not
1541
+ enter the ranking domain. Dense and sparse cell readers share this path, and
1542
+ the resulting hidden-row set remains one independently owned column entry.
1543
+
1544
+ Dynamic criteria use a separate pure compiler with an explicit local-clock
1545
+ context. Above/below-average consumes the column as an iterable, calculates one
1546
+ finite numeric mean, and returns a strict matcher without retaining the column.
1547
+ Date families compile one inclusive-start/exclusive-end serial interval and do
1548
+ not pre-read the column. They accept imported `Date` objects or finite numeric
1549
+ cells explicitly marked `ct.t='d'`, recover SheetJS local-date serials across
1550
+ time zones, reject the fictional serial 60, and never classify an unformatted
1551
+ number as a date. Relative weeks begin on Sunday; calendar month and quarter
1552
+ families classify independently of year. Column profiling is cached per
1553
+ immutable sheet and keeps typed dates out of numeric rank actions. The editor
1554
+ uses the current local clock, while model tests inject a deterministic clock.
1555
+ The controlled model still normalizes dates to the 1900 system; source-level
1556
+ 1904 retention remains an explicit import boundary.
1557
+
1558
+ The same closed `WorkSpreadsheetFilterCriteria` union now serves worksheet and
1559
+ table native OOXML. Package scan and import read only the worksheet root's
1560
+ direct `<autoFilter>` child, hydrate supported criteria, and retain imported
1561
+ unsupported typed criteria without pretending to evaluate them. Export patches
1562
+ the generated worksheet element with native `<filterColumn>` children. General
1563
+ two-item `<customFilters and="1|0">` groups, arbitrary positive/negative
1564
+ wildcard expressions, negative prefix/suffix forms, and
1565
+ `<top10 top="..." percent="..." val="..."/>` criteria round-trip through the
1566
+ shared worksheet/table path. Imported native dynamic filters are recomputed
1567
+ from current cells and emitted as native `<dynamicFilter>` elements. Canonical
1568
+ edge-star patterns still normalize to
1569
+ the narrower contains, begins-with, or ends-with variants. The
1570
+ React adapter owns only vendor-menu discovery, the accessible condition dialog,
1571
+ short-lived selection preservation, and focus restoration; unsafe vendor sort
1572
+ items are not exposed because they bypass typed sort and structural guards.
1573
+
1574
+ Partial-range planning is a separate controlled concern. The shared
1575
+ `spreadsheet-current-region` model reads dense `data` and sparse `celldata`
1576
+ without materializing worksheet dimensions, so AutoFilter and Sort cannot
1577
+ derive different bounds. The command layer creates exact and expanded
1578
+ candidates and evaluates mutation and structural guards independently. The
1579
+ React adapter owns only the accessible warning/custom-dialog transition and a
1580
+ short-lived authorization containing the frozen sort request plus its original
1581
+ selection. The command accepts an expanded destination only while the live
1582
+ selection still matches that origin; stale host state therefore fails closed.
1583
+ The header heuristic likewise reads raw non-formula text instead of formatted
1584
+ display strings, keeping numeric and formula result rows in the data body.
1585
+
1442
1586
  Exit criteria: scrolling and selection do not scale with total row count;
1443
1587
  incremental recalculation touches only affected dependency subgraphs; XLSX
1444
1588
  fixtures preserve formulas, styles, names, validation, conditional formatting,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/office",
3
- "version": "0.37.0",
3
+ "version": "0.37.2",
4
4
  "description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
5
5
  "keywords": [
6
6
  "office",
@@ -86,6 +86,7 @@
86
86
  "playground:bundle-check": "bun scripts/check-playground-bundle.ts",
87
87
  "playground:preview": "rspress preview -c website/rspress.config.ts --host 127.0.0.1 --port 4175",
88
88
  "playground:typecheck": "tsc --noEmit -p playground/tsconfig.json",
89
+ "playground:ime:webkit": "playwright test --config playwright.ime.config.ts",
89
90
  "playground:visual": "playwright test --config playwright.config.ts",
90
91
  "playground:visual:document-emphasis": "playwright test visual-tests/document-emphasis.functional.spec.ts --config playwright.config.ts",
91
92
  "playground:visual:document-index": "playwright test visual-tests/document-index.functional.spec.ts --config playwright.config.ts",
@@ -104,6 +105,12 @@
104
105
  "playground:visual:spreadsheet-data-validation": "playwright test visual-tests/spreadsheet-data-validation.functional.spec.ts --config playwright.config.ts",
105
106
  "playground:visual:spreadsheet-date-time": "playwright test visual-tests/spreadsheet-date-time.functional.spec.ts --config playwright.config.ts",
106
107
  "playground:visual:spreadsheet-copy-from-above": "playwright test visual-tests/spreadsheet-copy-from-above.functional.spec.ts --config playwright.config.ts",
108
+ "playground:visual:spreadsheet-custom-sort": "playwright test visual-tests/spreadsheet-custom-sort.functional.spec.ts --config playwright.config.ts",
109
+ "playground:visual:spreadsheet-custom-list-sort": "playwright test visual-tests/spreadsheet-custom-list-sort.functional.spec.ts --config playwright.config.ts",
110
+ "playground:visual:spreadsheet-appearance-sort": "playwright test visual-tests/spreadsheet-appearance-sort.functional.spec.ts --config playwright.config.ts",
111
+ "playground:visual:spreadsheet-row-sort": "playwright test visual-tests/spreadsheet-row-sort.functional.spec.ts --config playwright.config.ts",
112
+ "playground:visual:spreadsheet-text-sort": "playwright test visual-tests/spreadsheet-text-sort.functional.spec.ts --config playwright.config.ts",
113
+ "playground:visual:spreadsheet-sort-range": "playwright test visual-tests/spreadsheet-sort-range.functional.spec.ts --config playwright.config.ts",
107
114
  "playground:visual:spreadsheet-font-dialog-shortcuts": "playwright test visual-tests/spreadsheet-font-dialog-shortcuts.functional.spec.ts --config playwright.config.ts",
108
115
  "playground:visual:spreadsheet-diagonal-borders": "playwright test visual-tests/spreadsheet-diagonal-borders.functional.spec.ts --config playwright.config.ts",
109
116
  "playground:visual:spreadsheet-font-colors-shortcuts": "playwright test visual-tests/spreadsheet-font-colors-shortcuts.functional.spec.ts --config playwright.config.ts",
@@ -137,6 +144,8 @@
137
144
  "test:e2e:pdf-page-organization:check": "a3s-test check tests/e2e/pdf-page-organization.acl --json",
138
145
  "test:e2e:presentation-animation": "A3S_TEST_SUITE=tests/e2e/presentation-animation.acl bash scripts/run-a3s-test-web-gate.sh",
139
146
  "test:e2e:presentation-animation:check": "a3s-test check tests/e2e/presentation-animation.acl --json",
147
+ "test:e2e:presentation-chinese-ime": "A3S_TEST_SUITE=tests/e2e/presentation-chinese-ime.acl bash scripts/run-a3s-test-web-gate.sh",
148
+ "test:e2e:presentation-chinese-ime:check": "a3s-test check tests/e2e/presentation-chinese-ime.acl --json",
140
149
  "test:e2e:large-presentation": "bun .a3s-test/performance/generate-fixtures.ts --presentations-only && a3s-test run tests/e2e/presentation-large-windowing.acl --json",
141
150
  "test:e2e:large-presentation:check": "a3s-test check tests/e2e/presentation-large-windowing.acl --json",
142
151
  "test:e2e:initial-focus": "a3s-test run tests/e2e/office-editor-initial-focus.acl --json",
@@ -181,6 +190,18 @@
181
190
  "test:e2e:spreadsheet-table:check": "a3s-test check tests/e2e/spreadsheet-table.acl --json",
182
191
  "test:e2e:spreadsheet-table-totals": "a3s-test run tests/e2e/spreadsheet-table-totals.acl --json",
183
192
  "test:e2e:spreadsheet-table-totals:check": "a3s-test check tests/e2e/spreadsheet-table-totals.acl --json",
193
+ "test:e2e:spreadsheet-custom-sort": "A3S_TEST_SUITE=tests/e2e/spreadsheet-custom-sort.acl bash scripts/run-a3s-test-web-gate.sh",
194
+ "test:e2e:spreadsheet-custom-sort:check": "a3s-test check tests/e2e/spreadsheet-custom-sort.acl --json",
195
+ "test:e2e:spreadsheet-custom-list-sort": "A3S_TEST_SUITE=tests/e2e/spreadsheet-custom-list-sort.acl bash scripts/run-a3s-test-web-gate.sh",
196
+ "test:e2e:spreadsheet-custom-list-sort:check": "a3s-test check tests/e2e/spreadsheet-custom-list-sort.acl --json",
197
+ "test:e2e:spreadsheet-appearance-sort": "A3S_TEST_SUITE=tests/e2e/spreadsheet-appearance-sort.acl bash scripts/run-a3s-test-web-gate.sh",
198
+ "test:e2e:spreadsheet-appearance-sort:check": "a3s-test check tests/e2e/spreadsheet-appearance-sort.acl --json",
199
+ "test:e2e:spreadsheet-row-sort": "A3S_TEST_SUITE=tests/e2e/spreadsheet-row-sort.acl bash scripts/run-a3s-test-web-gate.sh",
200
+ "test:e2e:spreadsheet-row-sort:check": "a3s-test check tests/e2e/spreadsheet-row-sort.acl --json",
201
+ "test:e2e:spreadsheet-text-sort": "A3S_TEST_SUITE=tests/e2e/spreadsheet-text-sort.acl bash scripts/run-a3s-test-web-gate.sh",
202
+ "test:e2e:spreadsheet-text-sort:check": "a3s-test check tests/e2e/spreadsheet-text-sort.acl --json",
203
+ "test:e2e:spreadsheet-sort-range": "A3S_TEST_SUITE=tests/e2e/spreadsheet-sort-range.acl bash scripts/run-a3s-test-web-gate.sh",
204
+ "test:e2e:spreadsheet-sort-range:check": "a3s-test check tests/e2e/spreadsheet-sort-range.acl --json",
184
205
  "test:e2e:spreadsheet-cell-fill": "a3s-test run tests/e2e/spreadsheet-cell-fill.acl --json",
185
206
  "test:e2e:spreadsheet-cell-fill:check": "a3s-test check tests/e2e/spreadsheet-cell-fill.acl --json",
186
207
  "test:e2e:spreadsheet-auto-sum": "a3s-test run tests/e2e/spreadsheet-auto-sum.acl --json",