@a3s-lab/office 0.20.0 → 0.22.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/COLLABORATION_ROADMAP.md +1 -1
- package/README.md +88 -272
- package/dist/0~6090.js +1 -0
- package/dist/0~spreadsheet-editor.js +687 -162
- package/dist/0~work-office-diagnostics.js +1 -1
- package/dist/4104.js +36 -9
- package/dist/{6164.js → 5045.js} +54 -1
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/spreadsheet-cell-border.d.ts +8 -2
- package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +40 -3
- package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +2 -0
- package/dist/internal/features/work/editors/spreadsheet-date-time-command.d.ts +14 -0
- package/dist/internal/features/work/editors/spreadsheet-date-time-ribbon.d.ts +8 -0
- package/dist/internal/features/work/work-spreadsheet-diagonal-border-canvas.d.ts +12 -0
- package/dist/internal/features/work/work-spreadsheet-diagonal-borders.d.ts +13 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +53 -4
- package/docs/latest/en/browser-editor-architecture.md +16 -16
- package/package.json +8 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { __webpack_require__ } from "./0~rslib-runtime.js";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Workbook } from "@fortune-sheet/react";
|
|
4
|
-
import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowDownToLine, ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, ArrowUp, ArrowUpToLine, BadgeJapaneseYen, BarChart3, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, Bookmark, Calculator, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, Cloud, Columns3, Copy, CopyPlus, DecimalsArrowLeft, DecimalsArrowRight, Eraser, Eye, EyeOff, FileX2, Globe2, Grid2X2, Grid3X3, Hash, Italic, KeyRound, Layers2, Link2, Link2Off, ListChecks, ListFilter, LocateFixed, Merge, MessageSquareX, MoveHorizontal, MoveVertical, Paintbrush, Palette, PanelLeft, PanelTop, PanelsTopLeft, Pencil, Percent, Plus, Printer, Redo2, RefreshCw, Rows3, Save, Scissors, Search, Settings2, ShieldCheck, Sigma, SortAsc, SortDesc, Strikethrough, SwatchBook, Table2, TableProperties, Trash2, Underline, Undo2, WrapText, X } from "lucide-react";
|
|
4
|
+
import { AArrowDown, AArrowUp, AlignCenter, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowDownToLine, ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, ArrowUp, ArrowUpToLine, BadgeJapaneseYen, BarChart3, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, Bookmark, Calculator, CalendarClock, CalendarDays, Check, ChevronDown, ChevronLeft, ChevronRight, ClipboardPaste, Clock, Cloud, Columns3, Copy, CopyPlus, DecimalsArrowLeft, DecimalsArrowRight, Eraser, Eye, EyeOff, FileX2, Globe2, Grid2X2, Grid3X3, Hash, Italic, KeyRound, Layers2, Link2, Link2Off, ListChecks, ListFilter, LocateFixed, Merge, MessageSquareX, MoveHorizontal, MoveVertical, Paintbrush, Palette, PanelLeft, PanelTop, PanelsTopLeft, Pencil, Percent, Plus, Printer, Redo2, RefreshCw, Rows3, Save, Scissors, Search, Settings2, ShieldCheck, Sigma, SortAsc, SortDesc, Strikethrough, SwatchBook, Table2, TableProperties, Trash2, Underline, Undo2, WrapText, X } from "lucide-react";
|
|
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
|
-
import { freezeImportedSpreadsheetCell, spreadsheetTextOrientationFromChoice, spreadsheetMatrixProfile, withoutEditableRange, spreadsheetTextOrientationFromAngle, isSpreadsheetTextOrientationId, normalizeSpreadsheetConditionalVisualOptions, 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,
|
|
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
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";
|
|
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";
|
|
@@ -86,6 +86,74 @@ function drawCellValue(context, bounds, cell, conditionalTextColor) {
|
|
|
86
86
|
context.fillText(String(value), bounds.startX + 4, bounds.startY + height / 2, bounds.endX - bounds.startX - 8);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
+
function drawSpreadsheetDiagonalDownBorder(context, bounds, line) {
|
|
90
|
+
drawSpreadsheetDiagonalBorder(context, bounds, line, 'down');
|
|
91
|
+
}
|
|
92
|
+
function drawSpreadsheetDiagonalUpBorder(context, bounds, line) {
|
|
93
|
+
drawSpreadsheetDiagonalBorder(context, bounds, line, 'up');
|
|
94
|
+
}
|
|
95
|
+
function drawSpreadsheetDiagonalBorder(context, bounds, line, direction) {
|
|
96
|
+
const left = Math.round(bounds.startX) + 0.5;
|
|
97
|
+
const top = Math.round(bounds.startY) + 0.5;
|
|
98
|
+
const right = Math.round(bounds.endX) - 1.5;
|
|
99
|
+
const bottom = Math.round(bounds.endY) - 1.5;
|
|
100
|
+
if (right <= left || bottom <= top) return;
|
|
101
|
+
context.save();
|
|
102
|
+
context.strokeStyle = line.color;
|
|
103
|
+
context.lineCap = 'butt';
|
|
104
|
+
context.lineWidth = spreadsheetDiagonalLineWidth(line.style);
|
|
105
|
+
context.setLineDash(spreadsheetDiagonalLineDash(line.style));
|
|
106
|
+
const startY = 'down' === direction ? top : bottom;
|
|
107
|
+
const endY = 'down' === direction ? bottom : top;
|
|
108
|
+
if ('7' === line.style) {
|
|
109
|
+
drawLine(context, left, startY - 1, right, endY - 1);
|
|
110
|
+
drawLine(context, left, startY + 1, right, endY + 1);
|
|
111
|
+
} else drawLine(context, left, startY, right, endY);
|
|
112
|
+
context.restore();
|
|
113
|
+
}
|
|
114
|
+
function drawLine(context, startX, startY, endX, endY) {
|
|
115
|
+
context.beginPath();
|
|
116
|
+
context.moveTo(startX, startY);
|
|
117
|
+
context.lineTo(endX, endY);
|
|
118
|
+
context.stroke();
|
|
119
|
+
}
|
|
120
|
+
function spreadsheetDiagonalLineWidth(style) {
|
|
121
|
+
if ('2' === style) return 0.5;
|
|
122
|
+
if ([
|
|
123
|
+
'8',
|
|
124
|
+
'9',
|
|
125
|
+
'10',
|
|
126
|
+
'11',
|
|
127
|
+
'12'
|
|
128
|
+
].includes(style)) return 2;
|
|
129
|
+
if ('13' === style) return 3;
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
function spreadsheetDiagonalLineDash(style) {
|
|
133
|
+
if ('3' === style) return [
|
|
134
|
+
1,
|
|
135
|
+
2
|
|
136
|
+
];
|
|
137
|
+
if ('4' === style || '9' === style) return [
|
|
138
|
+
5,
|
|
139
|
+
3
|
|
140
|
+
];
|
|
141
|
+
if ('5' === style || '10' === style || '12' === style) return [
|
|
142
|
+
6,
|
|
143
|
+
3,
|
|
144
|
+
1,
|
|
145
|
+
3
|
|
146
|
+
];
|
|
147
|
+
if ('6' === style || '11' === style) return [
|
|
148
|
+
6,
|
|
149
|
+
3,
|
|
150
|
+
1,
|
|
151
|
+
3,
|
|
152
|
+
1,
|
|
153
|
+
3
|
|
154
|
+
];
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
89
157
|
function parseSpreadsheetConditionalColor(value) {
|
|
90
158
|
const hexadecimal = /^#?([0-9a-f]{6})$/i.exec(value.trim());
|
|
91
159
|
if (hexadecimal) return {
|
|
@@ -577,7 +645,8 @@ const spreadsheetCellBorderTargets = [
|
|
|
577
645
|
'inside',
|
|
578
646
|
'horizontal',
|
|
579
647
|
'vertical',
|
|
580
|
-
'
|
|
648
|
+
'diagonalDown',
|
|
649
|
+
'diagonalUp'
|
|
581
650
|
];
|
|
582
651
|
const spreadsheetCellBorderStyles = [
|
|
583
652
|
'thin',
|
|
@@ -615,8 +684,7 @@ const spreadsheetNativeBorderTypeByTarget = {
|
|
|
615
684
|
outside: 'border-outside',
|
|
616
685
|
inside: 'border-inside',
|
|
617
686
|
horizontal: 'border-horizontal',
|
|
618
|
-
vertical: 'border-vertical'
|
|
619
|
-
diagonal: 'border-slash'
|
|
687
|
+
vertical: 'border-vertical'
|
|
620
688
|
};
|
|
621
689
|
const spreadsheetNativeBorderStyleByName = {
|
|
622
690
|
thin: '1',
|
|
@@ -635,36 +703,29 @@ function spreadsheetNativeBorderStyle(style) {
|
|
|
635
703
|
}
|
|
636
704
|
function canSetSpreadsheetCellBorders(content, sheetId, range, format) {
|
|
637
705
|
const normalizedRange = spreadsheet_cell_range_normalizeSpreadsheetCellRange(range);
|
|
638
|
-
return Boolean(content.sheets.some((sheet)=>sheet.id === sheetId) && normalizedRange && normalizeSpreadsheetBorderFormat(format) && (
|
|
706
|
+
return Boolean(content.sheets.some((sheet)=>sheet.id === sheetId) && normalizedRange && normalizeSpreadsheetBorderFormat(format) && (!isSpreadsheetDiagonalBorderTarget(format.target) || spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) <= MAX_SPREADSHEET_DIAGONAL_BORDER_CELLS) && spreadsheetBorderInfoIsWritable(content.sheets.find((sheet)=>sheet.id === sheetId)));
|
|
639
707
|
}
|
|
640
708
|
function setSpreadsheetCellBorders(content, sheetId, range, format) {
|
|
641
709
|
const sheetIndex = content.sheets.findIndex((sheet)=>sheet.id === sheetId);
|
|
642
710
|
const sheet = content.sheets[sheetIndex];
|
|
643
711
|
const normalizedRange = spreadsheet_cell_range_normalizeSpreadsheetCellRange(range);
|
|
644
712
|
const normalizedFormat = normalizeSpreadsheetBorderFormat(format);
|
|
645
|
-
if (!sheet || !normalizedRange || !normalizedFormat || !spreadsheetBorderInfoIsWritable(sheet) ||
|
|
646
|
-
const borderType = spreadsheetNativeBorderTypeByTarget[normalizedFormat.target];
|
|
713
|
+
if (!sheet || !normalizedRange || !normalizedFormat || !spreadsheetBorderInfoIsWritable(sheet) || isSpreadsheetDiagonalBorderTarget(normalizedFormat.target) && spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) > MAX_SPREADSHEET_DIAGONAL_BORDER_CELLS) return null;
|
|
647
714
|
const source = Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : [];
|
|
715
|
+
if (isSpreadsheetDiagonalBorderTarget(normalizedFormat.target)) {
|
|
716
|
+
const borderInfo = [
|
|
717
|
+
...compactSpreadsheetBorderInfo(source, normalizedRange, 'border-slash'),
|
|
718
|
+
...spreadsheetDiagonalBorderRecords(sheet, normalizedRange, normalizedFormat.target, normalizedFormat.color, spreadsheetNativeBorderStyleByName[normalizedFormat.style])
|
|
719
|
+
];
|
|
720
|
+
return contentWithSpreadsheetBorderInfo(content, sheetIndex, sheet, borderInfo);
|
|
721
|
+
}
|
|
722
|
+
const borderType = spreadsheetNativeBorderTypeByTarget[normalizedFormat.target];
|
|
648
723
|
const compacted = compactSpreadsheetBorderInfo(source, normalizedRange, borderType);
|
|
649
724
|
const borderInfo = [
|
|
650
725
|
...compacted,
|
|
651
726
|
...spreadsheetNativeBorderRecords(normalizedRange, borderType, normalizedFormat.color, spreadsheetNativeBorderStyleByName[normalizedFormat.style])
|
|
652
727
|
];
|
|
653
|
-
|
|
654
|
-
...sheet,
|
|
655
|
-
config: {
|
|
656
|
-
...sheet.config,
|
|
657
|
-
borderInfo: borderInfo
|
|
658
|
-
}
|
|
659
|
-
};
|
|
660
|
-
const sheets = [
|
|
661
|
-
...content.sheets
|
|
662
|
-
];
|
|
663
|
-
sheets[sheetIndex] = nextSheet;
|
|
664
|
-
return {
|
|
665
|
-
...content,
|
|
666
|
-
sheets
|
|
667
|
-
};
|
|
728
|
+
return contentWithSpreadsheetBorderInfo(content, sheetIndex, sheet, borderInfo);
|
|
668
729
|
}
|
|
669
730
|
function spreadsheetCellBordersAt(sheet, row, column) {
|
|
670
731
|
const borders = {};
|
|
@@ -678,7 +739,7 @@ function spreadsheetCellBordersAt(sheet, row, column) {
|
|
|
678
739
|
applyResolvedCellBorderLine(borders, 'right', candidate.value.r);
|
|
679
740
|
applyResolvedCellBorderLine(borders, 'top', candidate.value.t);
|
|
680
741
|
applyResolvedCellBorderLine(borders, 'bottom', candidate.value.b);
|
|
681
|
-
|
|
742
|
+
applyResolvedCellDiagonalBorders(borders, candidate.value);
|
|
682
743
|
continue;
|
|
683
744
|
}
|
|
684
745
|
if ('range' !== candidate.rangeType || !isSpreadsheetNativeBorderType(candidate.borderType) || !Array.isArray(candidate.range)) continue;
|
|
@@ -690,6 +751,69 @@ function spreadsheetCellBordersAt(sheet, row, column) {
|
|
|
690
751
|
}
|
|
691
752
|
return borders;
|
|
692
753
|
}
|
|
754
|
+
function spreadsheetRenderableDiagonalBorders(sheet) {
|
|
755
|
+
const borders = new Map();
|
|
756
|
+
const source = Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : [];
|
|
757
|
+
for (const candidate of source){
|
|
758
|
+
if (!spreadsheet_cell_border_isRecord(candidate)) continue;
|
|
759
|
+
if ('cell' === candidate.rangeType) {
|
|
760
|
+
if (!spreadsheet_cell_border_isRecord(candidate.value)) continue;
|
|
761
|
+
const row = finiteSpreadsheetBorderIndex(candidate.value.row_index);
|
|
762
|
+
const column = finiteSpreadsheetBorderIndex(candidate.value.col_index);
|
|
763
|
+
if (null === row || null === column) continue;
|
|
764
|
+
const key = `${row}_${column}`;
|
|
765
|
+
const diagonal = spreadsheetDiagonalBorderFromCellValue(candidate.value);
|
|
766
|
+
if (void 0 === diagonal) continue;
|
|
767
|
+
if (!diagonal) {
|
|
768
|
+
borders.delete(key);
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
const line = resolvedCellBorderLine(diagonal.line);
|
|
772
|
+
if (!line) {
|
|
773
|
+
borders.delete(key);
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
borders.set(key, {
|
|
777
|
+
border: {
|
|
778
|
+
...diagonal.down ? {
|
|
779
|
+
down: line
|
|
780
|
+
} : {},
|
|
781
|
+
...diagonal.up ? {
|
|
782
|
+
up: line
|
|
783
|
+
} : {}
|
|
784
|
+
},
|
|
785
|
+
column,
|
|
786
|
+
row
|
|
787
|
+
});
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
if ('range' !== candidate.rangeType || 'border-none' !== candidate.borderType && 'border-slash' !== candidate.borderType || !Array.isArray(candidate.range)) continue;
|
|
791
|
+
const line = resolvedRangeBorderLine(candidate);
|
|
792
|
+
for (const rangeCandidate of candidate.range){
|
|
793
|
+
const range = parseSpreadsheetCellRange(rangeCandidate);
|
|
794
|
+
if (range) {
|
|
795
|
+
for (const [key, entry] of borders)if (spreadsheetCellRangeContains(range, entry.row, entry.column)) {
|
|
796
|
+
if ('border-none' === candidate.borderType || !entry.border.up) {
|
|
797
|
+
borders.delete(key);
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
borders.set(key, {
|
|
801
|
+
...entry,
|
|
802
|
+
border: {
|
|
803
|
+
up: line ?? entry.border.up
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return new Map([
|
|
811
|
+
...borders
|
|
812
|
+
].map(([key, entry])=>[
|
|
813
|
+
key,
|
|
814
|
+
entry.border
|
|
815
|
+
]));
|
|
816
|
+
}
|
|
693
817
|
function normalizeSpreadsheetBorderFormat(format) {
|
|
694
818
|
if (!spreadsheetCellBorderTargets.includes(format.target) || !spreadsheetCellBorderStyles.includes(format.style)) return null;
|
|
695
819
|
const color = normalizeSpreadsheetBorderColor(format.color);
|
|
@@ -716,14 +840,26 @@ function compactSpreadsheetBorderInfo(formats, range, appliedType) {
|
|
|
716
840
|
format
|
|
717
841
|
];
|
|
718
842
|
if ('cell' === format.rangeType) {
|
|
719
|
-
if (!
|
|
843
|
+
if (!spreadsheet_cell_border_isRecord(format.value)) return [
|
|
720
844
|
format
|
|
721
845
|
];
|
|
722
846
|
const row = finiteSpreadsheetBorderIndex(format.value.row_index);
|
|
723
847
|
const column = finiteSpreadsheetBorderIndex(format.value.col_index);
|
|
724
|
-
|
|
848
|
+
const selected = null !== row && null !== column && spreadsheetCellRangeContains(range, row, column);
|
|
849
|
+
if (!selected) return [
|
|
725
850
|
format
|
|
726
851
|
];
|
|
852
|
+
if (supersedesAll) return [];
|
|
853
|
+
if ('border-slash' !== appliedType) return [
|
|
854
|
+
format
|
|
855
|
+
];
|
|
856
|
+
const value = spreadsheetCellValueWithDiagonalBorder(format.value, null);
|
|
857
|
+
return Object.keys(value).some((key)=>'row_index' !== key && 'col_index' !== key) ? [
|
|
858
|
+
{
|
|
859
|
+
...format,
|
|
860
|
+
value
|
|
861
|
+
}
|
|
862
|
+
] : [];
|
|
727
863
|
}
|
|
728
864
|
if ('range' !== format.rangeType || !isSpreadsheetNativeBorderType(format.borderType) || !Array.isArray(format.range) || !supersedesAll && format.borderType !== appliedType) return [
|
|
729
865
|
format
|
|
@@ -733,9 +869,14 @@ function compactSpreadsheetBorderInfo(formats, range, appliedType) {
|
|
|
733
869
|
if (!parsed) return [
|
|
734
870
|
candidate
|
|
735
871
|
];
|
|
736
|
-
if ('border-slash' === format.borderType)
|
|
737
|
-
|
|
738
|
-
|
|
872
|
+
if ('border-slash' === format.borderType) {
|
|
873
|
+
if (!spreadsheetCellRangesIntersect(parsed, range)) return [
|
|
874
|
+
candidate
|
|
875
|
+
];
|
|
876
|
+
return 1 === spreadsheet_cell_range_spreadsheetCellRangeArea(parsed) ? [] : [
|
|
877
|
+
candidate
|
|
878
|
+
];
|
|
879
|
+
}
|
|
739
880
|
return subtractSpreadsheetCellRange(parsed, range);
|
|
740
881
|
});
|
|
741
882
|
return remaining.length ? [
|
|
@@ -747,7 +888,7 @@ function compactSpreadsheetBorderInfo(formats, range, appliedType) {
|
|
|
747
888
|
});
|
|
748
889
|
}
|
|
749
890
|
function spreadsheetNativeBorderRecords(range, borderType, color, style) {
|
|
750
|
-
|
|
891
|
+
return [
|
|
751
892
|
{
|
|
752
893
|
rangeType: 'range',
|
|
753
894
|
borderType,
|
|
@@ -758,28 +899,91 @@ function spreadsheetNativeBorderRecords(range, borderType, color, style) {
|
|
|
758
899
|
]
|
|
759
900
|
}
|
|
760
901
|
];
|
|
902
|
+
}
|
|
903
|
+
function spreadsheetDiagonalBorderRecords(sheet, range, target, color, style) {
|
|
761
904
|
const records = [];
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
905
|
+
const existing = spreadsheetDiagonalBorderDirectionsInRange(sheet, range);
|
|
906
|
+
for(let row = range.row[0]; row <= range.row[1]; row += 1)for(let column = range.column[0]; column <= range.column[1]; column += 1){
|
|
907
|
+
const current = existing.get(`${row}_${column}`);
|
|
908
|
+
const border = {
|
|
909
|
+
down: 'diagonalDown' === target || Boolean(current?.down),
|
|
910
|
+
line: {
|
|
911
|
+
color,
|
|
912
|
+
style
|
|
913
|
+
},
|
|
914
|
+
up: 'diagonalUp' === target || Boolean(current?.up)
|
|
915
|
+
};
|
|
916
|
+
records.push({
|
|
917
|
+
rangeType: 'cell',
|
|
918
|
+
value: spreadsheetCellValueWithDiagonalBorder({
|
|
919
|
+
col_index: column,
|
|
920
|
+
row_index: row
|
|
921
|
+
}, border)
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
return records;
|
|
925
|
+
}
|
|
926
|
+
function spreadsheetDiagonalBorderDirectionsInRange(sheet, selection) {
|
|
927
|
+
const directions = new Map();
|
|
928
|
+
const source = Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : [];
|
|
929
|
+
for (const candidate of source){
|
|
930
|
+
if (!spreadsheet_cell_border_isRecord(candidate)) continue;
|
|
931
|
+
if ('cell' === candidate.rangeType) {
|
|
932
|
+
if (!spreadsheet_cell_border_isRecord(candidate.value)) continue;
|
|
933
|
+
const row = finiteSpreadsheetBorderIndex(candidate.value.row_index);
|
|
934
|
+
const column = finiteSpreadsheetBorderIndex(candidate.value.col_index);
|
|
935
|
+
if (null === row || null === column || !spreadsheetCellRangeContains(selection, row, column)) continue;
|
|
936
|
+
const diagonal = spreadsheetDiagonalBorderFromCellValue(candidate.value);
|
|
937
|
+
if (void 0 === diagonal) continue;
|
|
938
|
+
const line = diagonal && resolvedCellBorderLine(diagonal.line);
|
|
939
|
+
setSpreadsheetDiagonalDirections(directions, row, column, Boolean(line && diagonal?.down), Boolean(line && diagonal?.up));
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
if ('range' !== candidate.rangeType || 'border-none' !== candidate.borderType && 'border-slash' !== candidate.borderType || !Array.isArray(candidate.range)) continue;
|
|
943
|
+
const line = resolvedRangeBorderLine(candidate);
|
|
944
|
+
for (const rangeCandidate of candidate.range){
|
|
945
|
+
const range = parseSpreadsheetCellRange(rangeCandidate);
|
|
946
|
+
if (!range || !spreadsheetCellRangesIntersect(range, selection)) continue;
|
|
947
|
+
const startRow = Math.max(range.row[0], selection.row[0]);
|
|
948
|
+
const endRow = Math.min(range.row[1], selection.row[1]);
|
|
949
|
+
const startColumn = Math.max(range.column[0], selection.column[0]);
|
|
950
|
+
const endColumn = Math.min(range.column[1], selection.column[1]);
|
|
951
|
+
for(let row = startRow; row <= endRow; row += 1)for(let column = startColumn; column <= endColumn; column += 1){
|
|
952
|
+
if ('border-none' === candidate.borderType) {
|
|
953
|
+
directions.delete(`${row}_${column}`);
|
|
954
|
+
continue;
|
|
955
|
+
}
|
|
956
|
+
const current = directions.get(`${row}_${column}`);
|
|
957
|
+
setSpreadsheetDiagonalDirections(directions, row, column, Boolean(line), Boolean(current?.up));
|
|
779
958
|
}
|
|
780
|
-
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return directions;
|
|
962
|
+
}
|
|
963
|
+
function setSpreadsheetDiagonalDirections(directions, row, column, down, up) {
|
|
964
|
+
const key = `${row}_${column}`;
|
|
965
|
+
if (!down && !up) return void directions.delete(key);
|
|
966
|
+
directions.set(key, {
|
|
967
|
+
down,
|
|
968
|
+
up
|
|
781
969
|
});
|
|
782
|
-
|
|
970
|
+
}
|
|
971
|
+
function contentWithSpreadsheetBorderInfo(content, sheetIndex, sheet, borderInfo) {
|
|
972
|
+
const nextSheet = {
|
|
973
|
+
...sheet,
|
|
974
|
+
config: {
|
|
975
|
+
...sheet.config,
|
|
976
|
+
borderInfo: borderInfo
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
const sheets = [
|
|
980
|
+
...content.sheets
|
|
981
|
+
];
|
|
982
|
+
sheets[sheetIndex] = nextSheet;
|
|
983
|
+
return {
|
|
984
|
+
...content,
|
|
985
|
+
sheets
|
|
986
|
+
};
|
|
783
987
|
}
|
|
784
988
|
function applyResolvedCellBorderLine(borders, side, value) {
|
|
785
989
|
if (null === value) return void delete borders[side];
|
|
@@ -791,6 +995,26 @@ function applyResolvedCellBorderLine(borders, side, value) {
|
|
|
791
995
|
style
|
|
792
996
|
};
|
|
793
997
|
}
|
|
998
|
+
function applyResolvedCellDiagonalBorders(borders, value) {
|
|
999
|
+
const diagonal = spreadsheetDiagonalBorderFromCellValue(value);
|
|
1000
|
+
if (void 0 === diagonal) return;
|
|
1001
|
+
delete borders.diagonalDown;
|
|
1002
|
+
delete borders.diagonalUp;
|
|
1003
|
+
if (!diagonal) return;
|
|
1004
|
+
const line = resolvedCellBorderLine(diagonal.line);
|
|
1005
|
+
if (!line) return;
|
|
1006
|
+
if (diagonal.down) borders.diagonalDown = line;
|
|
1007
|
+
if (diagonal.up) borders.diagonalUp = line;
|
|
1008
|
+
}
|
|
1009
|
+
function resolvedCellBorderLine(value) {
|
|
1010
|
+
if (!spreadsheet_cell_border_isRecord(value)) return null;
|
|
1011
|
+
const color = 'string' == typeof value.color ? normalizeSpreadsheetBorderColor(value.color) : null;
|
|
1012
|
+
const style = 'string' == typeof value.style ? value.style : null;
|
|
1013
|
+
return color && style ? {
|
|
1014
|
+
color,
|
|
1015
|
+
style
|
|
1016
|
+
} : null;
|
|
1017
|
+
}
|
|
794
1018
|
function resolvedRangeBorderLine(value) {
|
|
795
1019
|
const color = 'string' == typeof value.color ? normalizeSpreadsheetBorderColor(value.color) : null;
|
|
796
1020
|
const style = 'string' == typeof value.style ? value.style : null;
|
|
@@ -826,7 +1050,8 @@ function applyResolvedRangeBorder(borders, range, row, column, type, line) {
|
|
|
826
1050
|
delete borders.bottom;
|
|
827
1051
|
delete borders.left;
|
|
828
1052
|
delete borders.right;
|
|
829
|
-
delete borders.
|
|
1053
|
+
delete borders.diagonalDown;
|
|
1054
|
+
delete borders.diagonalUp;
|
|
830
1055
|
break;
|
|
831
1056
|
case 'border-all':
|
|
832
1057
|
set('top');
|
|
@@ -855,10 +1080,16 @@ function applyResolvedRangeBorder(borders, range, row, column, type, line) {
|
|
|
855
1080
|
if (!onRight) set('right');
|
|
856
1081
|
break;
|
|
857
1082
|
case 'border-slash':
|
|
858
|
-
|
|
1083
|
+
if (line) {
|
|
1084
|
+
borders.diagonalDown = line;
|
|
1085
|
+
if (borders.diagonalUp) borders.diagonalUp = line;
|
|
1086
|
+
} else delete borders.diagonalDown;
|
|
859
1087
|
break;
|
|
860
1088
|
}
|
|
861
1089
|
}
|
|
1090
|
+
function isSpreadsheetDiagonalBorderTarget(target) {
|
|
1091
|
+
return 'diagonalDown' === target || 'diagonalUp' === target;
|
|
1092
|
+
}
|
|
862
1093
|
function isSpreadsheetNativeBorderType(value) {
|
|
863
1094
|
return 'string' == typeof value && spreadsheetNativeBorderTypes.has(value);
|
|
864
1095
|
}
|
|
@@ -3005,6 +3236,38 @@ const spreadsheetCommandCatalog = {
|
|
|
3005
3236
|
group: 'number'
|
|
3006
3237
|
}
|
|
3007
3238
|
},
|
|
3239
|
+
insertCurrentDate: {
|
|
3240
|
+
id: 'number.insertCurrentDate',
|
|
3241
|
+
label: '插入当前日期',
|
|
3242
|
+
location: {
|
|
3243
|
+
area: 'ribbon',
|
|
3244
|
+
tab: 'home',
|
|
3245
|
+
group: 'number'
|
|
3246
|
+
},
|
|
3247
|
+
shortcut: {
|
|
3248
|
+
label: 'Ctrl+;',
|
|
3249
|
+
aria: 'Control+;',
|
|
3250
|
+
editor: [
|
|
3251
|
+
'Control-;'
|
|
3252
|
+
]
|
|
3253
|
+
}
|
|
3254
|
+
},
|
|
3255
|
+
insertCurrentTime: {
|
|
3256
|
+
id: 'number.insertCurrentTime',
|
|
3257
|
+
label: '插入当前时间',
|
|
3258
|
+
location: {
|
|
3259
|
+
area: 'ribbon',
|
|
3260
|
+
tab: 'home',
|
|
3261
|
+
group: 'number'
|
|
3262
|
+
},
|
|
3263
|
+
shortcut: {
|
|
3264
|
+
label: 'Ctrl+Shift+;',
|
|
3265
|
+
aria: 'Control+Shift+;',
|
|
3266
|
+
editor: [
|
|
3267
|
+
'Control-Shift-;'
|
|
3268
|
+
]
|
|
3269
|
+
}
|
|
3270
|
+
},
|
|
3008
3271
|
formatCells: {
|
|
3009
3272
|
id: 'number.formatCells',
|
|
3010
3273
|
label: '设置单元格格式',
|
|
@@ -3127,9 +3390,18 @@ const spreadsheetCommandCatalog = {
|
|
|
3127
3390
|
group: 'font'
|
|
3128
3391
|
}
|
|
3129
3392
|
},
|
|
3130
|
-
|
|
3131
|
-
id: 'font.
|
|
3132
|
-
label: '
|
|
3393
|
+
borderDiagonalDown: {
|
|
3394
|
+
id: 'font.borderDiagonalDown',
|
|
3395
|
+
label: '斜下框线',
|
|
3396
|
+
location: {
|
|
3397
|
+
area: 'ribbon',
|
|
3398
|
+
tab: 'home',
|
|
3399
|
+
group: 'font'
|
|
3400
|
+
}
|
|
3401
|
+
},
|
|
3402
|
+
borderDiagonalUp: {
|
|
3403
|
+
id: 'font.borderDiagonalUp',
|
|
3404
|
+
label: '斜上框线',
|
|
3133
3405
|
location: {
|
|
3134
3406
|
area: 'ribbon',
|
|
3135
3407
|
tab: 'home',
|
|
@@ -4077,14 +4349,16 @@ const MAX_SPREADSHEET_PER_CELL_BORDER_CELLS = 10000;
|
|
|
4077
4349
|
function setSpreadsheetCellBordersPerCell(content, sheetId, range, formats) {
|
|
4078
4350
|
const normalizedRange = spreadsheet_cell_range_normalizeSpreadsheetCellRange(range);
|
|
4079
4351
|
const normalizedFormats = formats.map(normalizeSpreadsheetBorderFormat);
|
|
4080
|
-
|
|
4352
|
+
const area = normalizedRange ? spreadsheet_cell_range_spreadsheetCellRangeArea(normalizedRange) : 1 / 0;
|
|
4353
|
+
if (!normalizedRange || area > MAX_SPREADSHEET_PER_CELL_BORDER_CELLS || normalizedFormats.some((format)=>!format || ![
|
|
4081
4354
|
'top',
|
|
4082
4355
|
'bottom',
|
|
4083
4356
|
'left',
|
|
4084
4357
|
'right',
|
|
4085
4358
|
'all',
|
|
4086
|
-
'
|
|
4087
|
-
|
|
4359
|
+
'diagonalDown',
|
|
4360
|
+
'diagonalUp'
|
|
4361
|
+
].includes(format.target)) || area > 4096 && normalizedFormats.some((format)=>format?.target === 'diagonalDown' || format?.target === 'diagonalUp')) return null;
|
|
4088
4362
|
const next = setSpreadsheetCellBorders(content, sheetId, normalizedRange, {
|
|
4089
4363
|
target: 'none',
|
|
4090
4364
|
color: '#000000',
|
|
@@ -4100,6 +4374,9 @@ function setSpreadsheetCellBordersPerCell(content, sheetId, range, formats) {
|
|
|
4100
4374
|
row_index: row,
|
|
4101
4375
|
col_index: column
|
|
4102
4376
|
};
|
|
4377
|
+
let diagonalDown = false;
|
|
4378
|
+
let diagonalUp = false;
|
|
4379
|
+
let diagonalLine = null;
|
|
4103
4380
|
for (const format of normalizedFormats){
|
|
4104
4381
|
if (!format) continue;
|
|
4105
4382
|
const line = {
|
|
@@ -4110,11 +4387,22 @@ function setSpreadsheetCellBordersPerCell(content, sheetId, range, formats) {
|
|
|
4110
4387
|
if ('all' === format.target || 'right' === format.target) value.r = line;
|
|
4111
4388
|
if ('all' === format.target || 'top' === format.target) value.t = line;
|
|
4112
4389
|
if ('all' === format.target || 'bottom' === format.target) value.b = line;
|
|
4113
|
-
if ('
|
|
4390
|
+
if ('diagonalDown' === format.target) {
|
|
4391
|
+
diagonalDown = true;
|
|
4392
|
+
diagonalLine = line;
|
|
4393
|
+
}
|
|
4394
|
+
if ('diagonalUp' === format.target) {
|
|
4395
|
+
diagonalUp = true;
|
|
4396
|
+
diagonalLine = line;
|
|
4397
|
+
}
|
|
4114
4398
|
}
|
|
4115
4399
|
records.push({
|
|
4116
4400
|
rangeType: 'cell',
|
|
4117
|
-
value
|
|
4401
|
+
value: diagonalLine && (diagonalDown || diagonalUp) ? spreadsheetCellValueWithDiagonalBorder(value, {
|
|
4402
|
+
down: diagonalDown,
|
|
4403
|
+
line: diagonalLine,
|
|
4404
|
+
up: diagonalUp
|
|
4405
|
+
}) : value
|
|
4118
4406
|
});
|
|
4119
4407
|
}
|
|
4120
4408
|
const borderInfo = [
|
|
@@ -4180,8 +4468,9 @@ function canApplySpreadsheetCellFormat(content, request) {
|
|
|
4180
4468
|
'left',
|
|
4181
4469
|
'right',
|
|
4182
4470
|
'all',
|
|
4183
|
-
'
|
|
4184
|
-
|
|
4471
|
+
'diagonalDown',
|
|
4472
|
+
'diagonalUp'
|
|
4473
|
+
].includes(format.target)) || normalized.some((format)=>format?.target === 'diagonalDown' || format?.target === 'diagonalUp') && spreadsheet_cell_range_spreadsheetCellRangeArea(range) > 4096) return false;
|
|
4185
4474
|
}
|
|
4186
4475
|
return true;
|
|
4187
4476
|
}
|
|
@@ -4699,14 +4988,16 @@ function sameCellStyleBorders(actual, formats) {
|
|
|
4699
4988
|
if ('all' === format.target || 'right' === format.target) expected.right = line;
|
|
4700
4989
|
if ('all' === format.target || 'top' === format.target) expected.top = line;
|
|
4701
4990
|
if ('all' === format.target || 'bottom' === format.target) expected.bottom = line;
|
|
4702
|
-
if ('
|
|
4991
|
+
if ('diagonalDown' === format.target) expected.diagonalDown = line;
|
|
4992
|
+
if ('diagonalUp' === format.target) expected.diagonalUp = line;
|
|
4703
4993
|
}
|
|
4704
4994
|
return [
|
|
4705
4995
|
'top',
|
|
4706
4996
|
'bottom',
|
|
4707
4997
|
'left',
|
|
4708
4998
|
'right',
|
|
4709
|
-
'
|
|
4999
|
+
'diagonalDown',
|
|
5000
|
+
'diagonalUp'
|
|
4710
5001
|
].every((side)=>actual[side]?.color === expected[side]?.color && actual[side]?.style === expected[side]?.style);
|
|
4711
5002
|
}
|
|
4712
5003
|
function createSpreadsheetCellStyleExtension() {
|
|
@@ -5777,6 +6068,207 @@ function clampSpreadsheetDataValidationFocus(value, range) {
|
|
|
5777
6068
|
const focus = 'number' == typeof value && Number.isFinite(value) ? Math.trunc(value) : minimum;
|
|
5778
6069
|
return Math.min(maximum, Math.max(minimum, focus));
|
|
5779
6070
|
}
|
|
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
|
+
const MILLISECONDS_PER_DAY = 86400000;
|
|
6147
|
+
const MINUTES_PER_DAY = 1440;
|
|
6148
|
+
const EXCEL_1900_EPOCH_UTC = Date.UTC(1899, 11, 30);
|
|
6149
|
+
function spreadsheetDateTimeEntry(kind, now) {
|
|
6150
|
+
if (!Number.isFinite(now.getTime())) return null;
|
|
6151
|
+
if ('date' === kind) {
|
|
6152
|
+
const year = now.getFullYear();
|
|
6153
|
+
const month = now.getMonth();
|
|
6154
|
+
const day = now.getDate();
|
|
6155
|
+
const value = (Date.UTC(year, month, day) - EXCEL_1900_EPOCH_UTC) / MILLISECONDS_PER_DAY;
|
|
6156
|
+
if (!Number.isFinite(value)) return null;
|
|
6157
|
+
return {
|
|
6158
|
+
format: {
|
|
6159
|
+
fa: 'yyyy-MM-dd',
|
|
6160
|
+
t: 'd'
|
|
6161
|
+
},
|
|
6162
|
+
formulaBarValue: `${padDatePart(year, 4)}-${padDatePart(month + 1)}-${padDatePart(day)}`,
|
|
6163
|
+
value
|
|
6164
|
+
};
|
|
6165
|
+
}
|
|
6166
|
+
if ('time' !== kind) return null;
|
|
6167
|
+
const hours = now.getHours();
|
|
6168
|
+
const minutes = now.getMinutes();
|
|
6169
|
+
return {
|
|
6170
|
+
format: {
|
|
6171
|
+
fa: 'hh:mm',
|
|
6172
|
+
t: 'd'
|
|
6173
|
+
},
|
|
6174
|
+
formulaBarValue: `${padDatePart(hours)}:${padDatePart(minutes)}`,
|
|
6175
|
+
value: (60 * hours + minutes) / MINUTES_PER_DAY
|
|
6176
|
+
};
|
|
6177
|
+
}
|
|
6178
|
+
function createSpreadsheetDateTimeExtension() {
|
|
6179
|
+
return createOfficeEditorExtension({
|
|
6180
|
+
name: 'spreadsheetDateTime',
|
|
6181
|
+
addCommands: ()=>({
|
|
6182
|
+
insertCurrentDateTime: {
|
|
6183
|
+
canExecute: (context, kind)=>isSpreadsheetDateTimeKind(kind) && null !== spreadsheetDateTimeTarget(context),
|
|
6184
|
+
execute: insertCurrentSpreadsheetDateTime
|
|
6185
|
+
}
|
|
6186
|
+
}),
|
|
6187
|
+
addKeyboardShortcuts: ()=>({
|
|
6188
|
+
[spreadsheetCommandCatalog.insertCurrentDate.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetDateTimeShortcut(event, 'date', can.insertCurrentDateTime, commands.insertCurrentDateTime),
|
|
6189
|
+
[spreadsheetCommandCatalog.insertCurrentTime.shortcut.editor["0"]]: ({ can, commands }, event)=>runSpreadsheetDateTimeShortcut(event, 'time', can.insertCurrentDateTime, commands.insertCurrentDateTime)
|
|
6190
|
+
})
|
|
6191
|
+
});
|
|
6192
|
+
}
|
|
6193
|
+
function insertCurrentSpreadsheetDateTime(context, kind) {
|
|
6194
|
+
if (!isSpreadsheetDateTimeKind(kind)) return false;
|
|
6195
|
+
const target = spreadsheetDateTimeTarget(context);
|
|
6196
|
+
const entry = spreadsheetDateTimeEntry(kind, new Date());
|
|
6197
|
+
if (!target || !entry || !context.workbook) return false;
|
|
6198
|
+
try {
|
|
6199
|
+
context.workbook.batchCallApis([
|
|
6200
|
+
{
|
|
6201
|
+
name: 'setCellValuesByRange',
|
|
6202
|
+
args: [
|
|
6203
|
+
[
|
|
6204
|
+
[
|
|
6205
|
+
entry.value
|
|
6206
|
+
]
|
|
6207
|
+
],
|
|
6208
|
+
target.range,
|
|
6209
|
+
{
|
|
6210
|
+
id: target.sheetId
|
|
6211
|
+
}
|
|
6212
|
+
]
|
|
6213
|
+
},
|
|
6214
|
+
{
|
|
6215
|
+
name: 'setCellFormatByRange',
|
|
6216
|
+
args: [
|
|
6217
|
+
'ct',
|
|
6218
|
+
entry.format,
|
|
6219
|
+
target.range,
|
|
6220
|
+
{
|
|
6221
|
+
id: target.sheetId
|
|
6222
|
+
}
|
|
6223
|
+
]
|
|
6224
|
+
}
|
|
6225
|
+
]);
|
|
6226
|
+
} catch {
|
|
6227
|
+
return false;
|
|
6228
|
+
}
|
|
6229
|
+
try {
|
|
6230
|
+
context.formulaBar?.setValue(entry.formulaBarValue);
|
|
6231
|
+
} catch {}
|
|
6232
|
+
return true;
|
|
6233
|
+
}
|
|
6234
|
+
function spreadsheetDateTimeTarget(context) {
|
|
6235
|
+
const workbook = context.workbook;
|
|
6236
|
+
const sheetId = context.targetSheetId;
|
|
6237
|
+
if (!context.editable || !workbook || !sheetId || sheetId !== context.activeSheetId) return null;
|
|
6238
|
+
try {
|
|
6239
|
+
const selection = finiteSpreadsheetSelection(workbook.getSelection()?.at(-1) ?? context.fallbackRange);
|
|
6240
|
+
const row = selection.row_focus ?? selection.row[0] ?? 0;
|
|
6241
|
+
const column = selection.column_focus ?? selection.column[0] ?? 0;
|
|
6242
|
+
if (!Number.isSafeInteger(row) || row < 0 || row >= MAX_SPREADSHEET_ROWS || !Number.isSafeInteger(column) || column < 0 || column >= 16384) return null;
|
|
6243
|
+
const range = {
|
|
6244
|
+
row: [
|
|
6245
|
+
row,
|
|
6246
|
+
row
|
|
6247
|
+
],
|
|
6248
|
+
column: [
|
|
6249
|
+
column,
|
|
6250
|
+
column
|
|
6251
|
+
]
|
|
6252
|
+
};
|
|
6253
|
+
const sheet = context.content.sheets.find((candidate)=>candidate.id === sheetId);
|
|
6254
|
+
return canMutateSpreadsheetCellRange(sheet, range) ? {
|
|
6255
|
+
range,
|
|
6256
|
+
sheetId
|
|
6257
|
+
} : null;
|
|
6258
|
+
} catch {
|
|
6259
|
+
return null;
|
|
6260
|
+
}
|
|
6261
|
+
}
|
|
6262
|
+
function runSpreadsheetDateTimeShortcut(event, kind, canExecute, execute) {
|
|
6263
|
+
if (event.repeat || event.isComposing || isOfficeShortcutBlocked(event.target) || isSpreadsheetNativeTextUndoTarget(event.target) || !isSpreadsheetGridKeyboardTarget(event.target) || !canExecute(kind)) return false;
|
|
6264
|
+
return execute(kind);
|
|
6265
|
+
}
|
|
6266
|
+
function isSpreadsheetDateTimeKind(value) {
|
|
6267
|
+
return 'date' === value || 'time' === value;
|
|
6268
|
+
}
|
|
6269
|
+
function padDatePart(value, length = 2) {
|
|
6270
|
+
return String(value).padStart(length, '0');
|
|
6271
|
+
}
|
|
5780
6272
|
function canApplySpreadsheetCellMerge(sheet, range, command) {
|
|
5781
6273
|
if (!sheet) return false;
|
|
5782
6274
|
const normalized = normalizeSpreadsheetCellMergeRange(range);
|
|
@@ -8109,6 +8601,7 @@ function createSpreadsheetEditorExtensions() {
|
|
|
8109
8601
|
createSpreadsheetCellBorderExtension(),
|
|
8110
8602
|
createSpreadsheetCellStyleExtension(),
|
|
8111
8603
|
createSpreadsheetNumberFormatExtension(),
|
|
8604
|
+
createSpreadsheetDateTimeExtension(),
|
|
8112
8605
|
createSpreadsheetNavigationExtension(),
|
|
8113
8606
|
createSpreadsheetDataValidationExtension(),
|
|
8114
8607
|
createSpreadsheetHyperlinkExtension(),
|
|
@@ -10195,8 +10688,12 @@ const spreadsheetBorderTargetOptions = [
|
|
|
10195
10688
|
definition: spreadsheetCommandCatalog.borderVertical
|
|
10196
10689
|
},
|
|
10197
10690
|
{
|
|
10198
|
-
target: '
|
|
10199
|
-
definition: spreadsheetCommandCatalog.
|
|
10691
|
+
target: 'diagonalDown',
|
|
10692
|
+
definition: spreadsheetCommandCatalog.borderDiagonalDown
|
|
10693
|
+
},
|
|
10694
|
+
{
|
|
10695
|
+
target: 'diagonalUp',
|
|
10696
|
+
definition: spreadsheetCommandCatalog.borderDiagonalUp
|
|
10200
10697
|
}
|
|
10201
10698
|
];
|
|
10202
10699
|
function SpreadsheetBorderRibbon({ can, commands }) {
|
|
@@ -10458,6 +10955,73 @@ function SpreadsheetUnderlineGlyph({ style }) {
|
|
|
10458
10955
|
})
|
|
10459
10956
|
});
|
|
10460
10957
|
}
|
|
10958
|
+
function SpreadsheetDateTimeMenu({ can, commands }) {
|
|
10959
|
+
const items = [
|
|
10960
|
+
{
|
|
10961
|
+
definition: spreadsheetCommandCatalog.insertCurrentDate,
|
|
10962
|
+
icon: /*#__PURE__*/ jsx(CalendarDays, {
|
|
10963
|
+
size: 16
|
|
10964
|
+
}),
|
|
10965
|
+
kind: 'date'
|
|
10966
|
+
},
|
|
10967
|
+
{
|
|
10968
|
+
definition: spreadsheetCommandCatalog.insertCurrentTime,
|
|
10969
|
+
icon: /*#__PURE__*/ jsx(Clock, {
|
|
10970
|
+
size: 16
|
|
10971
|
+
}),
|
|
10972
|
+
kind: 'time'
|
|
10973
|
+
}
|
|
10974
|
+
];
|
|
10975
|
+
const disabled = items.every(({ kind })=>!can.insertCurrentDateTime(kind));
|
|
10976
|
+
return /*#__PURE__*/ jsx(Popover, {
|
|
10977
|
+
label: "日期和时间",
|
|
10978
|
+
panelLabel: "插入日期和时间",
|
|
10979
|
+
panelRole: "menu",
|
|
10980
|
+
portal: true,
|
|
10981
|
+
className: "work-spreadsheet-ribbon-menu-root",
|
|
10982
|
+
panelClassName: "work-office-context-menu work-spreadsheet-ribbon-menu",
|
|
10983
|
+
disabled: disabled,
|
|
10984
|
+
focusFirstOnOpen: true,
|
|
10985
|
+
onPanelKeyDown: moveOfficeMenuFocus,
|
|
10986
|
+
trigger: (triggerProps, { open })=>/*#__PURE__*/ jsxs("button", {
|
|
10987
|
+
...triggerProps,
|
|
10988
|
+
className: `with-label work-spreadsheet-ribbon-menu-trigger work-spreadsheet-date-time-trigger${open ? ' active' : ''}`,
|
|
10989
|
+
title: "插入当前日期或时间(Ctrl+; / Ctrl+Shift+;)",
|
|
10990
|
+
children: [
|
|
10991
|
+
/*#__PURE__*/ jsx(CalendarClock, {
|
|
10992
|
+
size: 19
|
|
10993
|
+
}),
|
|
10994
|
+
/*#__PURE__*/ jsx("span", {
|
|
10995
|
+
children: "日期和时间"
|
|
10996
|
+
})
|
|
10997
|
+
]
|
|
10998
|
+
}),
|
|
10999
|
+
children: (close)=>items.map(({ definition, icon, kind })=>/*#__PURE__*/ jsxs("button", {
|
|
11000
|
+
type: "button",
|
|
11001
|
+
role: "menuitem",
|
|
11002
|
+
tabIndex: -1,
|
|
11003
|
+
"aria-label": definition.label,
|
|
11004
|
+
"aria-keyshortcuts": definition.shortcut.aria,
|
|
11005
|
+
disabled: !can.insertCurrentDateTime(kind),
|
|
11006
|
+
onClick: ()=>{
|
|
11007
|
+
close();
|
|
11008
|
+
commands.insertCurrentDateTime(kind);
|
|
11009
|
+
},
|
|
11010
|
+
children: [
|
|
11011
|
+
/*#__PURE__*/ jsx("span", {
|
|
11012
|
+
className: "work-spreadsheet-ribbon-menu-item-icon",
|
|
11013
|
+
children: icon
|
|
11014
|
+
}),
|
|
11015
|
+
/*#__PURE__*/ jsx("span", {
|
|
11016
|
+
children: definition.label
|
|
11017
|
+
}),
|
|
11018
|
+
/*#__PURE__*/ jsx("kbd", {
|
|
11019
|
+
children: definition.shortcut.label
|
|
11020
|
+
})
|
|
11021
|
+
]
|
|
11022
|
+
}, definition.id))
|
|
11023
|
+
});
|
|
11024
|
+
}
|
|
10461
11025
|
const spreadsheetNumberFormatOptions = [
|
|
10462
11026
|
{
|
|
10463
11027
|
value: 'general',
|
|
@@ -10655,16 +11219,25 @@ function SpreadsheetNumberRibbonGroup({ can, commands, toolbarCell }) {
|
|
|
10655
11219
|
label: "数字",
|
|
10656
11220
|
priority: "high",
|
|
10657
11221
|
children: [
|
|
10658
|
-
/*#__PURE__*/
|
|
10659
|
-
className: "work-spreadsheet-number-format",
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
11222
|
+
/*#__PURE__*/ jsxs("div", {
|
|
11223
|
+
className: "work-spreadsheet-number-format-stack",
|
|
11224
|
+
children: [
|
|
11225
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
11226
|
+
className: "work-spreadsheet-number-format",
|
|
11227
|
+
ariaLabel: "数字格式",
|
|
11228
|
+
value: numberFormatPreset,
|
|
11229
|
+
disabled: !can.setCellFormat('ct', currentNumberFormatValue),
|
|
11230
|
+
options: spreadsheetNumberFormatOptions,
|
|
11231
|
+
onValueChange: (preset)=>{
|
|
11232
|
+
if ('custom' === preset) return;
|
|
11233
|
+
commands.setCellFormat('ct', spreadsheetNumberFormatValue(spreadsheetNumberFormatCode(preset), toolbarCell));
|
|
11234
|
+
}
|
|
11235
|
+
}),
|
|
11236
|
+
/*#__PURE__*/ jsx(SpreadsheetDateTimeMenu, {
|
|
11237
|
+
can: can,
|
|
11238
|
+
commands: commands
|
|
11239
|
+
})
|
|
11240
|
+
]
|
|
10668
11241
|
}),
|
|
10669
11242
|
/*#__PURE__*/ jsx(WorkOfficeRibbonButton, {
|
|
10670
11243
|
label: `${currencyDefinition.label}格式`,
|
|
@@ -12680,8 +13253,12 @@ const borderTargets = [
|
|
|
12680
13253
|
label: '右框线'
|
|
12681
13254
|
},
|
|
12682
13255
|
{
|
|
12683
|
-
target: '
|
|
12684
|
-
label: '
|
|
13256
|
+
target: 'diagonalDown',
|
|
13257
|
+
label: '斜下框线'
|
|
13258
|
+
},
|
|
13259
|
+
{
|
|
13260
|
+
target: 'diagonalUp',
|
|
13261
|
+
label: '斜上框线'
|
|
12685
13262
|
}
|
|
12686
13263
|
];
|
|
12687
13264
|
function SpreadsheetFormatCellsPanel(props) {
|
|
@@ -13114,10 +13691,16 @@ function BorderPreview({ draft }) {
|
|
|
13114
13691
|
borderRight: line('right')
|
|
13115
13692
|
}
|
|
13116
13693
|
}),
|
|
13117
|
-
line('
|
|
13118
|
-
className: "diagonal",
|
|
13694
|
+
line('diagonalDown') && /*#__PURE__*/ jsx("span", {
|
|
13695
|
+
className: "diagonal-down",
|
|
13696
|
+
style: {
|
|
13697
|
+
borderTop: line('diagonalDown')
|
|
13698
|
+
}
|
|
13699
|
+
}),
|
|
13700
|
+
line('diagonalUp') && /*#__PURE__*/ jsx("span", {
|
|
13701
|
+
className: "diagonal-up",
|
|
13119
13702
|
style: {
|
|
13120
|
-
borderTop: line('
|
|
13703
|
+
borderTop: line('diagonalUp')
|
|
13121
13704
|
}
|
|
13122
13705
|
}),
|
|
13123
13706
|
/*#__PURE__*/ jsx("strong", {
|
|
@@ -13388,7 +13971,8 @@ function borderFormatsAt(sheet, row, column) {
|
|
|
13388
13971
|
'bottom',
|
|
13389
13972
|
'left',
|
|
13390
13973
|
'right',
|
|
13391
|
-
'
|
|
13974
|
+
'diagonalDown',
|
|
13975
|
+
'diagonalUp'
|
|
13392
13976
|
].flatMap((target)=>{
|
|
13393
13977
|
const line = resolved[target];
|
|
13394
13978
|
if (!line) return [];
|
|
@@ -13510,81 +14094,6 @@ function formatCellsSelectionDescription(source) {
|
|
|
13510
14094
|
const columns = source.range.column[1] - source.range.column[0] + 1;
|
|
13511
14095
|
return `设置当前选区的数字、对齐、字体、边框、填充和保护属性(${rows} 行 × ${columns} 列)。`;
|
|
13512
14096
|
}
|
|
13513
|
-
const MAX_SPREADSHEET_ROWS = 1048576;
|
|
13514
|
-
const spreadsheetPasteContentOptions = [
|
|
13515
|
-
{
|
|
13516
|
-
value: 'all',
|
|
13517
|
-
label: '全部',
|
|
13518
|
-
richOnly: false
|
|
13519
|
-
},
|
|
13520
|
-
{
|
|
13521
|
-
value: 'formulas',
|
|
13522
|
-
label: '公式',
|
|
13523
|
-
richOnly: false
|
|
13524
|
-
},
|
|
13525
|
-
{
|
|
13526
|
-
value: 'values',
|
|
13527
|
-
label: '值',
|
|
13528
|
-
richOnly: false
|
|
13529
|
-
},
|
|
13530
|
-
{
|
|
13531
|
-
value: 'formats',
|
|
13532
|
-
label: '格式',
|
|
13533
|
-
richOnly: true
|
|
13534
|
-
},
|
|
13535
|
-
{
|
|
13536
|
-
value: 'comments',
|
|
13537
|
-
label: '批注',
|
|
13538
|
-
richOnly: true
|
|
13539
|
-
},
|
|
13540
|
-
{
|
|
13541
|
-
value: 'validation',
|
|
13542
|
-
label: '数据验证',
|
|
13543
|
-
richOnly: true
|
|
13544
|
-
},
|
|
13545
|
-
{
|
|
13546
|
-
value: 'all-except-borders',
|
|
13547
|
-
label: '边框除外的全部',
|
|
13548
|
-
richOnly: true
|
|
13549
|
-
},
|
|
13550
|
-
{
|
|
13551
|
-
value: 'formulas-and-number-formats',
|
|
13552
|
-
label: '公式和数字格式',
|
|
13553
|
-
richOnly: true
|
|
13554
|
-
},
|
|
13555
|
-
{
|
|
13556
|
-
value: 'values-and-number-formats',
|
|
13557
|
-
label: '值和数字格式',
|
|
13558
|
-
richOnly: true
|
|
13559
|
-
},
|
|
13560
|
-
{
|
|
13561
|
-
value: 'column-widths',
|
|
13562
|
-
label: '列宽',
|
|
13563
|
-
richOnly: true
|
|
13564
|
-
}
|
|
13565
|
-
];
|
|
13566
|
-
const spreadsheetPasteOperationOptions = [
|
|
13567
|
-
{
|
|
13568
|
-
value: 'none',
|
|
13569
|
-
label: '无'
|
|
13570
|
-
},
|
|
13571
|
-
{
|
|
13572
|
-
value: 'add',
|
|
13573
|
-
label: '加'
|
|
13574
|
-
},
|
|
13575
|
-
{
|
|
13576
|
-
value: 'subtract',
|
|
13577
|
-
label: '减'
|
|
13578
|
-
},
|
|
13579
|
-
{
|
|
13580
|
-
value: 'multiply',
|
|
13581
|
-
label: '乘'
|
|
13582
|
-
},
|
|
13583
|
-
{
|
|
13584
|
-
value: 'divide',
|
|
13585
|
-
label: '除'
|
|
13586
|
-
}
|
|
13587
|
-
];
|
|
13588
14097
|
function captureSpreadsheetClipboardSnapshot(content, sheetId, selection, plainText) {
|
|
13589
14098
|
const range = spreadsheet_cell_range_normalizeSpreadsheetCellRange(selection);
|
|
13590
14099
|
const sheet = content.sheets.find((candidate)=>candidate.id === sheetId);
|
|
@@ -20326,20 +20835,22 @@ function applySpreadsheetPasteBorders(content, sheetId, snapshot, plan, processe
|
|
|
20326
20835
|
[
|
|
20327
20836
|
'bottom',
|
|
20328
20837
|
'b'
|
|
20329
|
-
],
|
|
20330
|
-
[
|
|
20331
|
-
'diagonal',
|
|
20332
|
-
's'
|
|
20333
20838
|
]
|
|
20334
20839
|
];
|
|
20335
20840
|
for (const [side, key] of sides){
|
|
20336
20841
|
const line = source.borders[side];
|
|
20337
20842
|
if (line) value[key] = structuredClone(line);
|
|
20338
20843
|
}
|
|
20339
|
-
|
|
20844
|
+
const diagonal = source.borders.diagonalUp ?? source.borders.diagonalDown ?? null;
|
|
20845
|
+
const withDiagonal = diagonal ? spreadsheetCellValueWithDiagonalBorder(value, {
|
|
20846
|
+
down: Boolean(source.borders.diagonalDown),
|
|
20847
|
+
line: structuredClone(diagonal),
|
|
20848
|
+
up: Boolean(source.borders.diagonalUp)
|
|
20849
|
+
}) : value;
|
|
20850
|
+
return Object.keys(withDiagonal).length > 2 ? [
|
|
20340
20851
|
{
|
|
20341
20852
|
rangeType: 'cell',
|
|
20342
|
-
value
|
|
20853
|
+
value: withDiagonal
|
|
20343
20854
|
}
|
|
20344
20855
|
] : [];
|
|
20345
20856
|
});
|
|
@@ -22627,6 +23138,16 @@ function SpreadsheetEditorSurface({ autoFocus = true, content, collaborationHist
|
|
|
22627
23138
|
]);
|
|
22628
23139
|
const tableStylesBySheetRef = useRef(tableStylesBySheet);
|
|
22629
23140
|
tableStylesBySheetRef.current = tableStylesBySheet;
|
|
23141
|
+
const diagonalBordersBySheet = useMemo(()=>new Map(materializedContent.sheets.flatMap((sheet)=>sheet.id ? [
|
|
23142
|
+
[
|
|
23143
|
+
sheet.id,
|
|
23144
|
+
spreadsheetRenderableDiagonalBorders(sheet)
|
|
23145
|
+
]
|
|
23146
|
+
] : [])), [
|
|
23147
|
+
materializedContent.sheets
|
|
23148
|
+
]);
|
|
23149
|
+
const diagonalBordersBySheetRef = useRef(diagonalBordersBySheet);
|
|
23150
|
+
diagonalBordersBySheetRef.current = diagonalBordersBySheet;
|
|
22630
23151
|
useEffect(()=>{
|
|
22631
23152
|
setPreviewActiveSheetId(preview ? contentActiveSheetId : null);
|
|
22632
23153
|
}, [
|
|
@@ -22758,6 +23279,9 @@ function SpreadsheetEditorSurface({ autoFocus = true, content, collaborationHist
|
|
|
22758
23279
|
}
|
|
22759
23280
|
} finally{
|
|
22760
23281
|
finishSpreadsheetTableCellRender(cell, cellInfo, tableStyle, context);
|
|
23282
|
+
const diagonal = diagonalBordersBySheetRef.current.get(activeSheetIdRef.current)?.get(`${cellInfo.row}_${cellInfo.column}`);
|
|
23283
|
+
if (diagonal?.down) drawSpreadsheetDiagonalDownBorder(context, cellInfo, diagonal.down);
|
|
23284
|
+
if (diagonal?.up) drawSpreadsheetDiagonalUpBorder(context, cellInfo, diagonal.up);
|
|
22761
23285
|
}
|
|
22762
23286
|
}
|
|
22763
23287
|
}), [
|
|
@@ -23699,6 +24223,7 @@ function spreadsheetCommandsWithGridFocus(commands, restoreFocus) {
|
|
|
23699
24223
|
deleteSelectedStructure: afterSuccessfulCommand(commands.deleteSelectedStructure),
|
|
23700
24224
|
fillSelectedCells: afterSuccessfulCommand(commands.fillSelectedCells),
|
|
23701
24225
|
insertSelectedStructure: afterSuccessfulCommand(commands.insertSelectedStructure),
|
|
24226
|
+
insertCurrentDateTime: afterSuccessfulCommand(commands.insertCurrentDateTime),
|
|
23702
24227
|
mergeSelectedCells: afterSuccessfulCommand(commands.mergeSelectedCells),
|
|
23703
24228
|
openPasteSpecial: afterSuccessfulCommand(commands.openPasteSpecial),
|
|
23704
24229
|
pasteSelection: afterSuccessfulCommand(commands.pasteSelection),
|