@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
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -3841,11 +3841,13 @@ const CellErrorType = {
|
|
|
3841
3841
|
NullError: "#NULL!",
|
|
3842
3842
|
};
|
|
3843
3843
|
const errorTypes = new Set(Object.values(CellErrorType));
|
|
3844
|
-
class EvaluationError
|
|
3844
|
+
class EvaluationError {
|
|
3845
|
+
message;
|
|
3845
3846
|
value;
|
|
3846
3847
|
constructor(message = _t("Error"), value = CellErrorType.GenericError) {
|
|
3847
|
-
|
|
3848
|
+
this.message = message;
|
|
3848
3849
|
this.value = value;
|
|
3850
|
+
this.message = message.toString();
|
|
3849
3851
|
}
|
|
3850
3852
|
}
|
|
3851
3853
|
class BadExpressionError extends EvaluationError {
|
|
@@ -6898,6 +6900,12 @@ function tokenizeString(chars) {
|
|
|
6898
6900
|
}
|
|
6899
6901
|
return null;
|
|
6900
6902
|
}
|
|
6903
|
+
/**
|
|
6904
|
+
- \p{L} is for any letter (from any language)
|
|
6905
|
+
- \p{N} is for any number
|
|
6906
|
+
- the u flag at the end is for unicode, which enables the `\p{...}` syntax
|
|
6907
|
+
*/
|
|
6908
|
+
const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
|
|
6901
6909
|
const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
|
|
6902
6910
|
/**
|
|
6903
6911
|
* A "Symbol" is just basically any word-like element that can appear in a
|
|
@@ -6938,7 +6946,8 @@ function tokenizeSymbol(chars) {
|
|
|
6938
6946
|
};
|
|
6939
6947
|
}
|
|
6940
6948
|
}
|
|
6941
|
-
while (chars.current &&
|
|
6949
|
+
while (chars.current &&
|
|
6950
|
+
(SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
|
|
6942
6951
|
result += chars.shift();
|
|
6943
6952
|
}
|
|
6944
6953
|
if (result.length) {
|
|
@@ -9245,7 +9254,7 @@ function transformZone(zone, executed) {
|
|
|
9245
9254
|
if (executed.type === "ADD_COLUMNS_ROWS") {
|
|
9246
9255
|
return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
|
|
9247
9256
|
}
|
|
9248
|
-
return
|
|
9257
|
+
return zone;
|
|
9249
9258
|
}
|
|
9250
9259
|
function transformRangeData(range, executed) {
|
|
9251
9260
|
const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
|
|
@@ -13743,7 +13752,7 @@ const RANK = {
|
|
|
13743
13752
|
}
|
|
13744
13753
|
}
|
|
13745
13754
|
if (!found) {
|
|
13746
|
-
|
|
13755
|
+
return new NotAvailableError(_t("Value not found in the given data."));
|
|
13747
13756
|
}
|
|
13748
13757
|
return rank;
|
|
13749
13758
|
},
|
|
@@ -15483,7 +15492,7 @@ const UNIQUE = {
|
|
|
15483
15492
|
result.push(row.data);
|
|
15484
15493
|
}
|
|
15485
15494
|
if (!result.length)
|
|
15486
|
-
|
|
15495
|
+
return new EvaluationError(_t("No unique values found"));
|
|
15487
15496
|
return _byColumn ? result : transposeMatrix(result);
|
|
15488
15497
|
},
|
|
15489
15498
|
isExported: true,
|
|
@@ -19262,7 +19271,7 @@ const OFFSET = {
|
|
|
19262
19271
|
}
|
|
19263
19272
|
const _cellReference = cellReference?.value;
|
|
19264
19273
|
if (!_cellReference) {
|
|
19265
|
-
|
|
19274
|
+
return new EvaluationError("In this context, the function OFFSET needs to have a cell or range in parameter.");
|
|
19266
19275
|
}
|
|
19267
19276
|
const zone = toZone(_cellReference);
|
|
19268
19277
|
let offsetHeight = zone.bottom - zone.top + 1;
|
|
@@ -33636,6 +33645,12 @@ function isMacOS() {
|
|
|
33636
33645
|
function isCtrlKey(ev) {
|
|
33637
33646
|
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
33638
33647
|
}
|
|
33648
|
+
/**
|
|
33649
|
+
* Detects if the current browser is Firefox
|
|
33650
|
+
*/
|
|
33651
|
+
function isBrowserFirefox() {
|
|
33652
|
+
return /Firefox/i.test(navigator.userAgent);
|
|
33653
|
+
}
|
|
33639
33654
|
|
|
33640
33655
|
/**
|
|
33641
33656
|
* Repeatedly calls a callback function with a time delay between calls.
|
|
@@ -39102,7 +39117,7 @@ class ColorPicker extends Component {
|
|
|
39102
39117
|
}
|
|
39103
39118
|
setHexColor(ev) {
|
|
39104
39119
|
// only support HEX code input
|
|
39105
|
-
const val = ev.target.value.slice(0, 7);
|
|
39120
|
+
const val = ev.target.value.replace("##", "#").slice(0, 7);
|
|
39106
39121
|
this.state.customHexColor = val;
|
|
39107
39122
|
if (!isColorValid(val)) ;
|
|
39108
39123
|
else {
|
|
@@ -50431,39 +50446,6 @@ function useCellHovered(env, gridRef, callback) {
|
|
|
50431
50446
|
}
|
|
50432
50447
|
return hoveredPosition;
|
|
50433
50448
|
}
|
|
50434
|
-
function useTouchMove(gridRef, handler, canMoveUp) {
|
|
50435
|
-
let x = null;
|
|
50436
|
-
let y = null;
|
|
50437
|
-
function onTouchStart(ev) {
|
|
50438
|
-
if (ev.touches.length !== 1)
|
|
50439
|
-
return;
|
|
50440
|
-
x = ev.touches[0].clientX;
|
|
50441
|
-
y = ev.touches[0].clientY;
|
|
50442
|
-
}
|
|
50443
|
-
function onTouchEnd() {
|
|
50444
|
-
x = null;
|
|
50445
|
-
y = null;
|
|
50446
|
-
}
|
|
50447
|
-
function onTouchMove(ev) {
|
|
50448
|
-
if (ev.touches.length !== 1)
|
|
50449
|
-
return;
|
|
50450
|
-
// On mobile browsers, swiping down is often associated with "pull to refresh".
|
|
50451
|
-
// We only want this behavior if the grid is already at the top.
|
|
50452
|
-
// Otherwise we only want to move the canvas up, without triggering any refresh.
|
|
50453
|
-
if (canMoveUp()) {
|
|
50454
|
-
ev.preventDefault();
|
|
50455
|
-
ev.stopPropagation();
|
|
50456
|
-
}
|
|
50457
|
-
const currentX = ev.touches[0].clientX;
|
|
50458
|
-
const currentY = ev.touches[0].clientY;
|
|
50459
|
-
handler(x - currentX, y - currentY);
|
|
50460
|
-
x = currentX;
|
|
50461
|
-
y = currentY;
|
|
50462
|
-
}
|
|
50463
|
-
useRefListener(gridRef, "touchstart", onTouchStart);
|
|
50464
|
-
useRefListener(gridRef, "touchend", onTouchEnd);
|
|
50465
|
-
useRefListener(gridRef, "touchmove", onTouchMove);
|
|
50466
|
-
}
|
|
50467
50449
|
class GridOverlay extends Component {
|
|
50468
50450
|
static template = "o-spreadsheet-GridOverlay";
|
|
50469
50451
|
static props = {
|
|
@@ -50511,10 +50493,6 @@ class GridOverlay extends Component {
|
|
|
50511
50493
|
onWillUnmount(() => {
|
|
50512
50494
|
resizeObserver.disconnect();
|
|
50513
50495
|
});
|
|
50514
|
-
useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
|
|
50515
|
-
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
50516
|
-
return scrollY > 0;
|
|
50517
|
-
});
|
|
50518
50496
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
50519
50497
|
this.paintFormatStore = useStore(PaintFormatStore);
|
|
50520
50498
|
}
|
|
@@ -51986,6 +51964,73 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51986
51964
|
}
|
|
51987
51965
|
}
|
|
51988
51966
|
|
|
51967
|
+
const friction = 0.95;
|
|
51968
|
+
const verticalScrollFactor = 1;
|
|
51969
|
+
const horizontalScrollFactor = 1;
|
|
51970
|
+
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
51971
|
+
let lastX = 0;
|
|
51972
|
+
let lastY = 0;
|
|
51973
|
+
let velocityX = 0;
|
|
51974
|
+
let velocityY = 0;
|
|
51975
|
+
let isMouseDown = false;
|
|
51976
|
+
let lastTime = 0;
|
|
51977
|
+
useRefListener(ref, "touchstart", onTouchStart, { capture: false });
|
|
51978
|
+
useRefListener(ref, "touchmove", onTouchMove, { capture: false });
|
|
51979
|
+
useRefListener(ref, "touchend", onTouchEnd, { capture: false });
|
|
51980
|
+
function onTouchStart(event) {
|
|
51981
|
+
isMouseDown = true;
|
|
51982
|
+
({ clientX: lastX, clientY: lastY } = event.touches[0]);
|
|
51983
|
+
velocityX = 0;
|
|
51984
|
+
velocityY = 0;
|
|
51985
|
+
}
|
|
51986
|
+
function onTouchMove(event) {
|
|
51987
|
+
if (!isMouseDown)
|
|
51988
|
+
return;
|
|
51989
|
+
const currentTime = Date.now();
|
|
51990
|
+
const { clientX, clientY } = event.touches[0];
|
|
51991
|
+
let deltaX = lastX - clientX;
|
|
51992
|
+
let deltaY = lastY - clientY;
|
|
51993
|
+
const elapsedTime = currentTime - lastTime;
|
|
51994
|
+
velocityX = deltaX / elapsedTime;
|
|
51995
|
+
velocityY = deltaY / elapsedTime;
|
|
51996
|
+
lastX = clientX;
|
|
51997
|
+
lastY = clientY;
|
|
51998
|
+
lastTime = currentTime;
|
|
51999
|
+
if (canMoveUp()) {
|
|
52000
|
+
if (event.cancelable) {
|
|
52001
|
+
event.preventDefault();
|
|
52002
|
+
}
|
|
52003
|
+
event.stopPropagation();
|
|
52004
|
+
}
|
|
52005
|
+
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
52006
|
+
}
|
|
52007
|
+
function onTouchEnd(ev) {
|
|
52008
|
+
isMouseDown = false;
|
|
52009
|
+
lastX = lastY = 0;
|
|
52010
|
+
requestAnimationFrame(scroll);
|
|
52011
|
+
}
|
|
52012
|
+
function scroll() {
|
|
52013
|
+
if (Math.abs(velocityX) < 0.05) {
|
|
52014
|
+
velocityX = 0;
|
|
52015
|
+
}
|
|
52016
|
+
if (Math.abs(velocityY) < 0.05) {
|
|
52017
|
+
velocityY = 0;
|
|
52018
|
+
}
|
|
52019
|
+
if (!velocityX && !velocityY) {
|
|
52020
|
+
return;
|
|
52021
|
+
}
|
|
52022
|
+
const currentTime = Date.now();
|
|
52023
|
+
const elapsedTime = Math.abs(currentTime - lastTime);
|
|
52024
|
+
const deltaX = velocityX * elapsedTime;
|
|
52025
|
+
const deltaY = velocityY * elapsedTime;
|
|
52026
|
+
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
52027
|
+
lastTime = currentTime;
|
|
52028
|
+
velocityX *= friction;
|
|
52029
|
+
velocityY *= friction;
|
|
52030
|
+
requestAnimationFrame(scroll);
|
|
52031
|
+
}
|
|
52032
|
+
}
|
|
52033
|
+
|
|
51989
52034
|
function useWheelHandler(handler) {
|
|
51990
52035
|
function normalize(val, deltaMode) {
|
|
51991
52036
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
@@ -52326,7 +52371,7 @@ class HorizontalScrollBar extends Component {
|
|
|
52326
52371
|
left: `${this.props.leftOffset + x}px`,
|
|
52327
52372
|
bottom: "0px",
|
|
52328
52373
|
height: `${SCROLLBAR_WIDTH}px`,
|
|
52329
|
-
right: `
|
|
52374
|
+
right: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
|
|
52330
52375
|
};
|
|
52331
52376
|
}
|
|
52332
52377
|
onScroll(offset) {
|
|
@@ -52371,7 +52416,7 @@ class VerticalScrollBar extends Component {
|
|
|
52371
52416
|
top: `${this.props.topOffset + y}px`,
|
|
52372
52417
|
right: "0px",
|
|
52373
52418
|
width: `${SCROLLBAR_WIDTH}px`,
|
|
52374
|
-
bottom: `
|
|
52419
|
+
bottom: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
|
|
52375
52420
|
};
|
|
52376
52421
|
}
|
|
52377
52422
|
onScroll(offset) {
|
|
@@ -52607,6 +52652,10 @@ class Grid extends Component {
|
|
|
52607
52652
|
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
52608
52653
|
}
|
|
52609
52654
|
}, () => [this.sidePanel.isOpen]);
|
|
52655
|
+
useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
|
|
52656
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
52657
|
+
return scrollY > 0;
|
|
52658
|
+
});
|
|
52610
52659
|
}
|
|
52611
52660
|
onCellHovered({ col, row }) {
|
|
52612
52661
|
this.hoveredCell.hover({ col, row });
|
|
@@ -62286,6 +62335,16 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
62286
62335
|
}
|
|
62287
62336
|
return values;
|
|
62288
62337
|
}
|
|
62338
|
+
else if (rowDomain.length === this.definition.rows.length &&
|
|
62339
|
+
colDomain.length &&
|
|
62340
|
+
colDomain.length < this.definition.columns.length) {
|
|
62341
|
+
const colSubTree = this.getSubTreeMatchingDomain(table.getColTree(), colDomain);
|
|
62342
|
+
const domains = this.treeToLeafDomains(colSubTree, colDomain);
|
|
62343
|
+
for (const domain of domains) {
|
|
62344
|
+
values.push(this._getPivotCellValueAndFormat(measure.id, rowDomain.concat(domain)));
|
|
62345
|
+
}
|
|
62346
|
+
return values;
|
|
62347
|
+
}
|
|
62289
62348
|
else {
|
|
62290
62349
|
const tree = table.getRowTree();
|
|
62291
62350
|
const subTree = this.getSubTreeMatchingDomain(tree, rowDomain);
|
|
@@ -63852,10 +63911,8 @@ function mergeTransformation(toTransform, executed) {
|
|
|
63852
63911
|
}
|
|
63853
63912
|
const target = [];
|
|
63854
63913
|
for (const zone1 of toTransform.target) {
|
|
63855
|
-
|
|
63856
|
-
|
|
63857
|
-
target.push({ ...zone1 });
|
|
63858
|
-
}
|
|
63914
|
+
if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
|
|
63915
|
+
target.push(zone1);
|
|
63859
63916
|
}
|
|
63860
63917
|
}
|
|
63861
63918
|
if (target.length) {
|
|
@@ -67987,24 +68044,14 @@ class InternalViewport {
|
|
|
67987
68044
|
first: this.boundaries.top,
|
|
67988
68045
|
last: this.boundaries.bottom,
|
|
67989
68046
|
});
|
|
67990
|
-
const { end: lastColEnd
|
|
67991
|
-
const { end: lastRowEnd
|
|
67992
|
-
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
|
|
67993
|
-
const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
|
|
67994
|
-
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
|
|
67995
|
-
const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
|
|
68047
|
+
const { end: lastColEnd } = this.getters.getColDimensions(this.sheetId, lastCol);
|
|
68048
|
+
const { end: lastRowEnd } = this.getters.getRowDimensions(this.sheetId, lastRow);
|
|
67996
68049
|
let width = lastColEnd - this.offsetCorrectionX;
|
|
67997
68050
|
if (this.canScrollHorizontally) {
|
|
67998
|
-
width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
|
|
67999
|
-
Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
|
|
68000
|
-
);
|
|
68001
68051
|
width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
|
|
68002
68052
|
}
|
|
68003
68053
|
let height = lastRowEnd - this.offsetCorrectionY;
|
|
68004
68054
|
if (this.canScrollVertically) {
|
|
68005
|
-
height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
|
|
68006
|
-
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
68007
|
-
);
|
|
68008
68055
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
68009
68056
|
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
68010
68057
|
height += FOOTER_HEIGHT;
|
|
@@ -68569,8 +68616,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68569
68616
|
const { width, height } = this.getMainViewportRect();
|
|
68570
68617
|
const viewport = this.getMainInternalViewport(sheetId);
|
|
68571
68618
|
return {
|
|
68572
|
-
maxOffsetX: Math.max(0, width - viewport.viewportWidth
|
|
68573
|
-
maxOffsetY: Math.max(0, height - viewport.viewportHeight
|
|
68619
|
+
maxOffsetX: Math.max(0, width - viewport.viewportWidth),
|
|
68620
|
+
maxOffsetY: Math.max(0, height - viewport.viewportHeight),
|
|
68574
68621
|
};
|
|
68575
68622
|
}
|
|
68576
68623
|
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
@@ -70092,6 +70139,10 @@ class SpreadsheetDashboard extends Component {
|
|
|
70092
70139
|
this.hoveredCell.clear();
|
|
70093
70140
|
});
|
|
70094
70141
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
70142
|
+
useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
|
|
70143
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
70144
|
+
return scrollY > 0;
|
|
70145
|
+
});
|
|
70095
70146
|
}
|
|
70096
70147
|
onCellHovered({ col, row }) {
|
|
70097
70148
|
this.hoveredCell.hover({ col, row });
|
|
@@ -71482,6 +71533,7 @@ css /* scss */ `
|
|
|
71482
71533
|
> canvas {
|
|
71483
71534
|
box-sizing: content-box;
|
|
71484
71535
|
border-bottom: 1px solid #e2e3e3;
|
|
71536
|
+
border-right: 1px solid #e2e3e3;
|
|
71485
71537
|
}
|
|
71486
71538
|
|
|
71487
71539
|
.o-grid-overlay {
|
|
@@ -76143,6 +76195,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
76143
76195
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
76144
76196
|
|
|
76145
76197
|
|
|
76146
|
-
__info__.version = "18.2.
|
|
76147
|
-
__info__.date = "2025-04-
|
|
76148
|
-
__info__.hash = "
|
|
76198
|
+
__info__.version = "18.2.9";
|
|
76199
|
+
__info__.date = "2025-04-25T08:06:52.677Z";
|
|
76200
|
+
__info__.hash = "3e88645";
|