@odoo/o-spreadsheet 18.2.7 → 18.2.9
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.js +123 -71
- package/dist/o-spreadsheet.d.ts +2 -1
- package/dist/o-spreadsheet.esm.js +123 -71
- package/dist/o-spreadsheet.iife.js +123 -71
- package/dist/o-spreadsheet.iife.min.js +378 -377
- package/dist/o_spreadsheet.xml +39 -38
- package/package.json +1 -1
|
@@ -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 18.2.
|
|
6
|
-
* @date 2025-04-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.9
|
|
6
|
+
* @date 2025-04-25T08:06:52.677Z
|
|
7
|
+
* @hash 3e88645
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3843,11 +3843,13 @@ const CellErrorType = {
|
|
|
3843
3843
|
NullError: "#NULL!",
|
|
3844
3844
|
};
|
|
3845
3845
|
const errorTypes = new Set(Object.values(CellErrorType));
|
|
3846
|
-
class EvaluationError
|
|
3846
|
+
class EvaluationError {
|
|
3847
|
+
message;
|
|
3847
3848
|
value;
|
|
3848
3849
|
constructor(message = _t("Error"), value = CellErrorType.GenericError) {
|
|
3849
|
-
|
|
3850
|
+
this.message = message;
|
|
3850
3851
|
this.value = value;
|
|
3852
|
+
this.message = message.toString();
|
|
3851
3853
|
}
|
|
3852
3854
|
}
|
|
3853
3855
|
class BadExpressionError extends EvaluationError {
|
|
@@ -6900,6 +6902,12 @@ function tokenizeString(chars) {
|
|
|
6900
6902
|
}
|
|
6901
6903
|
return null;
|
|
6902
6904
|
}
|
|
6905
|
+
/**
|
|
6906
|
+
- \p{L} is for any letter (from any language)
|
|
6907
|
+
- \p{N} is for any number
|
|
6908
|
+
- the u flag at the end is for unicode, which enables the `\p{...}` syntax
|
|
6909
|
+
*/
|
|
6910
|
+
const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
|
|
6903
6911
|
const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
|
|
6904
6912
|
/**
|
|
6905
6913
|
* A "Symbol" is just basically any word-like element that can appear in a
|
|
@@ -6940,7 +6948,8 @@ function tokenizeSymbol(chars) {
|
|
|
6940
6948
|
};
|
|
6941
6949
|
}
|
|
6942
6950
|
}
|
|
6943
|
-
while (chars.current &&
|
|
6951
|
+
while (chars.current &&
|
|
6952
|
+
(SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
|
|
6944
6953
|
result += chars.shift();
|
|
6945
6954
|
}
|
|
6946
6955
|
if (result.length) {
|
|
@@ -9247,7 +9256,7 @@ function transformZone(zone, executed) {
|
|
|
9247
9256
|
if (executed.type === "ADD_COLUMNS_ROWS") {
|
|
9248
9257
|
return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
|
|
9249
9258
|
}
|
|
9250
|
-
return
|
|
9259
|
+
return zone;
|
|
9251
9260
|
}
|
|
9252
9261
|
function transformRangeData(range, executed) {
|
|
9253
9262
|
const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
|
|
@@ -13745,7 +13754,7 @@ const RANK = {
|
|
|
13745
13754
|
}
|
|
13746
13755
|
}
|
|
13747
13756
|
if (!found) {
|
|
13748
|
-
|
|
13757
|
+
return new NotAvailableError(_t("Value not found in the given data."));
|
|
13749
13758
|
}
|
|
13750
13759
|
return rank;
|
|
13751
13760
|
},
|
|
@@ -15485,7 +15494,7 @@ const UNIQUE = {
|
|
|
15485
15494
|
result.push(row.data);
|
|
15486
15495
|
}
|
|
15487
15496
|
if (!result.length)
|
|
15488
|
-
|
|
15497
|
+
return new EvaluationError(_t("No unique values found"));
|
|
15489
15498
|
return _byColumn ? result : transposeMatrix(result);
|
|
15490
15499
|
},
|
|
15491
15500
|
isExported: true,
|
|
@@ -19264,7 +19273,7 @@ const OFFSET = {
|
|
|
19264
19273
|
}
|
|
19265
19274
|
const _cellReference = cellReference?.value;
|
|
19266
19275
|
if (!_cellReference) {
|
|
19267
|
-
|
|
19276
|
+
return new EvaluationError("In this context, the function OFFSET needs to have a cell or range in parameter.");
|
|
19268
19277
|
}
|
|
19269
19278
|
const zone = toZone(_cellReference);
|
|
19270
19279
|
let offsetHeight = zone.bottom - zone.top + 1;
|
|
@@ -33638,6 +33647,12 @@ function isMacOS() {
|
|
|
33638
33647
|
function isCtrlKey(ev) {
|
|
33639
33648
|
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
33640
33649
|
}
|
|
33650
|
+
/**
|
|
33651
|
+
* Detects if the current browser is Firefox
|
|
33652
|
+
*/
|
|
33653
|
+
function isBrowserFirefox() {
|
|
33654
|
+
return /Firefox/i.test(navigator.userAgent);
|
|
33655
|
+
}
|
|
33641
33656
|
|
|
33642
33657
|
/**
|
|
33643
33658
|
* Repeatedly calls a callback function with a time delay between calls.
|
|
@@ -39104,7 +39119,7 @@ class ColorPicker extends owl.Component {
|
|
|
39104
39119
|
}
|
|
39105
39120
|
setHexColor(ev) {
|
|
39106
39121
|
// only support HEX code input
|
|
39107
|
-
const val = ev.target.value.slice(0, 7);
|
|
39122
|
+
const val = ev.target.value.replace("##", "#").slice(0, 7);
|
|
39108
39123
|
this.state.customHexColor = val;
|
|
39109
39124
|
if (!isColorValid(val)) ;
|
|
39110
39125
|
else {
|
|
@@ -50433,39 +50448,6 @@ function useCellHovered(env, gridRef, callback) {
|
|
|
50433
50448
|
}
|
|
50434
50449
|
return hoveredPosition;
|
|
50435
50450
|
}
|
|
50436
|
-
function useTouchMove(gridRef, handler, canMoveUp) {
|
|
50437
|
-
let x = null;
|
|
50438
|
-
let y = null;
|
|
50439
|
-
function onTouchStart(ev) {
|
|
50440
|
-
if (ev.touches.length !== 1)
|
|
50441
|
-
return;
|
|
50442
|
-
x = ev.touches[0].clientX;
|
|
50443
|
-
y = ev.touches[0].clientY;
|
|
50444
|
-
}
|
|
50445
|
-
function onTouchEnd() {
|
|
50446
|
-
x = null;
|
|
50447
|
-
y = null;
|
|
50448
|
-
}
|
|
50449
|
-
function onTouchMove(ev) {
|
|
50450
|
-
if (ev.touches.length !== 1)
|
|
50451
|
-
return;
|
|
50452
|
-
// On mobile browsers, swiping down is often associated with "pull to refresh".
|
|
50453
|
-
// We only want this behavior if the grid is already at the top.
|
|
50454
|
-
// Otherwise we only want to move the canvas up, without triggering any refresh.
|
|
50455
|
-
if (canMoveUp()) {
|
|
50456
|
-
ev.preventDefault();
|
|
50457
|
-
ev.stopPropagation();
|
|
50458
|
-
}
|
|
50459
|
-
const currentX = ev.touches[0].clientX;
|
|
50460
|
-
const currentY = ev.touches[0].clientY;
|
|
50461
|
-
handler(x - currentX, y - currentY);
|
|
50462
|
-
x = currentX;
|
|
50463
|
-
y = currentY;
|
|
50464
|
-
}
|
|
50465
|
-
useRefListener(gridRef, "touchstart", onTouchStart);
|
|
50466
|
-
useRefListener(gridRef, "touchend", onTouchEnd);
|
|
50467
|
-
useRefListener(gridRef, "touchmove", onTouchMove);
|
|
50468
|
-
}
|
|
50469
50451
|
class GridOverlay extends owl.Component {
|
|
50470
50452
|
static template = "o-spreadsheet-GridOverlay";
|
|
50471
50453
|
static props = {
|
|
@@ -50513,10 +50495,6 @@ class GridOverlay extends owl.Component {
|
|
|
50513
50495
|
owl.onWillUnmount(() => {
|
|
50514
50496
|
resizeObserver.disconnect();
|
|
50515
50497
|
});
|
|
50516
|
-
useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
|
|
50517
|
-
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
50518
|
-
return scrollY > 0;
|
|
50519
|
-
});
|
|
50520
50498
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
50521
50499
|
this.paintFormatStore = useStore(PaintFormatStore);
|
|
50522
50500
|
}
|
|
@@ -51988,6 +51966,73 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51988
51966
|
}
|
|
51989
51967
|
}
|
|
51990
51968
|
|
|
51969
|
+
const friction = 0.95;
|
|
51970
|
+
const verticalScrollFactor = 1;
|
|
51971
|
+
const horizontalScrollFactor = 1;
|
|
51972
|
+
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
51973
|
+
let lastX = 0;
|
|
51974
|
+
let lastY = 0;
|
|
51975
|
+
let velocityX = 0;
|
|
51976
|
+
let velocityY = 0;
|
|
51977
|
+
let isMouseDown = false;
|
|
51978
|
+
let lastTime = 0;
|
|
51979
|
+
useRefListener(ref, "touchstart", onTouchStart, { capture: false });
|
|
51980
|
+
useRefListener(ref, "touchmove", onTouchMove, { capture: false });
|
|
51981
|
+
useRefListener(ref, "touchend", onTouchEnd, { capture: false });
|
|
51982
|
+
function onTouchStart(event) {
|
|
51983
|
+
isMouseDown = true;
|
|
51984
|
+
({ clientX: lastX, clientY: lastY } = event.touches[0]);
|
|
51985
|
+
velocityX = 0;
|
|
51986
|
+
velocityY = 0;
|
|
51987
|
+
}
|
|
51988
|
+
function onTouchMove(event) {
|
|
51989
|
+
if (!isMouseDown)
|
|
51990
|
+
return;
|
|
51991
|
+
const currentTime = Date.now();
|
|
51992
|
+
const { clientX, clientY } = event.touches[0];
|
|
51993
|
+
let deltaX = lastX - clientX;
|
|
51994
|
+
let deltaY = lastY - clientY;
|
|
51995
|
+
const elapsedTime = currentTime - lastTime;
|
|
51996
|
+
velocityX = deltaX / elapsedTime;
|
|
51997
|
+
velocityY = deltaY / elapsedTime;
|
|
51998
|
+
lastX = clientX;
|
|
51999
|
+
lastY = clientY;
|
|
52000
|
+
lastTime = currentTime;
|
|
52001
|
+
if (canMoveUp()) {
|
|
52002
|
+
if (event.cancelable) {
|
|
52003
|
+
event.preventDefault();
|
|
52004
|
+
}
|
|
52005
|
+
event.stopPropagation();
|
|
52006
|
+
}
|
|
52007
|
+
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
52008
|
+
}
|
|
52009
|
+
function onTouchEnd(ev) {
|
|
52010
|
+
isMouseDown = false;
|
|
52011
|
+
lastX = lastY = 0;
|
|
52012
|
+
requestAnimationFrame(scroll);
|
|
52013
|
+
}
|
|
52014
|
+
function scroll() {
|
|
52015
|
+
if (Math.abs(velocityX) < 0.05) {
|
|
52016
|
+
velocityX = 0;
|
|
52017
|
+
}
|
|
52018
|
+
if (Math.abs(velocityY) < 0.05) {
|
|
52019
|
+
velocityY = 0;
|
|
52020
|
+
}
|
|
52021
|
+
if (!velocityX && !velocityY) {
|
|
52022
|
+
return;
|
|
52023
|
+
}
|
|
52024
|
+
const currentTime = Date.now();
|
|
52025
|
+
const elapsedTime = Math.abs(currentTime - lastTime);
|
|
52026
|
+
const deltaX = velocityX * elapsedTime;
|
|
52027
|
+
const deltaY = velocityY * elapsedTime;
|
|
52028
|
+
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
52029
|
+
lastTime = currentTime;
|
|
52030
|
+
velocityX *= friction;
|
|
52031
|
+
velocityY *= friction;
|
|
52032
|
+
requestAnimationFrame(scroll);
|
|
52033
|
+
}
|
|
52034
|
+
}
|
|
52035
|
+
|
|
51991
52036
|
function useWheelHandler(handler) {
|
|
51992
52037
|
function normalize(val, deltaMode) {
|
|
51993
52038
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
@@ -52328,7 +52373,7 @@ class HorizontalScrollBar extends owl.Component {
|
|
|
52328
52373
|
left: `${this.props.leftOffset + x}px`,
|
|
52329
52374
|
bottom: "0px",
|
|
52330
52375
|
height: `${SCROLLBAR_WIDTH}px`,
|
|
52331
|
-
right: `
|
|
52376
|
+
right: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
|
|
52332
52377
|
};
|
|
52333
52378
|
}
|
|
52334
52379
|
onScroll(offset) {
|
|
@@ -52373,7 +52418,7 @@ class VerticalScrollBar extends owl.Component {
|
|
|
52373
52418
|
top: `${this.props.topOffset + y}px`,
|
|
52374
52419
|
right: "0px",
|
|
52375
52420
|
width: `${SCROLLBAR_WIDTH}px`,
|
|
52376
|
-
bottom: `
|
|
52421
|
+
bottom: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
|
|
52377
52422
|
};
|
|
52378
52423
|
}
|
|
52379
52424
|
onScroll(offset) {
|
|
@@ -52609,6 +52654,10 @@ class Grid extends owl.Component {
|
|
|
52609
52654
|
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
52610
52655
|
}
|
|
52611
52656
|
}, () => [this.sidePanel.isOpen]);
|
|
52657
|
+
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
52658
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
52659
|
+
return scrollY > 0;
|
|
52660
|
+
});
|
|
52612
52661
|
}
|
|
52613
52662
|
onCellHovered({ col, row }) {
|
|
52614
52663
|
this.hoveredCell.hover({ col, row });
|
|
@@ -62288,6 +62337,16 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
62288
62337
|
}
|
|
62289
62338
|
return values;
|
|
62290
62339
|
}
|
|
62340
|
+
else if (rowDomain.length === this.definition.rows.length &&
|
|
62341
|
+
colDomain.length &&
|
|
62342
|
+
colDomain.length < this.definition.columns.length) {
|
|
62343
|
+
const colSubTree = this.getSubTreeMatchingDomain(table.getColTree(), colDomain);
|
|
62344
|
+
const domains = this.treeToLeafDomains(colSubTree, colDomain);
|
|
62345
|
+
for (const domain of domains) {
|
|
62346
|
+
values.push(this._getPivotCellValueAndFormat(measure.id, rowDomain.concat(domain)));
|
|
62347
|
+
}
|
|
62348
|
+
return values;
|
|
62349
|
+
}
|
|
62291
62350
|
else {
|
|
62292
62351
|
const tree = table.getRowTree();
|
|
62293
62352
|
const subTree = this.getSubTreeMatchingDomain(tree, rowDomain);
|
|
@@ -63854,10 +63913,8 @@ function mergeTransformation(toTransform, executed) {
|
|
|
63854
63913
|
}
|
|
63855
63914
|
const target = [];
|
|
63856
63915
|
for (const zone1 of toTransform.target) {
|
|
63857
|
-
|
|
63858
|
-
|
|
63859
|
-
target.push({ ...zone1 });
|
|
63860
|
-
}
|
|
63916
|
+
if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
|
|
63917
|
+
target.push(zone1);
|
|
63861
63918
|
}
|
|
63862
63919
|
}
|
|
63863
63920
|
if (target.length) {
|
|
@@ -67989,24 +68046,14 @@ class InternalViewport {
|
|
|
67989
68046
|
first: this.boundaries.top,
|
|
67990
68047
|
last: this.boundaries.bottom,
|
|
67991
68048
|
});
|
|
67992
|
-
const { end: lastColEnd
|
|
67993
|
-
const { end: lastRowEnd
|
|
67994
|
-
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
|
|
67995
|
-
const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
|
|
67996
|
-
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
|
|
67997
|
-
const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
|
|
68049
|
+
const { end: lastColEnd } = this.getters.getColDimensions(this.sheetId, lastCol);
|
|
68050
|
+
const { end: lastRowEnd } = this.getters.getRowDimensions(this.sheetId, lastRow);
|
|
67998
68051
|
let width = lastColEnd - this.offsetCorrectionX;
|
|
67999
68052
|
if (this.canScrollHorizontally) {
|
|
68000
|
-
width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
|
|
68001
|
-
Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
|
|
68002
|
-
);
|
|
68003
68053
|
width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
|
|
68004
68054
|
}
|
|
68005
68055
|
let height = lastRowEnd - this.offsetCorrectionY;
|
|
68006
68056
|
if (this.canScrollVertically) {
|
|
68007
|
-
height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
|
|
68008
|
-
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
68009
|
-
);
|
|
68010
68057
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
68011
68058
|
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
68012
68059
|
height += FOOTER_HEIGHT;
|
|
@@ -68571,8 +68618,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68571
68618
|
const { width, height } = this.getMainViewportRect();
|
|
68572
68619
|
const viewport = this.getMainInternalViewport(sheetId);
|
|
68573
68620
|
return {
|
|
68574
|
-
maxOffsetX: Math.max(0, width - viewport.viewportWidth
|
|
68575
|
-
maxOffsetY: Math.max(0, height - viewport.viewportHeight
|
|
68621
|
+
maxOffsetX: Math.max(0, width - viewport.viewportWidth),
|
|
68622
|
+
maxOffsetY: Math.max(0, height - viewport.viewportHeight),
|
|
68576
68623
|
};
|
|
68577
68624
|
}
|
|
68578
68625
|
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
@@ -70094,6 +70141,10 @@ class SpreadsheetDashboard extends owl.Component {
|
|
|
70094
70141
|
this.hoveredCell.clear();
|
|
70095
70142
|
});
|
|
70096
70143
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
70144
|
+
useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
|
|
70145
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
70146
|
+
return scrollY > 0;
|
|
70147
|
+
});
|
|
70097
70148
|
}
|
|
70098
70149
|
onCellHovered({ col, row }) {
|
|
70099
70150
|
this.hoveredCell.hover({ col, row });
|
|
@@ -71484,6 +71535,7 @@ css /* scss */ `
|
|
|
71484
71535
|
> canvas {
|
|
71485
71536
|
box-sizing: content-box;
|
|
71486
71537
|
border-bottom: 1px solid #e2e3e3;
|
|
71538
|
+
border-right: 1px solid #e2e3e3;
|
|
71487
71539
|
}
|
|
71488
71540
|
|
|
71489
71541
|
.o-grid-overlay {
|
|
@@ -76190,6 +76242,6 @@ exports.tokenColors = tokenColors;
|
|
|
76190
76242
|
exports.tokenize = tokenize;
|
|
76191
76243
|
|
|
76192
76244
|
|
|
76193
|
-
__info__.version = "18.2.
|
|
76194
|
-
__info__.date = "2025-04-
|
|
76195
|
-
__info__.hash = "
|
|
76245
|
+
__info__.version = "18.2.9";
|
|
76246
|
+
__info__.date = "2025-04-25T08:06:52.677Z";
|
|
76247
|
+
__info__.hash = "3e88645";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -11676,7 +11676,8 @@ declare const CellErrorType: {
|
|
|
11676
11676
|
readonly GenericError: "#ERROR";
|
|
11677
11677
|
readonly NullError: "#NULL!";
|
|
11678
11678
|
};
|
|
11679
|
-
declare class EvaluationError
|
|
11679
|
+
declare class EvaluationError {
|
|
11680
|
+
readonly message: string;
|
|
11680
11681
|
readonly value: string;
|
|
11681
11682
|
constructor(message?: string, value?: string);
|
|
11682
11683
|
}
|