@a3s-lab/office 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/0~6090.js +1 -0
- package/dist/0~spreadsheet-editor.js +242 -76
- package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +28 -0
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +2 -0
- package/dist/internal/features/work/editors/spreadsheet-copy-from-above-command.d.ts +3 -0
- package/dist/internal/features/work/editors/spreadsheet-copy-from-above.d.ts +18 -0
- package/dist/office-kernel.wasm +0 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ baseline rather than one specific release.
|
|
|
123
123
|
|
|
124
124
|
| Capability | A3S Office today | Traditional Office baseline |
|
|
125
125
|
| --- | --- | --- |
|
|
126
|
-
| Cells, sheets, navigation, and history | **Supported** — multiple sheets, sparse editing, search, clipboard, fill, and undo/redo | Mature grid workflows across desktop and web |
|
|
126
|
+
| Cells, sheets, navigation, and history | **Supported** — multiple sheets, sparse editing, search, clipboard, four-direction fill, exact formula/value copy from above, and undo/redo | Mature grid workflows across desktop and web |
|
|
127
127
|
| Formatting and style rendering | **Partial** — native fonts, colors, borders, alignment, number formats, cell styles, and static date/time entry | Broader themes, locale formats, rich text, and advanced style effects |
|
|
128
128
|
| Ribbon and shortcuts | **Partial** — common Office-style Home/Data/View commands and grid-scoped shortcuts | Larger command catalog and platform-specific accelerators |
|
|
129
129
|
| Formulas and recalculation | **Partial** — dependency-aware calculation and common formula paths | Wider functions, arrays, volatile semantics, and calculation parity |
|
|
@@ -1347,6 +1347,7 @@ without hard-coded return URLs.
|
|
|
1347
1347
|
|
|
1348
1348
|
- [Live Playground](https://a3s-lab.github.io/Office/)
|
|
1349
1349
|
- [Documentation center](https://a3s-lab.github.io/Office/docs/)
|
|
1350
|
+
- [A3S Office 0.23.0 documentation](https://a3s-lab.github.io/Office/docs/0.23.0/)
|
|
1350
1351
|
- [A3S Office 0.22.0 documentation](https://a3s-lab.github.io/Office/docs/0.22.0/)
|
|
1351
1352
|
- [A3S Office 0.21.0 documentation](https://a3s-lab.github.io/Office/docs/0.21.0/)
|
|
1352
1353
|
- [A3S Office 0.20.0 documentation](https://a3s-lab.github.io/Office/docs/0.20.0/)
|
package/dist/0~6090.js
CHANGED
|
@@ -258,6 +258,7 @@ function shortcutCodeKey(code) {
|
|
|
258
258
|
if ('Equal' === code) return 'equal';
|
|
259
259
|
if ('Minus' === code) return 'minus';
|
|
260
260
|
if ('Semicolon' === code) return ';';
|
|
261
|
+
if ('Quote' === code) return "'";
|
|
261
262
|
if ('Comma' === code) return ',';
|
|
262
263
|
if ('Period' === code) return '.';
|
|
263
264
|
return null;
|
|
@@ -5,7 +5,7 @@ import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVertical
|
|
|
5
5
|
import { Fragment as external_react_Fragment, cloneElement, memo, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { genarate, indexToColumnChar, update as core_update } from "@fortune-sheet/core";
|
|
7
7
|
import { freezeImportedSpreadsheetCell, spreadsheetTextOrientationFromChoice, spreadsheetMatrixProfile, withoutEditableRange, spreadsheetTextOrientationFromAngle, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, spreadsheetCellValueWithDiagonalBorder, spreadsheetUnderlineCellValue, effectiveSpreadsheetPageSetup, attachSpreadsheetShownCommentCells, withEditableRange, sameSpreadsheetHistoryValue, createOfficeSpreadsheetCollaborationBinding as createWorkOfficeSpreadsheetCollaborationBinding, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconForValue, defaultSpreadsheetConditionalIconThresholds, spreadsheetUnderlineStyle, normalizeSpreadsheetDateValidationBoundary, sheetProtectionAuthority, editableRangeCellCount, unlockedCellCount, registerDerivedSpreadsheetMatrix, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, spreadsheetConditionalThresholdValue, spreadsheetTextOrientationChoiceFromCell, normalizeSheetProtectionAuthority, withSheetProtection, defaultSpreadsheetColorScaleThresholds, spreadsheetProtectionKey, spreadsheetDiagonalBorderFromCellValue, SPREADSHEET_CONDITIONAL_ICON_SETS, protectedSheetCount, withSheetSelectionPermissions, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, spreadsheetConditionalComparisonNeedsUpperValue, drawSpreadsheetConditionalIcon, spreadsheetTextOrientationFromCell, replaceOfficeSpreadsheetCollaboration as replaceWorkOfficeSpreadsheetCollaboration, readOfficeSpreadsheetCollaboration as readWorkOfficeSpreadsheetCollaboration, spreadsheetConditionalThresholdsEqual, isSpreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell } from "./5045.js";
|
|
8
|
-
import { workSpreadsheetChartSupportsGrouping, createSpreadsheetChartFromSelection, normalizeWorkSpreadsheetDataLabelPosition, normalizeSpreadsheetPrintTitleColumns, normalizeSpreadsheetPrintTitleRows, formulaHasStructuredReference, normalizeWorkSpreadsheetErrorBars, defaultPivotValueCaption, workSpreadsheetChartSupportsBarSpacing, normalizeWorkSpreadsheetChartGrouping, spreadsheetGridSize, normalizeWorkSpreadsheetChartAxisGroup, normalizeWorkSpreadsheetScatterStyle, cloneSparseMatrix, spreadsheetPivotAggregationLabel, workSpreadsheetChartAxisIsCategoryAxis, reconcileSpreadsheetChartPreviews, normalizeWorkSpreadsheetChartAxes, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartLegendPosition, spreadsheetChartCount, workSpreadsheetChartTypeLabel, sparseArrayEntries, normalizeWorkSpreadsheetTrendline, effectiveSpreadsheetCalculationSettings, spreadsheetPivotIntersects, normalizeWorkSpreadsheetDataLabels, spreadsheetPivotOutputContains, normalizeSpreadsheetPrintArea, spreadsheetCellAddress, formatSpreadsheetCellRanges, normalizeWorkSpreadsheetChartLayout, spreadsheetFormulaRangeForCell, workSpreadsheetChartAxisIsValueAxis, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, volatileSpreadsheetFormulaFunctions, sparseArrayIndexes, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, normalizeWorkSpreadsheetChartLegendOverlay, parseSpreadsheetChartReference, workSpreadsheetChartGroupingIsStacked, normalizeWorkSpreadsheetChartGapWidth, workSpreadsheetChartSupportsSmoothLines, refreshSpreadsheetPivotTables, createSpreadsheetPivotFromSelection, reconcileSpreadsheetPivots, spreadsheetPivotCount, sparseMatrixColumnCount, workSpreadsheetChartSupportsErrorBars, formulaHasExternalReference, isValidSpreadsheetDefinedName, spreadsheetPivotValidation, deleteSpreadsheetPivotTable, workSpreadsheetChartAxisDefaultLabelPosition, workSpreadsheetChartSupportsSeriesAnalysis, parseSpreadsheetCellRanges, spreadsheetPivotFilterItems, spreadsheetPivotFields, normalizeWorkSpreadsheetChartOverlap, spreadsheetFormulaRangeConflict, spreadsheetSheetsWithChartPreviews, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, workSpreadsheetChartSupportsAxes, normalizeWorkSpreadsheetCombinationSeriesType, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
|
|
8
|
+
import { workSpreadsheetChartSupportsGrouping, spreadsheetFormulaRangesForSelection, createSpreadsheetChartFromSelection, normalizeWorkSpreadsheetDataLabelPosition, normalizeSpreadsheetPrintTitleColumns, normalizeSpreadsheetPrintTitleRows, formulaHasStructuredReference, normalizeWorkSpreadsheetErrorBars, defaultPivotValueCaption, workSpreadsheetChartSupportsBarSpacing, normalizeWorkSpreadsheetChartGrouping, spreadsheetGridSize, normalizeWorkSpreadsheetChartAxisGroup, normalizeWorkSpreadsheetScatterStyle, cloneSparseMatrix, spreadsheetPivotAggregationLabel, workSpreadsheetChartAxisIsCategoryAxis, reconcileSpreadsheetChartPreviews, normalizeWorkSpreadsheetChartAxes, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartLegendPosition, spreadsheetChartCount, workSpreadsheetChartTypeLabel, sparseArrayEntries, normalizeWorkSpreadsheetTrendline, effectiveSpreadsheetCalculationSettings, spreadsheetPivotIntersects, normalizeWorkSpreadsheetDataLabels, spreadsheetPivotOutputContains, normalizeSpreadsheetPrintArea, spreadsheetCellAddress, formatSpreadsheetCellRanges, normalizeWorkSpreadsheetChartLayout, spreadsheetFormulaRangeForCell, workSpreadsheetChartAxisIsValueAxis, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, volatileSpreadsheetFormulaFunctions, sparseArrayIndexes, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, normalizeWorkSpreadsheetChartLegendOverlay, parseSpreadsheetChartReference, workSpreadsheetChartGroupingIsStacked, normalizeWorkSpreadsheetChartGapWidth, workSpreadsheetChartSupportsSmoothLines, refreshSpreadsheetPivotTables, createSpreadsheetPivotFromSelection, reconcileSpreadsheetPivots, spreadsheetPivotCount, sparseMatrixColumnCount, workSpreadsheetChartSupportsErrorBars, formulaHasExternalReference, isValidSpreadsheetDefinedName, spreadsheetPivotValidation, deleteSpreadsheetPivotTable, workSpreadsheetChartAxisDefaultLabelPosition, workSpreadsheetChartSupportsSeriesAnalysis, parseSpreadsheetCellRanges, spreadsheetPivotFilterItems, spreadsheetPivotFields, normalizeWorkSpreadsheetChartOverlap, spreadsheetFormulaRangeConflict, spreadsheetSheetsWithChartPreviews, workSpreadsheetChartUsesNumericXAxis, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, workSpreadsheetChartSupportsAxes, normalizeWorkSpreadsheetCombinationSeriesType, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
|
|
9
9
|
import { moveOfficeMenuFocus, stepOfficeZoom, useOfficeRemoteParticipants, Popover, officePresenceColor, useOfficePublishPresenceLocation, button_Button, icon_button_IconButton, moveOfficeGridMenuFocus, office_text_field_OfficeTextField, useDialogFocusScope, useOfficeEditorWheelZoom } from "./0~6090.js";
|
|
10
10
|
import { useOfficeTaskPaneEscape, OfficeCheckbox, CommittedOfficeNumberField, useOfficeDialog, useOfficeTaskPaneModal, createOfficeKernelClient, officeFontFamilies, CollectionState, OfficeNumberField, handleOfficeTaskPaneKeyDown } from "./0~7048.js";
|
|
11
11
|
import { isOfficeShortcutBlocked, OfficeColorPicker } from "./0~3635.js";
|
|
@@ -3752,6 +3752,38 @@ const spreadsheetCommandCatalog = {
|
|
|
3752
3752
|
group: 'editing'
|
|
3753
3753
|
}
|
|
3754
3754
|
},
|
|
3755
|
+
copyFormulaFromAbove: {
|
|
3756
|
+
id: 'editing.copyFormulaFromAbove',
|
|
3757
|
+
label: '复制上方公式',
|
|
3758
|
+
location: {
|
|
3759
|
+
area: 'ribbon',
|
|
3760
|
+
tab: 'home',
|
|
3761
|
+
group: 'editing'
|
|
3762
|
+
},
|
|
3763
|
+
shortcut: {
|
|
3764
|
+
label: "Ctrl+'",
|
|
3765
|
+
aria: "Control+'",
|
|
3766
|
+
editor: [
|
|
3767
|
+
"Control-'"
|
|
3768
|
+
]
|
|
3769
|
+
}
|
|
3770
|
+
},
|
|
3771
|
+
copyValueFromAbove: {
|
|
3772
|
+
id: 'editing.copyValueFromAbove',
|
|
3773
|
+
label: '复制上方值',
|
|
3774
|
+
location: {
|
|
3775
|
+
area: 'ribbon',
|
|
3776
|
+
tab: 'home',
|
|
3777
|
+
group: 'editing'
|
|
3778
|
+
},
|
|
3779
|
+
shortcut: {
|
|
3780
|
+
label: "Ctrl+Shift+'",
|
|
3781
|
+
aria: "Control+Shift+'",
|
|
3782
|
+
editor: [
|
|
3783
|
+
"Control-Shift-'"
|
|
3784
|
+
]
|
|
3785
|
+
}
|
|
3786
|
+
},
|
|
3755
3787
|
clearAll: {
|
|
3756
3788
|
id: 'editing.clearAll',
|
|
3757
3789
|
label: '清除全部',
|
|
@@ -5223,6 +5255,213 @@ function spreadsheetSelectedCellFillPlan(context, direction) {
|
|
|
5223
5255
|
const sheet = context.content.sheets.find((candidate)=>candidate.id === context.targetSheetId);
|
|
5224
5256
|
return canApplySpreadsheetCellFill(sheet, plan) ? plan : null;
|
|
5225
5257
|
}
|
|
5258
|
+
const MAX_SPREADSHEET_ROWS = 1048576;
|
|
5259
|
+
const spreadsheetPasteContentOptions = [
|
|
5260
|
+
{
|
|
5261
|
+
value: 'all',
|
|
5262
|
+
label: '全部',
|
|
5263
|
+
richOnly: false
|
|
5264
|
+
},
|
|
5265
|
+
{
|
|
5266
|
+
value: 'formulas',
|
|
5267
|
+
label: '公式',
|
|
5268
|
+
richOnly: false
|
|
5269
|
+
},
|
|
5270
|
+
{
|
|
5271
|
+
value: 'values',
|
|
5272
|
+
label: '值',
|
|
5273
|
+
richOnly: false
|
|
5274
|
+
},
|
|
5275
|
+
{
|
|
5276
|
+
value: 'formats',
|
|
5277
|
+
label: '格式',
|
|
5278
|
+
richOnly: true
|
|
5279
|
+
},
|
|
5280
|
+
{
|
|
5281
|
+
value: 'comments',
|
|
5282
|
+
label: '批注',
|
|
5283
|
+
richOnly: true
|
|
5284
|
+
},
|
|
5285
|
+
{
|
|
5286
|
+
value: 'validation',
|
|
5287
|
+
label: '数据验证',
|
|
5288
|
+
richOnly: true
|
|
5289
|
+
},
|
|
5290
|
+
{
|
|
5291
|
+
value: 'all-except-borders',
|
|
5292
|
+
label: '边框除外的全部',
|
|
5293
|
+
richOnly: true
|
|
5294
|
+
},
|
|
5295
|
+
{
|
|
5296
|
+
value: 'formulas-and-number-formats',
|
|
5297
|
+
label: '公式和数字格式',
|
|
5298
|
+
richOnly: true
|
|
5299
|
+
},
|
|
5300
|
+
{
|
|
5301
|
+
value: 'values-and-number-formats',
|
|
5302
|
+
label: '值和数字格式',
|
|
5303
|
+
richOnly: true
|
|
5304
|
+
},
|
|
5305
|
+
{
|
|
5306
|
+
value: 'column-widths',
|
|
5307
|
+
label: '列宽',
|
|
5308
|
+
richOnly: true
|
|
5309
|
+
}
|
|
5310
|
+
];
|
|
5311
|
+
const spreadsheetPasteOperationOptions = [
|
|
5312
|
+
{
|
|
5313
|
+
value: 'none',
|
|
5314
|
+
label: '无'
|
|
5315
|
+
},
|
|
5316
|
+
{
|
|
5317
|
+
value: 'add',
|
|
5318
|
+
label: '加'
|
|
5319
|
+
},
|
|
5320
|
+
{
|
|
5321
|
+
value: 'subtract',
|
|
5322
|
+
label: '减'
|
|
5323
|
+
},
|
|
5324
|
+
{
|
|
5325
|
+
value: 'multiply',
|
|
5326
|
+
label: '乘'
|
|
5327
|
+
},
|
|
5328
|
+
{
|
|
5329
|
+
value: 'divide',
|
|
5330
|
+
label: '除'
|
|
5331
|
+
}
|
|
5332
|
+
];
|
|
5333
|
+
function planSpreadsheetCopyFromAbove(sheet, target, kind) {
|
|
5334
|
+
if (!sheet || !isSpreadsheetCopyFromAboveKind(kind) || !spreadsheetCellCoordinateIsSupported(target.row, target.column) || 0 === target.row) return null;
|
|
5335
|
+
const targetRange = {
|
|
5336
|
+
row: [
|
|
5337
|
+
target.row,
|
|
5338
|
+
target.row
|
|
5339
|
+
],
|
|
5340
|
+
column: [
|
|
5341
|
+
target.column,
|
|
5342
|
+
target.column
|
|
5343
|
+
]
|
|
5344
|
+
};
|
|
5345
|
+
if (!canMutateSpreadsheetCellRange(sheet, targetRange)) return null;
|
|
5346
|
+
const source = {
|
|
5347
|
+
row: target.row - 1,
|
|
5348
|
+
column: target.column
|
|
5349
|
+
};
|
|
5350
|
+
const sourceCell = spreadsheetCopyFromAboveCellAt(sheet, source.row, source.column);
|
|
5351
|
+
const targetCell = spreadsheetCopyFromAboveCellAt(sheet, target.row, target.column);
|
|
5352
|
+
const formula = spreadsheetCopyableFormula(sheet, sourceCell, source.row, source.column);
|
|
5353
|
+
if ('formula' === kind && sourceCell?.f && null === formula) return null;
|
|
5354
|
+
const copiesFormula = 'formula' === kind && null !== formula;
|
|
5355
|
+
const value = copiesFormula ? formula : spreadsheetCopyFromAboveCellValue(sourceCell);
|
|
5356
|
+
if (copiesFormula ? targetCell?.f === value : !targetCell?.f && Object.is(spreadsheetCopyFromAboveCellValue(targetCell), value)) return null;
|
|
5357
|
+
return {
|
|
5358
|
+
formulaBarValue: value ?? '',
|
|
5359
|
+
kind,
|
|
5360
|
+
source,
|
|
5361
|
+
targetRange,
|
|
5362
|
+
value
|
|
5363
|
+
};
|
|
5364
|
+
}
|
|
5365
|
+
function spreadsheetCopyableFormula(sheet, cell, row, column) {
|
|
5366
|
+
if ('string' != typeof cell?.f || !cell.f.trim()) return null;
|
|
5367
|
+
const formula = cell.f.trim();
|
|
5368
|
+
if (!formula.startsWith('=') || formulaHasExternalReference(formula) || void 0 !== cell.spl || spreadsheetFormulaRangesForSelection(sheet, {
|
|
5369
|
+
startRow: row,
|
|
5370
|
+
endRow: row,
|
|
5371
|
+
startColumn: column,
|
|
5372
|
+
endColumn: column
|
|
5373
|
+
}).length > 0) return null;
|
|
5374
|
+
return formula;
|
|
5375
|
+
}
|
|
5376
|
+
function spreadsheetCopyFromAboveCellValue(cell) {
|
|
5377
|
+
if (cell?.v !== void 0 && null !== cell.v) return cell.v;
|
|
5378
|
+
const inlineText = spreadsheet_copy_from_above_spreadsheetInlineCellText(cell);
|
|
5379
|
+
if (null !== inlineText) return inlineText;
|
|
5380
|
+
if (cell?.m !== void 0 && null !== cell.m) return cell.m;
|
|
5381
|
+
return null;
|
|
5382
|
+
}
|
|
5383
|
+
function spreadsheet_copy_from_above_spreadsheetInlineCellText(cell) {
|
|
5384
|
+
const format = cell?.ct;
|
|
5385
|
+
if (format?.t !== 'inlineStr' || !Array.isArray(format.s)) return null;
|
|
5386
|
+
return format.s.map((run)=>spreadsheet_copy_from_above_isRecord(run) && ('string' == typeof run.v || 'number' == typeof run.v) ? String(run.v) : '').join('');
|
|
5387
|
+
}
|
|
5388
|
+
function spreadsheetCopyFromAboveCellAt(sheet, row, column) {
|
|
5389
|
+
if (void 0 !== sheet.data) return sheet.data[row]?.[column];
|
|
5390
|
+
return sheet.celldata?.find((entry)=>entry.r === row && entry.c === column)?.v;
|
|
5391
|
+
}
|
|
5392
|
+
function spreadsheetCellCoordinateIsSupported(row, column) {
|
|
5393
|
+
return Number.isSafeInteger(row) && row >= 0 && row < MAX_SPREADSHEET_ROWS && Number.isSafeInteger(column) && column >= 0 && column < 16384;
|
|
5394
|
+
}
|
|
5395
|
+
function isSpreadsheetCopyFromAboveKind(value) {
|
|
5396
|
+
return 'formula' === value || 'value' === value;
|
|
5397
|
+
}
|
|
5398
|
+
function spreadsheet_copy_from_above_isRecord(value) {
|
|
5399
|
+
return Boolean(value && 'object' == typeof value && !Array.isArray(value));
|
|
5400
|
+
}
|
|
5401
|
+
function createSpreadsheetCopyFromAboveExtension() {
|
|
5402
|
+
return createOfficeEditorExtension({
|
|
5403
|
+
name: 'spreadsheetCopyFromAbove',
|
|
5404
|
+
addCommands: ()=>({
|
|
5405
|
+
copyCellFromAbove: {
|
|
5406
|
+
canExecute: (context, kind)=>null !== spreadsheetSelectedCopyFromAbovePlan(context, kind),
|
|
5407
|
+
execute: copySpreadsheetCellFromAbove
|
|
5408
|
+
}
|
|
5409
|
+
}),
|
|
5410
|
+
addKeyboardShortcuts: ()=>({
|
|
5411
|
+
[spreadsheetCommandCatalog.copyFormulaFromAbove.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetCopyFromAboveShortcut(event, 'formula', can.copyCellFromAbove, commands.copyCellFromAbove),
|
|
5412
|
+
[spreadsheetCommandCatalog.copyValueFromAbove.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetCopyFromAboveShortcut(event, 'value', can.copyCellFromAbove, commands.copyCellFromAbove)
|
|
5413
|
+
})
|
|
5414
|
+
});
|
|
5415
|
+
}
|
|
5416
|
+
function copySpreadsheetCellFromAbove(context, kind) {
|
|
5417
|
+
const plan = spreadsheetSelectedCopyFromAbovePlan(context, kind);
|
|
5418
|
+
if (!plan || !context.workbook || !context.targetSheetId) return false;
|
|
5419
|
+
try {
|
|
5420
|
+
context.workbook.batchCallApis([
|
|
5421
|
+
{
|
|
5422
|
+
name: 'setCellValuesByRange',
|
|
5423
|
+
args: [
|
|
5424
|
+
[
|
|
5425
|
+
[
|
|
5426
|
+
plan.value
|
|
5427
|
+
]
|
|
5428
|
+
],
|
|
5429
|
+
plan.targetRange,
|
|
5430
|
+
{
|
|
5431
|
+
id: context.targetSheetId
|
|
5432
|
+
}
|
|
5433
|
+
]
|
|
5434
|
+
}
|
|
5435
|
+
]);
|
|
5436
|
+
} catch {
|
|
5437
|
+
return false;
|
|
5438
|
+
}
|
|
5439
|
+
try {
|
|
5440
|
+
context.formulaBar?.setValue(plan.formulaBarValue);
|
|
5441
|
+
} catch {}
|
|
5442
|
+
return true;
|
|
5443
|
+
}
|
|
5444
|
+
function spreadsheetSelectedCopyFromAbovePlan(context, kind) {
|
|
5445
|
+
const workbook = context.workbook;
|
|
5446
|
+
const sheetId = context.targetSheetId;
|
|
5447
|
+
if (!context.editable || !workbook || !sheetId || sheetId !== context.activeSheetId) return null;
|
|
5448
|
+
try {
|
|
5449
|
+
const selection = finiteSpreadsheetSelection(workbook.getSelection()?.at(-1) ?? context.fallbackRange);
|
|
5450
|
+
const row = selection.row_focus ?? selection.row[0] ?? 0;
|
|
5451
|
+
const column = selection.column_focus ?? selection.column[0] ?? 0;
|
|
5452
|
+
const sheet = context.content.sheets.find((candidate)=>candidate.id === sheetId);
|
|
5453
|
+
return planSpreadsheetCopyFromAbove(sheet, {
|
|
5454
|
+
row,
|
|
5455
|
+
column
|
|
5456
|
+
}, kind);
|
|
5457
|
+
} catch {
|
|
5458
|
+
return null;
|
|
5459
|
+
}
|
|
5460
|
+
}
|
|
5461
|
+
function runSpreadsheetCopyFromAboveShortcut(event, kind, canExecute, execute) {
|
|
5462
|
+
if (event.repeat || event.isComposing || isOfficeShortcutBlocked(event.target) || isSpreadsheetNativeTextUndoTarget(event.target) || !isSpreadsheetGridKeyboardTarget(event.target) || !canExecute(kind)) return false;
|
|
5463
|
+
return execute(kind);
|
|
5464
|
+
}
|
|
5226
5465
|
function canEditSpreadsheetSelection(context) {
|
|
5227
5466
|
return Boolean(context.editable && context.workbook && context.targetSheetId);
|
|
5228
5467
|
}
|
|
@@ -6068,81 +6307,6 @@ function clampSpreadsheetDataValidationFocus(value, range) {
|
|
|
6068
6307
|
const focus = 'number' == typeof value && Number.isFinite(value) ? Math.trunc(value) : minimum;
|
|
6069
6308
|
return Math.min(maximum, Math.max(minimum, focus));
|
|
6070
6309
|
}
|
|
6071
|
-
const MAX_SPREADSHEET_ROWS = 1048576;
|
|
6072
|
-
const spreadsheetPasteContentOptions = [
|
|
6073
|
-
{
|
|
6074
|
-
value: 'all',
|
|
6075
|
-
label: '全部',
|
|
6076
|
-
richOnly: false
|
|
6077
|
-
},
|
|
6078
|
-
{
|
|
6079
|
-
value: 'formulas',
|
|
6080
|
-
label: '公式',
|
|
6081
|
-
richOnly: false
|
|
6082
|
-
},
|
|
6083
|
-
{
|
|
6084
|
-
value: 'values',
|
|
6085
|
-
label: '值',
|
|
6086
|
-
richOnly: false
|
|
6087
|
-
},
|
|
6088
|
-
{
|
|
6089
|
-
value: 'formats',
|
|
6090
|
-
label: '格式',
|
|
6091
|
-
richOnly: true
|
|
6092
|
-
},
|
|
6093
|
-
{
|
|
6094
|
-
value: 'comments',
|
|
6095
|
-
label: '批注',
|
|
6096
|
-
richOnly: true
|
|
6097
|
-
},
|
|
6098
|
-
{
|
|
6099
|
-
value: 'validation',
|
|
6100
|
-
label: '数据验证',
|
|
6101
|
-
richOnly: true
|
|
6102
|
-
},
|
|
6103
|
-
{
|
|
6104
|
-
value: 'all-except-borders',
|
|
6105
|
-
label: '边框除外的全部',
|
|
6106
|
-
richOnly: true
|
|
6107
|
-
},
|
|
6108
|
-
{
|
|
6109
|
-
value: 'formulas-and-number-formats',
|
|
6110
|
-
label: '公式和数字格式',
|
|
6111
|
-
richOnly: true
|
|
6112
|
-
},
|
|
6113
|
-
{
|
|
6114
|
-
value: 'values-and-number-formats',
|
|
6115
|
-
label: '值和数字格式',
|
|
6116
|
-
richOnly: true
|
|
6117
|
-
},
|
|
6118
|
-
{
|
|
6119
|
-
value: 'column-widths',
|
|
6120
|
-
label: '列宽',
|
|
6121
|
-
richOnly: true
|
|
6122
|
-
}
|
|
6123
|
-
];
|
|
6124
|
-
const spreadsheetPasteOperationOptions = [
|
|
6125
|
-
{
|
|
6126
|
-
value: 'none',
|
|
6127
|
-
label: '无'
|
|
6128
|
-
},
|
|
6129
|
-
{
|
|
6130
|
-
value: 'add',
|
|
6131
|
-
label: '加'
|
|
6132
|
-
},
|
|
6133
|
-
{
|
|
6134
|
-
value: 'subtract',
|
|
6135
|
-
label: '减'
|
|
6136
|
-
},
|
|
6137
|
-
{
|
|
6138
|
-
value: 'multiply',
|
|
6139
|
-
label: '乘'
|
|
6140
|
-
},
|
|
6141
|
-
{
|
|
6142
|
-
value: 'divide',
|
|
6143
|
-
label: '除'
|
|
6144
|
-
}
|
|
6145
|
-
];
|
|
6146
6310
|
const MILLISECONDS_PER_DAY = 86400000;
|
|
6147
6311
|
const MINUTES_PER_DAY = 1440;
|
|
6148
6312
|
const EXCEL_1900_EPOCH_UTC = Date.UTC(1899, 11, 30);
|
|
@@ -8608,6 +8772,7 @@ function createSpreadsheetEditorExtensions() {
|
|
|
8608
8772
|
createSpreadsheetTableExtension(),
|
|
8609
8773
|
createSpreadsheetAutoSumExtension(),
|
|
8610
8774
|
createSpreadsheetCellFillExtension(),
|
|
8775
|
+
createSpreadsheetCopyFromAboveExtension(),
|
|
8611
8776
|
createSpreadsheetVisibilityShortcutExtension(),
|
|
8612
8777
|
createOfficeEditorExtension({
|
|
8613
8778
|
name: 'spreadsheetFormatPainter',
|
|
@@ -24217,6 +24382,7 @@ function spreadsheetCommandsWithGridFocus(commands, restoreFocus) {
|
|
|
24217
24382
|
activateFormatPainter: afterSuccessfulCommand(commands.activateFormatPainter),
|
|
24218
24383
|
cancelFormatPainter: afterSuccessfulCommand(commands.cancelFormatPainter),
|
|
24219
24384
|
clearSelectedCells: afterSuccessfulCommand(commands.clearSelectedCells),
|
|
24385
|
+
copyCellFromAbove: afterSuccessfulCommand(commands.copyCellFromAbove),
|
|
24220
24386
|
copySelection: afterSuccessfulCommand(commands.copySelection),
|
|
24221
24387
|
convertTableToRange: afterSuccessfulCommand(commands.convertTableToRange),
|
|
24222
24388
|
cutSelection: afterSuccessfulCommand(commands.cutSelection),
|
|
@@ -852,6 +852,34 @@ export declare const spreadsheetCommandCatalog: {
|
|
|
852
852
|
readonly group: "editing";
|
|
853
853
|
};
|
|
854
854
|
};
|
|
855
|
+
readonly copyFormulaFromAbove: {
|
|
856
|
+
readonly id: "editing.copyFormulaFromAbove";
|
|
857
|
+
readonly label: "复制上方公式";
|
|
858
|
+
readonly location: {
|
|
859
|
+
readonly area: "ribbon";
|
|
860
|
+
readonly tab: "home";
|
|
861
|
+
readonly group: "editing";
|
|
862
|
+
};
|
|
863
|
+
readonly shortcut: {
|
|
864
|
+
readonly label: "Ctrl+'";
|
|
865
|
+
readonly aria: "Control+'";
|
|
866
|
+
readonly editor: readonly ["Control-'"];
|
|
867
|
+
};
|
|
868
|
+
};
|
|
869
|
+
readonly copyValueFromAbove: {
|
|
870
|
+
readonly id: "editing.copyValueFromAbove";
|
|
871
|
+
readonly label: "复制上方值";
|
|
872
|
+
readonly location: {
|
|
873
|
+
readonly area: "ribbon";
|
|
874
|
+
readonly tab: "home";
|
|
875
|
+
readonly group: "editing";
|
|
876
|
+
};
|
|
877
|
+
readonly shortcut: {
|
|
878
|
+
readonly label: "Ctrl+Shift+'";
|
|
879
|
+
readonly aria: "Control+Shift+'";
|
|
880
|
+
readonly editor: readonly ["Control-Shift-'"];
|
|
881
|
+
};
|
|
882
|
+
};
|
|
855
883
|
readonly clearAll: {
|
|
856
884
|
readonly id: "editing.clearAll";
|
|
857
885
|
readonly label: "清除全部";
|
|
@@ -10,6 +10,7 @@ import type { SpreadsheetCellFormatRequest } from './spreadsheet-cell-format';
|
|
|
10
10
|
import type { SpreadsheetCellRange } from './spreadsheet-cell-range';
|
|
11
11
|
import type { SpreadsheetCellStyleChoice } from './spreadsheet-cell-style';
|
|
12
12
|
import type { SpreadsheetCellFillDirection } from './spreadsheet-cell-fill';
|
|
13
|
+
import type { SpreadsheetCopyFromAboveKind } from './spreadsheet-copy-from-above';
|
|
13
14
|
import { type SpreadsheetFontSizeDirection } from './spreadsheet-font-size-command';
|
|
14
15
|
import { type SpreadsheetDateTimeKind } from './spreadsheet-date-time-command';
|
|
15
16
|
import type { SpreadsheetDataValidationRequest, SpreadsheetDataValidationTarget } from './spreadsheet-data-validation';
|
|
@@ -162,6 +163,7 @@ export interface SpreadsheetEditorCommands {
|
|
|
162
163
|
applyTable: (request: SpreadsheetTableRequest) => boolean;
|
|
163
164
|
cancelFormatPainter: () => boolean;
|
|
164
165
|
clearSelectedCells: (mode?: SpreadsheetCellClearMode) => boolean;
|
|
166
|
+
copyCellFromAbove: (kind: SpreadsheetCopyFromAboveKind) => boolean;
|
|
165
167
|
copySelection: () => boolean;
|
|
166
168
|
cutSelection: () => boolean;
|
|
167
169
|
deleteSelectedStructure: (axis: SpreadsheetStructureAxis) => boolean;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type OfficeEditorExtension } from './office-editor-extension';
|
|
2
|
+
import type { SpreadsheetCommandContext, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
|
|
3
|
+
export declare function createSpreadsheetCopyFromAboveExtension(): OfficeEditorExtension<SpreadsheetCommandContext, SpreadsheetEditorCommands>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { WorkSpreadsheetSheet } from '../work-types';
|
|
2
|
+
import type { SpreadsheetCellRange } from './spreadsheet-cell-range';
|
|
3
|
+
export type SpreadsheetCopyFromAboveKind = 'formula' | 'value';
|
|
4
|
+
export type SpreadsheetCopyFromAboveValue = boolean | number | string | null;
|
|
5
|
+
export interface SpreadsheetCopyFromAbovePlan {
|
|
6
|
+
formulaBarValue: SpreadsheetCopyFromAboveValue | '';
|
|
7
|
+
kind: SpreadsheetCopyFromAboveKind;
|
|
8
|
+
source: {
|
|
9
|
+
row: number;
|
|
10
|
+
column: number;
|
|
11
|
+
};
|
|
12
|
+
targetRange: SpreadsheetCellRange;
|
|
13
|
+
value: SpreadsheetCopyFromAboveValue;
|
|
14
|
+
}
|
|
15
|
+
export declare function planSpreadsheetCopyFromAbove(sheet: WorkSpreadsheetSheet | undefined, target: {
|
|
16
|
+
row: number;
|
|
17
|
+
column: number;
|
|
18
|
+
}, kind: SpreadsheetCopyFromAboveKind): SpreadsheetCopyFromAbovePlan | null;
|
package/dist/office-kernel.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a3s-lab/office",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"office",
|
|
@@ -89,6 +89,7 @@
|
|
|
89
89
|
"playground:visual": "playwright test --config playwright.config.ts",
|
|
90
90
|
"playground:visual:spreadsheet-data-validation": "playwright test visual-tests/spreadsheet-data-validation.functional.spec.ts --config playwright.config.ts",
|
|
91
91
|
"playground:visual:spreadsheet-date-time": "playwright test visual-tests/spreadsheet-date-time.functional.spec.ts --config playwright.config.ts",
|
|
92
|
+
"playground:visual:spreadsheet-copy-from-above": "playwright test visual-tests/spreadsheet-copy-from-above.functional.spec.ts --config playwright.config.ts",
|
|
92
93
|
"playground:visual:spreadsheet-diagonal-borders": "playwright test visual-tests/spreadsheet-diagonal-borders.functional.spec.ts --config playwright.config.ts",
|
|
93
94
|
"playground:visual:spreadsheet-font-colors-shortcuts": "playwright test visual-tests/spreadsheet-font-colors-shortcuts.functional.spec.ts --config playwright.config.ts",
|
|
94
95
|
"playground:visual:spreadsheet-hyperlink": "playwright test visual-tests/spreadsheet-hyperlink.functional.spec.ts --config playwright.config.ts",
|
|
@@ -163,6 +164,8 @@
|
|
|
163
164
|
"test:e2e:spreadsheet-diagonal-borders:check": "a3s-test check tests/e2e/spreadsheet-diagonal-borders.acl --json",
|
|
164
165
|
"test:e2e:spreadsheet-date-time": "a3s-test run tests/e2e/spreadsheet-date-time.acl --json",
|
|
165
166
|
"test:e2e:spreadsheet-date-time:check": "a3s-test check tests/e2e/spreadsheet-date-time.acl --json",
|
|
167
|
+
"test:e2e:spreadsheet-copy-from-above": "A3S_TEST_SUITE=tests/e2e/spreadsheet-copy-from-above.acl bash scripts/run-a3s-test-web-gate.sh",
|
|
168
|
+
"test:e2e:spreadsheet-copy-from-above:check": "a3s-test check tests/e2e/spreadsheet-copy-from-above.acl --json",
|
|
166
169
|
"test:e2e:spreadsheet-hyperlink": "a3s-test run tests/e2e/spreadsheet-hyperlink.acl --json",
|
|
167
170
|
"test:e2e:spreadsheet-hyperlink:check": "a3s-test check tests/e2e/spreadsheet-hyperlink.acl --json",
|
|
168
171
|
"test:e2e:spreadsheet-maximum-sparse": "a3s-test run tests/e2e/spreadsheet-maximum-sparse.acl --json",
|