@odoo/o-spreadsheet 19.3.17 → 19.3.19
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/o_spreadsheet.cjs +67 -25
- package/dist/o_spreadsheet.css +10 -4
- package/dist/o_spreadsheet.esm.js +67 -25
- package/dist/o_spreadsheet.iife.js +67 -25
- package/dist/o_spreadsheet.min.iife.js +8 -8
- package/dist/o_spreadsheet.xml +3 -3
- package/dist/types/collaborative/session.d.ts +3 -1
- package/dist/types/plugins/core/carousel.d.ts +1 -1
- package/dist/types/plugins/core/squisher.d.ts +3 -0
- package/dist/types/types/collaborative/transport_service.d.ts +1 -0
- package/package.json +1 -1
package/dist/o_spreadsheet.cjs
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.3.
|
|
6
|
-
* @date 2026-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.19
|
|
6
|
+
* @date 2026-09-04T07:38:14.356Z
|
|
7
|
+
* @hash c8c526d
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
@@ -9593,16 +9593,16 @@ const chartShowValuesPlugin = {
|
|
|
9593
9593
|
drawLineOrBarOrRadarChartValues(chart, options, ctx);
|
|
9594
9594
|
break;
|
|
9595
9595
|
case "bar":
|
|
9596
|
-
options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
|
|
9596
|
+
options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true }) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
|
|
9597
9597
|
break;
|
|
9598
9598
|
case "pyramid":
|
|
9599
|
-
drawHorizontalBarChartValues(chart, options, ctx);
|
|
9599
|
+
drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true });
|
|
9600
9600
|
break;
|
|
9601
9601
|
case "calendar":
|
|
9602
9602
|
drawBarChartValues(chart, options, ctx);
|
|
9603
9603
|
break;
|
|
9604
9604
|
case "funnel":
|
|
9605
|
-
drawHorizontalBarChartValues(chart, options, ctx);
|
|
9605
|
+
drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: false });
|
|
9606
9606
|
break;
|
|
9607
9607
|
}
|
|
9608
9608
|
ctx.restore();
|
|
@@ -9672,7 +9672,7 @@ function drawBarChartValues(chart, options, ctx) {
|
|
|
9672
9672
|
}
|
|
9673
9673
|
}
|
|
9674
9674
|
}
|
|
9675
|
-
function drawHorizontalBarChartValues(chart, options, ctx) {
|
|
9675
|
+
function drawHorizontalBarChartValues(chart, options, ctx, args) {
|
|
9676
9676
|
const textsPositions = {};
|
|
9677
9677
|
for (const dataset of chart._metasets) {
|
|
9678
9678
|
if (isTrendLineAxis(dataset.xAxisID)) return;
|
|
@@ -9687,7 +9687,7 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
|
|
|
9687
9687
|
const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
|
|
9688
9688
|
const PADDING = 3;
|
|
9689
9689
|
let xPosition;
|
|
9690
|
-
if (distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
|
|
9690
|
+
if (args.offsetFromAxisOrigin && distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
|
|
9691
9691
|
else xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
|
|
9692
9692
|
if (!textsPositions[yPosition]) textsPositions[yPosition] = [];
|
|
9693
9693
|
for (const otherPosition of textsPositions[yPosition]) if (Math.abs(otherPosition - xPosition) < textWidth) xPosition = value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
|
|
@@ -10486,6 +10486,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
10486
10486
|
hidden,
|
|
10487
10487
|
borderColor,
|
|
10488
10488
|
backgroundColor: borderColor,
|
|
10489
|
+
pointBackgroundColor: borderColor,
|
|
10489
10490
|
pointRadius: definition.hideDataMarkers ? 0 : 3
|
|
10490
10491
|
};
|
|
10491
10492
|
if (fill) {
|
|
@@ -25445,9 +25446,10 @@ var Composer = class extends _odoo_owl.Component {
|
|
|
25445
25446
|
compositionActive = false;
|
|
25446
25447
|
spreadsheetRect = useSpreadsheetRect();
|
|
25447
25448
|
lastHoveredTokenIndex = void 0;
|
|
25448
|
-
debouncedHover = debounce((tokenIndex, hoveredRect) => {
|
|
25449
|
+
debouncedHover = debounce((tokenIndex, composerContent, hoveredRect) => {
|
|
25449
25450
|
const selection = this.contentHelper.getCurrentSelection();
|
|
25450
|
-
|
|
25451
|
+
const currentContent = this.props.composerStore.currentContent;
|
|
25452
|
+
if (selection.start !== selection.end || currentContent !== composerContent) return;
|
|
25451
25453
|
const currentHoveredContext = this.props.composerStore.hoveredTokens;
|
|
25452
25454
|
this.props.composerStore.hoverToken(tokenIndex);
|
|
25453
25455
|
if (!deepEquals(currentHoveredContext, this.props.composerStore.hoveredTokens)) this.composerState.hoveredRect = hoveredRect;
|
|
@@ -25765,7 +25767,8 @@ var Composer = class extends _odoo_owl.Component {
|
|
|
25765
25767
|
onTokenHover(tokenIndex, hoveredRect) {
|
|
25766
25768
|
if (this.lastHoveredTokenIndex !== tokenIndex) {
|
|
25767
25769
|
this.lastHoveredTokenIndex = tokenIndex;
|
|
25768
|
-
this.
|
|
25770
|
+
const composerContent = this.props.composerStore.currentContent;
|
|
25771
|
+
this.debouncedHover(tokenIndex, composerContent, hoveredRect);
|
|
25769
25772
|
}
|
|
25770
25773
|
}
|
|
25771
25774
|
/**
|
|
@@ -40076,7 +40079,13 @@ var PivotSpreadsheetSidePanel = class extends _odoo_owl.Component {
|
|
|
40076
40079
|
}
|
|
40077
40080
|
onSelectionChanged(ranges) {
|
|
40078
40081
|
this.state.rangeHasChanged = true;
|
|
40079
|
-
|
|
40082
|
+
if (ranges.length === 0) {
|
|
40083
|
+
this.state.range = void 0;
|
|
40084
|
+
return;
|
|
40085
|
+
}
|
|
40086
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
40087
|
+
const range = this.env.model.getters.getRangeFromSheetXC(sheetId, ranges[0]);
|
|
40088
|
+
this.state.range = this.env.model.getters.getRangeString(range, "forceSheetReference", { useBoundedReference: true });
|
|
40080
40089
|
}
|
|
40081
40090
|
onSelectionConfirmed() {
|
|
40082
40091
|
if (this.state.range) {
|
|
@@ -49735,6 +49744,7 @@ var CarouselPlugin = class extends CorePlugin {
|
|
|
49735
49744
|
return "Success";
|
|
49736
49745
|
case "UPDATE_CAROUSEL":
|
|
49737
49746
|
if (!this.carousels[cmd.sheetId]?.[cmd.figureId]) return "InvalidFigureId";
|
|
49747
|
+
for (const item of cmd.definition.items) if (item.type === "chart" && !this.getters.getChart(item.chartId)) return "ChartDoesNotExist";
|
|
49738
49748
|
return "Success";
|
|
49739
49749
|
}
|
|
49740
49750
|
return "Success";
|
|
@@ -49839,6 +49849,7 @@ var Squisher = class {
|
|
|
49839
49849
|
baseFormulaWasTransformed = false;
|
|
49840
49850
|
rangeToStringOptions = { doNotSimplifyRange: true };
|
|
49841
49851
|
baseNumber = void 0;
|
|
49852
|
+
baseNumberFormat = void 0;
|
|
49842
49853
|
constructor(getters) {
|
|
49843
49854
|
this.getters = getters;
|
|
49844
49855
|
}
|
|
@@ -49873,6 +49884,11 @@ var Squisher = class {
|
|
|
49873
49884
|
this.baseFormulaWasTransformed = false;
|
|
49874
49885
|
}
|
|
49875
49886
|
}
|
|
49887
|
+
/** Reset the base number literal chain, so the next literal number cannot be squished as an offset of it */
|
|
49888
|
+
resetBaseNumber() {
|
|
49889
|
+
this.baseNumber = void 0;
|
|
49890
|
+
this.baseNumberFormat = void 0;
|
|
49891
|
+
}
|
|
49876
49892
|
/**
|
|
49877
49893
|
* Takes a cell and squish their formulas against the previous one (in the previous call).
|
|
49878
49894
|
* We should call this method for each cell in the sheet, in order from top to bottom, then from left to right (all cells of a columns, for each columns left to right).
|
|
@@ -49911,8 +49927,9 @@ var Squisher = class {
|
|
|
49911
49927
|
if (typeof cell.parsedValue === "number" && cell.parsedValue % 1 === 0) {
|
|
49912
49928
|
this.resetBaseFormula();
|
|
49913
49929
|
const numberValue = cell.parsedValue;
|
|
49914
|
-
if (this.baseNumber === void 0) {
|
|
49930
|
+
if (this.baseNumber === void 0 || cell.format !== this.baseNumberFormat) {
|
|
49915
49931
|
this.baseNumber = numberValue;
|
|
49932
|
+
this.baseNumberFormat = cell.format;
|
|
49916
49933
|
return cell.content;
|
|
49917
49934
|
}
|
|
49918
49935
|
const numberOffset = numberValue - this.baseNumber;
|
|
@@ -49923,7 +49940,7 @@ var Squisher = class {
|
|
|
49923
49940
|
}
|
|
49924
49941
|
}
|
|
49925
49942
|
this.resetBaseFormula();
|
|
49926
|
-
this.
|
|
49943
|
+
this.resetBaseNumber();
|
|
49927
49944
|
return cell.content;
|
|
49928
49945
|
}
|
|
49929
49946
|
squishCommand(command) {
|
|
@@ -49932,6 +49949,8 @@ var Squisher = class {
|
|
|
49932
49949
|
const squished = this.squish(cell, command.sheetId);
|
|
49933
49950
|
return typeof squished === "string" ? command.content : squished;
|
|
49934
49951
|
}
|
|
49952
|
+
this.resetBaseFormula();
|
|
49953
|
+
this.resetBaseNumber();
|
|
49935
49954
|
return command.content;
|
|
49936
49955
|
}
|
|
49937
49956
|
/**
|
|
@@ -50085,8 +50104,10 @@ var Unsquisher = class {
|
|
|
50085
50104
|
continue;
|
|
50086
50105
|
}
|
|
50087
50106
|
const current = command.content;
|
|
50088
|
-
if (current === void 0 || current === null || current === "")
|
|
50089
|
-
|
|
50107
|
+
if (current === void 0 || current === null || current === "") {
|
|
50108
|
+
this.rebase();
|
|
50109
|
+
strategy = "NOT_A_FORMULA";
|
|
50110
|
+
} else strategy = this.chooseStrategy(current, strategy, command.sheetId, getters);
|
|
50090
50111
|
let targetPositions;
|
|
50091
50112
|
if (command.type === "SQUISHED_UPDATE_CELL" && "targetRange" in command) {
|
|
50092
50113
|
const [start, end] = command.targetRange.split(":");
|
|
@@ -50131,8 +50152,11 @@ var Unsquisher = class {
|
|
|
50131
50152
|
let strategy;
|
|
50132
50153
|
for (const { key } of keys) {
|
|
50133
50154
|
const current = squished[key];
|
|
50134
|
-
if (current === void 0 || current === null || current === "")
|
|
50135
|
-
|
|
50155
|
+
if (current === void 0 || current === null || current === "") {
|
|
50156
|
+
this.rebase();
|
|
50157
|
+
strategy = void 0;
|
|
50158
|
+
continue;
|
|
50159
|
+
} else strategy = this.chooseStrategy(current, strategy, sheetId, getters);
|
|
50136
50160
|
const parts = key.split(":");
|
|
50137
50161
|
const targetPositions = parts.length === 1 ? expandXc(key) : expandRange(parts[0], parts[1]);
|
|
50138
50162
|
yield* this.applyStrategy(strategy, targetPositions, current, sheetId, getters);
|
|
@@ -50178,6 +50202,9 @@ var Unsquisher = class {
|
|
|
50178
50202
|
case "FIRST_OFFSET":
|
|
50179
50203
|
strategy = "COMBINE_OFFSET";
|
|
50180
50204
|
break;
|
|
50205
|
+
case "COMBINE_OFFSET":
|
|
50206
|
+
case "OFFSET_NUMBER": break;
|
|
50207
|
+
default: throw new Error(`Cannot unsquish an offset without a preceding base cell: ${strategy}`);
|
|
50181
50208
|
}
|
|
50182
50209
|
}
|
|
50183
50210
|
return strategy;
|
|
@@ -54896,6 +54923,7 @@ var FormulaDependencyGraph = class {
|
|
|
54896
54923
|
}
|
|
54897
54924
|
getCellsDependingOn(ranges, visited = new RangeSet()) {
|
|
54898
54925
|
visited = visited.copy();
|
|
54926
|
+
let initialRangesToRemove = visited.copy();
|
|
54899
54927
|
const queue = Array.from(ranges).reverse();
|
|
54900
54928
|
while (queue.length > 0) {
|
|
54901
54929
|
const range = queue.pop();
|
|
@@ -54911,8 +54939,9 @@ var FormulaDependencyGraph = class {
|
|
|
54911
54939
|
for (const interval of overlappingIntervals) impactedRanges.add(interval.dependents);
|
|
54912
54940
|
}
|
|
54913
54941
|
queue.push(...impactedRanges.difference(visited));
|
|
54942
|
+
initialRangesToRemove = initialRangesToRemove.difference(impactedRanges);
|
|
54914
54943
|
}
|
|
54915
|
-
for (const range of
|
|
54944
|
+
for (const range of initialRangesToRemove) visited.delete(range);
|
|
54916
54945
|
return visited;
|
|
54917
54946
|
}
|
|
54918
54947
|
getOrCreateIntervalTree(sheetId, col) {
|
|
@@ -60960,6 +60989,7 @@ var Session = class extends EventBus {
|
|
|
60960
60989
|
transportService;
|
|
60961
60990
|
serverRevisionId;
|
|
60962
60991
|
commandSquisher;
|
|
60992
|
+
shouldVerifySquish;
|
|
60963
60993
|
/**
|
|
60964
60994
|
* Positions of the others client.
|
|
60965
60995
|
*/
|
|
@@ -60994,13 +61024,15 @@ var Session = class extends EventBus {
|
|
|
60994
61024
|
* between all connected clients
|
|
60995
61025
|
* @param serverRevisionId
|
|
60996
61026
|
* @param commandSquisher used to squish and unsquish commands to reduce the size of messages sent to the server
|
|
61027
|
+
* @param shouldVerifySquish either the commands should be unsquished and verified before being sent to the server
|
|
60997
61028
|
*/
|
|
60998
|
-
constructor(revisions, transportService, serverRevisionId = DEFAULT_REVISION_ID, commandSquisher) {
|
|
61029
|
+
constructor(revisions, transportService, serverRevisionId = DEFAULT_REVISION_ID, commandSquisher, shouldVerifySquish = true) {
|
|
60999
61030
|
super();
|
|
61000
61031
|
this.revisions = revisions;
|
|
61001
61032
|
this.transportService = transportService;
|
|
61002
61033
|
this.serverRevisionId = serverRevisionId;
|
|
61003
61034
|
this.commandSquisher = commandSquisher;
|
|
61035
|
+
this.shouldVerifySquish = shouldVerifySquish;
|
|
61004
61036
|
}
|
|
61005
61037
|
canApplyOptimisticUpdate() {
|
|
61006
61038
|
return !this.waitingUndoRedoAck;
|
|
@@ -61256,10 +61288,20 @@ var Session = class extends EventBus {
|
|
|
61256
61288
|
this.revisions.rebase(revision.id);
|
|
61257
61289
|
revision = this.revisions.get(message.nextRevisionId);
|
|
61258
61290
|
}
|
|
61259
|
-
|
|
61291
|
+
const squishedCommands = this.commandSquisher.squish(revision.commands);
|
|
61292
|
+
if (!squishedCommands.some((x) => x.type === "SQUISHED_UPDATE_CELL")) message = {
|
|
61260
61293
|
...message,
|
|
61261
61294
|
commands: revision.commands
|
|
61262
61295
|
};
|
|
61296
|
+
else if (this.shouldVerifySquish && !deepEquals(revision.commands, this.commandSquisher.unsquish(squishedCommands))) message = {
|
|
61297
|
+
...message,
|
|
61298
|
+
commands: revision.commands,
|
|
61299
|
+
squishedFailed: true
|
|
61300
|
+
};
|
|
61301
|
+
else message = {
|
|
61302
|
+
...message,
|
|
61303
|
+
commands: squishedCommands
|
|
61304
|
+
};
|
|
61263
61305
|
}
|
|
61264
61306
|
if (this.isReplayingInitialRevisions) throw new Error(`Trying to send a new revision while replaying initial revision. This can lead to endless dispatches every time the spreadsheet is open.
|
|
61265
61307
|
${JSON.stringify(message)}`);
|
|
@@ -68956,7 +68998,7 @@ var FigureRendererStore = class extends DisposableStore {
|
|
|
68956
68998
|
if (!this.getters.isDashboard()) {
|
|
68957
68999
|
ctx.strokeStyle = GRAY_400;
|
|
68958
69000
|
ctx.lineWidth = 1;
|
|
68959
|
-
ctx.strokeRect(x, y, figure.width, figure.height);
|
|
69001
|
+
ctx.strokeRect(x + .5, y + .5, figure.width - 1, figure.height - 1);
|
|
68960
69002
|
}
|
|
68961
69003
|
}
|
|
68962
69004
|
}
|
|
@@ -84971,6 +85013,6 @@ exports.stores = stores;
|
|
|
84971
85013
|
exports.tokenColors = tokenColors;
|
|
84972
85014
|
exports.tokenize = tokenize;
|
|
84973
85015
|
|
|
84974
|
-
__info__.version = "19.3.
|
|
84975
|
-
__info__.date = "2026-
|
|
84976
|
-
__info__.hash = "
|
|
85016
|
+
__info__.version = "19.3.19";
|
|
85017
|
+
__info__.date = "2026-09-04T07:38:14.356Z";
|
|
85018
|
+
__info__.hash = "c8c526d";
|
package/dist/o_spreadsheet.css
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/*
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.3.
|
|
6
|
-
* @date 2026-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.19
|
|
6
|
+
* @date 2026-09-04T07:38:15.963Z
|
|
7
|
+
* @hash c8c526d
|
|
8
8
|
*/
|
|
9
9
|
:root {
|
|
10
10
|
--os-gray-100: light-dark(#f9fafb, #1b1d26);
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
--os-white-bg: light-dark(#ffffff, var(--os-gray-200));
|
|
23
23
|
--os-popover-bg: light-dark(#ffffff, var(--os-gray-300));
|
|
24
24
|
|
|
25
|
-
--os-default-font: "Roboto", "Arial";
|
|
25
|
+
--os-default-font: "Roboto", "Arial", "Liberation Sans";
|
|
26
26
|
--os-default-font-size: 10px;
|
|
27
27
|
--os-link-color: light-dark(#017e84, #02c7b5);
|
|
28
28
|
--os-link-hover-color: light-dark(#01585c, #4ed8cb);
|
|
@@ -1480,6 +1480,12 @@
|
|
|
1480
1480
|
background-color: var(--os-action-color);
|
|
1481
1481
|
border-color: var(--os-action-color) !important;
|
|
1482
1482
|
}
|
|
1483
|
+
|
|
1484
|
+
&:focus {
|
|
1485
|
+
outline: none;
|
|
1486
|
+
box-shadow: 0 0 0 0.25rem rgba(113, 75, 103, 0.25);
|
|
1487
|
+
border-color: var(--os-action-color);
|
|
1488
|
+
}
|
|
1483
1489
|
}
|
|
1484
1490
|
}
|
|
1485
1491
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 19.3.
|
|
6
|
-
* @date 2026-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.19
|
|
6
|
+
* @date 2026-09-04T07:38:14.356Z
|
|
7
|
+
* @hash c8c526d
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { App, Component, blockDom, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, whenReady, xml } from "@odoo/owl";
|
|
@@ -9592,16 +9592,16 @@ const chartShowValuesPlugin = {
|
|
|
9592
9592
|
drawLineOrBarOrRadarChartValues(chart, options, ctx);
|
|
9593
9593
|
break;
|
|
9594
9594
|
case "bar":
|
|
9595
|
-
options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
|
|
9595
|
+
options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true }) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
|
|
9596
9596
|
break;
|
|
9597
9597
|
case "pyramid":
|
|
9598
|
-
drawHorizontalBarChartValues(chart, options, ctx);
|
|
9598
|
+
drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true });
|
|
9599
9599
|
break;
|
|
9600
9600
|
case "calendar":
|
|
9601
9601
|
drawBarChartValues(chart, options, ctx);
|
|
9602
9602
|
break;
|
|
9603
9603
|
case "funnel":
|
|
9604
|
-
drawHorizontalBarChartValues(chart, options, ctx);
|
|
9604
|
+
drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: false });
|
|
9605
9605
|
break;
|
|
9606
9606
|
}
|
|
9607
9607
|
ctx.restore();
|
|
@@ -9671,7 +9671,7 @@ function drawBarChartValues(chart, options, ctx) {
|
|
|
9671
9671
|
}
|
|
9672
9672
|
}
|
|
9673
9673
|
}
|
|
9674
|
-
function drawHorizontalBarChartValues(chart, options, ctx) {
|
|
9674
|
+
function drawHorizontalBarChartValues(chart, options, ctx, args) {
|
|
9675
9675
|
const textsPositions = {};
|
|
9676
9676
|
for (const dataset of chart._metasets) {
|
|
9677
9677
|
if (isTrendLineAxis(dataset.xAxisID)) return;
|
|
@@ -9686,7 +9686,7 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
|
|
|
9686
9686
|
const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
|
|
9687
9687
|
const PADDING = 3;
|
|
9688
9688
|
let xPosition;
|
|
9689
|
-
if (distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
|
|
9689
|
+
if (args.offsetFromAxisOrigin && distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
|
|
9690
9690
|
else xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
|
|
9691
9691
|
if (!textsPositions[yPosition]) textsPositions[yPosition] = [];
|
|
9692
9692
|
for (const otherPosition of textsPositions[yPosition]) if (Math.abs(otherPosition - xPosition) < textWidth) xPosition = value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
|
|
@@ -10485,6 +10485,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
10485
10485
|
hidden,
|
|
10486
10486
|
borderColor,
|
|
10487
10487
|
backgroundColor: borderColor,
|
|
10488
|
+
pointBackgroundColor: borderColor,
|
|
10488
10489
|
pointRadius: definition.hideDataMarkers ? 0 : 3
|
|
10489
10490
|
};
|
|
10490
10491
|
if (fill) {
|
|
@@ -25444,9 +25445,10 @@ var Composer = class extends Component {
|
|
|
25444
25445
|
compositionActive = false;
|
|
25445
25446
|
spreadsheetRect = useSpreadsheetRect();
|
|
25446
25447
|
lastHoveredTokenIndex = void 0;
|
|
25447
|
-
debouncedHover = debounce((tokenIndex, hoveredRect) => {
|
|
25448
|
+
debouncedHover = debounce((tokenIndex, composerContent, hoveredRect) => {
|
|
25448
25449
|
const selection = this.contentHelper.getCurrentSelection();
|
|
25449
|
-
|
|
25450
|
+
const currentContent = this.props.composerStore.currentContent;
|
|
25451
|
+
if (selection.start !== selection.end || currentContent !== composerContent) return;
|
|
25450
25452
|
const currentHoveredContext = this.props.composerStore.hoveredTokens;
|
|
25451
25453
|
this.props.composerStore.hoverToken(tokenIndex);
|
|
25452
25454
|
if (!deepEquals(currentHoveredContext, this.props.composerStore.hoveredTokens)) this.composerState.hoveredRect = hoveredRect;
|
|
@@ -25764,7 +25766,8 @@ var Composer = class extends Component {
|
|
|
25764
25766
|
onTokenHover(tokenIndex, hoveredRect) {
|
|
25765
25767
|
if (this.lastHoveredTokenIndex !== tokenIndex) {
|
|
25766
25768
|
this.lastHoveredTokenIndex = tokenIndex;
|
|
25767
|
-
this.
|
|
25769
|
+
const composerContent = this.props.composerStore.currentContent;
|
|
25770
|
+
this.debouncedHover(tokenIndex, composerContent, hoveredRect);
|
|
25768
25771
|
}
|
|
25769
25772
|
}
|
|
25770
25773
|
/**
|
|
@@ -40075,7 +40078,13 @@ var PivotSpreadsheetSidePanel = class extends Component {
|
|
|
40075
40078
|
}
|
|
40076
40079
|
onSelectionChanged(ranges) {
|
|
40077
40080
|
this.state.rangeHasChanged = true;
|
|
40078
|
-
|
|
40081
|
+
if (ranges.length === 0) {
|
|
40082
|
+
this.state.range = void 0;
|
|
40083
|
+
return;
|
|
40084
|
+
}
|
|
40085
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
40086
|
+
const range = this.env.model.getters.getRangeFromSheetXC(sheetId, ranges[0]);
|
|
40087
|
+
this.state.range = this.env.model.getters.getRangeString(range, "forceSheetReference", { useBoundedReference: true });
|
|
40079
40088
|
}
|
|
40080
40089
|
onSelectionConfirmed() {
|
|
40081
40090
|
if (this.state.range) {
|
|
@@ -49734,6 +49743,7 @@ var CarouselPlugin = class extends CorePlugin {
|
|
|
49734
49743
|
return "Success";
|
|
49735
49744
|
case "UPDATE_CAROUSEL":
|
|
49736
49745
|
if (!this.carousels[cmd.sheetId]?.[cmd.figureId]) return "InvalidFigureId";
|
|
49746
|
+
for (const item of cmd.definition.items) if (item.type === "chart" && !this.getters.getChart(item.chartId)) return "ChartDoesNotExist";
|
|
49737
49747
|
return "Success";
|
|
49738
49748
|
}
|
|
49739
49749
|
return "Success";
|
|
@@ -49838,6 +49848,7 @@ var Squisher = class {
|
|
|
49838
49848
|
baseFormulaWasTransformed = false;
|
|
49839
49849
|
rangeToStringOptions = { doNotSimplifyRange: true };
|
|
49840
49850
|
baseNumber = void 0;
|
|
49851
|
+
baseNumberFormat = void 0;
|
|
49841
49852
|
constructor(getters) {
|
|
49842
49853
|
this.getters = getters;
|
|
49843
49854
|
}
|
|
@@ -49872,6 +49883,11 @@ var Squisher = class {
|
|
|
49872
49883
|
this.baseFormulaWasTransformed = false;
|
|
49873
49884
|
}
|
|
49874
49885
|
}
|
|
49886
|
+
/** Reset the base number literal chain, so the next literal number cannot be squished as an offset of it */
|
|
49887
|
+
resetBaseNumber() {
|
|
49888
|
+
this.baseNumber = void 0;
|
|
49889
|
+
this.baseNumberFormat = void 0;
|
|
49890
|
+
}
|
|
49875
49891
|
/**
|
|
49876
49892
|
* Takes a cell and squish their formulas against the previous one (in the previous call).
|
|
49877
49893
|
* We should call this method for each cell in the sheet, in order from top to bottom, then from left to right (all cells of a columns, for each columns left to right).
|
|
@@ -49910,8 +49926,9 @@ var Squisher = class {
|
|
|
49910
49926
|
if (typeof cell.parsedValue === "number" && cell.parsedValue % 1 === 0) {
|
|
49911
49927
|
this.resetBaseFormula();
|
|
49912
49928
|
const numberValue = cell.parsedValue;
|
|
49913
|
-
if (this.baseNumber === void 0) {
|
|
49929
|
+
if (this.baseNumber === void 0 || cell.format !== this.baseNumberFormat) {
|
|
49914
49930
|
this.baseNumber = numberValue;
|
|
49931
|
+
this.baseNumberFormat = cell.format;
|
|
49915
49932
|
return cell.content;
|
|
49916
49933
|
}
|
|
49917
49934
|
const numberOffset = numberValue - this.baseNumber;
|
|
@@ -49922,7 +49939,7 @@ var Squisher = class {
|
|
|
49922
49939
|
}
|
|
49923
49940
|
}
|
|
49924
49941
|
this.resetBaseFormula();
|
|
49925
|
-
this.
|
|
49942
|
+
this.resetBaseNumber();
|
|
49926
49943
|
return cell.content;
|
|
49927
49944
|
}
|
|
49928
49945
|
squishCommand(command) {
|
|
@@ -49931,6 +49948,8 @@ var Squisher = class {
|
|
|
49931
49948
|
const squished = this.squish(cell, command.sheetId);
|
|
49932
49949
|
return typeof squished === "string" ? command.content : squished;
|
|
49933
49950
|
}
|
|
49951
|
+
this.resetBaseFormula();
|
|
49952
|
+
this.resetBaseNumber();
|
|
49934
49953
|
return command.content;
|
|
49935
49954
|
}
|
|
49936
49955
|
/**
|
|
@@ -50084,8 +50103,10 @@ var Unsquisher = class {
|
|
|
50084
50103
|
continue;
|
|
50085
50104
|
}
|
|
50086
50105
|
const current = command.content;
|
|
50087
|
-
if (current === void 0 || current === null || current === "")
|
|
50088
|
-
|
|
50106
|
+
if (current === void 0 || current === null || current === "") {
|
|
50107
|
+
this.rebase();
|
|
50108
|
+
strategy = "NOT_A_FORMULA";
|
|
50109
|
+
} else strategy = this.chooseStrategy(current, strategy, command.sheetId, getters);
|
|
50089
50110
|
let targetPositions;
|
|
50090
50111
|
if (command.type === "SQUISHED_UPDATE_CELL" && "targetRange" in command) {
|
|
50091
50112
|
const [start, end] = command.targetRange.split(":");
|
|
@@ -50130,8 +50151,11 @@ var Unsquisher = class {
|
|
|
50130
50151
|
let strategy;
|
|
50131
50152
|
for (const { key } of keys) {
|
|
50132
50153
|
const current = squished[key];
|
|
50133
|
-
if (current === void 0 || current === null || current === "")
|
|
50134
|
-
|
|
50154
|
+
if (current === void 0 || current === null || current === "") {
|
|
50155
|
+
this.rebase();
|
|
50156
|
+
strategy = void 0;
|
|
50157
|
+
continue;
|
|
50158
|
+
} else strategy = this.chooseStrategy(current, strategy, sheetId, getters);
|
|
50135
50159
|
const parts = key.split(":");
|
|
50136
50160
|
const targetPositions = parts.length === 1 ? expandXc(key) : expandRange(parts[0], parts[1]);
|
|
50137
50161
|
yield* this.applyStrategy(strategy, targetPositions, current, sheetId, getters);
|
|
@@ -50177,6 +50201,9 @@ var Unsquisher = class {
|
|
|
50177
50201
|
case "FIRST_OFFSET":
|
|
50178
50202
|
strategy = "COMBINE_OFFSET";
|
|
50179
50203
|
break;
|
|
50204
|
+
case "COMBINE_OFFSET":
|
|
50205
|
+
case "OFFSET_NUMBER": break;
|
|
50206
|
+
default: throw new Error(`Cannot unsquish an offset without a preceding base cell: ${strategy}`);
|
|
50180
50207
|
}
|
|
50181
50208
|
}
|
|
50182
50209
|
return strategy;
|
|
@@ -54895,6 +54922,7 @@ var FormulaDependencyGraph = class {
|
|
|
54895
54922
|
}
|
|
54896
54923
|
getCellsDependingOn(ranges, visited = new RangeSet()) {
|
|
54897
54924
|
visited = visited.copy();
|
|
54925
|
+
let initialRangesToRemove = visited.copy();
|
|
54898
54926
|
const queue = Array.from(ranges).reverse();
|
|
54899
54927
|
while (queue.length > 0) {
|
|
54900
54928
|
const range = queue.pop();
|
|
@@ -54910,8 +54938,9 @@ var FormulaDependencyGraph = class {
|
|
|
54910
54938
|
for (const interval of overlappingIntervals) impactedRanges.add(interval.dependents);
|
|
54911
54939
|
}
|
|
54912
54940
|
queue.push(...impactedRanges.difference(visited));
|
|
54941
|
+
initialRangesToRemove = initialRangesToRemove.difference(impactedRanges);
|
|
54913
54942
|
}
|
|
54914
|
-
for (const range of
|
|
54943
|
+
for (const range of initialRangesToRemove) visited.delete(range);
|
|
54915
54944
|
return visited;
|
|
54916
54945
|
}
|
|
54917
54946
|
getOrCreateIntervalTree(sheetId, col) {
|
|
@@ -60775,6 +60804,7 @@ var Session = class extends EventBus {
|
|
|
60775
60804
|
transportService;
|
|
60776
60805
|
serverRevisionId;
|
|
60777
60806
|
commandSquisher;
|
|
60807
|
+
shouldVerifySquish;
|
|
60778
60808
|
/**
|
|
60779
60809
|
* Positions of the others client.
|
|
60780
60810
|
*/
|
|
@@ -60809,13 +60839,15 @@ var Session = class extends EventBus {
|
|
|
60809
60839
|
* between all connected clients
|
|
60810
60840
|
* @param serverRevisionId
|
|
60811
60841
|
* @param commandSquisher used to squish and unsquish commands to reduce the size of messages sent to the server
|
|
60842
|
+
* @param shouldVerifySquish either the commands should be unsquished and verified before being sent to the server
|
|
60812
60843
|
*/
|
|
60813
|
-
constructor(revisions, transportService, serverRevisionId = DEFAULT_REVISION_ID, commandSquisher) {
|
|
60844
|
+
constructor(revisions, transportService, serverRevisionId = DEFAULT_REVISION_ID, commandSquisher, shouldVerifySquish = true) {
|
|
60814
60845
|
super();
|
|
60815
60846
|
this.revisions = revisions;
|
|
60816
60847
|
this.transportService = transportService;
|
|
60817
60848
|
this.serverRevisionId = serverRevisionId;
|
|
60818
60849
|
this.commandSquisher = commandSquisher;
|
|
60850
|
+
this.shouldVerifySquish = shouldVerifySquish;
|
|
60819
60851
|
}
|
|
60820
60852
|
canApplyOptimisticUpdate() {
|
|
60821
60853
|
return !this.waitingUndoRedoAck;
|
|
@@ -61071,10 +61103,20 @@ var Session = class extends EventBus {
|
|
|
61071
61103
|
this.revisions.rebase(revision.id);
|
|
61072
61104
|
revision = this.revisions.get(message.nextRevisionId);
|
|
61073
61105
|
}
|
|
61074
|
-
|
|
61106
|
+
const squishedCommands = this.commandSquisher.squish(revision.commands);
|
|
61107
|
+
if (!squishedCommands.some((x) => x.type === "SQUISHED_UPDATE_CELL")) message = {
|
|
61075
61108
|
...message,
|
|
61076
61109
|
commands: revision.commands
|
|
61077
61110
|
};
|
|
61111
|
+
else if (this.shouldVerifySquish && !deepEquals(revision.commands, this.commandSquisher.unsquish(squishedCommands))) message = {
|
|
61112
|
+
...message,
|
|
61113
|
+
commands: revision.commands,
|
|
61114
|
+
squishedFailed: true
|
|
61115
|
+
};
|
|
61116
|
+
else message = {
|
|
61117
|
+
...message,
|
|
61118
|
+
commands: squishedCommands
|
|
61119
|
+
};
|
|
61078
61120
|
}
|
|
61079
61121
|
if (this.isReplayingInitialRevisions) throw new Error(`Trying to send a new revision while replaying initial revision. This can lead to endless dispatches every time the spreadsheet is open.
|
|
61080
61122
|
${JSON.stringify(message)}`);
|
|
@@ -68771,7 +68813,7 @@ var FigureRendererStore = class extends DisposableStore {
|
|
|
68771
68813
|
if (!this.getters.isDashboard()) {
|
|
68772
68814
|
ctx.strokeStyle = GRAY_400;
|
|
68773
68815
|
ctx.lineWidth = 1;
|
|
68774
|
-
ctx.strokeRect(x, y, figure.width, figure.height);
|
|
68816
|
+
ctx.strokeRect(x + .5, y + .5, figure.width - 1, figure.height - 1);
|
|
68775
68817
|
}
|
|
68776
68818
|
}
|
|
68777
68819
|
}
|
|
@@ -84728,6 +84770,6 @@ const chartHelpers = {
|
|
|
84728
84770
|
//#endregion
|
|
84729
84771
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CompiledFormula, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, canExecuteInReadonly, categories, chartHelpers, components, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, isCoreCommand, isSheetDependent, iterateAstNodes, links, load, lockedSheetAllowedCommands, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
84730
84772
|
|
|
84731
|
-
__info__.version = "19.3.
|
|
84732
|
-
__info__.date = "2026-
|
|
84733
|
-
__info__.hash = "
|
|
84773
|
+
__info__.version = "19.3.19";
|
|
84774
|
+
__info__.date = "2026-09-04T07:38:14.356Z";
|
|
84775
|
+
__info__.hash = "c8c526d";
|