@extend-ai/react-xlsx 0.8.3 → 0.8.4
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/dist/index.cjs +904 -178
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +904 -178
- package/dist/index.js.map +1 -1
- package/dist/xlsx-worker.js +67 -21
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4527,6 +4527,10 @@ function parseSheetState(archive, path, options) {
|
|
|
4527
4527
|
let hasVerticalMerges = false;
|
|
4528
4528
|
let maxHorizontalMergeEndCol = -1;
|
|
4529
4529
|
let maxVerticalMergeEndRow = -1;
|
|
4530
|
+
let minContentCol = Number.POSITIVE_INFINITY;
|
|
4531
|
+
let minContentRow = Number.POSITIVE_INFINITY;
|
|
4532
|
+
let maxContentCol = -1;
|
|
4533
|
+
let maxContentRow = -1;
|
|
4530
4534
|
const columnWidthCharacterWidthPx = measureColumnCharacterWidthPx(
|
|
4531
4535
|
options?.defaultFont?.family,
|
|
4532
4536
|
options?.defaultFont?.sizePt
|
|
@@ -4539,6 +4543,26 @@ function parseSheetState(archive, path, options) {
|
|
|
4539
4543
|
sheetViewNode?.getAttribute("zoomScale") ?? sheetViewNode?.getAttribute("zoomScaleNormal") ?? Number.NaN
|
|
4540
4544
|
);
|
|
4541
4545
|
const zoomScale = Number.isFinite(rawZoomScale) && rawZoomScale > 0 ? rawZoomScale : 100;
|
|
4546
|
+
const trackContentCell = (cellRef) => {
|
|
4547
|
+
if (!cellRef) {
|
|
4548
|
+
return;
|
|
4549
|
+
}
|
|
4550
|
+
const cell = parseA1CellReference(cellRef);
|
|
4551
|
+
if (!cell) {
|
|
4552
|
+
return;
|
|
4553
|
+
}
|
|
4554
|
+
minContentCol = Math.min(minContentCol, cell.col);
|
|
4555
|
+
minContentRow = Math.min(minContentRow, cell.row);
|
|
4556
|
+
maxContentCol = Math.max(maxContentCol, cell.col);
|
|
4557
|
+
maxContentRow = Math.max(maxContentRow, cell.row);
|
|
4558
|
+
};
|
|
4559
|
+
const isMeaningfulCellNode = (cellNode) => {
|
|
4560
|
+
if (getFirstChild(cellNode, "f") || getFirstChild(cellNode, "is")) {
|
|
4561
|
+
return true;
|
|
4562
|
+
}
|
|
4563
|
+
const valueNode = getFirstChild(cellNode, "v");
|
|
4564
|
+
return Boolean(valueNode && (valueNode.textContent ?? "").length > 0);
|
|
4565
|
+
};
|
|
4542
4566
|
getLocalElements(document2, "row").forEach((rowNode) => {
|
|
4543
4567
|
const rowIndex = Number(rowNode.getAttribute("r") ?? 0) - 1;
|
|
4544
4568
|
const height = Number(rowNode.getAttribute("ht") ?? Number.NaN);
|
|
@@ -4553,17 +4577,36 @@ function parseSheetState(archive, path, options) {
|
|
|
4553
4577
|
if (rowIndex >= 0 && isHidden) {
|
|
4554
4578
|
hiddenRows.add(rowIndex);
|
|
4555
4579
|
}
|
|
4556
|
-
|
|
4557
|
-
|
|
4580
|
+
getChildElements(rowNode, "c").forEach((cellNode) => {
|
|
4581
|
+
const cellRef = cellNode.getAttribute("r");
|
|
4582
|
+
if (isMeaningfulCellNode(cellNode)) {
|
|
4583
|
+
trackContentCell(cellRef);
|
|
4584
|
+
}
|
|
4585
|
+
if (includeCachedFormulaValues) {
|
|
4558
4586
|
const formulaNode = getFirstChild(cellNode, "f");
|
|
4559
4587
|
const valueNode = getFirstChild(cellNode, "v");
|
|
4560
|
-
const cellRef = cellNode.getAttribute("r");
|
|
4561
4588
|
if (formulaNode && valueNode && cellRef) {
|
|
4562
4589
|
cachedFormulaValues[cellRef] = valueNode.textContent ?? "";
|
|
4563
4590
|
}
|
|
4564
|
-
}
|
|
4591
|
+
}
|
|
4592
|
+
});
|
|
4593
|
+
});
|
|
4594
|
+
getLocalElements(document2, "mergeCell").forEach((mergeNode) => {
|
|
4595
|
+
const reference = mergeNode.getAttribute("ref");
|
|
4596
|
+
const range = reference ? parseA1RangeReference(reference) : null;
|
|
4597
|
+
if (!range) {
|
|
4598
|
+
return;
|
|
4599
|
+
}
|
|
4600
|
+
if (range.end.col > range.start.col) {
|
|
4601
|
+
hasHorizontalMerges = true;
|
|
4602
|
+
maxHorizontalMergeEndCol = Math.max(maxHorizontalMergeEndCol, range.end.col);
|
|
4603
|
+
}
|
|
4604
|
+
if (range.end.row > range.start.row) {
|
|
4605
|
+
hasVerticalMerges = true;
|
|
4606
|
+
maxVerticalMergeEndRow = Math.max(maxVerticalMergeEndRow, range.end.row);
|
|
4565
4607
|
}
|
|
4566
4608
|
});
|
|
4609
|
+
const maxMetadataCol = Math.max(maxContentCol, maxHorizontalMergeEndCol, 0) + 256;
|
|
4567
4610
|
getLocalElements(document2, "col").forEach((colNode) => {
|
|
4568
4611
|
const min = Number(colNode.getAttribute("min") ?? 0) - 1;
|
|
4569
4612
|
const max = Number(colNode.getAttribute("max") ?? 0) - 1;
|
|
@@ -4575,7 +4618,7 @@ function parseSheetState(archive, path, options) {
|
|
|
4575
4618
|
return;
|
|
4576
4619
|
}
|
|
4577
4620
|
}
|
|
4578
|
-
for (let col = min; col <= max; col += 1) {
|
|
4621
|
+
for (let col = min; col <= Math.min(max, maxMetadataCol); col += 1) {
|
|
4579
4622
|
if (col >= 0) {
|
|
4580
4623
|
if (Number.isFinite(width)) {
|
|
4581
4624
|
const widthPx = sheetColumnWidthToPixels(width, columnWidthCharacterWidthPx);
|
|
@@ -4590,21 +4633,6 @@ function parseSheetState(archive, path, options) {
|
|
|
4590
4633
|
}
|
|
4591
4634
|
}
|
|
4592
4635
|
});
|
|
4593
|
-
getLocalElements(document2, "mergeCell").forEach((mergeNode) => {
|
|
4594
|
-
const reference = mergeNode.getAttribute("ref");
|
|
4595
|
-
const range = reference ? parseA1RangeReference(reference) : null;
|
|
4596
|
-
if (!range) {
|
|
4597
|
-
return;
|
|
4598
|
-
}
|
|
4599
|
-
if (range.end.col > range.start.col) {
|
|
4600
|
-
hasHorizontalMerges = true;
|
|
4601
|
-
maxHorizontalMergeEndCol = Math.max(maxHorizontalMergeEndCol, range.end.col);
|
|
4602
|
-
}
|
|
4603
|
-
if (range.end.row > range.start.row) {
|
|
4604
|
-
hasVerticalMerges = true;
|
|
4605
|
-
maxVerticalMergeEndRow = Math.max(maxVerticalMergeEndRow, range.end.row);
|
|
4606
|
-
}
|
|
4607
|
-
});
|
|
4608
4636
|
return {
|
|
4609
4637
|
cachedFormulaValues,
|
|
4610
4638
|
columnWidthCharacterWidthPx,
|
|
@@ -4617,6 +4645,10 @@ function parseSheetState(archive, path, options) {
|
|
|
4617
4645
|
hasVerticalMerges,
|
|
4618
4646
|
maxHorizontalMergeEndCol,
|
|
4619
4647
|
maxVerticalMergeEndRow,
|
|
4648
|
+
maxContentCol,
|
|
4649
|
+
maxContentRow,
|
|
4650
|
+
minContentCol: Number.isFinite(minContentCol) ? minContentCol : -1,
|
|
4651
|
+
minContentRow: Number.isFinite(minContentRow) ? minContentRow : -1,
|
|
4620
4652
|
hiddenCols: [...hiddenCols].sort((left, right) => left - right),
|
|
4621
4653
|
hiddenRows: [...hiddenRows].sort((left, right) => left - right),
|
|
4622
4654
|
rowHeightOverridesPx,
|
|
@@ -6645,6 +6677,20 @@ function resolveDisplayFileName(src, fileName) {
|
|
|
6645
6677
|
return lastSegment;
|
|
6646
6678
|
}
|
|
6647
6679
|
}
|
|
6680
|
+
function resolveSheetDisplayUsedRange(usedRange, sheetState) {
|
|
6681
|
+
const [minRow, minCol, maxRow, maxCol] = usedRange;
|
|
6682
|
+
const maxMeaningfulRow = Math.max(sheetState?.maxContentRow ?? -1, sheetState?.maxVerticalMergeEndRow ?? -1);
|
|
6683
|
+
const maxMeaningfulCol = Math.max(sheetState?.maxContentCol ?? -1, sheetState?.maxHorizontalMergeEndCol ?? -1);
|
|
6684
|
+
if (maxMeaningfulRow < 0 && maxMeaningfulCol < 0) {
|
|
6685
|
+
return usedRange;
|
|
6686
|
+
}
|
|
6687
|
+
return [
|
|
6688
|
+
sheetState?.minContentRow !== void 0 && sheetState.minContentRow >= 0 ? Math.min(minRow, sheetState.minContentRow) : minRow,
|
|
6689
|
+
sheetState?.minContentCol !== void 0 && sheetState.minContentCol >= 0 ? Math.min(minCol, sheetState.minContentCol) : minCol,
|
|
6690
|
+
maxMeaningfulRow >= 0 ? Math.min(maxRow, maxMeaningfulRow) : maxRow,
|
|
6691
|
+
maxMeaningfulCol >= 0 ? Math.min(maxCol, maxMeaningfulCol) : maxCol
|
|
6692
|
+
];
|
|
6693
|
+
}
|
|
6648
6694
|
function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette, styleById, namedCellStyleByName, tableStyleByName, showHiddenSheets = false) {
|
|
6649
6695
|
const sheets = [];
|
|
6650
6696
|
for (let index = 0; index < workbook.sheetCount; index += 1) {
|
|
@@ -6711,7 +6757,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
6711
6757
|
});
|
|
6712
6758
|
continue;
|
|
6713
6759
|
}
|
|
6714
|
-
const [minRow, minCol, maxRow, maxCol] = usedRange;
|
|
6760
|
+
const [minRow, minCol, maxRow, maxCol] = resolveSheetDisplayUsedRange(usedRange, sheetState);
|
|
6715
6761
|
let visibleRowsCache = null;
|
|
6716
6762
|
let visibleColsCache = null;
|
|
6717
6763
|
let rowHeightsCache = null;
|
|
@@ -16470,7 +16516,11 @@ var SELECTION_DRAG_THRESHOLD_PX = 4;
|
|
|
16470
16516
|
var IMAGE_MIN_SIZE_PX = 16;
|
|
16471
16517
|
var IMAGE_HANDLE_SIZE_PX = 10;
|
|
16472
16518
|
var CANVAS_RESIZE_HIT_SLOP_PX = 8;
|
|
16473
|
-
var CANVAS_VIEWPORT_OVERSCAN_PX =
|
|
16519
|
+
var CANVAS_VIEWPORT_OVERSCAN_PX = 480;
|
|
16520
|
+
var CANVAS_SCROLL_BUFFER_PX = 480;
|
|
16521
|
+
var CANVAS_DEFERRED_VIEWPORT_SYNC_THRESHOLD_PX = CANVAS_SCROLL_BUFFER_PX - 96;
|
|
16522
|
+
var CANVAS_IMMEDIATE_VIEWPORT_SYNC_THRESHOLD_PX = CANVAS_SCROLL_BUFFER_PX * 1.5;
|
|
16523
|
+
var CANVAS_DIRTY_CELL_CULL_MARGIN_PX = CANVAS_VIEWPORT_OVERSCAN_PX * 2;
|
|
16474
16524
|
var THUMBNAIL_DEFAULT_MAX_DIMENSION = 192;
|
|
16475
16525
|
var THUMBNAIL_FALLBACK_ROWS = 12;
|
|
16476
16526
|
var THUMBNAIL_FALLBACK_COLS = 8;
|
|
@@ -16485,6 +16535,12 @@ var CHART_SOURCE_HIGHLIGHT_COLORS = ["#2563eb", "#dc2626", "#7c3aed", "#059669",
|
|
|
16485
16535
|
var SHEET_SURFACE = "#ffffff";
|
|
16486
16536
|
var DEFAULT_CELL_PADDING = "0 4px";
|
|
16487
16537
|
var IMAGE_HANDLE_POSITIONS = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
|
|
16538
|
+
var CANVAS_CELL_STYLE_CACHE_LIMIT = 4096;
|
|
16539
|
+
var CANVAS_TEXT_MEASURE_CACHE_LIMIT = 2e4;
|
|
16540
|
+
var CANVAS_TEXT_TRUNCATE_CACHE_LIMIT = 4096;
|
|
16541
|
+
var CANVAS_TEXT_WRAP_CACHE_LIMIT = 2048;
|
|
16542
|
+
var CANVAS_PATH2D_CACHE_LIMIT = 512;
|
|
16543
|
+
var EMPTY_VIRTUAL_ITEMS = [];
|
|
16488
16544
|
var IMAGE_HANDLE_CURSOR = {
|
|
16489
16545
|
e: "ew-resize",
|
|
16490
16546
|
n: "ns-resize",
|
|
@@ -16528,6 +16584,50 @@ var NUMERIC_LENGTH_STYLE_KEYS = /* @__PURE__ */ new Set([
|
|
|
16528
16584
|
"top",
|
|
16529
16585
|
"width"
|
|
16530
16586
|
]);
|
|
16587
|
+
var canvasCellStyleCache = /* @__PURE__ */ new Map();
|
|
16588
|
+
var canvasTextMeasureCache = /* @__PURE__ */ new Map();
|
|
16589
|
+
var canvasTextTruncateCache = /* @__PURE__ */ new Map();
|
|
16590
|
+
var canvasTextWrapCache = /* @__PURE__ */ new Map();
|
|
16591
|
+
var canvasPath2DCache = /* @__PURE__ */ new Map();
|
|
16592
|
+
function rememberBoundedCacheValue(cache, key, value, limit) {
|
|
16593
|
+
if (cache.size >= limit) {
|
|
16594
|
+
const oldestKey = cache.keys().next().value;
|
|
16595
|
+
if (oldestKey !== void 0) {
|
|
16596
|
+
cache.delete(oldestKey);
|
|
16597
|
+
}
|
|
16598
|
+
}
|
|
16599
|
+
cache.set(key, value);
|
|
16600
|
+
return value;
|
|
16601
|
+
}
|
|
16602
|
+
function roundCanvasCacheWidth(width) {
|
|
16603
|
+
return Math.round(width * 4) / 4;
|
|
16604
|
+
}
|
|
16605
|
+
function measureCanvasTextWidth(context, text) {
|
|
16606
|
+
if (text.length === 0) {
|
|
16607
|
+
return 0;
|
|
16608
|
+
}
|
|
16609
|
+
const cacheKey = `${context.font}\0${text}`;
|
|
16610
|
+
const cached = canvasTextMeasureCache.get(cacheKey);
|
|
16611
|
+
if (cached !== void 0) {
|
|
16612
|
+
return cached;
|
|
16613
|
+
}
|
|
16614
|
+
return rememberBoundedCacheValue(
|
|
16615
|
+
canvasTextMeasureCache,
|
|
16616
|
+
cacheKey,
|
|
16617
|
+
context.measureText(text).width,
|
|
16618
|
+
CANVAS_TEXT_MEASURE_CACHE_LIMIT
|
|
16619
|
+
);
|
|
16620
|
+
}
|
|
16621
|
+
function getCachedCanvasPath2D(path) {
|
|
16622
|
+
if (typeof Path2D === "undefined") {
|
|
16623
|
+
return null;
|
|
16624
|
+
}
|
|
16625
|
+
const cached = canvasPath2DCache.get(path);
|
|
16626
|
+
if (cached) {
|
|
16627
|
+
return cached;
|
|
16628
|
+
}
|
|
16629
|
+
return rememberBoundedCacheValue(canvasPath2DCache, path, new Path2D(path), CANVAS_PATH2D_CACHE_LIMIT);
|
|
16630
|
+
}
|
|
16531
16631
|
function scaleCssLengthExpression(value, scale) {
|
|
16532
16632
|
if (scale === 1) {
|
|
16533
16633
|
return value;
|
|
@@ -16708,7 +16808,6 @@ function strokeCanvasBorderSide(context, side, rect, border) {
|
|
|
16708
16808
|
const right = rect.left + rect.width;
|
|
16709
16809
|
const top = rect.top;
|
|
16710
16810
|
const bottom = rect.top + rect.height;
|
|
16711
|
-
context.save();
|
|
16712
16811
|
context.strokeStyle = border.color;
|
|
16713
16812
|
context.lineWidth = border.width;
|
|
16714
16813
|
applyCanvasBorderDash(context, border.style, border.width);
|
|
@@ -16738,13 +16837,22 @@ function strokeCanvasBorderSide(context, side, rect, border) {
|
|
|
16738
16837
|
} else {
|
|
16739
16838
|
strokeLine(0);
|
|
16740
16839
|
}
|
|
16741
|
-
context.
|
|
16840
|
+
context.setLineDash([]);
|
|
16841
|
+
context.lineCap = "butt";
|
|
16842
|
+
context.lineWidth = 1;
|
|
16742
16843
|
}
|
|
16743
16844
|
function truncateCanvasText(context, text, maxWidth) {
|
|
16744
16845
|
if (maxWidth <= 0 || text.length === 0) {
|
|
16745
16846
|
return "";
|
|
16746
16847
|
}
|
|
16747
|
-
|
|
16848
|
+
const roundedMaxWidth = roundCanvasCacheWidth(maxWidth);
|
|
16849
|
+
const cacheKey = `${context.font}\0${roundedMaxWidth}\0${text}`;
|
|
16850
|
+
const cached = canvasTextTruncateCache.get(cacheKey);
|
|
16851
|
+
if (cached !== void 0) {
|
|
16852
|
+
return cached;
|
|
16853
|
+
}
|
|
16854
|
+
if (measureCanvasTextWidth(context, text) <= maxWidth) {
|
|
16855
|
+
rememberBoundedCacheValue(canvasTextTruncateCache, cacheKey, text, CANVAS_TEXT_TRUNCATE_CACHE_LIMIT);
|
|
16748
16856
|
return text;
|
|
16749
16857
|
}
|
|
16750
16858
|
const ellipsis = "\u2026";
|
|
@@ -16753,13 +16861,18 @@ function truncateCanvasText(context, text, maxWidth) {
|
|
|
16753
16861
|
while (low < high) {
|
|
16754
16862
|
const mid = Math.ceil((low + high) / 2);
|
|
16755
16863
|
const candidate = `${text.slice(0, mid)}${ellipsis}`;
|
|
16756
|
-
if (context
|
|
16864
|
+
if (measureCanvasTextWidth(context, candidate) <= maxWidth) {
|
|
16757
16865
|
low = mid;
|
|
16758
16866
|
} else {
|
|
16759
16867
|
high = mid - 1;
|
|
16760
16868
|
}
|
|
16761
16869
|
}
|
|
16762
|
-
return
|
|
16870
|
+
return rememberBoundedCacheValue(
|
|
16871
|
+
canvasTextTruncateCache,
|
|
16872
|
+
cacheKey,
|
|
16873
|
+
low <= 0 ? ellipsis : `${text.slice(0, low)}${ellipsis}`,
|
|
16874
|
+
CANVAS_TEXT_TRUNCATE_CACHE_LIMIT
|
|
16875
|
+
);
|
|
16763
16876
|
}
|
|
16764
16877
|
function resolveCanvasFontSizePx(style, fallbackSize = 12) {
|
|
16765
16878
|
const rawFontSize = style.fontSize;
|
|
@@ -16818,7 +16931,7 @@ function resolveCanvasWrapIndex(context, text, maxWidth) {
|
|
|
16818
16931
|
while (low <= high) {
|
|
16819
16932
|
const mid = Math.floor((low + high) / 2);
|
|
16820
16933
|
const candidate = text.slice(0, mid);
|
|
16821
|
-
if (context
|
|
16934
|
+
if (measureCanvasTextWidth(context, candidate) <= maxWidth) {
|
|
16822
16935
|
best = mid;
|
|
16823
16936
|
low = mid + 1;
|
|
16824
16937
|
} else {
|
|
@@ -16835,6 +16948,12 @@ function wrapCanvasText(context, text, maxWidth) {
|
|
|
16835
16948
|
return text.replace(/\r\n?/g, "\n").split("\n");
|
|
16836
16949
|
}
|
|
16837
16950
|
const normalized = text.replace(/\r\n?/g, "\n");
|
|
16951
|
+
const roundedMaxWidth = roundCanvasCacheWidth(maxWidth);
|
|
16952
|
+
const cacheKey = `${context.font}\0${roundedMaxWidth}\0${normalized}`;
|
|
16953
|
+
const cached = canvasTextWrapCache.get(cacheKey);
|
|
16954
|
+
if (cached) {
|
|
16955
|
+
return cached;
|
|
16956
|
+
}
|
|
16838
16957
|
const paragraphs = normalized.split("\n");
|
|
16839
16958
|
const lines = [];
|
|
16840
16959
|
for (const paragraph of paragraphs) {
|
|
@@ -16844,7 +16963,7 @@ function wrapCanvasText(context, text, maxWidth) {
|
|
|
16844
16963
|
}
|
|
16845
16964
|
let remaining = paragraph;
|
|
16846
16965
|
while (remaining.length > 0) {
|
|
16847
|
-
if (context
|
|
16966
|
+
if (measureCanvasTextWidth(context, remaining) <= maxWidth) {
|
|
16848
16967
|
lines.push(remaining);
|
|
16849
16968
|
break;
|
|
16850
16969
|
}
|
|
@@ -16862,10 +16981,31 @@ function wrapCanvasText(context, text, maxWidth) {
|
|
|
16862
16981
|
remaining = remaining.slice(breakIndex).replace(/^\s+/g, "");
|
|
16863
16982
|
}
|
|
16864
16983
|
}
|
|
16865
|
-
return lines;
|
|
16984
|
+
return rememberBoundedCacheValue(canvasTextWrapCache, cacheKey, lines, CANVAS_TEXT_WRAP_CACHE_LIMIT);
|
|
16866
16985
|
}
|
|
16867
16986
|
function buildCanvasCellStyleCache(style) {
|
|
16868
|
-
|
|
16987
|
+
const cacheKey = [
|
|
16988
|
+
style.font,
|
|
16989
|
+
style.fontStyle,
|
|
16990
|
+
style.fontWeight,
|
|
16991
|
+
style.fontSize,
|
|
16992
|
+
style.fontFamily,
|
|
16993
|
+
style.borderTop,
|
|
16994
|
+
style.borderRight,
|
|
16995
|
+
style.borderBottom,
|
|
16996
|
+
style.borderLeft,
|
|
16997
|
+
style.padding,
|
|
16998
|
+
style.textAlign,
|
|
16999
|
+
style.color,
|
|
17000
|
+
style.textDecoration,
|
|
17001
|
+
style.textOverflow,
|
|
17002
|
+
style.whiteSpace
|
|
17003
|
+
].map((value) => value == null ? "" : String(value)).join("");
|
|
17004
|
+
const cached = canvasCellStyleCache.get(cacheKey);
|
|
17005
|
+
if (cached) {
|
|
17006
|
+
return cached;
|
|
17007
|
+
}
|
|
17008
|
+
return rememberBoundedCacheValue(canvasCellStyleCache, cacheKey, {
|
|
16869
17009
|
baseFont: resolveCanvasFont(style, 12),
|
|
16870
17010
|
bottomBorder: parseCanvasBorderDeclaration(style.borderBottom),
|
|
16871
17011
|
leftBorder: parseCanvasBorderDeclaration(style.borderLeft),
|
|
@@ -16877,7 +17017,7 @@ function buildCanvasCellStyleCache(style) {
|
|
|
16877
17017
|
textOverflowEllipsis: style.textOverflow === "ellipsis",
|
|
16878
17018
|
topBorder: parseCanvasBorderDeclaration(style.borderTop),
|
|
16879
17019
|
usesWrappedText: style.whiteSpace === "pre-wrap"
|
|
16880
|
-
};
|
|
17020
|
+
}, CANVAS_CELL_STYLE_CACHE_LIMIT);
|
|
16881
17021
|
}
|
|
16882
17022
|
function splitCssGradientArgs(value) {
|
|
16883
17023
|
const parts = [];
|
|
@@ -18386,6 +18526,44 @@ function resolveShapeVector(shape) {
|
|
|
18386
18526
|
}
|
|
18387
18527
|
return buildPresetShapePath(shape);
|
|
18388
18528
|
}
|
|
18529
|
+
function drawCanvasRoundedRect(context, left, top, width, height, radius) {
|
|
18530
|
+
const safeRadius = Math.max(0, Math.min(radius, width / 2, height / 2));
|
|
18531
|
+
context.beginPath();
|
|
18532
|
+
context.moveTo(left + safeRadius, top);
|
|
18533
|
+
context.lineTo(left + width - safeRadius, top);
|
|
18534
|
+
context.quadraticCurveTo(left + width, top, left + width, top + safeRadius);
|
|
18535
|
+
context.lineTo(left + width, top + height - safeRadius);
|
|
18536
|
+
context.quadraticCurveTo(left + width, top + height, left + width - safeRadius, top + height);
|
|
18537
|
+
context.lineTo(left + safeRadius, top + height);
|
|
18538
|
+
context.quadraticCurveTo(left, top + height, left, top + height - safeRadius);
|
|
18539
|
+
context.lineTo(left, top + safeRadius);
|
|
18540
|
+
context.quadraticCurveTo(left, top, left + safeRadius, top);
|
|
18541
|
+
context.closePath();
|
|
18542
|
+
}
|
|
18543
|
+
function applyCanvasShapeDash(context, dash, lineWidth) {
|
|
18544
|
+
if (!dash) {
|
|
18545
|
+
context.setLineDash([]);
|
|
18546
|
+
return;
|
|
18547
|
+
}
|
|
18548
|
+
const unit = Math.max(1, lineWidth);
|
|
18549
|
+
switch (dash) {
|
|
18550
|
+
case "dash":
|
|
18551
|
+
context.setLineDash([4 * unit, 3 * unit]);
|
|
18552
|
+
break;
|
|
18553
|
+
case "dashDot":
|
|
18554
|
+
context.setLineDash([4 * unit, 2 * unit, unit, 2 * unit]);
|
|
18555
|
+
break;
|
|
18556
|
+
case "dot":
|
|
18557
|
+
context.setLineDash([unit, 2 * unit]);
|
|
18558
|
+
break;
|
|
18559
|
+
case "lgDash":
|
|
18560
|
+
context.setLineDash([8 * unit, 3 * unit]);
|
|
18561
|
+
break;
|
|
18562
|
+
default:
|
|
18563
|
+
context.setLineDash([]);
|
|
18564
|
+
break;
|
|
18565
|
+
}
|
|
18566
|
+
}
|
|
18389
18567
|
function resolveShapeLineEndMarker(type, markerId, color, strokeWidth, rect, viewBox) {
|
|
18390
18568
|
if (type !== "triangle") {
|
|
18391
18569
|
return null;
|
|
@@ -18988,12 +19166,12 @@ function measureTextWidth(value, style) {
|
|
|
18988
19166
|
return value.length * 7;
|
|
18989
19167
|
}
|
|
18990
19168
|
textMeasureCanvas ??= document.createElement("canvas");
|
|
18991
|
-
const context = textMeasureCanvas.getContext("2d");
|
|
19169
|
+
const context = textMeasureCanvas.getContext("2d", { alpha: false });
|
|
18992
19170
|
if (!context) {
|
|
18993
19171
|
return value.length * 7;
|
|
18994
19172
|
}
|
|
18995
19173
|
context.font = buildCanvasFont(style);
|
|
18996
|
-
return context
|
|
19174
|
+
return measureCanvasTextWidth(context, value);
|
|
18997
19175
|
}
|
|
18998
19176
|
function measureWrappedTextHeight(value, style, widthPx) {
|
|
18999
19177
|
if (!value) {
|
|
@@ -19007,7 +19185,7 @@ function measureWrappedTextHeight(value, style, widthPx) {
|
|
|
19007
19185
|
return fallbackLineCount * lineHeight + padding.top + padding.bottom;
|
|
19008
19186
|
}
|
|
19009
19187
|
textMeasureCanvas ??= document.createElement("canvas");
|
|
19010
|
-
const context = textMeasureCanvas.getContext("2d");
|
|
19188
|
+
const context = textMeasureCanvas.getContext("2d", { alpha: false });
|
|
19011
19189
|
if (!context) {
|
|
19012
19190
|
return fallbackLineCount * lineHeight + padding.top + padding.bottom;
|
|
19013
19191
|
}
|
|
@@ -20105,7 +20283,7 @@ function blitCanvasWithScrollDelta(canvas, context, bufferCanvas, dpr, width, he
|
|
|
20105
20283
|
if (bufferCanvas.height !== deviceHeight) {
|
|
20106
20284
|
bufferCanvas.height = deviceHeight;
|
|
20107
20285
|
}
|
|
20108
|
-
const bufferContext = bufferCanvas.getContext("2d");
|
|
20286
|
+
const bufferContext = bufferCanvas.getContext("2d", { alpha: false });
|
|
20109
20287
|
if (!bufferContext) {
|
|
20110
20288
|
return null;
|
|
20111
20289
|
}
|
|
@@ -20962,6 +21140,8 @@ function XlsxGrid({
|
|
|
20962
21140
|
selectionHeaderColor,
|
|
20963
21141
|
showImages = true
|
|
20964
21142
|
}) {
|
|
21143
|
+
const xlsxCanvasProfileTarget = typeof window !== "undefined" ? window.__xlsxCanvasProfile : void 0;
|
|
21144
|
+
const xlsxGridRenderStart = xlsxCanvasProfileTarget ? performance.now() : 0;
|
|
20965
21145
|
const {
|
|
20966
21146
|
activeCell,
|
|
20967
21147
|
activeSheet,
|
|
@@ -21045,6 +21225,11 @@ function XlsxGrid({
|
|
|
21045
21225
|
const leftFrozenHeaderCanvasRef = React4.useRef(null);
|
|
21046
21226
|
const leftScrollHeaderCanvasRef = React4.useRef(null);
|
|
21047
21227
|
const cornerHeaderCanvasRef = React4.useRef(null);
|
|
21228
|
+
const canvasScrollOverlayContentRef = React4.useRef(null);
|
|
21229
|
+
const canvasTopOverlayContentRef = React4.useRef(null);
|
|
21230
|
+
const canvasLeftOverlayContentRef = React4.useRef(null);
|
|
21231
|
+
const canvasCornerOverlayContentRef = React4.useRef(null);
|
|
21232
|
+
const canvasImageCacheRef = React4.useRef(/* @__PURE__ */ new Map());
|
|
21048
21233
|
const selectionOverlayRef = React4.useRef(null);
|
|
21049
21234
|
const activeValidationOverlayRef = React4.useRef(null);
|
|
21050
21235
|
const fillHandleRef = React4.useRef(null);
|
|
@@ -21073,6 +21258,7 @@ function XlsxGrid({
|
|
|
21073
21258
|
const pendingLiveZoomCommitRef = React4.useRef(null);
|
|
21074
21259
|
const touchPinchStateRef = React4.useRef(null);
|
|
21075
21260
|
const safariPinchStartZoomRef = React4.useRef(null);
|
|
21261
|
+
const canvasTransformStyleCacheRef = React4.useRef(/* @__PURE__ */ new WeakMap());
|
|
21076
21262
|
const displayedSelectionRef = React4.useRef(null);
|
|
21077
21263
|
const firstVisibleColRef = React4.useRef(void 0);
|
|
21078
21264
|
const lastVisibleColRef = React4.useRef(void 0);
|
|
@@ -21098,12 +21284,19 @@ function XlsxGrid({
|
|
|
21098
21284
|
const [fillPreviewRange, setFillPreviewRange] = React4.useState(null);
|
|
21099
21285
|
const [chartPreviewRect, setChartPreviewRect] = React4.useState(null);
|
|
21100
21286
|
const [liveGestureZoom, setLiveGestureZoom] = React4.useState(null);
|
|
21287
|
+
const [canvasImageLoadVersion, setCanvasImageLoadVersion] = React4.useState(0);
|
|
21101
21288
|
const liveDrawingViewportRef = React4.useRef({
|
|
21102
21289
|
height: 0,
|
|
21103
21290
|
left: 0,
|
|
21104
21291
|
top: 0,
|
|
21105
21292
|
width: 0
|
|
21106
21293
|
});
|
|
21294
|
+
const canvasLayoutMetricsRef = React4.useRef({
|
|
21295
|
+
displayHeaderHeight: HEADER_HEIGHT,
|
|
21296
|
+
displayRowHeaderWidth: ROW_HEADER_WIDTH,
|
|
21297
|
+
frozenPaneBottom: HEADER_HEIGHT,
|
|
21298
|
+
frozenPaneRight: ROW_HEADER_WIDTH
|
|
21299
|
+
});
|
|
21107
21300
|
const paintedDrawingViewportRef = React4.useRef({
|
|
21108
21301
|
height: 0,
|
|
21109
21302
|
left: 0,
|
|
@@ -21213,6 +21406,12 @@ function XlsxGrid({
|
|
|
21213
21406
|
const applyCanvasViewportCompensation = React4.useCallback((liveViewport) => {
|
|
21214
21407
|
const nextLiveViewport = liveViewport ?? liveDrawingViewportRef.current;
|
|
21215
21408
|
const paintedViewport = paintedDrawingViewportRef.current;
|
|
21409
|
+
const {
|
|
21410
|
+
displayHeaderHeight: liveDisplayHeaderHeight,
|
|
21411
|
+
displayRowHeaderWidth: liveDisplayRowHeaderWidth,
|
|
21412
|
+
frozenPaneBottom: liveFrozenPaneBottom,
|
|
21413
|
+
frozenPaneRight: liveFrozenPaneRight
|
|
21414
|
+
} = canvasLayoutMetricsRef.current;
|
|
21216
21415
|
const currentLiveGestureZoom = liveGestureZoomRef.current;
|
|
21217
21416
|
const isLiveZooming2 = currentLiveGestureZoom !== null && zoomScale === currentLiveGestureZoom.baseZoomScale;
|
|
21218
21417
|
const liveZoomScale2 = isLiveZooming2 ? Math.max(0.1, currentLiveGestureZoom.targetZoomScale / currentLiveGestureZoom.baseZoomScale) : 1;
|
|
@@ -21220,12 +21419,41 @@ function XlsxGrid({
|
|
|
21220
21419
|
const scrollDeltaY = paintedViewport.top - nextLiveViewport.top;
|
|
21221
21420
|
const liveZoomTranslateX2 = isLiveZooming2 ? currentLiveGestureZoom.anchor.x * (1 - liveZoomScale2) : 0;
|
|
21222
21421
|
const liveZoomTranslateY2 = isLiveZooming2 ? currentLiveGestureZoom.anchor.y * (1 - liveZoomScale2) : 0;
|
|
21223
|
-
const
|
|
21224
|
-
if (!
|
|
21422
|
+
const applyElementTransform = (element, transform, willChange, transformOrigin = null) => {
|
|
21423
|
+
if (!element) {
|
|
21225
21424
|
return;
|
|
21226
21425
|
}
|
|
21227
|
-
|
|
21228
|
-
|
|
21426
|
+
const cached = canvasTransformStyleCacheRef.current.get(element);
|
|
21427
|
+
if (cached?.transform !== transform || element.style.transform !== transform) {
|
|
21428
|
+
element.style.transform = transform;
|
|
21429
|
+
}
|
|
21430
|
+
if (cached?.willChange !== willChange || element.style.willChange !== willChange) {
|
|
21431
|
+
element.style.willChange = willChange;
|
|
21432
|
+
}
|
|
21433
|
+
if (transformOrigin !== null && (cached?.transformOrigin !== transformOrigin || element.style.transformOrigin !== transformOrigin)) {
|
|
21434
|
+
element.style.transformOrigin = transformOrigin;
|
|
21435
|
+
}
|
|
21436
|
+
canvasTransformStyleCacheRef.current.set(element, {
|
|
21437
|
+
transform,
|
|
21438
|
+
transformOrigin,
|
|
21439
|
+
willChange
|
|
21440
|
+
});
|
|
21441
|
+
};
|
|
21442
|
+
const applyCanvasTransform = (canvas, translateX, translateY) => {
|
|
21443
|
+
const shouldTransform = translateX !== 0 || translateY !== 0 || liveZoomScale2 !== 1;
|
|
21444
|
+
applyElementTransform(
|
|
21445
|
+
canvas,
|
|
21446
|
+
shouldTransform ? `translate3d(${translateX}px, ${translateY}px, 0) scale(${liveZoomScale2})` : "",
|
|
21447
|
+
shouldTransform ? "transform" : ""
|
|
21448
|
+
);
|
|
21449
|
+
};
|
|
21450
|
+
const applyOverlayTransform = (element, translateX, translateY) => {
|
|
21451
|
+
applyElementTransform(
|
|
21452
|
+
element,
|
|
21453
|
+
liveZoomScale2 !== 1 ? `translate3d(${translateX + liveZoomTranslateX2}px, ${translateY + liveZoomTranslateY2}px, 0) scale(${liveZoomScale2})` : `translate3d(${translateX}px, ${translateY}px, 0)`,
|
|
21454
|
+
"transform",
|
|
21455
|
+
"0 0"
|
|
21456
|
+
);
|
|
21229
21457
|
};
|
|
21230
21458
|
applyCanvasTransform(
|
|
21231
21459
|
scrollBodyCanvasRef.current,
|
|
@@ -21272,6 +21500,26 @@ function XlsxGrid({
|
|
|
21272
21500
|
liveZoomTranslateX2,
|
|
21273
21501
|
liveZoomTranslateY2
|
|
21274
21502
|
);
|
|
21503
|
+
applyOverlayTransform(
|
|
21504
|
+
canvasScrollOverlayContentRef.current,
|
|
21505
|
+
-nextLiveViewport.left - liveFrozenPaneRight,
|
|
21506
|
+
-nextLiveViewport.top - liveFrozenPaneBottom
|
|
21507
|
+
);
|
|
21508
|
+
applyOverlayTransform(
|
|
21509
|
+
canvasTopOverlayContentRef.current,
|
|
21510
|
+
-nextLiveViewport.left - liveFrozenPaneRight,
|
|
21511
|
+
-liveDisplayHeaderHeight
|
|
21512
|
+
);
|
|
21513
|
+
applyOverlayTransform(
|
|
21514
|
+
canvasLeftOverlayContentRef.current,
|
|
21515
|
+
-liveDisplayRowHeaderWidth,
|
|
21516
|
+
-nextLiveViewport.top - liveFrozenPaneBottom
|
|
21517
|
+
);
|
|
21518
|
+
applyOverlayTransform(
|
|
21519
|
+
canvasCornerOverlayContentRef.current,
|
|
21520
|
+
-liveDisplayRowHeaderWidth,
|
|
21521
|
+
-liveDisplayHeaderHeight
|
|
21522
|
+
);
|
|
21275
21523
|
}, [zoomScale]);
|
|
21276
21524
|
const updateLiveGestureZoomState = React4.useCallback((nextState) => {
|
|
21277
21525
|
const resolvedState = typeof nextState === "function" ? nextState(liveGestureZoomRef.current) : nextState;
|
|
@@ -21374,6 +21622,11 @@ function XlsxGrid({
|
|
|
21374
21622
|
if (matchesLiveViewport && matchesStateViewport) {
|
|
21375
21623
|
return;
|
|
21376
21624
|
}
|
|
21625
|
+
const shouldCommitDeferredViewport = !matchesStateViewport && (stateViewport.width !== nextViewport.width || stateViewport.height !== nextViewport.height || Math.abs(nextViewport.left - stateViewport.left) >= CANVAS_DEFERRED_VIEWPORT_SYNC_THRESHOLD_PX || Math.abs(nextViewport.top - stateViewport.top) >= CANVAS_DEFERRED_VIEWPORT_SYNC_THRESHOLD_PX);
|
|
21626
|
+
if (!shouldCommitDeferredViewport) {
|
|
21627
|
+
pendingDrawingViewportRef.current = null;
|
|
21628
|
+
return;
|
|
21629
|
+
}
|
|
21377
21630
|
pendingDrawingViewportRef.current = nextViewport;
|
|
21378
21631
|
if (drawingViewportFrameRef.current !== null) {
|
|
21379
21632
|
return;
|
|
@@ -21661,6 +21914,12 @@ function XlsxGrid({
|
|
|
21661
21914
|
) : displayRowHeaderWidth,
|
|
21662
21915
|
[displayActualColWidths, displayDefaultColWidth, displayRowHeaderWidth, frozenCols, stickyLeftByCol]
|
|
21663
21916
|
);
|
|
21917
|
+
canvasLayoutMetricsRef.current = {
|
|
21918
|
+
displayHeaderHeight,
|
|
21919
|
+
displayRowHeaderWidth,
|
|
21920
|
+
frozenPaneBottom,
|
|
21921
|
+
frozenPaneRight
|
|
21922
|
+
};
|
|
21664
21923
|
const rowPrefixSumsRef = React4.useRef(rowPrefixSums);
|
|
21665
21924
|
const colPrefixSumsRef = React4.useRef(colPrefixSums);
|
|
21666
21925
|
const firstVisibleRow = visibleRows[0];
|
|
@@ -21712,6 +21971,7 @@ function XlsxGrid({
|
|
|
21712
21971
|
}, [charts, images, shapes]);
|
|
21713
21972
|
const shouldVirtualizeRows = visibleRows.length > 0;
|
|
21714
21973
|
const shouldVirtualizeCols = visibleCols.length > 0 && frozenCols.length === 0;
|
|
21974
|
+
const shouldUseDomVirtualizer = !experimentalCanvas;
|
|
21715
21975
|
const getScrollElement = React4.useCallback(() => scrollRef.current, []);
|
|
21716
21976
|
const estimateRowSize = React4.useCallback(
|
|
21717
21977
|
(index) => displayEffectiveRowHeights[index] ?? displayDefaultRowHeight,
|
|
@@ -21725,6 +21985,7 @@ function XlsxGrid({
|
|
|
21725
21985
|
const getColItemKey = React4.useCallback((index) => visibleCols[index] ?? index, [visibleCols]);
|
|
21726
21986
|
const rowVirtualizer = useVirtualizer({
|
|
21727
21987
|
count: visibleRows.length,
|
|
21988
|
+
enabled: shouldUseDomVirtualizer,
|
|
21728
21989
|
estimateSize: estimateRowSize,
|
|
21729
21990
|
getScrollElement,
|
|
21730
21991
|
getItemKey: getRowItemKey,
|
|
@@ -21732,14 +21993,15 @@ function XlsxGrid({
|
|
|
21732
21993
|
});
|
|
21733
21994
|
const colVirtualizer = useVirtualizer({
|
|
21734
21995
|
count: visibleCols.length,
|
|
21996
|
+
enabled: shouldUseDomVirtualizer,
|
|
21735
21997
|
estimateSize: estimateColSize,
|
|
21736
21998
|
getScrollElement,
|
|
21737
21999
|
getItemKey: getColItemKey,
|
|
21738
22000
|
horizontal: true,
|
|
21739
22001
|
overscan: 6
|
|
21740
22002
|
});
|
|
21741
|
-
const currentRowVirtualItems = rowVirtualizer.getVirtualItems();
|
|
21742
|
-
const currentColVirtualItems = colVirtualizer.getVirtualItems();
|
|
22003
|
+
const currentRowVirtualItems = shouldUseDomVirtualizer ? rowVirtualizer.getVirtualItems() : EMPTY_VIRTUAL_ITEMS;
|
|
22004
|
+
const currentColVirtualItems = shouldUseDomVirtualizer ? colVirtualizer.getVirtualItems() : EMPTY_VIRTUAL_ITEMS;
|
|
21743
22005
|
const frozenRowVirtualIndices = React4.useMemo(
|
|
21744
22006
|
() => frozenRows.map((row) => rowIndexByActual.get(row)).filter((index) => index !== void 0),
|
|
21745
22007
|
[frozenRows, rowIndexByActual]
|
|
@@ -21975,10 +22237,12 @@ function XlsxGrid({
|
|
|
21975
22237
|
scroller.scrollTop = scroller.scrollTop / previousZoomFactor * zoomFactor;
|
|
21976
22238
|
}
|
|
21977
22239
|
previousZoomFactorRef.current = zoomFactor;
|
|
21978
|
-
|
|
21979
|
-
|
|
22240
|
+
if (shouldUseDomVirtualizer) {
|
|
22241
|
+
rowVirtualizer.measure();
|
|
22242
|
+
colVirtualizer.measure();
|
|
22243
|
+
}
|
|
21980
22244
|
syncDrawingViewport(scroller, { immediate: true });
|
|
21981
|
-
}, [syncDrawingViewport, zoomFactor]);
|
|
22245
|
+
}, [shouldUseDomVirtualizer, syncDrawingViewport, zoomFactor]);
|
|
21982
22246
|
React4.useLayoutEffect(() => {
|
|
21983
22247
|
syncDrawingViewport(scrollRef.current, { immediate: true });
|
|
21984
22248
|
}, [activeSheet, activeTabIndex, displayColLimit, displayRowLimit, syncDrawingViewport, zoomFactor]);
|
|
@@ -22074,7 +22338,7 @@ function XlsxGrid({
|
|
|
22074
22338
|
const initialUsedCol = resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1);
|
|
22075
22339
|
const initialScrollTop = initialUsedRow > 0 ? sumPrefixRange(actualRowPrefixSums, 0, initialUsedRow - 1) : 0;
|
|
22076
22340
|
const initialScrollLeft = initialUsedCol > 0 ? sumPrefixRange(actualColPrefixSums, 0, initialUsedCol - 1) : 0;
|
|
22077
|
-
if (shouldVirtualizeRows) {
|
|
22341
|
+
if (shouldUseDomVirtualizer && shouldVirtualizeRows) {
|
|
22078
22342
|
rowVirtualizer.scrollToOffset(initialScrollTop);
|
|
22079
22343
|
} else if (scrollRef.current) {
|
|
22080
22344
|
scrollRef.current.scrollTop = initialScrollTop;
|
|
@@ -22082,7 +22346,7 @@ function XlsxGrid({
|
|
|
22082
22346
|
if (scrollRef.current) {
|
|
22083
22347
|
scrollRef.current.scrollLeft = initialScrollLeft;
|
|
22084
22348
|
}
|
|
22085
|
-
if (shouldVirtualizeCols && frozenCols.length === 0) {
|
|
22349
|
+
if (shouldUseDomVirtualizer && shouldVirtualizeCols && frozenCols.length === 0) {
|
|
22086
22350
|
colVirtualizer.scrollToOffset(initialScrollLeft);
|
|
22087
22351
|
}
|
|
22088
22352
|
if (scrollRef.current) {
|
|
@@ -22103,6 +22367,7 @@ function XlsxGrid({
|
|
|
22103
22367
|
isWorkerBacked,
|
|
22104
22368
|
shouldVirtualizeCols,
|
|
22105
22369
|
shouldVirtualizeRows,
|
|
22370
|
+
shouldUseDomVirtualizer,
|
|
22106
22371
|
syncDrawingViewport,
|
|
22107
22372
|
rowVirtualizer,
|
|
22108
22373
|
visibleCols,
|
|
@@ -22122,24 +22387,40 @@ function XlsxGrid({
|
|
|
22122
22387
|
setPendingNavigation(null);
|
|
22123
22388
|
}, [activeSheetIndex, pendingNavigation, selectCell]);
|
|
22124
22389
|
React4.useEffect(() => {
|
|
22125
|
-
if (shouldVirtualizeRows) {
|
|
22390
|
+
if (shouldUseDomVirtualizer && shouldVirtualizeRows) {
|
|
22126
22391
|
rowVirtualizer.measure();
|
|
22127
22392
|
}
|
|
22128
|
-
if (shouldVirtualizeCols) {
|
|
22393
|
+
if (shouldUseDomVirtualizer && shouldVirtualizeCols) {
|
|
22129
22394
|
colVirtualizer.measure();
|
|
22130
22395
|
}
|
|
22131
|
-
}, [
|
|
22396
|
+
}, [
|
|
22397
|
+
activeSheetIndex,
|
|
22398
|
+
revision,
|
|
22399
|
+
shouldUseDomVirtualizer,
|
|
22400
|
+
shouldVirtualizeCols,
|
|
22401
|
+
shouldVirtualizeRows,
|
|
22402
|
+
visibleCols.length,
|
|
22403
|
+
visibleRows.length
|
|
22404
|
+
]);
|
|
22132
22405
|
const handleScrollerScroll = React4.useCallback((event) => {
|
|
22133
22406
|
const currentScroller = event.currentTarget;
|
|
22134
22407
|
cachedScrollerRectRef.current = null;
|
|
22135
|
-
|
|
22408
|
+
const paintedViewport = paintedDrawingViewportRef.current;
|
|
22409
|
+
const shouldSyncDrawingViewportImmediately = Math.abs(currentScroller.scrollLeft - paintedViewport.left) > CANVAS_IMMEDIATE_VIEWPORT_SYNC_THRESHOLD_PX || Math.abs(currentScroller.scrollTop - paintedViewport.top) > CANVAS_IMMEDIATE_VIEWPORT_SYNC_THRESHOLD_PX;
|
|
22410
|
+
syncDrawingViewport(currentScroller, { immediate: shouldSyncDrawingViewportImmediately });
|
|
22136
22411
|
if (currentScroller.scrollHeight - (currentScroller.scrollTop + currentScroller.clientHeight) < OPEN_GRID_VERTICAL_EDGE_PX) {
|
|
22137
|
-
setDisplayRowLimit((current) =>
|
|
22412
|
+
setDisplayRowLimit((current) => {
|
|
22413
|
+
const nextLimit = current + OPEN_GRID_ROW_GROWTH;
|
|
22414
|
+
return readOnly && current < maxRowDisplayLimit ? Math.min(maxRowDisplayLimit, nextLimit) : nextLimit;
|
|
22415
|
+
});
|
|
22138
22416
|
}
|
|
22139
22417
|
if (currentScroller.scrollWidth - (currentScroller.scrollLeft + currentScroller.clientWidth) < OPEN_GRID_HORIZONTAL_EDGE_PX) {
|
|
22140
|
-
setDisplayColLimit((current) =>
|
|
22418
|
+
setDisplayColLimit((current) => {
|
|
22419
|
+
const nextLimit = current + OPEN_GRID_COL_GROWTH;
|
|
22420
|
+
return readOnly && current < maxColDisplayLimit ? Math.min(maxColDisplayLimit, nextLimit) : nextLimit;
|
|
22421
|
+
});
|
|
22141
22422
|
}
|
|
22142
|
-
}, [syncDrawingViewport]);
|
|
22423
|
+
}, [maxColDisplayLimit, maxRowDisplayLimit, readOnly, syncDrawingViewport]);
|
|
22143
22424
|
React4.useEffect(() => {
|
|
22144
22425
|
const scroller = scrollRef.current;
|
|
22145
22426
|
if (!scroller || !enableGestureZoom) {
|
|
@@ -23045,14 +23326,14 @@ function XlsxGrid({
|
|
|
23045
23326
|
},
|
|
23046
23327
|
left: {
|
|
23047
23328
|
cols: frozenColItems,
|
|
23048
|
-
rows:
|
|
23329
|
+
rows: scrollRowItems
|
|
23049
23330
|
},
|
|
23050
23331
|
scroll: {
|
|
23051
|
-
cols:
|
|
23052
|
-
rows:
|
|
23332
|
+
cols: scrollColItems,
|
|
23333
|
+
rows: scrollRowItems
|
|
23053
23334
|
},
|
|
23054
23335
|
top: {
|
|
23055
|
-
cols:
|
|
23336
|
+
cols: scrollColItems,
|
|
23056
23337
|
rows: frozenRowItems
|
|
23057
23338
|
}
|
|
23058
23339
|
};
|
|
@@ -23186,6 +23467,51 @@ function XlsxGrid({
|
|
|
23186
23467
|
visibleRows
|
|
23187
23468
|
]
|
|
23188
23469
|
);
|
|
23470
|
+
const shouldBakeCanvasStaticDrawings = Boolean(experimentalCanvas && readOnly && showImages);
|
|
23471
|
+
const shouldBakeCanvasImages = Boolean(shouldBakeCanvasStaticDrawings && !renderImage && !renderImageSelection);
|
|
23472
|
+
const bakedShapeRects = React4.useMemo(
|
|
23473
|
+
() => shouldBakeCanvasStaticDrawings ? shapeRects.filter(({ shape }) => !shape.hyperlink) : [],
|
|
23474
|
+
[shapeRects, shouldBakeCanvasStaticDrawings]
|
|
23475
|
+
);
|
|
23476
|
+
const domShapeRects = React4.useMemo(
|
|
23477
|
+
() => shouldBakeCanvasStaticDrawings ? shapeRects.filter(({ shape }) => shape.hyperlink) : shapeRects,
|
|
23478
|
+
[shapeRects, shouldBakeCanvasStaticDrawings]
|
|
23479
|
+
);
|
|
23480
|
+
const bakedFormControlRects = React4.useMemo(
|
|
23481
|
+
() => shouldBakeCanvasStaticDrawings ? formControlRects : [],
|
|
23482
|
+
[formControlRects, shouldBakeCanvasStaticDrawings]
|
|
23483
|
+
);
|
|
23484
|
+
const domFormControlRects = React4.useMemo(
|
|
23485
|
+
() => shouldBakeCanvasStaticDrawings ? [] : formControlRects,
|
|
23486
|
+
[formControlRects, shouldBakeCanvasStaticDrawings]
|
|
23487
|
+
);
|
|
23488
|
+
const bakedImageRects = React4.useMemo(
|
|
23489
|
+
() => shouldBakeCanvasImages ? imageRects.filter(({ image }) => !image.hyperlink && selectedImageId !== image.id) : [],
|
|
23490
|
+
[imageRects, selectedImageId, shouldBakeCanvasImages]
|
|
23491
|
+
);
|
|
23492
|
+
const domImageRects = React4.useMemo(
|
|
23493
|
+
() => shouldBakeCanvasImages ? imageRects.filter(({ image }) => image.hyperlink || selectedImageId === image.id) : imageRects,
|
|
23494
|
+
[imageRects, selectedImageId, shouldBakeCanvasImages]
|
|
23495
|
+
);
|
|
23496
|
+
const hasCanvasDomDrawingOverlays = Boolean(
|
|
23497
|
+
showImages && (chartRects.length > 0 || domShapeRects.length > 0 || domFormControlRects.length > 0 || domImageRects.length > 0)
|
|
23498
|
+
);
|
|
23499
|
+
const bakedCanvasDrawingSignature = React4.useMemo(() => {
|
|
23500
|
+
if (!shouldBakeCanvasStaticDrawings) {
|
|
23501
|
+
return "";
|
|
23502
|
+
}
|
|
23503
|
+
const shapeSignature = bakedShapeRects.map(({ rect, shape }) => `s:${shape.id}:${shape.zIndex}:${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`).join("|");
|
|
23504
|
+
const controlSignature = bakedFormControlRects.map(({ control, rect }) => `f:${control.id}:${control.zIndex}:${Boolean(control.checked)}:${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`).join("|");
|
|
23505
|
+
const imageSignature = bakedImageRects.map(({ image, rect }) => `i:${image.id}:${image.src}:${image.zIndex}:${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`).join("|");
|
|
23506
|
+
return `${revision}:${canvasImageLoadVersion}:${shapeSignature}:${controlSignature}:${imageSignature}`;
|
|
23507
|
+
}, [
|
|
23508
|
+
bakedFormControlRects,
|
|
23509
|
+
bakedImageRects,
|
|
23510
|
+
bakedShapeRects,
|
|
23511
|
+
canvasImageLoadVersion,
|
|
23512
|
+
revision,
|
|
23513
|
+
shouldBakeCanvasStaticDrawings
|
|
23514
|
+
]);
|
|
23189
23515
|
const resolveMountedCellOverlayRect = React4.useCallback((element) => {
|
|
23190
23516
|
const wrapper = wrapperRef.current;
|
|
23191
23517
|
if (!wrapper) {
|
|
@@ -24054,6 +24380,24 @@ function XlsxGrid({
|
|
|
24054
24380
|
rowPrefixSums,
|
|
24055
24381
|
stickyTopByRow
|
|
24056
24382
|
]);
|
|
24383
|
+
const scrollBodyViewportWidth = Math.max(0, drawingViewport.width - frozenPaneRight);
|
|
24384
|
+
const scrollBodyViewportHeight = Math.max(0, drawingViewport.height - frozenPaneBottom);
|
|
24385
|
+
const canvasScrollBufferX = Math.min(CANVAS_SCROLL_BUFFER_PX, scrollBodyViewportWidth);
|
|
24386
|
+
const canvasScrollBufferY = Math.min(CANVAS_SCROLL_BUFFER_PX, scrollBodyViewportHeight);
|
|
24387
|
+
const scrollBodyCanvasLeft = frozenPaneRight - canvasScrollBufferX;
|
|
24388
|
+
const scrollBodyCanvasTop = frozenPaneBottom - canvasScrollBufferY;
|
|
24389
|
+
const scrollBodyCanvasWidth = scrollBodyViewportWidth + canvasScrollBufferX * 2;
|
|
24390
|
+
const scrollBodyCanvasHeight = scrollBodyViewportHeight + canvasScrollBufferY * 2;
|
|
24391
|
+
const topBodyCanvasWidth = scrollBodyCanvasWidth;
|
|
24392
|
+
const topBodyCanvasHeight = Math.max(0, frozenPaneBottom - displayHeaderHeight);
|
|
24393
|
+
const leftBodyCanvasWidth = Math.max(0, frozenPaneRight - displayRowHeaderWidth);
|
|
24394
|
+
const leftBodyCanvasHeight = scrollBodyCanvasHeight;
|
|
24395
|
+
const cornerBodyCanvasWidth = leftBodyCanvasWidth;
|
|
24396
|
+
const cornerBodyCanvasHeight = topBodyCanvasHeight;
|
|
24397
|
+
const topFrozenHeaderCanvasWidth = leftBodyCanvasWidth;
|
|
24398
|
+
const topScrollHeaderCanvasWidth = scrollBodyCanvasWidth;
|
|
24399
|
+
const leftFrozenHeaderCanvasHeight = topBodyCanvasHeight;
|
|
24400
|
+
const leftScrollHeaderCanvasHeight = scrollBodyCanvasHeight;
|
|
24057
24401
|
const canvasColumnHeaderCells = React4.useMemo(
|
|
24058
24402
|
() => canvasVisibleColItems.flatMap((column) => {
|
|
24059
24403
|
const rect = resolveCanvasColumnHeaderRect(column.actualCol);
|
|
@@ -24066,7 +24410,7 @@ function XlsxGrid({
|
|
|
24066
24410
|
height: displayHeaderHeight,
|
|
24067
24411
|
isFrozen,
|
|
24068
24412
|
left: rect.left,
|
|
24069
|
-
localLeft: rect.left - (isFrozen ? displayRowHeaderWidth :
|
|
24413
|
+
localLeft: rect.left - (isFrozen ? displayRowHeaderWidth : scrollBodyCanvasLeft),
|
|
24070
24414
|
width: rect.width
|
|
24071
24415
|
}];
|
|
24072
24416
|
}),
|
|
@@ -24074,8 +24418,8 @@ function XlsxGrid({
|
|
|
24074
24418
|
canvasVisibleColItems,
|
|
24075
24419
|
displayHeaderHeight,
|
|
24076
24420
|
displayRowHeaderWidth,
|
|
24077
|
-
frozenPaneRight,
|
|
24078
24421
|
resolveCanvasColumnHeaderRect,
|
|
24422
|
+
scrollBodyCanvasLeft,
|
|
24079
24423
|
stickyLeftByCol
|
|
24080
24424
|
]
|
|
24081
24425
|
);
|
|
@@ -24090,15 +24434,15 @@ function XlsxGrid({
|
|
|
24090
24434
|
actualRow: row.actualRow,
|
|
24091
24435
|
height: rect.height,
|
|
24092
24436
|
isFrozen,
|
|
24093
|
-
localTop: rect.top - (isFrozen ? displayHeaderHeight :
|
|
24437
|
+
localTop: rect.top - (isFrozen ? displayHeaderHeight : scrollBodyCanvasTop),
|
|
24094
24438
|
top: rect.top
|
|
24095
24439
|
}];
|
|
24096
24440
|
}),
|
|
24097
24441
|
[
|
|
24098
24442
|
canvasVisibleRowItems,
|
|
24099
24443
|
displayHeaderHeight,
|
|
24100
|
-
frozenPaneBottom,
|
|
24101
24444
|
resolveCanvasRowHeaderRect,
|
|
24445
|
+
scrollBodyCanvasTop,
|
|
24102
24446
|
stickyTopByRow
|
|
24103
24447
|
]
|
|
24104
24448
|
);
|
|
@@ -24365,10 +24709,46 @@ function XlsxGrid({
|
|
|
24365
24709
|
rowPrefixSums,
|
|
24366
24710
|
startCellSelection
|
|
24367
24711
|
]);
|
|
24712
|
+
const getCanvasImage = React4.useCallback((image) => {
|
|
24713
|
+
if (typeof Image === "undefined") {
|
|
24714
|
+
return null;
|
|
24715
|
+
}
|
|
24716
|
+
const cacheKey = image.id;
|
|
24717
|
+
const cached = canvasImageCacheRef.current.get(cacheKey);
|
|
24718
|
+
if (cached && cached.src === image.src) {
|
|
24719
|
+
return cached.loaded && !cached.failed ? cached.image : null;
|
|
24720
|
+
}
|
|
24721
|
+
const imageElement = new Image();
|
|
24722
|
+
const entry = {
|
|
24723
|
+
failed: false,
|
|
24724
|
+
image: imageElement,
|
|
24725
|
+
loaded: false,
|
|
24726
|
+
src: image.src
|
|
24727
|
+
};
|
|
24728
|
+
canvasImageCacheRef.current.set(cacheKey, entry);
|
|
24729
|
+
imageElement.onload = () => {
|
|
24730
|
+
entry.loaded = true;
|
|
24731
|
+
setCanvasImageLoadVersion((version) => version + 1);
|
|
24732
|
+
};
|
|
24733
|
+
imageElement.onerror = () => {
|
|
24734
|
+
entry.failed = true;
|
|
24735
|
+
setCanvasImageLoadVersion((version) => version + 1);
|
|
24736
|
+
};
|
|
24737
|
+
imageElement.src = image.src;
|
|
24738
|
+
return null;
|
|
24739
|
+
}, []);
|
|
24368
24740
|
React4.useLayoutEffect(() => {
|
|
24369
24741
|
if (!experimentalCanvas) {
|
|
24370
24742
|
return;
|
|
24371
24743
|
}
|
|
24744
|
+
const canvasProfileTarget = typeof window !== "undefined" ? window.__xlsxCanvasProfile : void 0;
|
|
24745
|
+
const canvasProfileStart = canvasProfileTarget ? performance.now() : 0;
|
|
24746
|
+
let canvasProfileBodyStart = 0;
|
|
24747
|
+
let canvasProfileBodyMs = 0;
|
|
24748
|
+
let canvasProfileCulledCells = 0;
|
|
24749
|
+
let canvasProfileDirtyRects = 0;
|
|
24750
|
+
let canvasProfileLookedUpCells = 0;
|
|
24751
|
+
let canvasProfilePaintedCells = 0;
|
|
24372
24752
|
const dpr = typeof window === "undefined" ? 1 : Math.max(1, window.devicePixelRatio || 1);
|
|
24373
24753
|
function configureCanvas(canvas, width, height, options) {
|
|
24374
24754
|
if (!canvas) {
|
|
@@ -24388,7 +24768,7 @@ function XlsxGrid({
|
|
|
24388
24768
|
if (canvas.style.height !== `${height}px`) {
|
|
24389
24769
|
canvas.style.height = `${height}px`;
|
|
24390
24770
|
}
|
|
24391
|
-
const context = canvas.getContext("2d");
|
|
24771
|
+
const context = canvas.getContext("2d", { alpha: false });
|
|
24392
24772
|
if (!context) {
|
|
24393
24773
|
return null;
|
|
24394
24774
|
}
|
|
@@ -24407,6 +24787,7 @@ function XlsxGrid({
|
|
|
24407
24787
|
const rangeSignature = buildRangeSignature(normalizedVisibleRange);
|
|
24408
24788
|
const nextBodyCanvasSignature = {
|
|
24409
24789
|
activeSheet: activeSheet ?? null,
|
|
24790
|
+
bakedDrawingSignature: bakedCanvasDrawingSignature,
|
|
24410
24791
|
bodyHeight,
|
|
24411
24792
|
bodyWidth,
|
|
24412
24793
|
colSignature: buildRenderedAxisSignature(canvasVisibleColItems, (item) => item.index),
|
|
@@ -24434,10 +24815,10 @@ function XlsxGrid({
|
|
|
24434
24815
|
const previousBodyCanvasSignature = paintedBodyCanvasSignatureRef.current;
|
|
24435
24816
|
const previousHeaderCanvasSignature = paintedHeaderCanvasSignatureRef.current;
|
|
24436
24817
|
const previousPaintedViewport = paintedDrawingViewportRef.current;
|
|
24437
|
-
const shouldRepaintBody = !(previousBodyCanvasSignature && previousBodyCanvasSignature.activeSheet === nextBodyCanvasSignature.activeSheet && previousBodyCanvasSignature.bodyHeight === nextBodyCanvasSignature.bodyHeight && previousBodyCanvasSignature.bodyWidth === nextBodyCanvasSignature.bodyWidth && previousBodyCanvasSignature.colSignature === nextBodyCanvasSignature.colSignature && previousBodyCanvasSignature.getCellData === nextBodyCanvasSignature.getCellData && previousBodyCanvasSignature.headerHeight === nextBodyCanvasSignature.headerHeight && previousBodyCanvasSignature.palette === nextBodyCanvasSignature.palette && previousBodyCanvasSignature.rowHeaderWidth === nextBodyCanvasSignature.rowHeaderWidth && previousBodyCanvasSignature.rowSignature === nextBodyCanvasSignature.rowSignature && previousBodyCanvasSignature.zoomFactor === nextBodyCanvasSignature.zoomFactor);
|
|
24818
|
+
const shouldRepaintBody = !(previousBodyCanvasSignature && previousBodyCanvasSignature.activeSheet === nextBodyCanvasSignature.activeSheet && previousBodyCanvasSignature.bakedDrawingSignature === nextBodyCanvasSignature.bakedDrawingSignature && previousBodyCanvasSignature.bodyHeight === nextBodyCanvasSignature.bodyHeight && previousBodyCanvasSignature.bodyWidth === nextBodyCanvasSignature.bodyWidth && previousBodyCanvasSignature.colSignature === nextBodyCanvasSignature.colSignature && previousBodyCanvasSignature.getCellData === nextBodyCanvasSignature.getCellData && previousBodyCanvasSignature.headerHeight === nextBodyCanvasSignature.headerHeight && previousBodyCanvasSignature.palette === nextBodyCanvasSignature.palette && previousBodyCanvasSignature.rowHeaderWidth === nextBodyCanvasSignature.rowHeaderWidth && previousBodyCanvasSignature.rowSignature === nextBodyCanvasSignature.rowSignature && previousBodyCanvasSignature.zoomFactor === nextBodyCanvasSignature.zoomFactor);
|
|
24438
24819
|
const shouldRepaintHeaders = !(previousHeaderCanvasSignature && previousHeaderCanvasSignature.activeSheet === nextHeaderCanvasSignature.activeSheet && previousHeaderCanvasSignature.bodyHeight === nextHeaderCanvasSignature.bodyHeight && previousHeaderCanvasSignature.bodyWidth === nextHeaderCanvasSignature.bodyWidth && previousHeaderCanvasSignature.colSignature === nextHeaderCanvasSignature.colSignature && previousHeaderCanvasSignature.headerHeight === nextHeaderCanvasSignature.headerHeight && previousHeaderCanvasSignature.palette === nextHeaderCanvasSignature.palette && previousHeaderCanvasSignature.rangeSignature === nextHeaderCanvasSignature.rangeSignature && previousHeaderCanvasSignature.rowHeaderWidth === nextHeaderCanvasSignature.rowHeaderWidth && previousHeaderCanvasSignature.rowSignature === nextHeaderCanvasSignature.rowSignature && previousHeaderCanvasSignature.viewportLeft === nextHeaderCanvasSignature.viewportLeft && previousHeaderCanvasSignature.viewportTop === nextHeaderCanvasSignature.viewportTop && previousHeaderCanvasSignature.zoomFactor === nextHeaderCanvasSignature.zoomFactor);
|
|
24439
24820
|
const canBlitBody = Boolean(
|
|
24440
|
-
shouldRepaintBody && previousBodyCanvasSignature && previousBodyCanvasSignature.activeSheet === nextBodyCanvasSignature.activeSheet && previousBodyCanvasSignature.bodyHeight === nextBodyCanvasSignature.bodyHeight && previousBodyCanvasSignature.bodyWidth === nextBodyCanvasSignature.bodyWidth && previousBodyCanvasSignature.getCellData === nextBodyCanvasSignature.getCellData && previousBodyCanvasSignature.headerHeight === nextBodyCanvasSignature.headerHeight && previousBodyCanvasSignature.palette === nextBodyCanvasSignature.palette && previousBodyCanvasSignature.rowHeaderWidth === nextBodyCanvasSignature.rowHeaderWidth && previousBodyCanvasSignature.zoomFactor === nextBodyCanvasSignature.zoomFactor
|
|
24821
|
+
shouldRepaintBody && previousBodyCanvasSignature && previousBodyCanvasSignature.activeSheet === nextBodyCanvasSignature.activeSheet && previousBodyCanvasSignature.bakedDrawingSignature === nextBodyCanvasSignature.bakedDrawingSignature && previousBodyCanvasSignature.bodyHeight === nextBodyCanvasSignature.bodyHeight && previousBodyCanvasSignature.bodyWidth === nextBodyCanvasSignature.bodyWidth && previousBodyCanvasSignature.getCellData === nextBodyCanvasSignature.getCellData && previousBodyCanvasSignature.headerHeight === nextBodyCanvasSignature.headerHeight && previousBodyCanvasSignature.palette === nextBodyCanvasSignature.palette && previousBodyCanvasSignature.rowHeaderWidth === nextBodyCanvasSignature.rowHeaderWidth && previousBodyCanvasSignature.zoomFactor === nextBodyCanvasSignature.zoomFactor
|
|
24441
24822
|
);
|
|
24442
24823
|
const canBlitTopHeader = Boolean(
|
|
24443
24824
|
shouldRepaintHeaders && previousHeaderCanvasSignature && previousHeaderCanvasSignature.activeSheet === nextHeaderCanvasSignature.activeSheet && previousHeaderCanvasSignature.bodyHeight === nextHeaderCanvasSignature.bodyHeight && previousHeaderCanvasSignature.bodyWidth === nextHeaderCanvasSignature.bodyWidth && previousHeaderCanvasSignature.headerHeight === nextHeaderCanvasSignature.headerHeight && previousHeaderCanvasSignature.palette === nextHeaderCanvasSignature.palette && previousHeaderCanvasSignature.rangeSignature === nextHeaderCanvasSignature.rangeSignature && previousHeaderCanvasSignature.rowHeaderWidth === nextHeaderCanvasSignature.rowHeaderWidth && previousHeaderCanvasSignature.zoomFactor === nextHeaderCanvasSignature.zoomFactor
|
|
@@ -24448,49 +24829,37 @@ function XlsxGrid({
|
|
|
24448
24829
|
if (!shouldRepaintBody && !shouldRepaintHeaders) {
|
|
24449
24830
|
return;
|
|
24450
24831
|
}
|
|
24451
|
-
const scrollBodyCanvasWidth2 = Math.max(0, drawingViewport.width - frozenPaneRight);
|
|
24452
|
-
const scrollBodyCanvasHeight2 = Math.max(0, drawingViewport.height - frozenPaneBottom);
|
|
24453
|
-
const topBodyCanvasWidth2 = scrollBodyCanvasWidth2;
|
|
24454
|
-
const topBodyCanvasHeight2 = Math.max(0, frozenPaneBottom - displayHeaderHeight);
|
|
24455
|
-
const leftBodyCanvasWidth2 = Math.max(0, frozenPaneRight - displayRowHeaderWidth);
|
|
24456
|
-
const leftBodyCanvasHeight2 = scrollBodyCanvasHeight2;
|
|
24457
|
-
const cornerBodyCanvasWidth2 = leftBodyCanvasWidth2;
|
|
24458
|
-
const cornerBodyCanvasHeight2 = topBodyCanvasHeight2;
|
|
24459
|
-
const topFrozenHeaderCanvasWidth2 = leftBodyCanvasWidth2;
|
|
24460
|
-
const topScrollHeaderCanvasWidth2 = scrollBodyCanvasWidth2;
|
|
24461
|
-
const leftFrozenHeaderCanvasHeight2 = topBodyCanvasHeight2;
|
|
24462
|
-
const leftScrollHeaderCanvasHeight2 = scrollBodyCanvasHeight2;
|
|
24463
24832
|
const paneBounds = {
|
|
24464
24833
|
corner: {
|
|
24465
|
-
height:
|
|
24834
|
+
height: cornerBodyCanvasHeight,
|
|
24466
24835
|
left: displayRowHeaderWidth,
|
|
24467
24836
|
top: displayHeaderHeight,
|
|
24468
|
-
width:
|
|
24837
|
+
width: cornerBodyCanvasWidth
|
|
24469
24838
|
},
|
|
24470
24839
|
left: {
|
|
24471
|
-
height:
|
|
24840
|
+
height: leftBodyCanvasHeight,
|
|
24472
24841
|
left: displayRowHeaderWidth,
|
|
24473
|
-
top:
|
|
24474
|
-
width:
|
|
24842
|
+
top: scrollBodyCanvasTop,
|
|
24843
|
+
width: leftBodyCanvasWidth
|
|
24475
24844
|
},
|
|
24476
24845
|
scroll: {
|
|
24477
|
-
height:
|
|
24478
|
-
left:
|
|
24479
|
-
top:
|
|
24480
|
-
width:
|
|
24846
|
+
height: scrollBodyCanvasHeight,
|
|
24847
|
+
left: scrollBodyCanvasLeft,
|
|
24848
|
+
top: scrollBodyCanvasTop,
|
|
24849
|
+
width: scrollBodyCanvasWidth
|
|
24481
24850
|
},
|
|
24482
24851
|
top: {
|
|
24483
|
-
height:
|
|
24484
|
-
left:
|
|
24852
|
+
height: topBodyCanvasHeight,
|
|
24853
|
+
left: scrollBodyCanvasLeft,
|
|
24485
24854
|
top: displayHeaderHeight,
|
|
24486
|
-
width:
|
|
24855
|
+
width: topBodyCanvasWidth
|
|
24487
24856
|
}
|
|
24488
24857
|
};
|
|
24489
24858
|
const bodyContexts = shouldRepaintBody ? {
|
|
24490
|
-
corner: configureCanvas(cornerBodyCanvasRef.current,
|
|
24491
|
-
left: configureCanvas(leftBodyCanvasRef.current,
|
|
24492
|
-
scroll: configureCanvas(scrollBodyCanvasRef.current,
|
|
24493
|
-
top: configureCanvas(topBodyCanvasRef.current,
|
|
24859
|
+
corner: configureCanvas(cornerBodyCanvasRef.current, cornerBodyCanvasWidth, cornerBodyCanvasHeight, { clear: !canBlitBody }),
|
|
24860
|
+
left: configureCanvas(leftBodyCanvasRef.current, leftBodyCanvasWidth, leftBodyCanvasHeight, { clear: !canBlitBody }),
|
|
24861
|
+
scroll: configureCanvas(scrollBodyCanvasRef.current, scrollBodyCanvasWidth, scrollBodyCanvasHeight, { clear: !canBlitBody }),
|
|
24862
|
+
top: configureCanvas(topBodyCanvasRef.current, topBodyCanvasWidth, topBodyCanvasHeight, { clear: !canBlitBody })
|
|
24494
24863
|
} : {
|
|
24495
24864
|
corner: null,
|
|
24496
24865
|
left: null,
|
|
@@ -24498,21 +24867,21 @@ function XlsxGrid({
|
|
|
24498
24867
|
top: null
|
|
24499
24868
|
};
|
|
24500
24869
|
const topHeaderContexts = shouldRepaintHeaders ? {
|
|
24501
|
-
frozen: configureCanvas(topFrozenHeaderCanvasRef.current,
|
|
24502
|
-
scroll: configureCanvas(topScrollHeaderCanvasRef.current,
|
|
24870
|
+
frozen: configureCanvas(topFrozenHeaderCanvasRef.current, topFrozenHeaderCanvasWidth, headerHeight),
|
|
24871
|
+
scroll: configureCanvas(topScrollHeaderCanvasRef.current, topScrollHeaderCanvasWidth, headerHeight, { clear: !canBlitTopHeader })
|
|
24503
24872
|
} : {
|
|
24504
24873
|
frozen: null,
|
|
24505
24874
|
scroll: null
|
|
24506
24875
|
};
|
|
24507
24876
|
const leftHeaderContexts = shouldRepaintHeaders ? {
|
|
24508
|
-
frozen: configureCanvas(leftFrozenHeaderCanvasRef.current, rowHeaderWidth,
|
|
24509
|
-
scroll: configureCanvas(leftScrollHeaderCanvasRef.current, rowHeaderWidth,
|
|
24877
|
+
frozen: configureCanvas(leftFrozenHeaderCanvasRef.current, rowHeaderWidth, leftFrozenHeaderCanvasHeight),
|
|
24878
|
+
scroll: configureCanvas(leftScrollHeaderCanvasRef.current, rowHeaderWidth, leftScrollHeaderCanvasHeight, { clear: !canBlitLeftHeader })
|
|
24510
24879
|
} : {
|
|
24511
24880
|
frozen: null,
|
|
24512
24881
|
scroll: null
|
|
24513
24882
|
};
|
|
24514
24883
|
const cornerContext = shouldRepaintHeaders ? configureCanvas(cornerHeaderCanvasRef.current, rowHeaderWidth, headerHeight) : null;
|
|
24515
|
-
if (shouldRepaintBody && (!bodyContexts.scroll || !bodyContexts.top || !bodyContexts.left || !bodyContexts.corner) || shouldRepaintHeaders && (!cornerContext ||
|
|
24884
|
+
if (shouldRepaintBody && (!bodyContexts.scroll || !bodyContexts.top || !bodyContexts.left || !bodyContexts.corner) || shouldRepaintHeaders && (!cornerContext || topFrozenHeaderCanvasWidth > 0 && !topHeaderContexts.frozen || topScrollHeaderCanvasWidth > 0 && !topHeaderContexts.scroll || leftFrozenHeaderCanvasHeight > 0 && !leftHeaderContexts.frozen || leftScrollHeaderCanvasHeight > 0 && !leftHeaderContexts.scroll)) {
|
|
24516
24885
|
return;
|
|
24517
24886
|
}
|
|
24518
24887
|
const showGridLines = activeSheet?.showGridLines ?? true;
|
|
@@ -24529,10 +24898,282 @@ function XlsxGrid({
|
|
|
24529
24898
|
scroll: [],
|
|
24530
24899
|
top: []
|
|
24531
24900
|
};
|
|
24532
|
-
let topScrollHeaderDirtyRects = buildFullCanvasDirtyRect(
|
|
24533
|
-
let leftScrollHeaderDirtyRects = buildFullCanvasDirtyRect(rowHeaderWidth,
|
|
24901
|
+
let topScrollHeaderDirtyRects = buildFullCanvasDirtyRect(topScrollHeaderCanvasWidth, headerHeight);
|
|
24902
|
+
let leftScrollHeaderDirtyRects = buildFullCanvasDirtyRect(rowHeaderWidth, leftScrollHeaderCanvasHeight);
|
|
24903
|
+
const bakedCanvasDrawingEntries = shouldBakeCanvasStaticDrawings ? [
|
|
24904
|
+
...bakedShapeRects.map(({ rect, shape }) => ({
|
|
24905
|
+
kind: "shape",
|
|
24906
|
+
rect,
|
|
24907
|
+
shape,
|
|
24908
|
+
zIndex: shape.zIndex
|
|
24909
|
+
})),
|
|
24910
|
+
...bakedFormControlRects.map(({ control, rect }) => ({
|
|
24911
|
+
control,
|
|
24912
|
+
kind: "formControl",
|
|
24913
|
+
rect,
|
|
24914
|
+
zIndex: control.zIndex
|
|
24915
|
+
})),
|
|
24916
|
+
...bakedImageRects.map(({ image, rect }) => ({
|
|
24917
|
+
image,
|
|
24918
|
+
kind: "image",
|
|
24919
|
+
rect,
|
|
24920
|
+
zIndex: image.zIndex
|
|
24921
|
+
}))
|
|
24922
|
+
].sort((left, right) => left.zIndex - right.zIndex) : [];
|
|
24923
|
+
const resolveBakedCanvasLocalRect = (rect, pane) => {
|
|
24924
|
+
const bounds = paneBounds[pane];
|
|
24925
|
+
const scrollX = pane === "scroll" || pane === "top" ? drawingViewport.left : 0;
|
|
24926
|
+
const scrollY = pane === "scroll" || pane === "left" ? drawingViewport.top : 0;
|
|
24927
|
+
return {
|
|
24928
|
+
height: rect.height,
|
|
24929
|
+
left: rect.left - scrollX - bounds.left,
|
|
24930
|
+
top: rect.top - scrollY - bounds.top,
|
|
24931
|
+
width: rect.width
|
|
24932
|
+
};
|
|
24933
|
+
};
|
|
24934
|
+
const drawBakedShapeText = (context, shape, left, top, width, height) => {
|
|
24935
|
+
if (shape.paragraphs.length === 0) {
|
|
24936
|
+
return;
|
|
24937
|
+
}
|
|
24938
|
+
const inset = shape.textBox?.insetPx;
|
|
24939
|
+
const paddingLeft = (inset?.left ?? 6) * zoomFactor;
|
|
24940
|
+
const paddingRight = (inset?.right ?? 6) * zoomFactor;
|
|
24941
|
+
const paddingTop = (inset?.top ?? 4) * zoomFactor;
|
|
24942
|
+
const paddingBottom = (inset?.bottom ?? 4) * zoomFactor;
|
|
24943
|
+
const textLeft = left + paddingLeft;
|
|
24944
|
+
const textTop = top + paddingTop;
|
|
24945
|
+
const textWidth = Math.max(0, width - paddingLeft - paddingRight);
|
|
24946
|
+
const textHeight = Math.max(0, height - paddingTop - paddingBottom);
|
|
24947
|
+
if (textWidth <= 0 || textHeight <= 0) {
|
|
24948
|
+
return;
|
|
24949
|
+
}
|
|
24950
|
+
const lineMetrics = shape.paragraphs.map((paragraph) => {
|
|
24951
|
+
const lineHeight = Math.max(
|
|
24952
|
+
12 * zoomFactor,
|
|
24953
|
+
...paragraph.runs.map((run) => (run.fontSizePt ?? 11) * 96 / 72 * zoomFactor * 1.2)
|
|
24954
|
+
);
|
|
24955
|
+
const widthPx = paragraph.runs.reduce((total, run) => {
|
|
24956
|
+
const fontSize = (run.fontSizePt ?? 11) * 96 / 72 * zoomFactor;
|
|
24957
|
+
context.font = `${run.italic ? "italic " : ""}${run.bold ? "700 " : "400 "}${fontSize}px ${run.fontFamily ?? "Calibri, sans-serif"}`;
|
|
24958
|
+
return total + measureCanvasTextWidth(context, run.text);
|
|
24959
|
+
}, 0);
|
|
24960
|
+
return { lineHeight, widthPx };
|
|
24961
|
+
});
|
|
24962
|
+
const totalTextHeight = lineMetrics.reduce((total, metric) => total + metric.lineHeight, 0);
|
|
24963
|
+
let y = textTop;
|
|
24964
|
+
if (shape.textBox?.verticalAlign === "middle") {
|
|
24965
|
+
y = textTop + Math.max(0, (textHeight - totalTextHeight) / 2);
|
|
24966
|
+
} else if (shape.textBox?.verticalAlign === "bottom") {
|
|
24967
|
+
y = textTop + Math.max(0, textHeight - totalTextHeight);
|
|
24968
|
+
}
|
|
24969
|
+
context.save();
|
|
24970
|
+
context.beginPath();
|
|
24971
|
+
context.rect(textLeft, textTop, textWidth, textHeight);
|
|
24972
|
+
context.clip();
|
|
24973
|
+
context.textBaseline = "middle";
|
|
24974
|
+
shape.paragraphs.forEach((paragraph, paragraphIndex) => {
|
|
24975
|
+
const metric = lineMetrics[paragraphIndex] ?? { lineHeight: 14 * zoomFactor, widthPx: 0 };
|
|
24976
|
+
let x = textLeft;
|
|
24977
|
+
const align = paragraph.align ?? shape.textBox?.horizontalAlign ?? "left";
|
|
24978
|
+
if (align === "center") {
|
|
24979
|
+
x = textLeft + Math.max(0, (textWidth - metric.widthPx) / 2);
|
|
24980
|
+
} else if (align === "right") {
|
|
24981
|
+
x = textLeft + Math.max(0, textWidth - metric.widthPx);
|
|
24982
|
+
}
|
|
24983
|
+
paragraph.runs.forEach((run) => {
|
|
24984
|
+
const fontSize = (run.fontSizePt ?? 11) * 96 / 72 * zoomFactor;
|
|
24985
|
+
context.font = `${run.italic ? "italic " : ""}${run.bold ? "700 " : "400 "}${fontSize}px ${run.fontFamily ?? "Calibri, sans-serif"}`;
|
|
24986
|
+
context.fillStyle = run.color ?? "#000000";
|
|
24987
|
+
context.textAlign = "left";
|
|
24988
|
+
const textY = y + metric.lineHeight / 2;
|
|
24989
|
+
context.fillText(run.text, x, textY);
|
|
24990
|
+
if (run.underline && run.text.length > 0) {
|
|
24991
|
+
const textWidthPx = measureCanvasTextWidth(context, run.text);
|
|
24992
|
+
context.strokeStyle = run.color ?? "#000000";
|
|
24993
|
+
context.lineWidth = Math.max(1, zoomFactor * 0.75);
|
|
24994
|
+
context.beginPath();
|
|
24995
|
+
context.moveTo(x, textY + Math.max(2, fontSize * 0.28));
|
|
24996
|
+
context.lineTo(x + textWidthPx, textY + Math.max(2, fontSize * 0.28));
|
|
24997
|
+
context.stroke();
|
|
24998
|
+
}
|
|
24999
|
+
x += measureCanvasTextWidth(context, run.text);
|
|
25000
|
+
});
|
|
25001
|
+
y += metric.lineHeight;
|
|
25002
|
+
});
|
|
25003
|
+
context.restore();
|
|
25004
|
+
};
|
|
25005
|
+
const drawBakedShape = (context, shape, rect) => {
|
|
25006
|
+
const fillColor = shape.fill?.none ? "transparent" : shape.fill?.color ?? "transparent";
|
|
25007
|
+
const strokeColor = shape.stroke?.none ? "transparent" : shape.stroke?.color ?? "transparent";
|
|
25008
|
+
const lineWidth = Math.max(0, (shape.stroke?.widthPx ?? (shape.geometry === "line" ? 2 : 1)) * zoomFactor);
|
|
25009
|
+
const vectorShape = resolveShapeVector(shape);
|
|
25010
|
+
const opacity = Math.min(shape.fill?.opacity ?? 1, shape.stroke?.opacity ?? 1);
|
|
25011
|
+
context.save();
|
|
25012
|
+
context.translate(rect.left + rect.width / 2, rect.top + rect.height / 2);
|
|
25013
|
+
if (shape.rotationDeg) {
|
|
25014
|
+
context.rotate(shape.rotationDeg * Math.PI / 180);
|
|
25015
|
+
}
|
|
25016
|
+
context.scale(shape.flipH ? -1 : 1, shape.flipV ? -1 : 1);
|
|
25017
|
+
context.globalAlpha *= opacity;
|
|
25018
|
+
context.lineWidth = lineWidth;
|
|
25019
|
+
context.strokeStyle = strokeColor;
|
|
25020
|
+
context.fillStyle = fillColor;
|
|
25021
|
+
applyCanvasShapeDash(context, shape.stroke?.dash, lineWidth);
|
|
25022
|
+
const localLeft = -rect.width / 2;
|
|
25023
|
+
const localTop = -rect.height / 2;
|
|
25024
|
+
if (vectorShape && typeof Path2D !== "undefined") {
|
|
25025
|
+
context.save();
|
|
25026
|
+
context.translate(localLeft, localTop);
|
|
25027
|
+
context.scale(
|
|
25028
|
+
rect.width / Math.max(1, vectorShape.viewBox.width),
|
|
25029
|
+
rect.height / Math.max(1, vectorShape.viewBox.height)
|
|
25030
|
+
);
|
|
25031
|
+
const path = getCachedCanvasPath2D(vectorShape.path);
|
|
25032
|
+
if (!path) {
|
|
25033
|
+
context.restore();
|
|
25034
|
+
context.restore();
|
|
25035
|
+
return;
|
|
25036
|
+
}
|
|
25037
|
+
if (fillColor !== "transparent") {
|
|
25038
|
+
context.fill(path);
|
|
25039
|
+
}
|
|
25040
|
+
if (strokeColor !== "transparent" && lineWidth > 0) {
|
|
25041
|
+
context.stroke(path);
|
|
25042
|
+
}
|
|
25043
|
+
context.restore();
|
|
25044
|
+
} else if (shape.geometry === "ellipse") {
|
|
25045
|
+
context.beginPath();
|
|
25046
|
+
context.ellipse(0, 0, rect.width / 2, rect.height / 2, 0, 0, Math.PI * 2);
|
|
25047
|
+
if (fillColor !== "transparent") {
|
|
25048
|
+
context.fill();
|
|
25049
|
+
}
|
|
25050
|
+
if (strokeColor !== "transparent" && lineWidth > 0) {
|
|
25051
|
+
context.stroke();
|
|
25052
|
+
}
|
|
25053
|
+
} else {
|
|
25054
|
+
const radius = shape.geometry === "roundRect" ? 12 * zoomFactor : 0;
|
|
25055
|
+
drawCanvasRoundedRect(context, localLeft, localTop, rect.width, rect.height, radius);
|
|
25056
|
+
if (fillColor !== "transparent") {
|
|
25057
|
+
context.fill();
|
|
25058
|
+
}
|
|
25059
|
+
if (strokeColor !== "transparent" && lineWidth > 0) {
|
|
25060
|
+
context.stroke();
|
|
25061
|
+
}
|
|
25062
|
+
}
|
|
25063
|
+
drawBakedShapeText(context, shape, localLeft, localTop, rect.width, rect.height);
|
|
25064
|
+
context.restore();
|
|
25065
|
+
};
|
|
25066
|
+
const drawBakedFormControl = (context, control, rect) => {
|
|
25067
|
+
const label = resolveFormControlLabel(control);
|
|
25068
|
+
const stroke = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
25069
|
+
const textColor = control.textColor ?? "#000000";
|
|
25070
|
+
const fontSizePx = Math.max(9 * zoomFactor, (control.fontSizePt ?? 9) * 96 / 72 * zoomFactor);
|
|
25071
|
+
const iconSize = Math.min(14 * zoomFactor, Math.max(0, rect.height - 4 * zoomFactor));
|
|
25072
|
+
context.save();
|
|
25073
|
+
context.font = `400 ${fontSizePx}px ${control.fontFamily ?? "Calibri, sans-serif"}`;
|
|
25074
|
+
context.textBaseline = "middle";
|
|
25075
|
+
context.fillStyle = textColor;
|
|
25076
|
+
context.strokeStyle = stroke;
|
|
25077
|
+
context.lineWidth = Math.max(1, zoomFactor);
|
|
25078
|
+
if (control.kind === "group-box") {
|
|
25079
|
+
const labelInset = label ? Math.max(7, fontSizePx * 0.5) : 0;
|
|
25080
|
+
drawCanvasRoundedRect(context, rect.left, rect.top + labelInset, rect.width, Math.max(0, rect.height - labelInset), 2 * zoomFactor);
|
|
25081
|
+
context.stroke();
|
|
25082
|
+
if (label) {
|
|
25083
|
+
context.fillStyle = SHEET_SURFACE;
|
|
25084
|
+
const labelWidth = Math.min(rect.width - 16 * zoomFactor, measureCanvasTextWidth(context, label) + 8 * zoomFactor);
|
|
25085
|
+
context.fillRect(rect.left + 8 * zoomFactor, rect.top, labelWidth, fontSizePx * 1.2);
|
|
25086
|
+
context.fillStyle = textColor;
|
|
25087
|
+
context.textAlign = "left";
|
|
25088
|
+
context.fillText(label, rect.left + 12 * zoomFactor, rect.top + fontSizePx * 0.55);
|
|
25089
|
+
}
|
|
25090
|
+
context.restore();
|
|
25091
|
+
return;
|
|
25092
|
+
}
|
|
25093
|
+
if (control.kind === "button" || control.kind === "dropdown" || control.kind === "editbox" || control.kind === "listbox" || control.kind === "scrollbar" || control.kind === "spinner" || control.kind === "unknown") {
|
|
25094
|
+
if (control.kind === "button") {
|
|
25095
|
+
const gradient = context.createLinearGradient(rect.left, rect.top, rect.left, rect.top + rect.height);
|
|
25096
|
+
gradient.addColorStop(0, "#f8fafc");
|
|
25097
|
+
gradient.addColorStop(1, "#e2e8f0");
|
|
25098
|
+
context.fillStyle = gradient;
|
|
25099
|
+
} else {
|
|
25100
|
+
context.fillStyle = "transparent";
|
|
25101
|
+
}
|
|
25102
|
+
drawCanvasRoundedRect(context, rect.left, rect.top, rect.width, rect.height, control.kind === "button" ? 4 * zoomFactor : 2 * zoomFactor);
|
|
25103
|
+
if (control.kind === "button") {
|
|
25104
|
+
context.fill();
|
|
25105
|
+
}
|
|
25106
|
+
context.stroke();
|
|
25107
|
+
}
|
|
25108
|
+
let textLeft = rect.left + 2 * zoomFactor;
|
|
25109
|
+
const textRightInset = control.kind === "dropdown" ? 18 * zoomFactor : 6 * zoomFactor;
|
|
25110
|
+
if (control.kind === "checkbox") {
|
|
25111
|
+
context.strokeRect(rect.left + 2 * zoomFactor, rect.top + (rect.height - iconSize) / 2, iconSize, iconSize);
|
|
25112
|
+
if (control.checked) {
|
|
25113
|
+
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
25114
|
+
context.fillRect(rect.left + 2 * zoomFactor + 1.5, rect.top + (rect.height - iconSize) / 2 + 1.5, Math.max(0, iconSize - 3), Math.max(0, iconSize - 3));
|
|
25115
|
+
context.strokeStyle = paletteIsDark(palette) ? "#020617" : "#ffffff";
|
|
25116
|
+
context.beginPath();
|
|
25117
|
+
context.moveTo(rect.left + 2 * zoomFactor + iconSize * 0.24, rect.top + rect.height / 2 + iconSize * 0.06);
|
|
25118
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.45, rect.top + rect.height / 2 + iconSize * 0.26);
|
|
25119
|
+
context.lineTo(rect.left + 2 * zoomFactor + iconSize * 0.8, rect.top + rect.height / 2 - iconSize * 0.2);
|
|
25120
|
+
context.stroke();
|
|
25121
|
+
}
|
|
25122
|
+
textLeft += iconSize + 4 * zoomFactor;
|
|
25123
|
+
} else if (control.kind === "radio") {
|
|
25124
|
+
context.beginPath();
|
|
25125
|
+
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize / 2, 0, Math.PI * 2);
|
|
25126
|
+
context.stroke();
|
|
25127
|
+
if (control.checked) {
|
|
25128
|
+
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
25129
|
+
context.beginPath();
|
|
25130
|
+
context.arc(rect.left + 2 * zoomFactor + iconSize / 2, rect.top + rect.height / 2, iconSize * 0.25, 0, Math.PI * 2);
|
|
25131
|
+
context.fill();
|
|
25132
|
+
}
|
|
25133
|
+
textLeft += iconSize + 4 * zoomFactor;
|
|
25134
|
+
}
|
|
25135
|
+
if (label) {
|
|
25136
|
+
const maxTextWidth = Math.max(0, rect.left + rect.width - textLeft - textRightInset);
|
|
25137
|
+
const text = truncateCanvasText(context, label, maxTextWidth);
|
|
25138
|
+
context.fillStyle = textColor;
|
|
25139
|
+
context.textAlign = control.textAlign === "right" ? "right" : control.textAlign === "center" ? "center" : "left";
|
|
25140
|
+
const textX = context.textAlign === "right" ? rect.left + rect.width - textRightInset : context.textAlign === "center" ? textLeft + maxTextWidth / 2 : textLeft;
|
|
25141
|
+
context.fillText(text, textX, rect.top + rect.height / 2);
|
|
25142
|
+
}
|
|
25143
|
+
if (control.kind === "dropdown") {
|
|
25144
|
+
context.fillStyle = textColor;
|
|
25145
|
+
context.textAlign = "center";
|
|
25146
|
+
context.fillText("\u25BC", rect.left + rect.width - 10 * zoomFactor, rect.top + rect.height / 2);
|
|
25147
|
+
}
|
|
25148
|
+
context.restore();
|
|
25149
|
+
};
|
|
25150
|
+
const drawBakedCanvasDrawings = (pane, context, dirtyRects) => {
|
|
25151
|
+
if (bakedCanvasDrawingEntries.length === 0 || dirtyRects.length === 0) {
|
|
25152
|
+
return;
|
|
25153
|
+
}
|
|
25154
|
+
for (const entry of bakedCanvasDrawingEntries) {
|
|
25155
|
+
if (resolveDrawingPane(entry.rect) !== pane) {
|
|
25156
|
+
continue;
|
|
25157
|
+
}
|
|
25158
|
+
const localRect = resolveBakedCanvasLocalRect(entry.rect, pane);
|
|
25159
|
+
if (localRect.left + localRect.width < 0 || localRect.top + localRect.height < 0 || localRect.left > paneBounds[pane].width || localRect.top > paneBounds[pane].height || !intersectsCanvasDirtyRects(localRect.left, localRect.top, localRect.width, localRect.height, dirtyRects)) {
|
|
25160
|
+
continue;
|
|
25161
|
+
}
|
|
25162
|
+
if (entry.kind === "shape") {
|
|
25163
|
+
drawBakedShape(context, entry.shape, localRect);
|
|
25164
|
+
} else if (entry.kind === "formControl") {
|
|
25165
|
+
drawBakedFormControl(context, entry.control, localRect);
|
|
25166
|
+
} else {
|
|
25167
|
+
const imageElement = getCanvasImage(entry.image);
|
|
25168
|
+
if (imageElement) {
|
|
25169
|
+
context.drawImage(imageElement, localRect.left, localRect.top, localRect.width, localRect.height);
|
|
25170
|
+
}
|
|
25171
|
+
}
|
|
25172
|
+
}
|
|
25173
|
+
};
|
|
24534
25174
|
const cellPaneOrder = ["scroll", "top", "left", "corner"];
|
|
24535
25175
|
if (shouldRepaintBody) {
|
|
25176
|
+
canvasProfileBodyStart = canvasProfileTarget ? performance.now() : 0;
|
|
24536
25177
|
for (const pane of Object.keys(bodyContexts)) {
|
|
24537
25178
|
const context = bodyContexts[pane];
|
|
24538
25179
|
const bounds = paneBounds[pane];
|
|
@@ -24563,6 +25204,7 @@ function XlsxGrid({
|
|
|
24563
25204
|
context.clearRect(0, 0, bounds.width, bounds.height);
|
|
24564
25205
|
}
|
|
24565
25206
|
bodyDirtyRectsByPane[pane] = dirtyRects;
|
|
25207
|
+
canvasProfileDirtyRects += dirtyRects.length;
|
|
24566
25208
|
if (dirtyRects.length === 0) {
|
|
24567
25209
|
continue;
|
|
24568
25210
|
}
|
|
@@ -24579,6 +25221,22 @@ function XlsxGrid({
|
|
|
24579
25221
|
if (!paneContext || paneDirtyRects.length === 0 || paneBoundsForCell.width <= 0 || paneBoundsForCell.height <= 0 || paneAxisItems.rows.length === 0 || paneAxisItems.cols.length === 0) {
|
|
24580
25222
|
continue;
|
|
24581
25223
|
}
|
|
25224
|
+
let hasPendingGridlinePath = false;
|
|
25225
|
+
const enqueueGridlinePath = () => {
|
|
25226
|
+
if (!hasPendingGridlinePath) {
|
|
25227
|
+
paneContext.beginPath();
|
|
25228
|
+
hasPendingGridlinePath = true;
|
|
25229
|
+
}
|
|
25230
|
+
};
|
|
25231
|
+
const flushPendingGridlines = () => {
|
|
25232
|
+
if (!hasPendingGridlinePath) {
|
|
25233
|
+
return;
|
|
25234
|
+
}
|
|
25235
|
+
paneContext.strokeStyle = palette.border;
|
|
25236
|
+
paneContext.lineWidth = 1;
|
|
25237
|
+
paneContext.stroke();
|
|
25238
|
+
hasPendingGridlinePath = false;
|
|
25239
|
+
};
|
|
24582
25240
|
const drawnMergedAnchorKeys = /* @__PURE__ */ new Set();
|
|
24583
25241
|
for (const rowItem of paneAxisItems.rows) {
|
|
24584
25242
|
for (const colItem of paneAxisItems.cols) {
|
|
@@ -24586,6 +25244,33 @@ function XlsxGrid({
|
|
|
24586
25244
|
const anchorCell = resolveMergeAnchorCell(cell);
|
|
24587
25245
|
const anchorKey = `${anchorCell.row}:${anchorCell.col}`;
|
|
24588
25246
|
let drawCell = anchorCell;
|
|
25247
|
+
const drawRowIndex = rowIndexByActual.get(drawCell.row);
|
|
25248
|
+
const drawColIndex = colIndexByActual.get(drawCell.col);
|
|
25249
|
+
if (drawRowIndex === void 0 || drawColIndex === void 0) {
|
|
25250
|
+
continue;
|
|
25251
|
+
}
|
|
25252
|
+
const baseCellLeft = displayRowHeaderWidth + (colPrefixSums[drawColIndex] ?? 0);
|
|
25253
|
+
const baseCellTop = displayHeaderHeight + (rowPrefixSums[drawRowIndex] ?? 0);
|
|
25254
|
+
const useFrozenHorizontalPosition = pane === "left" || pane === "corner";
|
|
25255
|
+
const useFrozenVerticalPosition = pane === "top" || pane === "corner";
|
|
25256
|
+
const roughLocalRect = {
|
|
25257
|
+
height: displayEffectiveRowHeights[drawRowIndex] ?? rowItem.size,
|
|
25258
|
+
left: (useFrozenHorizontalPosition ? stickyLeftByCol.get(drawCell.col) ?? baseCellLeft - drawingViewport.left : baseCellLeft - drawingViewport.left) - paneBoundsForCell.left,
|
|
25259
|
+
top: (useFrozenVerticalPosition ? stickyTopByRow.get(drawCell.row) ?? baseCellTop - drawingViewport.top : baseCellTop - drawingViewport.top) - paneBoundsForCell.top,
|
|
25260
|
+
width: displayEffectiveColWidths[drawColIndex] ?? colItem.size
|
|
25261
|
+
};
|
|
25262
|
+
const isMergedSecondaryProbe = anchorCell.row !== cell.row || anchorCell.col !== cell.col;
|
|
25263
|
+
if (!isMergedSecondaryProbe && !intersectsCanvasDirtyRects(
|
|
25264
|
+
roughLocalRect.left - CANVAS_DIRTY_CELL_CULL_MARGIN_PX,
|
|
25265
|
+
roughLocalRect.top - CANVAS_DIRTY_CELL_CULL_MARGIN_PX,
|
|
25266
|
+
roughLocalRect.width + CANVAS_DIRTY_CELL_CULL_MARGIN_PX * 2,
|
|
25267
|
+
roughLocalRect.height + CANVAS_DIRTY_CELL_CULL_MARGIN_PX * 2,
|
|
25268
|
+
paneDirtyRects
|
|
25269
|
+
)) {
|
|
25270
|
+
canvasProfileCulledCells += 1;
|
|
25271
|
+
continue;
|
|
25272
|
+
}
|
|
25273
|
+
canvasProfileLookedUpCells += 1;
|
|
24589
25274
|
let cellData = getCellData(drawCell.row, drawCell.col);
|
|
24590
25275
|
if ((cellData.colSpan || cellData.rowSpan) && drawnMergedAnchorKeys.has(anchorKey)) {
|
|
24591
25276
|
continue;
|
|
@@ -24596,16 +25281,9 @@ function XlsxGrid({
|
|
|
24596
25281
|
if (cellData.colSpan || cellData.rowSpan) {
|
|
24597
25282
|
drawnMergedAnchorKeys.add(anchorKey);
|
|
24598
25283
|
}
|
|
24599
|
-
const drawRowIndex = rowIndexByActual.get(drawCell.row);
|
|
24600
|
-
const drawColIndex = colIndexByActual.get(drawCell.col);
|
|
24601
|
-
if (drawRowIndex === void 0 || drawColIndex === void 0) {
|
|
24602
|
-
continue;
|
|
24603
|
-
}
|
|
24604
25284
|
const displayRect = cellData.colSpan || cellData.rowSpan ? resolveCellDisplayRect(drawCell) : null;
|
|
24605
|
-
const baseLeft = displayRect?.left ??
|
|
24606
|
-
const baseTop = displayRect?.top ??
|
|
24607
|
-
const useFrozenHorizontalPosition = pane === "left" || pane === "corner";
|
|
24608
|
-
const useFrozenVerticalPosition = pane === "top" || pane === "corner";
|
|
25285
|
+
const baseLeft = displayRect?.left ?? baseCellLeft;
|
|
25286
|
+
const baseTop = displayRect?.top ?? baseCellTop;
|
|
24609
25287
|
const localRect = {
|
|
24610
25288
|
height: displayRect?.height ?? (displayEffectiveRowHeights[drawRowIndex] ?? rowItem.size),
|
|
24611
25289
|
left: (useFrozenHorizontalPosition ? stickyLeftByCol.get(drawCell.col) ?? baseLeft - drawingViewport.left : baseLeft - drawingViewport.left) - paneBoundsForCell.left,
|
|
@@ -24617,13 +25295,18 @@ function XlsxGrid({
|
|
|
24617
25295
|
continue;
|
|
24618
25296
|
}
|
|
24619
25297
|
if (!intersectsCanvasDirtyRects(localRect.left, localRect.top, drawableWidth, localRect.height, paneDirtyRects)) {
|
|
25298
|
+
canvasProfileCulledCells += 1;
|
|
24620
25299
|
continue;
|
|
24621
25300
|
}
|
|
25301
|
+
canvasProfilePaintedCells += 1;
|
|
24622
25302
|
const cellStyle = cellData.style;
|
|
24623
25303
|
const canvasCellStyle = cellData.canvas ?? buildCanvasCellStyleCache(cellStyle);
|
|
24624
25304
|
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellStyle.backgroundColor === "string" ? cellStyle.backgroundColor : sheetSurface);
|
|
24625
25305
|
const gradientFill = !cellData.conditionalColorScale && typeof cellStyle.backgroundImage === "string" ? resolveCanvasGradientFill(paneContext, localRect, cellStyle.backgroundImage) : null;
|
|
24626
25306
|
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellStyle.backgroundColor === "string" && cellStyle.backgroundColor !== sheetSurface;
|
|
25307
|
+
if (hasExplicitCellFill || cellData.chartHighlight) {
|
|
25308
|
+
flushPendingGridlines();
|
|
25309
|
+
}
|
|
24627
25310
|
paneContext.fillStyle = gradientFill ?? fillColor;
|
|
24628
25311
|
paneContext.fillRect(localRect.left, localRect.top, localRect.width, localRect.height);
|
|
24629
25312
|
if (cellData.chartHighlight) {
|
|
@@ -24669,10 +25352,8 @@ function XlsxGrid({
|
|
|
24669
25352
|
const bottomNeighborTopBorder = bottomNeighborData?.isMergedSecondary ? null : bottomNeighborData?.canvas?.topBorder ?? parseCanvasBorderDeclaration(bottomNeighborData?.style.borderTop);
|
|
24670
25353
|
const resolvedRightBorder = resolveCanvasBoundaryBorder(rightBorder, rightNeighborLeftBorder);
|
|
24671
25354
|
const resolvedBottomBorder = resolveCanvasBoundaryBorder(bottomBorder, bottomNeighborTopBorder);
|
|
24672
|
-
if (showGridLines && !hasExplicitCellFill) {
|
|
24673
|
-
|
|
24674
|
-
paneContext.lineWidth = 1;
|
|
24675
|
-
paneContext.beginPath();
|
|
25355
|
+
if (showGridLines && !hasExplicitCellFill && (!resolvedRightBorder || !resolvedBottomBorder)) {
|
|
25356
|
+
enqueueGridlinePath();
|
|
24676
25357
|
if (!resolvedRightBorder) {
|
|
24677
25358
|
paneContext.moveTo(localRect.left + localRect.width - 0.5, localRect.top);
|
|
24678
25359
|
paneContext.lineTo(localRect.left + localRect.width - 0.5, localRect.top + localRect.height);
|
|
@@ -24681,7 +25362,9 @@ function XlsxGrid({
|
|
|
24681
25362
|
paneContext.moveTo(localRect.left, localRect.top + localRect.height - 0.5);
|
|
24682
25363
|
paneContext.lineTo(localRect.left + localRect.width, localRect.top + localRect.height - 0.5);
|
|
24683
25364
|
}
|
|
24684
|
-
|
|
25365
|
+
}
|
|
25366
|
+
if (topBorder || resolvedRightBorder || resolvedBottomBorder || leftBorder || cellData.chartHighlight) {
|
|
25367
|
+
flushPendingGridlines();
|
|
24685
25368
|
}
|
|
24686
25369
|
if (topBorder && drawRowIndex === 0) {
|
|
24687
25370
|
strokeCanvasBorderSide(paneContext, "top", localRect, topBorder);
|
|
@@ -24714,17 +25397,26 @@ function XlsxGrid({
|
|
|
24714
25397
|
strokeCanvasBorderSide(paneContext, "left", localRect, highlightBorder);
|
|
24715
25398
|
}
|
|
24716
25399
|
}
|
|
25400
|
+
const rawText = cellData.value ?? "";
|
|
25401
|
+
const shouldDrawCanvasContent = cellData.checkboxState != null || cellData.sparkline || rawText.length > 0 || cellData.conditionalIcon || cellData.isTableHeader;
|
|
25402
|
+
if (!shouldDrawCanvasContent) {
|
|
25403
|
+
continue;
|
|
25404
|
+
}
|
|
24717
25405
|
const padding = canvasCellStyle.padding;
|
|
24718
25406
|
const contentLeft = localRect.left + padding.left;
|
|
24719
25407
|
const contentTop = localRect.top + padding.top;
|
|
24720
25408
|
const contentWidth = Math.max(0, localRect.width - padding.left - padding.right);
|
|
24721
25409
|
const contentHeight = Math.max(0, localRect.height - padding.top - padding.bottom);
|
|
25410
|
+
if (contentWidth <= 0 || contentHeight <= 0) {
|
|
25411
|
+
continue;
|
|
25412
|
+
}
|
|
24722
25413
|
const activeFontSizePx = cellData.shrinkToFitFontSizePx ?? resolveCanvasFontSizePx(cellStyle, 12 * zoomFactor);
|
|
24723
25414
|
const textClipOverscan = Math.max(
|
|
24724
25415
|
1,
|
|
24725
25416
|
zoomFactor * 1.5,
|
|
24726
25417
|
activeFontSizePx * (cellData.textRotationDeg ? 0.75 : 0.18)
|
|
24727
25418
|
);
|
|
25419
|
+
flushPendingGridlines();
|
|
24728
25420
|
paneContext.save();
|
|
24729
25421
|
paneContext.beginPath();
|
|
24730
25422
|
paneContext.rect(
|
|
@@ -24856,7 +25548,6 @@ function XlsxGrid({
|
|
|
24856
25548
|
const trailingInset = (cellData.conditionalIcon ? 18 * zoomFactor : 0) + (cellData.isTableHeader ? 16 * zoomFactor : 0);
|
|
24857
25549
|
const spillMaxWidth = cellData.spillWidth && cellData.spillWidth > 0 ? Math.max(0, cellData.spillWidth - trailingInset) : null;
|
|
24858
25550
|
const maxTextWidth = spillMaxWidth ?? Math.max(0, contentWidth - trailingInset);
|
|
24859
|
-
const rawText = cellData.value ?? "";
|
|
24860
25551
|
const textColor = canvasCellStyle.textColor;
|
|
24861
25552
|
const shouldEllipsizeText = canvasCellStyle.textOverflowEllipsis;
|
|
24862
25553
|
const shouldWrapText = canvasCellStyle.usesWrappedText || rawText.includes("\n");
|
|
@@ -24888,7 +25579,7 @@ function XlsxGrid({
|
|
|
24888
25579
|
const textY = textBlockTop + lineIndex * lineHeight + lineHeight / 2;
|
|
24889
25580
|
paneContext.fillText(line, textX, textY);
|
|
24890
25581
|
if (canvasCellStyle.textDecoration?.includes("underline") && line.length > 0) {
|
|
24891
|
-
const measured = Math.min(maxTextWidth, paneContext
|
|
25582
|
+
const measured = Math.min(maxTextWidth, measureCanvasTextWidth(paneContext, line));
|
|
24892
25583
|
const underlineStartX = align === "right" ? textX - measured : align === "center" ? textX - measured / 2 : textX;
|
|
24893
25584
|
paneContext.beginPath();
|
|
24894
25585
|
paneContext.moveTo(underlineStartX, textY + Math.max(2, lineHeight * 0.24));
|
|
@@ -24922,7 +25613,7 @@ function XlsxGrid({
|
|
|
24922
25613
|
const textY = contentTop + contentHeight / 2;
|
|
24923
25614
|
paneContext.fillText(text, textX, textY);
|
|
24924
25615
|
if (canvasCellStyle.textDecoration?.includes("underline") && text.length > 0) {
|
|
24925
|
-
const measured = shouldEllipsizeText ? Math.min(maxTextWidth, paneContext
|
|
25616
|
+
const measured = shouldEllipsizeText ? Math.min(maxTextWidth, measureCanvasTextWidth(paneContext, text)) : measureCanvasTextWidth(paneContext, text);
|
|
24926
25617
|
const underlineStartX = align === "right" ? textX - measured : align === "center" ? textX - measured / 2 : textX;
|
|
24927
25618
|
paneContext.beginPath();
|
|
24928
25619
|
paneContext.moveTo(underlineStartX, textY + 6 * zoomFactor);
|
|
@@ -24947,6 +25638,7 @@ function XlsxGrid({
|
|
|
24947
25638
|
paneContext.restore();
|
|
24948
25639
|
}
|
|
24949
25640
|
}
|
|
25641
|
+
flushPendingGridlines();
|
|
24950
25642
|
}
|
|
24951
25643
|
for (const pane of cellPaneOrder) {
|
|
24952
25644
|
const paneContext = bodyContexts[pane];
|
|
@@ -24964,7 +25656,7 @@ function XlsxGrid({
|
|
|
24964
25656
|
paneContext.textBaseline = "middle";
|
|
24965
25657
|
paneContext.fillText(spillText.text, spillText.textX, spillText.textY);
|
|
24966
25658
|
if (spillText.textDecoration?.includes("underline") && spillText.text.length > 0) {
|
|
24967
|
-
const measured = spillText.ellipsize ? Math.min(spillText.maxWidth, paneContext
|
|
25659
|
+
const measured = spillText.ellipsize ? Math.min(spillText.maxWidth, measureCanvasTextWidth(paneContext, spillText.text)) : measureCanvasTextWidth(paneContext, spillText.text);
|
|
24968
25660
|
const underlineStartX = spillText.align === "right" ? spillText.textX - measured : spillText.align === "center" ? spillText.textX - measured / 2 : spillText.textX;
|
|
24969
25661
|
paneContext.beginPath();
|
|
24970
25662
|
paneContext.moveTo(underlineStartX, spillText.underlineY);
|
|
@@ -24976,6 +25668,14 @@ function XlsxGrid({
|
|
|
24976
25668
|
paneContext.restore();
|
|
24977
25669
|
}
|
|
24978
25670
|
}
|
|
25671
|
+
for (const pane of cellPaneOrder) {
|
|
25672
|
+
const paneContext = bodyContexts[pane];
|
|
25673
|
+
if (!paneContext) {
|
|
25674
|
+
continue;
|
|
25675
|
+
}
|
|
25676
|
+
drawBakedCanvasDrawings(pane, paneContext, bodyDirtyRectsByPane[pane]);
|
|
25677
|
+
}
|
|
25678
|
+
canvasProfileBodyMs = canvasProfileTarget ? performance.now() - canvasProfileBodyStart : 0;
|
|
24979
25679
|
}
|
|
24980
25680
|
if (shouldRepaintHeaders && cornerContext) {
|
|
24981
25681
|
const topFrozenHeaderContext = topHeaderContexts.frozen;
|
|
@@ -24990,7 +25690,7 @@ function XlsxGrid({
|
|
|
24990
25690
|
topScrollHeaderContext,
|
|
24991
25691
|
bufferCanvas,
|
|
24992
25692
|
dpr,
|
|
24993
|
-
|
|
25693
|
+
topScrollHeaderCanvasWidth,
|
|
24994
25694
|
headerHeight,
|
|
24995
25695
|
drawingViewport.left - previousPaintedViewport.left,
|
|
24996
25696
|
0
|
|
@@ -25009,7 +25709,7 @@ function XlsxGrid({
|
|
|
25009
25709
|
bufferCanvas,
|
|
25010
25710
|
dpr,
|
|
25011
25711
|
rowHeaderWidth,
|
|
25012
|
-
|
|
25712
|
+
leftScrollHeaderCanvasHeight,
|
|
25013
25713
|
0,
|
|
25014
25714
|
drawingViewport.top - previousPaintedViewport.top
|
|
25015
25715
|
);
|
|
@@ -25018,11 +25718,11 @@ function XlsxGrid({
|
|
|
25018
25718
|
}
|
|
25019
25719
|
}
|
|
25020
25720
|
}
|
|
25021
|
-
if (topFrozenHeaderContext &&
|
|
25721
|
+
if (topFrozenHeaderContext && topFrozenHeaderCanvasWidth > 0) {
|
|
25022
25722
|
topFrozenHeaderContext.fillStyle = palette.headerSurface;
|
|
25023
|
-
topFrozenHeaderContext.fillRect(0, 0,
|
|
25723
|
+
topFrozenHeaderContext.fillRect(0, 0, topFrozenHeaderCanvasWidth, headerHeight);
|
|
25024
25724
|
}
|
|
25025
|
-
if (topScrollHeaderContext &&
|
|
25725
|
+
if (topScrollHeaderContext && topScrollHeaderCanvasWidth > 0) {
|
|
25026
25726
|
topScrollHeaderContext.fillStyle = palette.headerSurface;
|
|
25027
25727
|
for (const dirtyRect of topScrollHeaderDirtyRects) {
|
|
25028
25728
|
topScrollHeaderContext.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
@@ -25041,7 +25741,7 @@ function XlsxGrid({
|
|
|
25041
25741
|
if (!paneContext) {
|
|
25042
25742
|
continue;
|
|
25043
25743
|
}
|
|
25044
|
-
if (column.localLeft + column.width < 0 || column.localLeft > (column.isFrozen ?
|
|
25744
|
+
if (column.localLeft + column.width < 0 || column.localLeft > (column.isFrozen ? topFrozenHeaderCanvasWidth : topScrollHeaderCanvasWidth)) {
|
|
25045
25745
|
continue;
|
|
25046
25746
|
}
|
|
25047
25747
|
if (!column.isFrozen && !intersectsCanvasDirtyRects(column.localLeft, 0, column.width, column.height, topScrollHeaderDirtyRects)) {
|
|
@@ -25067,11 +25767,11 @@ function XlsxGrid({
|
|
|
25067
25767
|
column.height / 2
|
|
25068
25768
|
);
|
|
25069
25769
|
}
|
|
25070
|
-
if (leftFrozenHeaderContext &&
|
|
25770
|
+
if (leftFrozenHeaderContext && leftFrozenHeaderCanvasHeight > 0) {
|
|
25071
25771
|
leftFrozenHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
25072
|
-
leftFrozenHeaderContext.fillRect(0, 0, rowHeaderWidth,
|
|
25772
|
+
leftFrozenHeaderContext.fillRect(0, 0, rowHeaderWidth, leftFrozenHeaderCanvasHeight);
|
|
25073
25773
|
}
|
|
25074
|
-
if (leftScrollHeaderContext &&
|
|
25774
|
+
if (leftScrollHeaderContext && leftScrollHeaderCanvasHeight > 0) {
|
|
25075
25775
|
leftScrollHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
25076
25776
|
for (const dirtyRect of leftScrollHeaderDirtyRects) {
|
|
25077
25777
|
leftScrollHeaderContext.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
@@ -25090,7 +25790,7 @@ function XlsxGrid({
|
|
|
25090
25790
|
if (!paneContext) {
|
|
25091
25791
|
continue;
|
|
25092
25792
|
}
|
|
25093
|
-
if (row.localTop + row.height < 0 || row.localTop > (row.isFrozen ?
|
|
25793
|
+
if (row.localTop + row.height < 0 || row.localTop > (row.isFrozen ? leftFrozenHeaderCanvasHeight : leftScrollHeaderCanvasHeight)) {
|
|
25094
25794
|
continue;
|
|
25095
25795
|
}
|
|
25096
25796
|
if (!row.isFrozen && !intersectsCanvasDirtyRects(0, row.localTop, rowHeaderWidth, row.height, leftScrollHeaderDirtyRects)) {
|
|
@@ -25130,9 +25830,29 @@ function XlsxGrid({
|
|
|
25130
25830
|
paintedHeaderCanvasSignatureRef.current = nextHeaderCanvasSignature;
|
|
25131
25831
|
}
|
|
25132
25832
|
applyCanvasViewportCompensation();
|
|
25833
|
+
if (canvasProfileTarget) {
|
|
25834
|
+
canvasProfileTarget.push({
|
|
25835
|
+
bodyMs: canvasProfileBodyMs,
|
|
25836
|
+
culledCells: canvasProfileCulledCells,
|
|
25837
|
+
dirtyRects: canvasProfileDirtyRects,
|
|
25838
|
+
lookedUpCells: canvasProfileLookedUpCells,
|
|
25839
|
+
paintedCells: canvasProfilePaintedCells,
|
|
25840
|
+
repaintBody: shouldRepaintBody,
|
|
25841
|
+
repaintHeaders: shouldRepaintHeaders,
|
|
25842
|
+
renderToLayoutMs: canvasProfileStart - xlsxGridRenderStart,
|
|
25843
|
+
totalMs: performance.now() - canvasProfileStart
|
|
25844
|
+
});
|
|
25845
|
+
if (canvasProfileTarget.length > 500) {
|
|
25846
|
+
canvasProfileTarget.splice(0, canvasProfileTarget.length - 500);
|
|
25847
|
+
}
|
|
25848
|
+
}
|
|
25133
25849
|
}, [
|
|
25134
25850
|
activeSheet,
|
|
25135
25851
|
applyCanvasViewportCompensation,
|
|
25852
|
+
bakedCanvasDrawingSignature,
|
|
25853
|
+
bakedFormControlRects,
|
|
25854
|
+
bakedImageRects,
|
|
25855
|
+
bakedShapeRects,
|
|
25136
25856
|
canvasColumnHeaderCells,
|
|
25137
25857
|
canvasPaneAxisItems,
|
|
25138
25858
|
canvasRowHeaderCells,
|
|
@@ -25153,15 +25873,16 @@ function XlsxGrid({
|
|
|
25153
25873
|
frozenPaneBottom,
|
|
25154
25874
|
frozenPaneRight,
|
|
25155
25875
|
getCellData,
|
|
25876
|
+
getCanvasImage,
|
|
25156
25877
|
getBodyBlitBufferCanvas,
|
|
25157
25878
|
getHeaderBlitBufferCanvas,
|
|
25158
25879
|
palette,
|
|
25159
25880
|
resolveCellDisplayRect,
|
|
25160
25881
|
resolveMergeAnchorCell,
|
|
25161
|
-
resizeGuide,
|
|
25162
25882
|
rowIndexByActual,
|
|
25163
25883
|
rowPrefixSums,
|
|
25164
25884
|
selectionHeaderSurface,
|
|
25885
|
+
shouldBakeCanvasStaticDrawings,
|
|
25165
25886
|
stickyLeftByCol,
|
|
25166
25887
|
stickyTopByRow,
|
|
25167
25888
|
visibleCols,
|
|
@@ -25379,7 +26100,7 @@ function XlsxGrid({
|
|
|
25379
26100
|
start: virtualRow?.start ?? (rowPrefixSums[index] ?? 0)
|
|
25380
26101
|
};
|
|
25381
26102
|
});
|
|
25382
|
-
const totalHeight = shouldVirtualizeRows ? rowVirtualizer.getTotalSize() : rowPrefixSums[rowPrefixSums.length - 1] ?? 0;
|
|
26103
|
+
const totalHeight = shouldUseDomVirtualizer && shouldVirtualizeRows ? rowVirtualizer.getTotalSize() : rowPrefixSums[rowPrefixSums.length - 1] ?? 0;
|
|
25383
26104
|
const totalWidth = totalContentWidth + displayRowHeaderWidth;
|
|
25384
26105
|
const sheetContentHeight = displayHeaderHeight + totalHeight;
|
|
25385
26106
|
const isLiveZooming = liveGestureZoom !== null && zoomScale === liveGestureZoom.baseZoomScale;
|
|
@@ -25453,18 +26174,6 @@ function XlsxGrid({
|
|
|
25453
26174
|
width: 0,
|
|
25454
26175
|
zIndex: canvasHeaderOverlayZIndex
|
|
25455
26176
|
};
|
|
25456
|
-
const scrollBodyCanvasWidth = Math.max(0, drawingViewport.width - frozenPaneRight);
|
|
25457
|
-
const scrollBodyCanvasHeight = Math.max(0, drawingViewport.height - frozenPaneBottom);
|
|
25458
|
-
const topBodyCanvasWidth = scrollBodyCanvasWidth;
|
|
25459
|
-
const topBodyCanvasHeight = Math.max(0, frozenPaneBottom - displayHeaderHeight);
|
|
25460
|
-
const leftBodyCanvasWidth = Math.max(0, frozenPaneRight - displayRowHeaderWidth);
|
|
25461
|
-
const leftBodyCanvasHeight = scrollBodyCanvasHeight;
|
|
25462
|
-
const cornerBodyCanvasWidth = leftBodyCanvasWidth;
|
|
25463
|
-
const cornerBodyCanvasHeight = topBodyCanvasHeight;
|
|
25464
|
-
const topFrozenHeaderCanvasWidth = leftBodyCanvasWidth;
|
|
25465
|
-
const topScrollHeaderCanvasWidth = scrollBodyCanvasWidth;
|
|
25466
|
-
const leftFrozenHeaderCanvasHeight = topBodyCanvasHeight;
|
|
25467
|
-
const leftScrollHeaderCanvasHeight = scrollBodyCanvasHeight;
|
|
25468
26177
|
const canvasBodyBaseStyle = {
|
|
25469
26178
|
cursor: "cell",
|
|
25470
26179
|
pointerEvents: "auto",
|
|
@@ -25476,13 +26185,13 @@ function XlsxGrid({
|
|
|
25476
26185
|
const canvasScrollBodyStyle = {
|
|
25477
26186
|
...canvasBodyBaseStyle,
|
|
25478
26187
|
display: scrollBodyCanvasWidth > 0 && scrollBodyCanvasHeight > 0 ? "block" : "none",
|
|
25479
|
-
left:
|
|
25480
|
-
top:
|
|
26188
|
+
left: scrollBodyCanvasLeft,
|
|
26189
|
+
top: scrollBodyCanvasTop
|
|
25481
26190
|
};
|
|
25482
26191
|
const canvasTopBodyStyle = {
|
|
25483
26192
|
...canvasBodyBaseStyle,
|
|
25484
26193
|
display: topBodyCanvasWidth > 0 && topBodyCanvasHeight > 0 ? "block" : "none",
|
|
25485
|
-
left:
|
|
26194
|
+
left: scrollBodyCanvasLeft,
|
|
25486
26195
|
top: displayHeaderHeight,
|
|
25487
26196
|
zIndex: 30
|
|
25488
26197
|
};
|
|
@@ -25490,7 +26199,7 @@ function XlsxGrid({
|
|
|
25490
26199
|
...canvasBodyBaseStyle,
|
|
25491
26200
|
display: leftBodyCanvasWidth > 0 && leftBodyCanvasHeight > 0 ? "block" : "none",
|
|
25492
26201
|
left: displayRowHeaderWidth,
|
|
25493
|
-
top:
|
|
26202
|
+
top: scrollBodyCanvasTop,
|
|
25494
26203
|
zIndex: 30
|
|
25495
26204
|
};
|
|
25496
26205
|
const canvasCornerBodyStyle = {
|
|
@@ -25516,7 +26225,7 @@ function XlsxGrid({
|
|
|
25516
26225
|
const canvasTopScrollHeaderStyle = {
|
|
25517
26226
|
...canvasHeaderBaseStyle,
|
|
25518
26227
|
display: topScrollHeaderCanvasWidth > 0 && drawingViewport.height > 0 ? "block" : "none",
|
|
25519
|
-
left:
|
|
26228
|
+
left: scrollBodyCanvasLeft,
|
|
25520
26229
|
top: 0,
|
|
25521
26230
|
zIndex: canvasHeaderOverlayZIndex
|
|
25522
26231
|
};
|
|
@@ -25531,7 +26240,7 @@ function XlsxGrid({
|
|
|
25531
26240
|
...canvasHeaderBaseStyle,
|
|
25532
26241
|
display: leftScrollHeaderCanvasHeight > 0 && drawingViewport.width > 0 ? "block" : "none",
|
|
25533
26242
|
left: 0,
|
|
25534
|
-
top:
|
|
26243
|
+
top: scrollBodyCanvasTop,
|
|
25535
26244
|
zIndex: canvasHeaderOverlayZIndex
|
|
25536
26245
|
};
|
|
25537
26246
|
const canvasCornerHeaderStyle = {
|
|
@@ -26087,26 +26796,26 @@ function XlsxGrid({
|
|
|
26087
26796
|
};
|
|
26088
26797
|
const canvasScrollOverlayPaneStyle = {
|
|
26089
26798
|
...canvasOverlayPaneBaseStyle,
|
|
26090
|
-
display:
|
|
26091
|
-
height:
|
|
26799
|
+
display: scrollBodyViewportWidth > 0 && scrollBodyViewportHeight > 0 ? "block" : "none",
|
|
26800
|
+
height: scrollBodyViewportHeight,
|
|
26092
26801
|
left: frozenPaneRight,
|
|
26093
26802
|
top: frozenPaneBottom,
|
|
26094
|
-
width:
|
|
26803
|
+
width: scrollBodyViewportWidth,
|
|
26095
26804
|
zIndex: 20
|
|
26096
26805
|
};
|
|
26097
26806
|
const canvasTopOverlayPaneStyle = {
|
|
26098
26807
|
...canvasOverlayPaneBaseStyle,
|
|
26099
|
-
display:
|
|
26808
|
+
display: scrollBodyViewportWidth > 0 && topBodyCanvasHeight > 0 ? "block" : "none",
|
|
26100
26809
|
height: topBodyCanvasHeight,
|
|
26101
26810
|
left: frozenPaneRight,
|
|
26102
26811
|
top: displayHeaderHeight,
|
|
26103
|
-
width:
|
|
26812
|
+
width: scrollBodyViewportWidth,
|
|
26104
26813
|
zIndex: 35
|
|
26105
26814
|
};
|
|
26106
26815
|
const canvasLeftOverlayPaneStyle = {
|
|
26107
26816
|
...canvasOverlayPaneBaseStyle,
|
|
26108
|
-
display: leftBodyCanvasWidth > 0 &&
|
|
26109
|
-
height:
|
|
26817
|
+
display: leftBodyCanvasWidth > 0 && scrollBodyViewportHeight > 0 ? "block" : "none",
|
|
26818
|
+
height: scrollBodyViewportHeight,
|
|
26110
26819
|
left: displayRowHeaderWidth,
|
|
26111
26820
|
top: frozenPaneBottom,
|
|
26112
26821
|
width: leftBodyCanvasWidth,
|
|
@@ -26121,8 +26830,9 @@ function XlsxGrid({
|
|
|
26121
26830
|
width: cornerBodyCanvasWidth,
|
|
26122
26831
|
zIndex: 36
|
|
26123
26832
|
};
|
|
26833
|
+
const drawingViewportCacheSignature = `${Math.floor(drawingViewport.left / CANVAS_VIEWPORT_OVERSCAN_PX)}:${Math.floor(drawingViewport.top / CANVAS_VIEWPORT_OVERSCAN_PX)}:${drawingViewport.width}:${drawingViewport.height}`;
|
|
26124
26834
|
const previousPaneDrawingNodes = paneDrawingNodesCacheRef.current;
|
|
26125
|
-
const canReusePaneDrawingNodes = previousPaneDrawingNodes !== null && previousPaneDrawingNodes.showImages === showImages && previousPaneDrawingNodes.chartRects === chartRects && previousPaneDrawingNodes.formControlRects ===
|
|
26835
|
+
const canReusePaneDrawingNodes = previousPaneDrawingNodes !== null && previousPaneDrawingNodes.showImages === showImages && previousPaneDrawingNodes.chartRects === chartRects && previousPaneDrawingNodes.formControlRects === domFormControlRects && previousPaneDrawingNodes.shapeRects === domShapeRects && previousPaneDrawingNodes.imageRects === domImageRects && previousPaneDrawingNodes.selectedChartId === selectedChartId && previousPaneDrawingNodes.selectedImageId === selectedImageId && previousPaneDrawingNodes.readOnly === readOnly && previousPaneDrawingNodes.selectionStroke === selectionStroke && previousPaneDrawingNodes.renderChartLoading === renderChartLoading && previousPaneDrawingNodes.renderImage === renderImage && previousPaneDrawingNodes.renderImageSelection === renderImageSelection && previousPaneDrawingNodes.isChartsLoading === isChartsLoading && previousPaneDrawingNodes.palette === palette && previousPaneDrawingNodes.drawingViewportSignature === drawingViewportCacheSignature;
|
|
26126
26836
|
const paneDrawingNodes = canReusePaneDrawingNodes ? previousPaneDrawingNodes.value : !showImages ? {
|
|
26127
26837
|
corner: null,
|
|
26128
26838
|
left: null,
|
|
@@ -26131,35 +26841,35 @@ function XlsxGrid({
|
|
|
26131
26841
|
} : {
|
|
26132
26842
|
corner: /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
26133
26843
|
chartRects.map(({ chart, rect }) => renderChartDrawing(chart, rect, "corner")),
|
|
26134
|
-
|
|
26135
|
-
|
|
26136
|
-
|
|
26844
|
+
domShapeRects.map(({ shape, rect }) => renderShapeDrawing(shape, rect, "corner")),
|
|
26845
|
+
domFormControlRects.map(({ control, rect }) => renderFormControlDrawing(control, rect, "corner")),
|
|
26846
|
+
domImageRects.map(({ image, rect }) => renderImageDrawing(image, rect, "corner"))
|
|
26137
26847
|
] }),
|
|
26138
26848
|
left: /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
26139
26849
|
chartRects.map(({ chart, rect }) => renderChartDrawing(chart, rect, "left")),
|
|
26140
|
-
|
|
26141
|
-
|
|
26142
|
-
|
|
26850
|
+
domShapeRects.map(({ shape, rect }) => renderShapeDrawing(shape, rect, "left")),
|
|
26851
|
+
domFormControlRects.map(({ control, rect }) => renderFormControlDrawing(control, rect, "left")),
|
|
26852
|
+
domImageRects.map(({ image, rect }) => renderImageDrawing(image, rect, "left"))
|
|
26143
26853
|
] }),
|
|
26144
26854
|
scroll: /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
26145
26855
|
chartRects.map(({ chart, rect }) => renderChartDrawing(chart, rect, "scroll")),
|
|
26146
|
-
|
|
26147
|
-
|
|
26148
|
-
|
|
26856
|
+
domShapeRects.map(({ shape, rect }) => renderShapeDrawing(shape, rect, "scroll")),
|
|
26857
|
+
domFormControlRects.map(({ control, rect }) => renderFormControlDrawing(control, rect, "scroll")),
|
|
26858
|
+
domImageRects.map(({ image, rect }) => renderImageDrawing(image, rect, "scroll"))
|
|
26149
26859
|
] }),
|
|
26150
26860
|
top: /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
26151
26861
|
chartRects.map(({ chart, rect }) => renderChartDrawing(chart, rect, "top")),
|
|
26152
|
-
|
|
26153
|
-
|
|
26154
|
-
|
|
26862
|
+
domShapeRects.map(({ shape, rect }) => renderShapeDrawing(shape, rect, "top")),
|
|
26863
|
+
domFormControlRects.map(({ control, rect }) => renderFormControlDrawing(control, rect, "top")),
|
|
26864
|
+
domImageRects.map(({ image, rect }) => renderImageDrawing(image, rect, "top"))
|
|
26155
26865
|
] })
|
|
26156
26866
|
};
|
|
26157
26867
|
if (!canReusePaneDrawingNodes) {
|
|
26158
26868
|
paneDrawingNodesCacheRef.current = {
|
|
26159
26869
|
chartRects,
|
|
26160
|
-
|
|
26161
|
-
formControlRects,
|
|
26162
|
-
imageRects,
|
|
26870
|
+
drawingViewportSignature: drawingViewportCacheSignature,
|
|
26871
|
+
formControlRects: domFormControlRects,
|
|
26872
|
+
imageRects: domImageRects,
|
|
26163
26873
|
isChartsLoading,
|
|
26164
26874
|
palette,
|
|
26165
26875
|
readOnly,
|
|
@@ -26169,7 +26879,7 @@ function XlsxGrid({
|
|
|
26169
26879
|
selectedChartId,
|
|
26170
26880
|
selectedImageId,
|
|
26171
26881
|
selectionStroke,
|
|
26172
|
-
shapeRects,
|
|
26882
|
+
shapeRects: domShapeRects,
|
|
26173
26883
|
showImages,
|
|
26174
26884
|
value: paneDrawingNodes
|
|
26175
26885
|
};
|
|
@@ -26677,10 +27387,11 @@ function XlsxGrid({
|
|
|
26677
27387
|
style: canvasCornerBodyStyle
|
|
26678
27388
|
}
|
|
26679
27389
|
),
|
|
26680
|
-
|
|
27390
|
+
hasCanvasDomDrawingOverlays ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
26681
27391
|
/* @__PURE__ */ jsx3("div", { style: canvasScrollOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
26682
27392
|
"div",
|
|
26683
27393
|
{
|
|
27394
|
+
ref: canvasScrollOverlayContentRef,
|
|
26684
27395
|
style: {
|
|
26685
27396
|
height: sheetContentHeight,
|
|
26686
27397
|
left: 0,
|
|
@@ -26688,6 +27399,7 @@ function XlsxGrid({
|
|
|
26688
27399
|
position: "absolute",
|
|
26689
27400
|
top: 0,
|
|
26690
27401
|
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
27402
|
+
transformOrigin: "0 0",
|
|
26691
27403
|
width: totalWidth
|
|
26692
27404
|
},
|
|
26693
27405
|
children: paneDrawingNodes.scroll
|
|
@@ -26696,6 +27408,7 @@ function XlsxGrid({
|
|
|
26696
27408
|
/* @__PURE__ */ jsx3("div", { style: canvasTopOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
26697
27409
|
"div",
|
|
26698
27410
|
{
|
|
27411
|
+
ref: canvasTopOverlayContentRef,
|
|
26699
27412
|
style: {
|
|
26700
27413
|
height: sheetContentHeight,
|
|
26701
27414
|
left: 0,
|
|
@@ -26703,6 +27416,7 @@ function XlsxGrid({
|
|
|
26703
27416
|
position: "absolute",
|
|
26704
27417
|
top: 0,
|
|
26705
27418
|
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-displayHeaderHeight}px)`,
|
|
27419
|
+
transformOrigin: "0 0",
|
|
26706
27420
|
width: totalWidth
|
|
26707
27421
|
},
|
|
26708
27422
|
children: paneDrawingNodes.top
|
|
@@ -26711,6 +27425,7 @@ function XlsxGrid({
|
|
|
26711
27425
|
/* @__PURE__ */ jsx3("div", { style: canvasLeftOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
26712
27426
|
"div",
|
|
26713
27427
|
{
|
|
27428
|
+
ref: canvasLeftOverlayContentRef,
|
|
26714
27429
|
style: {
|
|
26715
27430
|
height: sheetContentHeight,
|
|
26716
27431
|
left: 0,
|
|
@@ -26718,6 +27433,7 @@ function XlsxGrid({
|
|
|
26718
27433
|
position: "absolute",
|
|
26719
27434
|
top: 0,
|
|
26720
27435
|
transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
27436
|
+
transformOrigin: "0 0",
|
|
26721
27437
|
width: totalWidth
|
|
26722
27438
|
},
|
|
26723
27439
|
children: paneDrawingNodes.left
|
|
@@ -26726,6 +27442,7 @@ function XlsxGrid({
|
|
|
26726
27442
|
/* @__PURE__ */ jsx3("div", { style: canvasCornerOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
26727
27443
|
"div",
|
|
26728
27444
|
{
|
|
27445
|
+
ref: canvasCornerOverlayContentRef,
|
|
26729
27446
|
style: {
|
|
26730
27447
|
height: sheetContentHeight,
|
|
26731
27448
|
left: 0,
|
|
@@ -26733,6 +27450,7 @@ function XlsxGrid({
|
|
|
26733
27450
|
position: "absolute",
|
|
26734
27451
|
top: 0,
|
|
26735
27452
|
transform: `translate(${-displayRowHeaderWidth}px, ${-displayHeaderHeight}px)`,
|
|
27453
|
+
transformOrigin: "0 0",
|
|
26736
27454
|
width: totalWidth
|
|
26737
27455
|
},
|
|
26738
27456
|
children: paneDrawingNodes.corner
|
|
@@ -27652,7 +28370,7 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
27652
28370
|
if (!canvas) {
|
|
27653
28371
|
return false;
|
|
27654
28372
|
}
|
|
27655
|
-
const context = canvas.getContext("2d");
|
|
28373
|
+
const context = canvas.getContext("2d", { alpha: false });
|
|
27656
28374
|
if (!context) {
|
|
27657
28375
|
return false;
|
|
27658
28376
|
}
|
|
@@ -27676,9 +28394,10 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
27676
28394
|
}
|
|
27677
28395
|
context.setTransform(dpr * scale, 0, 0, dpr * scale, 0, 0);
|
|
27678
28396
|
context.clearRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
28397
|
+
const thumbnailSheetSurface = resolveSheetSurface(sheet, palette);
|
|
27679
28398
|
context.fillStyle = palette.canvas;
|
|
27680
28399
|
context.fillRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
27681
|
-
context.fillStyle =
|
|
28400
|
+
context.fillStyle = thumbnailSheetSurface;
|
|
27682
28401
|
context.fillRect(rowHeaderWidth, headerHeight, Math.max(1, colAxis.totalSize), Math.max(1, rowAxis.totalSize));
|
|
27683
28402
|
if (includeHeaders) {
|
|
27684
28403
|
context.fillStyle = palette.headerSurface;
|
|
@@ -27799,8 +28518,8 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
27799
28518
|
};
|
|
27800
28519
|
const canvasCellStyle = cellData.canvas ?? buildCanvasCellStyleCache(cellData.style);
|
|
27801
28520
|
const gradientFill = typeof cellData.style.backgroundImage === "string" ? resolveCanvasGradientFill(context, rect, cellData.style.backgroundImage) : null;
|
|
27802
|
-
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellData.style.backgroundColor === "string" ? cellData.style.backgroundColor :
|
|
27803
|
-
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellData.style.backgroundColor === "string" && cellData.style.backgroundColor !==
|
|
28521
|
+
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellData.style.backgroundColor === "string" ? cellData.style.backgroundColor : thumbnailSheetSurface);
|
|
28522
|
+
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellData.style.backgroundColor === "string" && cellData.style.backgroundColor !== thumbnailSheetSurface;
|
|
27804
28523
|
context.fillStyle = gradientFill ?? fillColor;
|
|
27805
28524
|
context.fillRect(rect.left, rect.top, rect.width, rect.height);
|
|
27806
28525
|
if (cellData.conditionalDataBar) {
|
|
@@ -27855,12 +28574,19 @@ function useXlsxViewerThumbnails(options = {}) {
|
|
|
27855
28574
|
if (canvasCellStyle.leftBorder) {
|
|
27856
28575
|
strokeCanvasBorderSide(context, "left", rect, canvasCellStyle.leftBorder);
|
|
27857
28576
|
}
|
|
28577
|
+
const rawText = cellData.value ?? "";
|
|
28578
|
+
const shouldDrawThumbnailContent = cellData.checkboxState != null || cellData.sparkline || rawText.length > 0 || cellData.conditionalIcon;
|
|
28579
|
+
if (!shouldDrawThumbnailContent) {
|
|
28580
|
+
continue;
|
|
28581
|
+
}
|
|
27858
28582
|
const padding = canvasCellStyle.padding;
|
|
27859
28583
|
const contentLeft = rect.left + padding.left;
|
|
27860
28584
|
const contentTop = rect.top + padding.top;
|
|
27861
28585
|
const contentWidth = Math.max(0, rect.width - padding.left - padding.right);
|
|
27862
28586
|
const contentHeight = Math.max(0, rect.height - padding.top - padding.bottom);
|
|
27863
|
-
|
|
28587
|
+
if (contentWidth <= 0 || contentHeight <= 0) {
|
|
28588
|
+
continue;
|
|
28589
|
+
}
|
|
27864
28590
|
context.save();
|
|
27865
28591
|
context.beginPath();
|
|
27866
28592
|
context.rect(contentLeft, contentTop, contentWidth, contentHeight);
|