@a3s-lab/office 0.36.0 → 0.37.1
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 +18 -6
- package/dist/0~3557.js +2 -1
- package/dist/0~3635.js +4 -1
- package/dist/0~7048.js +93 -1
- package/dist/0~9073.js +7 -2
- package/dist/0~presentation-editor.js +45 -9
- package/dist/0~spreadsheet-editor.js +20321 -16966
- package/dist/4121.js +1942 -1939
- package/dist/{3266.js → 5416.js} +1504 -20
- package/dist/9333.js +1 -1
- package/dist/core.d.ts +1 -0
- package/dist/core.js +141 -28
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/office-shortcuts.d.ts +1 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-command.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog-model.d.ts +27 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-condition-dialog.d.ts +17 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter-menu.d.ts +10 -0
- package/dist/internal/features/work/editors/spreadsheet-auto-filter.d.ts +16 -4
- package/dist/internal/features/work/editors/spreadsheet-cell-range.d.ts +1 -0
- package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +13 -1
- package/dist/internal/features/work/editors/spreadsheet-current-region.d.ts +12 -0
- package/dist/internal/features/work/editors/spreadsheet-editor.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-appearance.d.ts +45 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-collation.d.ts +8 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-command.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-editor.d.ts +8 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-custom-list-store.d.ts +13 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-custom-list.d.ts +26 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-dialog.d.ts +9 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-matrix.d.ts +4 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-options-dialog.d.ts +7 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-order-controls.d.ts +16 -0
- package/dist/internal/features/work/editors/spreadsheet-sort-range-dialog.d.ts +7 -0
- package/dist/internal/features/work/editors/spreadsheet-sort.d.ts +138 -0
- package/dist/internal/features/work/editors/spreadsheet-table-totals.d.ts +39 -0
- package/dist/internal/features/work/editors/spreadsheet-table.d.ts +11 -1
- package/dist/internal/features/work/editors/use-spreadsheet-auto-filter.d.ts +12 -3
- package/dist/internal/features/work/editors/use-spreadsheet-sort.d.ts +26 -0
- package/dist/internal/features/work/editors/work-office-chrome.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-auto-filter.d.ts +14 -0
- package/dist/internal/features/work/work-spreadsheet-dynamic-filter.d.ts +7 -0
- package/dist/internal/features/work/work-spreadsheet-filter-contract.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-wildcard.d.ts +7 -0
- package/dist/internal/features/work/work-types.d.ts +45 -7
- package/dist/internal/features/work/work-xlsx-interop.d.ts +2 -1
- package/dist/internal/features/work/work-xlsx-table-filters.d.ts +3 -1
- package/dist/internal/kernel/office-kernel-spreadsheet-fallback-formula.d.ts +11 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/office-kernel.worker.js +93 -1
- package/dist/styles.css +789 -145
- package/dist/vue.d.ts +3 -1
- package/dist/vue.js +2 -0
- package/dist/web-component.d.ts +3 -1
- package/dist/web-component.js +9 -0
- package/dist/work-spreadsheet-package-scan.worker.js +2 -1
- package/docs/latest/en/browser-editor-architecture.md +136 -2
- package/package.json +24 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ workflows, and a separate Rust automation plane.
|
|
|
56
56
|
|
|
57
57
|
## Latest on `main`
|
|
58
58
|
|
|
59
|
-
The `0.
|
|
59
|
+
The `0.37.1` release exposes these capabilities as normal user-facing
|
|
60
60
|
Playground templates, with matching implementation detail in the documentation:
|
|
61
61
|
|
|
62
62
|
| Editor | Latest capability | Public entry |
|
|
@@ -68,7 +68,7 @@ Playground templates, with matching implementation detail in the documentation:
|
|
|
68
68
|
| Writer | Native character shading with exact `w:shd` patterns, foreground/background color identity, explicit resets, authoring, and DOCX reopen | Playground **Latest capabilities → 字符底纹** · [Document reference](docs/latest/en/components/document.mdx#native-character-shading) |
|
|
69
69
|
| Writer | Independent Latin, East Asian, and bidi proofing languages plus explicit `w:noProof` inclusion/exclusion | Playground **Latest capabilities → 校对语言** · [Document reference](docs/latest/en/components/document.mdx#native-proofing-languages) |
|
|
70
70
|
| Spreadsheet | Complete common Data Validation input, blank/dropdown, and Stop/Warning/Information error settings with native XLSX round trips | Playground **Latest capabilities → 数据验证** · [Spreadsheet reference](docs/latest/en/components/spreadsheet.mdx#data-validation) |
|
|
71
|
-
| Spreadsheet |
|
|
71
|
+
| Spreadsheet | Native totals-row authoring with per-column aggregates, labels, custom formulas, filtered-row-aware `SUBTOTAL`, automatic calculated-column fill for newly inserted table body rows, and bounded structured-reference calculation across Rust/WASM and JavaScript fallback | Playground **Latest capabilities → 结构化引用** · [Totals-row reference](docs/latest/en/components/spreadsheet.mdx#native-totals-row-authoring) · [Structured-reference calculation](docs/latest/en/components/spreadsheet.mdx#structured-reference-calculation) |
|
|
72
72
|
| PDF | Insert, delete, rotate, reorder, extract, merge, and split pages through a dedicated Web Worker, with Blob-level Undo/Redo and independent binary reopen verification | Playground **Latest capabilities → 组织 PDF 页面** · [PDF reference](docs/latest/en/components/pdf.mdx#page-organization) |
|
|
73
73
|
|
|
74
74
|
All nine entries are reachable from the first Playground viewport. The
|
|
@@ -152,7 +152,8 @@ baseline rather than one specific release.
|
|
|
152
152
|
| Formatting and style rendering | **Partial** — native fonts, colors, borders, alignment, number formats, cell styles, all 17 native non-solid OOXML pattern fills, native linear/path XLSX gradients, and one Format Cells surface that authors none, solid, pattern, or gradient fills with exact geometry and 2–256 ordered stops; static date/time entry, contrast-safe font preview, native XLSX rich-text runs, selected-text font formatting, direct formula-bar/F2 insertion or deletion, and bounded authenticated formatted-HTML paste | Disjoint multi-edit rich-text authoring, broader themes, locale formats, and advanced style effects |
|
|
153
153
|
| Ribbon and shortcuts | **Partial** — common Office-style Home/Data/View commands, grid-scoped shortcuts, and focused Font-dialog aliases | Larger command catalog and platform-specific accelerators |
|
|
154
154
|
| Formulas and recalculation | **Partial** — dependency-aware calculation plus bounded structured references (`Table[Column]`, contiguous ranges, `#All`/`#Headers`/`#Data`/`#Totals`/`#This Row`, and `[@Column]`) in the shared Rust/WASM and JavaScript paths | Wider functions, arrays, volatile semantics, and calculation parity |
|
|
155
|
-
|
|
|
155
|
+
| Sort and filter | **Partial** — Traditional Office-style current-region expansion warnings for partial selections; Traditional Office-compatible top-to-bottom or left-to-right Custom Sort with stable value, custom-list, effective cell-color, effective font-color, and conditional-format icon keys; offline Simplified Chinese pinyin/stroke comparison, optional lowercase-before-uppercase case sensitivity, and lexical numeric text; seven built-in month/weekday sequences; bounded typed host-stored or mounted-session sequences; header retention for top-to-bottom sorting; top/bottom or left/right appearance placement; up to 64 ordered keys; blanks-last value behavior; axis-aware relative-formula translation; and one-step Undo; plus worksheet AutoFilter authoring, keyboard menus, common text/value/numeric/blank conditions, exactly two same-column conditions joined by AND or OR, native OOXML `*`/`?`/`~` wildcard expressions, negative prefix/suffix operators, tie-aware Top/Bottom item and percentage filters, locally evaluated above/below-average and complete native relative-date, month, and quarter dynamic families on typed 1900-system date cells, multi-column row ownership, manual-hide preservation, and native XLSX criteria round trips with imported dynamic-filter recomputation | Custom-list deletion/reordering UI, broader locale collation, source-level 1904 date-system retention for dynamic dates, large aggregate/rank Worker/WASM offload, and table/AutoFilter-integrated custom sorting |
|
|
156
|
+
| Tables, pivots, charts, and rules | **Partial** — native tables, bounded structured-reference formulas, calculated-column formulas with automatic fill for newly inserted body rows, complete common totals-row authoring, pivots, charts, conditional formatting, and common validation rules with complete input/error-setting authoring | Slicers, pivot charts, custom/dependent validation rules, advanced analysis, and broader browser alert flows |
|
|
156
157
|
| Large worksheets | **Supported with boundaries** — maximum-dimension sparse import/editing and viewport-bounded Canvas painting | Highly optimized native grid with hardware-dependent limits |
|
|
157
158
|
| Files and printing | **Partial** — XLS/XLSX/ODS/CSV import, XLSX export, and PDF output | Broader round trips, external data, print fidelity, and legacy conversion |
|
|
158
159
|
| External data, macros, and specialist analysis | **Gap** — active macros are never executed; bounded models are still needed for data connections and solver-like tools | Established data, macro/add-in, scenario, and optimization ecosystems |
|
|
@@ -216,6 +217,9 @@ is requested. The complete gap inventory and exit evidence live in the
|
|
|
216
217
|
preserving spatial arrow-key navigation.
|
|
217
218
|
Shared Office selects use 44 px phone option rows and bounded internal
|
|
218
219
|
scrolling while retaining keyboard selection and exact focus restoration.
|
|
220
|
+
Host-provided file menus keep every action visually identifiable with an
|
|
221
|
+
explicit or neutral fallback icon, readable long labels, grouped destructive
|
|
222
|
+
actions, and a visible keyboard focus ring.
|
|
219
223
|
- **Editor-scoped zoom** — Status controls and Ctrl/Cmd + mouse-wheel gestures
|
|
220
224
|
share each surface's bounded zoom model without changing the host browser's
|
|
221
225
|
page scale.
|
|
@@ -756,9 +760,15 @@ conflicting column fails closed and drops its automatic rule. XLSX
|
|
|
756
760
|
`<calculatedColumnFormula>` metadata round-trips with the leading `=` restored
|
|
757
761
|
in the controlled model, while unsafe or external formulas are omitted.
|
|
758
762
|
The Playground's **结构化引用** template shows a calculated `Revenue` column,
|
|
759
|
-
an insertion hint,
|
|
760
|
-
totals
|
|
761
|
-
|
|
763
|
+
an insertion hint, an editable totals row, and a worksheet-qualified summary.
|
|
764
|
+
The Table Design totals menu enables or disables the row and assigns each
|
|
765
|
+
column a label, one of ten native aggregate functions, or a bounded custom
|
|
766
|
+
formula. Native aggregates emit filtered-row-aware `SUBTOTAL` formulas; direct
|
|
767
|
+
cell edits reconcile back into table metadata, table structure changes move
|
|
768
|
+
the row without overwriting manual cells, and table renames rewrite only
|
|
769
|
+
generated formulas. Dense and sparse worksheets, Yjs collaboration, and XLSX
|
|
770
|
+
`totalsRowFunction`, `totalsRowLabel`, and `totalsRowFormula` round trips share
|
|
771
|
+
the same model. Slicers and external/query tables remain explicit boundaries.
|
|
762
772
|
|
|
763
773
|
Use `downloadArtifact` to start a browser download or
|
|
764
774
|
`createArtifactBlob` when your application owns upload and persistence.
|
|
@@ -1641,6 +1651,8 @@ keep working without hard-coded return URLs.
|
|
|
1641
1651
|
|
|
1642
1652
|
- [Live Playground](https://a3s-lab.github.io/Office/playground/)
|
|
1643
1653
|
- [Documentation center](https://a3s-lab.github.io/Office/docs/)
|
|
1654
|
+
- [A3S Office 0.37.1 documentation](https://a3s-lab.github.io/Office/docs/0.37.1/)
|
|
1655
|
+
- [A3S Office 0.37.0 documentation](https://a3s-lab.github.io/Office/docs/0.37.0/)
|
|
1644
1656
|
- [A3S Office 0.36.0 documentation](https://a3s-lab.github.io/Office/docs/0.36.0/)
|
|
1645
1657
|
- [A3S Office 0.34.0 documentation](https://a3s-lab.github.io/Office/docs/0.34.0/)
|
|
1646
1658
|
- [A3S Office 0.33.0 documentation](https://a3s-lab.github.io/Office/docs/0.33.0/)
|
package/dist/0~3557.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
2
|
+
import { isOfficeCompositionKeyboardEvent } from "./0~3635.js";
|
|
2
3
|
import { matchesOfficeEditorKeyboardShortcut } from "./0~8136.js";
|
|
3
4
|
const DEFAULT_EXTENSION_PRIORITY = 100;
|
|
4
5
|
function createOfficeEditorExtension(config) {
|
|
@@ -97,7 +98,7 @@ function createOfficeEditorRuntime(initialContext, extensions, options = {}) {
|
|
|
97
98
|
storage: Object.freeze(storage),
|
|
98
99
|
can: ()=>canApi,
|
|
99
100
|
handleKeyDown: (event)=>{
|
|
100
|
-
if (event.defaultPrevented) return false;
|
|
101
|
+
if (event.defaultPrevented || isOfficeCompositionKeyboardEvent(event)) return false;
|
|
101
102
|
for (const instance of instances)for (const shortcut of instance.keyboardShortcuts)if (matchesOfficeEditorKeyboardShortcut(event, shortcut.shortcut) && shortcut.handler(readContext(), commandApi, canApi, event)) {
|
|
102
103
|
event.preventDefault();
|
|
103
104
|
return true;
|
package/dist/0~3635.js
CHANGED
|
@@ -314,10 +314,13 @@ function swatchForeground(color) {
|
|
|
314
314
|
}
|
|
315
315
|
const MODAL_DIALOG_SELECTOR = '[role="dialog"][aria-modal="true"]';
|
|
316
316
|
const OFFICE_SHORTCUT_IGNORE_SELECTOR = '[data-office-shortcuts="ignore"]';
|
|
317
|
+
function isOfficeCompositionKeyboardEvent(event) {
|
|
318
|
+
return event.isComposing || 'Process' === event.key || 229 === event.keyCode;
|
|
319
|
+
}
|
|
317
320
|
function isOfficeShortcutBlocked(target) {
|
|
318
321
|
if ("u" < typeof document) return false;
|
|
319
322
|
if (target instanceof Element && (target.closest(MODAL_DIALOG_SELECTOR) || target.closest(OFFICE_SHORTCUT_IGNORE_SELECTOR))) return true;
|
|
320
323
|
if (document.activeElement instanceof Element && (document.activeElement.closest(MODAL_DIALOG_SELECTOR) || document.activeElement.closest(OFFICE_SHORTCUT_IGNORE_SELECTOR))) return true;
|
|
321
324
|
return null !== document.querySelector(MODAL_DIALOG_SELECTOR);
|
|
322
325
|
}
|
|
323
|
-
export { OfficeColorPicker, isOfficeShortcutBlocked };
|
|
326
|
+
export { OfficeColorPicker, isOfficeCompositionKeyboardEvent, isOfficeShortcutBlocked };
|
package/dist/0~7048.js
CHANGED
|
@@ -1352,6 +1352,13 @@ const browserScalarFunctionArities = new Map([
|
|
|
1352
1352
|
1
|
|
1353
1353
|
]
|
|
1354
1354
|
],
|
|
1355
|
+
[
|
|
1356
|
+
'SUBTOTAL',
|
|
1357
|
+
[
|
|
1358
|
+
2,
|
|
1359
|
+
255
|
|
1360
|
+
]
|
|
1361
|
+
],
|
|
1355
1362
|
[
|
|
1356
1363
|
'SUM',
|
|
1357
1364
|
[
|
|
@@ -1372,6 +1379,90 @@ function normalizeSpreadsheetFunctionName(name) {
|
|
|
1372
1379
|
while(normalized.startsWith('_XLFN.') || normalized.startsWith('_XLWS.'))normalized = normalized.slice(6);
|
|
1373
1380
|
return normalized;
|
|
1374
1381
|
}
|
|
1382
|
+
function evaluateParserSubtotal(parameters) {
|
|
1383
|
+
const codeValue = parserNumericValue(parameters[0]);
|
|
1384
|
+
if (void 0 === codeValue) return 'VALUE!';
|
|
1385
|
+
const code = Math.trunc(codeValue);
|
|
1386
|
+
const values = parameters.slice(1).flatMap((parameter)=>flattenParserValues(parameter));
|
|
1387
|
+
for (const value of values){
|
|
1388
|
+
const error = parserErrorValue(value);
|
|
1389
|
+
if (error) return error;
|
|
1390
|
+
}
|
|
1391
|
+
switch(code){
|
|
1392
|
+
case 1:
|
|
1393
|
+
case 101:
|
|
1394
|
+
return parserSubtotalNumeric(values, 'average');
|
|
1395
|
+
case 2:
|
|
1396
|
+
case 102:
|
|
1397
|
+
return values.filter((value)=>'number' == typeof value).length;
|
|
1398
|
+
case 3:
|
|
1399
|
+
case 103:
|
|
1400
|
+
return values.filter((value)=>null != value).length;
|
|
1401
|
+
case 4:
|
|
1402
|
+
case 104:
|
|
1403
|
+
return parserSubtotalNumeric(values, 'max');
|
|
1404
|
+
case 5:
|
|
1405
|
+
case 105:
|
|
1406
|
+
return parserSubtotalNumeric(values, 'min');
|
|
1407
|
+
case 6:
|
|
1408
|
+
case 106:
|
|
1409
|
+
return parserSubtotalNumeric(values, 'product');
|
|
1410
|
+
case 7:
|
|
1411
|
+
case 107:
|
|
1412
|
+
return parserSubtotalNumeric(values, 'stddev');
|
|
1413
|
+
case 8:
|
|
1414
|
+
case 108:
|
|
1415
|
+
return parserSubtotalNumeric(values, 'stddevp');
|
|
1416
|
+
case 9:
|
|
1417
|
+
case 109:
|
|
1418
|
+
return parserSubtotalNumeric(values, 'sum');
|
|
1419
|
+
case 10:
|
|
1420
|
+
case 110:
|
|
1421
|
+
return parserSubtotalNumeric(values, 'var');
|
|
1422
|
+
case 11:
|
|
1423
|
+
case 111:
|
|
1424
|
+
return parserSubtotalNumeric(values, 'varp');
|
|
1425
|
+
default:
|
|
1426
|
+
return 'VALUE!';
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
function parserSubtotalNumeric(values, operation) {
|
|
1430
|
+
const numbers = values.filter((value)=>'number' == typeof value && Number.isFinite(value));
|
|
1431
|
+
const count = numbers.length;
|
|
1432
|
+
const sum = numbers.reduce((total, value)=>total + value, 0);
|
|
1433
|
+
if ('sum' === operation) return finiteParserNumber(sum);
|
|
1434
|
+
if ('average' === operation) return count ? finiteParserNumber(sum / count) : 'DIV/0!';
|
|
1435
|
+
if ('max' === operation) return finiteParserNumber(Math.max(...numbers, 0));
|
|
1436
|
+
if ('min' === operation) return finiteParserNumber(Math.min(...numbers, 0));
|
|
1437
|
+
if ('product' === operation) return finiteParserNumber(count ? numbers.reduce((total, value)=>total * value, 1) : 0);
|
|
1438
|
+
if ('stddev' === operation || 'var' === operation) {
|
|
1439
|
+
if (count < 2) return 'DIV/0!';
|
|
1440
|
+
} else if (0 === count) return 'DIV/0!';
|
|
1441
|
+
const mean = sum / count;
|
|
1442
|
+
const divisor = 'stddev' === operation || 'var' === operation ? count - 1 : count;
|
|
1443
|
+
const variance = numbers.reduce((total, value)=>total + (value - mean) ** 2, 0) / divisor;
|
|
1444
|
+
return finiteParserNumber('stddev' === operation || 'stddevp' === operation ? Math.sqrt(variance) : variance);
|
|
1445
|
+
}
|
|
1446
|
+
function flattenParserValues(value) {
|
|
1447
|
+
if (!Array.isArray(value)) return [
|
|
1448
|
+
value
|
|
1449
|
+
];
|
|
1450
|
+
return value.flatMap((entry)=>flattenParserValues(entry));
|
|
1451
|
+
}
|
|
1452
|
+
function parserNumericValue(value) {
|
|
1453
|
+
if ('number' == typeof value) return Number.isFinite(value) ? value : void 0;
|
|
1454
|
+
if ('boolean' == typeof value) return value ? 1 : 0;
|
|
1455
|
+
if ('string' != typeof value || !value.trim()) return;
|
|
1456
|
+
const parsed = Number(value);
|
|
1457
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
1458
|
+
}
|
|
1459
|
+
function parserErrorValue(value) {
|
|
1460
|
+
if (value instanceof Error) return value.message.startsWith('#') ? value.message.slice(1) : 'VALUE!';
|
|
1461
|
+
return 'string' == typeof value && value.startsWith('#') ? value.slice(1) : void 0;
|
|
1462
|
+
}
|
|
1463
|
+
function finiteParserNumber(value) {
|
|
1464
|
+
return Number.isFinite(value) ? value : 'NUM!';
|
|
1465
|
+
}
|
|
1375
1466
|
function normalizeFormulaForFortuneParser(formula) {
|
|
1376
1467
|
const source = formula.replace(/^=/, '');
|
|
1377
1468
|
let output = '';
|
|
@@ -2154,10 +2245,11 @@ class JavaScriptSpreadsheetEvaluator {
|
|
|
2154
2245
|
let unsupportedFunction;
|
|
2155
2246
|
let materializedRangeCells = 0;
|
|
2156
2247
|
parser.setFunction('IFERROR', evaluateParserIfError).setFunction('ROW', (parameters)=>parameters.length ? null : coordinate.row + 1).setFunction('COLUMN', (parameters)=>parameters.length ? null : coordinate.column + 1);
|
|
2157
|
-
parser.on('callFunction', (name, parameters)=>{
|
|
2248
|
+
parser.on('callFunction', (name, parameters, done)=>{
|
|
2158
2249
|
const normalized = normalizeSpreadsheetFunctionName(name);
|
|
2159
2250
|
const arity = browserScalarFunctionArities.get(normalized);
|
|
2160
2251
|
if (!arity || parameters.length < arity[0] || parameters.length > arity[1]) unsupportedFunction ??= name.toUpperCase();
|
|
2252
|
+
if ('SUBTOTAL' === normalized) done(evaluateParserSubtotal(parameters));
|
|
2161
2253
|
});
|
|
2162
2254
|
parser.on('callCellValue', (cell, _options, done)=>{
|
|
2163
2255
|
const dependency = this.resolveCoordinate(indexed.sheet, cell);
|
package/dist/0~9073.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as jsx_runtime_Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
|
-
import { ArrowUpRight, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Eye, Minus, Plus } from "lucide-react";
|
|
4
|
+
import { ArrowUpRight, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Eye, File, Minus, Plus } from "lucide-react";
|
|
5
5
|
import { WorkOfficeCollaborationParticipants, moveOfficeMenuFocus, Popover, matchesAriaKeyShortcuts, officeOverlayPortalRoot } from "./0~8136.js";
|
|
6
6
|
const CONTEXT_MENU_MARGIN = 8;
|
|
7
7
|
const CONTEXT_MENU_TAB_STOP_SELECTOR = 'a[href]:not([tabindex="-1"]), button:not(:disabled):not([tabindex="-1"]), input:not(:disabled):not([type="hidden"]):not([tabindex="-1"]), select:not(:disabled):not([tabindex="-1"]), textarea:not(:disabled):not([tabindex="-1"]), [contenteditable="true"]:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])';
|
|
@@ -1071,6 +1071,8 @@ function WorkOfficeFileMenu({ actions }) {
|
|
|
1071
1071
|
type: "button",
|
|
1072
1072
|
role: "menuitem",
|
|
1073
1073
|
tabIndex: -1,
|
|
1074
|
+
className: action.danger ? 'danger' : void 0,
|
|
1075
|
+
"data-danger": action.danger ? 'true' : void 0,
|
|
1074
1076
|
disabled: action.disabled,
|
|
1075
1077
|
onClick: ()=>{
|
|
1076
1078
|
close();
|
|
@@ -1080,9 +1082,12 @@ function WorkOfficeFileMenu({ actions }) {
|
|
|
1080
1082
|
/*#__PURE__*/ jsx("span", {
|
|
1081
1083
|
className: "work-office-file-action-icon",
|
|
1082
1084
|
"aria-hidden": "true",
|
|
1083
|
-
children: action.icon
|
|
1085
|
+
children: action.icon ?? /*#__PURE__*/ jsx(File, {
|
|
1086
|
+
size: 16
|
|
1087
|
+
})
|
|
1084
1088
|
}),
|
|
1085
1089
|
/*#__PURE__*/ jsx("span", {
|
|
1090
|
+
className: "work-office-file-action-label",
|
|
1086
1091
|
children: action.label
|
|
1087
1092
|
}),
|
|
1088
1093
|
action.shortcut && /*#__PURE__*/ jsx("kbd", {
|
|
@@ -21,7 +21,7 @@ import { WorkspaceContextMenu, isWorkspaceContextMenuKeyboardEvent, WorkOfficeZo
|
|
|
21
21
|
import { presentationAgentProposalTargets, SpreadsheetChartSeriesStyleEditor, applyPresentationAgentProposalChanges, normalizeOptionalOfficeNumber, SpreadsheetErrorBarEditor, useOfficeHistory, presentationNotesProposalTarget, presentationAgentSelection, SpreadsheetTrendlineEditor, presentationAgentMenuItems } from "./0~3539.js";
|
|
22
22
|
import { slideTransitionDurationMilliseconds, workSlideAnimationIndex, workSlideAnimationForElement, remapWorkSlideAnimations, createWorkSlideTransition, workSlideTransitionsEqual, workSlideAnimationCues, initialWorkSlideAnimationCueIndex, normalizeWorkSlideAnimation, createWorkSlideAnimation, removeWorkSlideAnimationsForElements } from "./0~5809.js";
|
|
23
23
|
import { createOfficeEditorExtension, useOfficeEditorRuntime, useOfficeEditorKeyboardShortcuts } from "./0~3557.js";
|
|
24
|
-
import { isOfficeShortcutBlocked, OfficeColorPicker } from "./0~3635.js";
|
|
24
|
+
import { isOfficeShortcutBlocked, OfficeColorPicker, isOfficeCompositionKeyboardEvent } from "./0~3635.js";
|
|
25
25
|
import { normalizeDocumentHref, DOCUMENT_LINK_VALIDATION_MESSAGE } from "./0~work-document-links.js";
|
|
26
26
|
import { showToast } from "./6489.js";
|
|
27
27
|
import { scaledPresentationVisuals } from "./0~work-presentation-visual-scale.js";
|
|
@@ -4357,6 +4357,8 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4357
4357
|
const onEditorChangeRef = useRef(onEditorChange);
|
|
4358
4358
|
const onExitEditingRef = useRef(onExitEditing);
|
|
4359
4359
|
const onSelectionChangeRef = useRef(onSelectionChange);
|
|
4360
|
+
const editorRef = useRef(null);
|
|
4361
|
+
const compositionPublishTimerRef = useRef(null);
|
|
4360
4362
|
const appliedSignatureRef = useRef(presentationTextElementSignature(element));
|
|
4361
4363
|
const initialContentRef = useRef(presentationTextElementHtml(element));
|
|
4362
4364
|
const initialFocusTargetRef = useRef("u" > typeof document && document.activeElement instanceof HTMLElement ? document.activeElement : null);
|
|
@@ -4368,6 +4370,30 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4368
4370
|
const extensions = useMemo(()=>createPresentationTextEditorExtensions(element.placeholder?.prompt ?? '输入文字'), [
|
|
4369
4371
|
element.placeholder?.prompt
|
|
4370
4372
|
]);
|
|
4373
|
+
const publishEditorValue = (current)=>{
|
|
4374
|
+
const value = presentationTextValue(current, elementRef.current);
|
|
4375
|
+
const signature = presentationTextElementSignature({
|
|
4376
|
+
...elementRef.current,
|
|
4377
|
+
...value
|
|
4378
|
+
});
|
|
4379
|
+
if (signature === appliedSignatureRef.current) return;
|
|
4380
|
+
appliedSignatureRef.current = signature;
|
|
4381
|
+
onChangeRef.current(value);
|
|
4382
|
+
};
|
|
4383
|
+
const cancelCompositionPublication = ()=>{
|
|
4384
|
+
if (null === compositionPublishTimerRef.current) return;
|
|
4385
|
+
window.clearTimeout(compositionPublishTimerRef.current);
|
|
4386
|
+
compositionPublishTimerRef.current = null;
|
|
4387
|
+
};
|
|
4388
|
+
const publishCommittedComposition = ()=>{
|
|
4389
|
+
cancelCompositionPublication();
|
|
4390
|
+
compositionPublishTimerRef.current = window.setTimeout(()=>{
|
|
4391
|
+
compositionPublishTimerRef.current = null;
|
|
4392
|
+
const current = editorRef.current;
|
|
4393
|
+
if (!current || current.isDestroyed || current.view.composing) return;
|
|
4394
|
+
publishEditorValue(current);
|
|
4395
|
+
}, 0);
|
|
4396
|
+
};
|
|
4371
4397
|
const editor = useEditor({
|
|
4372
4398
|
extensions,
|
|
4373
4399
|
content: initialContentRef.current,
|
|
@@ -4380,7 +4406,18 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4380
4406
|
role: 'textbox',
|
|
4381
4407
|
spellcheck: 'true'
|
|
4382
4408
|
},
|
|
4409
|
+
handleDOMEvents: {
|
|
4410
|
+
compositionstart: ()=>{
|
|
4411
|
+
cancelCompositionPublication();
|
|
4412
|
+
return false;
|
|
4413
|
+
},
|
|
4414
|
+
compositionend: ()=>{
|
|
4415
|
+
publishCommittedComposition();
|
|
4416
|
+
return false;
|
|
4417
|
+
}
|
|
4418
|
+
},
|
|
4383
4419
|
handleKeyDown: (view, event)=>{
|
|
4420
|
+
if (view.composing || isOfficeCompositionKeyboardEvent(event)) return false;
|
|
4384
4421
|
if ('Escape' !== event.key || !onExitEditingRef.current) return false;
|
|
4385
4422
|
const object = view.dom.closest('[data-slide-element-origin]');
|
|
4386
4423
|
event.preventDefault();
|
|
@@ -4390,18 +4427,17 @@ function PresentationTextEditor({ autoFocus = false, element, onChange, onEditor
|
|
|
4390
4427
|
}
|
|
4391
4428
|
},
|
|
4392
4429
|
onCreate: ({ editor: current })=>{
|
|
4430
|
+
editorRef.current = current;
|
|
4393
4431
|
applyPresentationTextStoredMarks(current, elementRef.current);
|
|
4394
4432
|
},
|
|
4433
|
+
onDestroy: ()=>{
|
|
4434
|
+
editorRef.current = null;
|
|
4435
|
+
cancelCompositionPublication();
|
|
4436
|
+
},
|
|
4395
4437
|
onSelectionUpdate: ()=>onSelectionChangeRef.current?.(),
|
|
4396
4438
|
onUpdate: ({ editor: current })=>{
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
...elementRef.current,
|
|
4400
|
-
...value
|
|
4401
|
-
});
|
|
4402
|
-
if (signature === appliedSignatureRef.current) return;
|
|
4403
|
-
appliedSignatureRef.current = signature;
|
|
4404
|
-
onChangeRef.current(value);
|
|
4439
|
+
if (current.view.composing) return;
|
|
4440
|
+
publishEditorValue(current);
|
|
4405
4441
|
}
|
|
4406
4442
|
});
|
|
4407
4443
|
useEffect(()=>{
|