@odoo/o-spreadsheet 17.0.50 → 17.0.52
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 +252 -157
- package/dist/o-spreadsheet.d.ts +8 -4
- package/dist/o-spreadsheet.esm.js +252 -157
- package/dist/o-spreadsheet.iife.js +252 -157
- package/dist/o-spreadsheet.iife.min.js +272 -254
- package/dist/o_spreadsheet.xml +48 -36
- package/package.json +2 -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 17.0.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.52
|
|
6
|
+
* @date 2025-03-07T10:30:04.783Z
|
|
7
|
+
* @hash c19cd9a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -4732,11 +4732,12 @@
|
|
|
4732
4732
|
if (this.isFastIdStrategy) {
|
|
4733
4733
|
this.fastIdStart++;
|
|
4734
4734
|
return String(this.fastIdStart);
|
|
4735
|
-
//@ts-ignore
|
|
4736
4735
|
}
|
|
4737
|
-
else if (window.crypto
|
|
4738
|
-
|
|
4739
|
-
|
|
4736
|
+
else if (window.crypto) {
|
|
4737
|
+
return "10000000-1000".replace(/[01]/g, (c) => {
|
|
4738
|
+
const n = Number(c);
|
|
4739
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
4740
|
+
});
|
|
4740
4741
|
}
|
|
4741
4742
|
else {
|
|
4742
4743
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -4754,11 +4755,12 @@
|
|
|
4754
4755
|
if (this.isFastIdStrategy) {
|
|
4755
4756
|
this.fastIdStart++;
|
|
4756
4757
|
return String(this.fastIdStart);
|
|
4757
|
-
//@ts-ignore
|
|
4758
4758
|
}
|
|
4759
|
-
else if (window.crypto
|
|
4760
|
-
|
|
4761
|
-
|
|
4759
|
+
else if (window.crypto) {
|
|
4760
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
4761
|
+
const n = Number(c);
|
|
4762
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
4763
|
+
});
|
|
4762
4764
|
}
|
|
4763
4765
|
else {
|
|
4764
4766
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -6211,7 +6213,7 @@
|
|
|
6211
6213
|
condition: (cell) => !cell.isFormula &&
|
|
6212
6214
|
evaluateLiteral(cell.content, { locale: DEFAULT_LOCALE }).type === CellValueType.text &&
|
|
6213
6215
|
alphaNumericValueRegExp.test(cell.content),
|
|
6214
|
-
generateRule: (cell, cells) => {
|
|
6216
|
+
generateRule: (cell, cells, direction) => {
|
|
6215
6217
|
const numberPostfix = parseInt(cell.content.match(numberPostfixRegExp)[0]);
|
|
6216
6218
|
const prefix = cell.content.match(stringPrefixRegExp)[0];
|
|
6217
6219
|
const numberPostfixLength = cell.content.length - prefix.length;
|
|
@@ -6219,7 +6221,10 @@
|
|
|
6219
6221
|
alphaNumericValueRegExp.test(evaluatedCell.value)) // get consecutive alphanumeric cells, no matter what the prefix is
|
|
6220
6222
|
.filter((cell) => prefix === cell.value.toString().match(stringPrefixRegExp)[0])
|
|
6221
6223
|
.map((cell) => parseInt(cell.value.toString().match(numberPostfixRegExp)[0]));
|
|
6222
|
-
|
|
6224
|
+
let increment = calculateIncrementBasedOnGroup(group);
|
|
6225
|
+
if (["up", "left"].includes(direction) && group.length === 1) {
|
|
6226
|
+
increment = -increment;
|
|
6227
|
+
}
|
|
6223
6228
|
return {
|
|
6224
6229
|
type: "ALPHANUMERIC_INCREMENT_MODIFIER",
|
|
6225
6230
|
prefix,
|
|
@@ -6248,9 +6253,12 @@
|
|
|
6248
6253
|
.add("increment_number", {
|
|
6249
6254
|
condition: (cell) => !cell.isFormula &&
|
|
6250
6255
|
evaluateLiteral(cell.content, { locale: DEFAULT_LOCALE }).type === CellValueType.number,
|
|
6251
|
-
generateRule: (cell, cells) => {
|
|
6256
|
+
generateRule: (cell, cells, direction) => {
|
|
6252
6257
|
const group = getGroup(cell, cells, (evaluatedCell) => evaluatedCell.type === CellValueType.number).map((cell) => Number(cell.value));
|
|
6253
|
-
|
|
6258
|
+
let increment = calculateIncrementBasedOnGroup(group);
|
|
6259
|
+
if (["up", "left"].includes(direction) && group.length === 1) {
|
|
6260
|
+
increment = -increment;
|
|
6261
|
+
}
|
|
6254
6262
|
const evaluation = evaluateLiteral(cell.content, { locale: DEFAULT_LOCALE });
|
|
6255
6263
|
return {
|
|
6256
6264
|
type: "INCREMENT_MODIFIER",
|
|
@@ -6984,10 +6992,6 @@
|
|
|
6984
6992
|
this.currentDisplayValue = newDisplay;
|
|
6985
6993
|
if (!anchor)
|
|
6986
6994
|
return;
|
|
6987
|
-
el.style.top = "";
|
|
6988
|
-
el.style.left = "";
|
|
6989
|
-
el.style["max-height"] = "";
|
|
6990
|
-
el.style["max-width"] = "";
|
|
6991
6995
|
const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
|
|
6992
6996
|
let elDims = {
|
|
6993
6997
|
width: el.getBoundingClientRect().width,
|
|
@@ -9729,7 +9733,7 @@
|
|
|
9729
9733
|
const dataset = {
|
|
9730
9734
|
label,
|
|
9731
9735
|
data,
|
|
9732
|
-
borderColor: "#FFFFFF",
|
|
9736
|
+
borderColor: chart.background || "#FFFFFF",
|
|
9733
9737
|
backgroundColor,
|
|
9734
9738
|
};
|
|
9735
9739
|
config.data.datasets.push(dataset);
|
|
@@ -26761,25 +26765,21 @@
|
|
|
26761
26765
|
}
|
|
26762
26766
|
}
|
|
26763
26767
|
}
|
|
26768
|
+
}
|
|
26769
|
+
.o-spreadsheet .o-composer-assistant {
|
|
26770
|
+
pointer-events: none;
|
|
26764
26771
|
|
|
26765
|
-
.o-
|
|
26766
|
-
|
|
26767
|
-
|
|
26768
|
-
|
|
26769
|
-
|
|
26770
|
-
|
|
26771
|
-
.o-semi-bold {
|
|
26772
|
-
/** FIXME: to remove in favor of Bootstrap
|
|
26773
|
-
* 'fw-semibold' when we upgrade to Bootstrap 5.2
|
|
26774
|
-
*/
|
|
26775
|
-
font-weight: 600 !important;
|
|
26776
|
-
}
|
|
26772
|
+
.o-semi-bold {
|
|
26773
|
+
/** FIXME: to remove in favor of Bootstrap
|
|
26774
|
+
* 'fw-semibold' when we upgrade to Bootstrap 5.2
|
|
26775
|
+
*/
|
|
26776
|
+
font-weight: 600 !important;
|
|
26777
26777
|
}
|
|
26778
26778
|
}
|
|
26779
26779
|
`;
|
|
26780
26780
|
class Composer extends owl.Component {
|
|
26781
26781
|
static template = "o-spreadsheet-Composer";
|
|
26782
|
-
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
26782
|
+
static components = { TextValueProvider, FunctionDescriptionProvider, Popover };
|
|
26783
26783
|
static defaultProps = {
|
|
26784
26784
|
inputStyle: "",
|
|
26785
26785
|
isDefaultFocus: false,
|
|
@@ -26804,35 +26804,13 @@
|
|
|
26804
26804
|
argToFocus: 0,
|
|
26805
26805
|
});
|
|
26806
26806
|
compositionActive = false;
|
|
26807
|
-
spreadsheetRect = useSpreadsheetRect();
|
|
26808
26807
|
get assistantStyle() {
|
|
26809
|
-
const composerRect = this.composerRef.el.getBoundingClientRect();
|
|
26810
26808
|
const assistantStyle = {};
|
|
26811
|
-
|
|
26809
|
+
const minWidth = Math.min(getBoundingRectAsPOJO(this.composerRef.el).width || Infinity, ASSISTANT_WIDTH);
|
|
26810
|
+
assistantStyle["min-width"] = `${minWidth}px`;
|
|
26812
26811
|
if (this.autoCompleteState.type === "function") {
|
|
26813
26812
|
assistantStyle.width = `${ASSISTANT_WIDTH}px`;
|
|
26814
26813
|
}
|
|
26815
|
-
if (this.props.delimitation && this.props.rect) {
|
|
26816
|
-
const { x: cellX, y: cellY, height: cellHeight } = this.props.rect;
|
|
26817
|
-
const remainingHeight = this.props.delimitation.height - (cellY + cellHeight);
|
|
26818
|
-
assistantStyle["max-height"] = `${remainingHeight}px`;
|
|
26819
|
-
if (cellY > remainingHeight) {
|
|
26820
|
-
const availableSpaceAbove = cellY;
|
|
26821
|
-
assistantStyle["max-height"] = `${availableSpaceAbove}px`;
|
|
26822
|
-
// render top
|
|
26823
|
-
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
26824
|
-
assistantStyle.top = `-3px`;
|
|
26825
|
-
assistantStyle.transform = `translate(0, -100%)`;
|
|
26826
|
-
}
|
|
26827
|
-
if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
|
|
26828
|
-
// render left
|
|
26829
|
-
assistantStyle.right = `0px`;
|
|
26830
|
-
}
|
|
26831
|
-
}
|
|
26832
|
-
if (this.props.focus === "contentFocus" &&
|
|
26833
|
-
composerRect.left + ASSISTANT_WIDTH > this.spreadsheetRect.width) {
|
|
26834
|
-
assistantStyle.right = "0px";
|
|
26835
|
-
}
|
|
26836
26814
|
return cssPropertiesToCss(assistantStyle);
|
|
26837
26815
|
}
|
|
26838
26816
|
// we can't allow input events to be triggered while we remove and add back the content of the composer in processContent
|
|
@@ -27081,7 +27059,7 @@
|
|
|
27081
27059
|
this.autoCompleteState.selectedIndex = 0;
|
|
27082
27060
|
}
|
|
27083
27061
|
updateAutoCompleteIndex(index) {
|
|
27084
|
-
this.autoCompleteState.selectedIndex =
|
|
27062
|
+
this.autoCompleteState.selectedIndex = index;
|
|
27085
27063
|
}
|
|
27086
27064
|
/**
|
|
27087
27065
|
* This is required to ensure the content helper selection is
|
|
@@ -27369,11 +27347,16 @@
|
|
|
27369
27347
|
this.autoCompleteState.values = values.map((value) => ({ text: value, description: "" }));
|
|
27370
27348
|
this.autoCompleteState.getHtmlContent = (value) => [{ value }];
|
|
27371
27349
|
}
|
|
27350
|
+
get popoverProps() {
|
|
27351
|
+
return {
|
|
27352
|
+
anchorRect: getBoundingRectAsPOJO(this.composerRef.el),
|
|
27353
|
+
positioning: "BottomLeft",
|
|
27354
|
+
verticalOffset: 0,
|
|
27355
|
+
};
|
|
27356
|
+
}
|
|
27372
27357
|
}
|
|
27373
27358
|
Composer.props = {
|
|
27374
27359
|
inputStyle: { type: String, optional: true },
|
|
27375
|
-
rect: { type: Object, optional: true },
|
|
27376
|
-
delimitation: { type: Object, optional: true },
|
|
27377
27360
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
27378
27361
|
onComposerCellFocused: { type: Function, optional: true },
|
|
27379
27362
|
onComposerContentFocused: Function,
|
|
@@ -27443,13 +27426,7 @@
|
|
|
27443
27426
|
});
|
|
27444
27427
|
}
|
|
27445
27428
|
get composerProps() {
|
|
27446
|
-
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
27447
27429
|
return {
|
|
27448
|
-
rect: { ...this.rect },
|
|
27449
|
-
delimitation: {
|
|
27450
|
-
width,
|
|
27451
|
-
height,
|
|
27452
|
-
},
|
|
27453
27430
|
focus: this.props.focus,
|
|
27454
27431
|
isDefaultFocus: true,
|
|
27455
27432
|
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
@@ -28991,6 +28968,9 @@
|
|
|
28991
28968
|
this.MAX_SIZE_MARGIN = 90;
|
|
28992
28969
|
this.MIN_ELEMENT_SIZE = MIN_COL_WIDTH;
|
|
28993
28970
|
}
|
|
28971
|
+
get sheetId() {
|
|
28972
|
+
return this.env.model.getters.getActiveSheetId();
|
|
28973
|
+
}
|
|
28994
28974
|
_getEvOffset(ev) {
|
|
28995
28975
|
return ev.offsetX;
|
|
28996
28976
|
}
|
|
@@ -29013,10 +28993,10 @@
|
|
|
29013
28993
|
return this.env.model.getters.getEdgeScrollCol(position, position, position);
|
|
29014
28994
|
}
|
|
29015
28995
|
_getDimensionsInViewport(index) {
|
|
29016
|
-
return this.env.model.getters.getColDimensionsInViewport(this.
|
|
28996
|
+
return this.env.model.getters.getColDimensionsInViewport(this.sheetId, index);
|
|
29017
28997
|
}
|
|
29018
28998
|
_getElementSize(index) {
|
|
29019
|
-
return this.env.model.getters.getColSize(this.
|
|
28999
|
+
return this.env.model.getters.getColSize(this.sheetId, index);
|
|
29020
29000
|
}
|
|
29021
29001
|
_getMaxSize() {
|
|
29022
29002
|
return this.colResizerRef.el.clientWidth;
|
|
@@ -29027,7 +29007,7 @@
|
|
|
29027
29007
|
const cols = this.env.model.getters.getActiveCols();
|
|
29028
29008
|
this.env.model.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
29029
29009
|
dimension: "COL",
|
|
29030
|
-
sheetId: this.
|
|
29010
|
+
sheetId: this.sheetId,
|
|
29031
29011
|
elements: cols.has(index) ? [...cols] : [index],
|
|
29032
29012
|
size,
|
|
29033
29013
|
});
|
|
@@ -29040,7 +29020,7 @@
|
|
|
29040
29020
|
elements.push(colIndex);
|
|
29041
29021
|
}
|
|
29042
29022
|
const result = this.env.model.dispatch("MOVE_COLUMNS_ROWS", {
|
|
29043
|
-
sheetId: this.
|
|
29023
|
+
sheetId: this.sheetId,
|
|
29044
29024
|
dimension: "COL",
|
|
29045
29025
|
base: this.state.base,
|
|
29046
29026
|
elements,
|
|
@@ -29059,7 +29039,7 @@
|
|
|
29059
29039
|
_fitElementSize(index) {
|
|
29060
29040
|
const cols = this.env.model.getters.getActiveCols();
|
|
29061
29041
|
this.env.model.dispatch("AUTORESIZE_COLUMNS", {
|
|
29062
|
-
sheetId: this.
|
|
29042
|
+
sheetId: this.sheetId,
|
|
29063
29043
|
cols: cols.has(index) ? [...cols] : [index],
|
|
29064
29044
|
});
|
|
29065
29045
|
}
|
|
@@ -29070,7 +29050,7 @@
|
|
|
29070
29050
|
return this.env.model.getters.getActiveCols();
|
|
29071
29051
|
}
|
|
29072
29052
|
_getPreviousVisibleElement(index) {
|
|
29073
|
-
const sheetId = this.
|
|
29053
|
+
const sheetId = this.sheetId;
|
|
29074
29054
|
let row;
|
|
29075
29055
|
for (row = index - 1; row >= 0; row--) {
|
|
29076
29056
|
if (!this.env.model.getters.isColHidden(sheetId, row)) {
|
|
@@ -29081,7 +29061,7 @@
|
|
|
29081
29061
|
}
|
|
29082
29062
|
unhide(hiddenElements) {
|
|
29083
29063
|
this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
|
|
29084
|
-
sheetId: this.
|
|
29064
|
+
sheetId: this.sheetId,
|
|
29085
29065
|
elements: hiddenElements,
|
|
29086
29066
|
dimension: "COL",
|
|
29087
29067
|
});
|
|
@@ -29097,7 +29077,7 @@
|
|
|
29097
29077
|
left: 0;
|
|
29098
29078
|
right: 0;
|
|
29099
29079
|
width: ${HEADER_WIDTH}px;
|
|
29100
|
-
height: 100
|
|
29080
|
+
height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
|
|
29101
29081
|
&.o-dragging {
|
|
29102
29082
|
cursor: grabbing;
|
|
29103
29083
|
}
|
|
@@ -29165,6 +29145,9 @@
|
|
|
29165
29145
|
this.MIN_ELEMENT_SIZE = MIN_ROW_HEIGHT;
|
|
29166
29146
|
}
|
|
29167
29147
|
rowResizerRef;
|
|
29148
|
+
get sheetId() {
|
|
29149
|
+
return this.env.model.getters.getActiveSheetId();
|
|
29150
|
+
}
|
|
29168
29151
|
_getEvOffset(ev) {
|
|
29169
29152
|
return ev.offsetY;
|
|
29170
29153
|
}
|
|
@@ -29187,10 +29170,10 @@
|
|
|
29187
29170
|
return this.env.model.getters.getEdgeScrollRow(position, position, position);
|
|
29188
29171
|
}
|
|
29189
29172
|
_getDimensionsInViewport(index) {
|
|
29190
|
-
return this.env.model.getters.getRowDimensionsInViewport(this.
|
|
29173
|
+
return this.env.model.getters.getRowDimensionsInViewport(this.sheetId, index);
|
|
29191
29174
|
}
|
|
29192
29175
|
_getElementSize(index) {
|
|
29193
|
-
return this.env.model.getters.getRowSize(this.
|
|
29176
|
+
return this.env.model.getters.getRowSize(this.sheetId, index);
|
|
29194
29177
|
}
|
|
29195
29178
|
_getMaxSize() {
|
|
29196
29179
|
return this.rowResizerRef.el.clientHeight;
|
|
@@ -29201,7 +29184,7 @@
|
|
|
29201
29184
|
const rows = this.env.model.getters.getActiveRows();
|
|
29202
29185
|
this.env.model.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
29203
29186
|
dimension: "ROW",
|
|
29204
|
-
sheetId: this.
|
|
29187
|
+
sheetId: this.sheetId,
|
|
29205
29188
|
elements: rows.has(index) ? [...rows] : [index],
|
|
29206
29189
|
size,
|
|
29207
29190
|
});
|
|
@@ -29214,7 +29197,7 @@
|
|
|
29214
29197
|
elements.push(rowIndex);
|
|
29215
29198
|
}
|
|
29216
29199
|
const result = this.env.model.dispatch("MOVE_COLUMNS_ROWS", {
|
|
29217
|
-
sheetId: this.
|
|
29200
|
+
sheetId: this.sheetId,
|
|
29218
29201
|
dimension: "ROW",
|
|
29219
29202
|
base: this.state.base,
|
|
29220
29203
|
elements,
|
|
@@ -29233,7 +29216,7 @@
|
|
|
29233
29216
|
_fitElementSize(index) {
|
|
29234
29217
|
const rows = this.env.model.getters.getActiveRows();
|
|
29235
29218
|
this.env.model.dispatch("AUTORESIZE_ROWS", {
|
|
29236
|
-
sheetId: this.
|
|
29219
|
+
sheetId: this.sheetId,
|
|
29237
29220
|
rows: rows.has(index) ? [...rows] : [index],
|
|
29238
29221
|
});
|
|
29239
29222
|
}
|
|
@@ -29244,7 +29227,7 @@
|
|
|
29244
29227
|
return this.env.model.getters.getActiveRows();
|
|
29245
29228
|
}
|
|
29246
29229
|
_getPreviousVisibleElement(index) {
|
|
29247
|
-
const sheetId = this.
|
|
29230
|
+
const sheetId = this.sheetId;
|
|
29248
29231
|
let row;
|
|
29249
29232
|
for (row = index - 1; row >= 0; row--) {
|
|
29250
29233
|
if (!this.env.model.getters.isRowHidden(sheetId, row)) {
|
|
@@ -29255,7 +29238,7 @@
|
|
|
29255
29238
|
}
|
|
29256
29239
|
unhide(hiddenElements) {
|
|
29257
29240
|
this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
|
|
29258
|
-
sheetId: this.
|
|
29241
|
+
sheetId: this.sheetId,
|
|
29259
29242
|
dimension: "ROW",
|
|
29260
29243
|
elements: hiddenElements,
|
|
29261
29244
|
});
|
|
@@ -30400,6 +30383,7 @@
|
|
|
30400
30383
|
const CONTENT_TYPES = {
|
|
30401
30384
|
workbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
|
|
30402
30385
|
sheet: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
|
|
30386
|
+
metadata: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
|
|
30403
30387
|
sharedStrings: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
|
|
30404
30388
|
styles: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
|
30405
30389
|
drawing: "application/vnd.openxmlformats-officedocument.drawing+xml",
|
|
@@ -30412,6 +30396,7 @@
|
|
|
30412
30396
|
const XLSX_RELATION_TYPE = {
|
|
30413
30397
|
document: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
|
|
30414
30398
|
sheet: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
|
|
30399
|
+
metadata: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
|
|
30415
30400
|
sharedStrings: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
|
|
30416
30401
|
styles: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
|
|
30417
30402
|
drawing: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
|
|
@@ -30421,6 +30406,7 @@
|
|
|
30421
30406
|
hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
|
30422
30407
|
image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
|
30423
30408
|
};
|
|
30409
|
+
const ARRAY_FORMULA_URI = "bdbb8cdc-fa1e-496e-a857-3c3f30c029c3";
|
|
30424
30410
|
const RELATIONSHIP_NSR = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
30425
30411
|
const HEIGHT_FACTOR = 0.75; // 100px => 75 u
|
|
30426
30412
|
/**
|
|
@@ -32250,29 +32236,33 @@
|
|
|
32250
32236
|
* In all the sheets, replace the table-only references in the formula cells with standard references.
|
|
32251
32237
|
*/
|
|
32252
32238
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
32253
|
-
for (let
|
|
32254
|
-
const tables = xlsxSheets.find((s) => s.sheetName ===
|
|
32239
|
+
for (let tableSheet of convertedSheets) {
|
|
32240
|
+
const tables = xlsxSheets.find((s) => s.sheetName === tableSheet.name).tables;
|
|
32255
32241
|
for (let table of tables) {
|
|
32256
32242
|
const tabRef = table.name + "[";
|
|
32257
|
-
for (let
|
|
32258
|
-
|
|
32259
|
-
|
|
32260
|
-
|
|
32261
|
-
|
|
32262
|
-
|
|
32263
|
-
|
|
32264
|
-
|
|
32265
|
-
|
|
32266
|
-
|
|
32267
|
-
|
|
32268
|
-
|
|
32243
|
+
for (let sheet of convertedSheets) {
|
|
32244
|
+
for (let xc in sheet.cells) {
|
|
32245
|
+
const cell = sheet.cells[xc];
|
|
32246
|
+
if (cell && cell.content && cell.content.startsWith("=")) {
|
|
32247
|
+
let refIndex;
|
|
32248
|
+
while ((refIndex = cell.content.indexOf(tabRef)) !== -1) {
|
|
32249
|
+
let endIndex = refIndex + tabRef.length;
|
|
32250
|
+
let openBrackets = 1;
|
|
32251
|
+
while (openBrackets > 0 && endIndex < cell.content.length) {
|
|
32252
|
+
if (cell.content[endIndex] === "[") {
|
|
32253
|
+
openBrackets++;
|
|
32254
|
+
}
|
|
32255
|
+
else if (cell.content[endIndex] === "]") {
|
|
32256
|
+
openBrackets--;
|
|
32257
|
+
}
|
|
32258
|
+
endIndex++;
|
|
32259
|
+
}
|
|
32260
|
+
let reference = cell.content.slice(refIndex + tabRef.length, endIndex - 1);
|
|
32261
|
+
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
32262
|
+
const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
|
|
32263
|
+
cell.content =
|
|
32264
|
+
cell.content.slice(0, refIndex) + convertedRef + cell.content.slice(endIndex);
|
|
32269
32265
|
}
|
|
32270
|
-
reference = reference.slice(0, endIndex);
|
|
32271
|
-
const convertedRef = convertTableReference(reference, table, xc);
|
|
32272
|
-
cell.content =
|
|
32273
|
-
cell.content.slice(0, refIndex) +
|
|
32274
|
-
convertedRef +
|
|
32275
|
-
cell.content.slice(tabRef.length + refIndex + endIndex + 1);
|
|
32276
32266
|
}
|
|
32277
32267
|
}
|
|
32278
32268
|
}
|
|
@@ -32280,11 +32270,17 @@
|
|
|
32280
32270
|
}
|
|
32281
32271
|
}
|
|
32282
32272
|
/**
|
|
32283
|
-
* Convert table-specific references in formulas into standard references.
|
|
32273
|
+
* Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
|
|
32274
|
+
* and of keywords determining the rows of the table to reference.
|
|
32284
32275
|
*
|
|
32285
32276
|
* A reference in a table can have the form (only the part between brackets should be given to this function):
|
|
32286
32277
|
* - tableName[colName] : reference to the whole column "colName"
|
|
32278
|
+
* - tableName[#keyword] : reference to the whatever row the keyword refers to
|
|
32287
32279
|
* - tableName[[#keyword], [colName]] : reference to some of the element(s) of the column colName
|
|
32280
|
+
* - tableName[[#keyword], [colName]:[col2Name]] : reference to some of the element(s) of the columns colName to col2Name
|
|
32281
|
+
* - tableName[[#keyword1], [#keyword2], [colName]] : reference to all the rows referenced by the keywords in the column colName
|
|
32282
|
+
* - tableName[[#keyword1], [colName], [#keyword2]]: the keywords and colName can be in any order
|
|
32283
|
+
*
|
|
32288
32284
|
*
|
|
32289
32285
|
* The available keywords are :
|
|
32290
32286
|
* - #All : all the column (including totals)
|
|
@@ -32292,58 +32288,109 @@
|
|
|
32292
32288
|
* - #Headers : only the header of the column
|
|
32293
32289
|
* - #Totals : only the totals of the column
|
|
32294
32290
|
* - #This Row : only the element in the same row as the cell
|
|
32291
|
+
*
|
|
32292
|
+
* Note that the only valid combination of multiple keywords are #Data + #Totals and #Headers + #Data.
|
|
32295
32293
|
*/
|
|
32296
|
-
function convertTableReference(expr, table, cellXc) {
|
|
32297
|
-
|
|
32294
|
+
function convertTableReference(sheetPrefix, expr, table, cellXc) {
|
|
32295
|
+
// TODO: Ideally we'd want to make a real tokenizer, this simple approach won't work if for example the column name
|
|
32296
|
+
// contain # or , characters. But that's probably an edge case that we can ignore for now.
|
|
32297
|
+
const parts = expr.split(",").map((part) => part.trim());
|
|
32298
32298
|
const tableZone = toZone(table.ref);
|
|
32299
|
-
const
|
|
32300
|
-
|
|
32301
|
-
|
|
32302
|
-
|
|
32303
|
-
|
|
32304
|
-
|
|
32305
|
-
|
|
32306
|
-
|
|
32307
|
-
|
|
32308
|
-
|
|
32309
|
-
|
|
32299
|
+
const colIndexes = [];
|
|
32300
|
+
const rowIndexes = [];
|
|
32301
|
+
const foundKeywords = [];
|
|
32302
|
+
for (const part of parts) {
|
|
32303
|
+
if (removeBrackets(part).startsWith("#")) {
|
|
32304
|
+
const keyWord = removeBrackets(part);
|
|
32305
|
+
foundKeywords.push(keyWord);
|
|
32306
|
+
switch (keyWord) {
|
|
32307
|
+
case "#All":
|
|
32308
|
+
rowIndexes.push(tableZone.top, tableZone.bottom);
|
|
32309
|
+
break;
|
|
32310
|
+
case "#Data":
|
|
32311
|
+
const top = table.headerRowCount ? tableZone.top + table.headerRowCount : tableZone.top;
|
|
32312
|
+
const bottom = table.totalsRowCount
|
|
32313
|
+
? tableZone.bottom - table.totalsRowCount
|
|
32314
|
+
: tableZone.bottom;
|
|
32315
|
+
rowIndexes.push(top, bottom);
|
|
32316
|
+
break;
|
|
32317
|
+
case "#This Row":
|
|
32318
|
+
rowIndexes.push(toCartesian(cellXc).row);
|
|
32319
|
+
break;
|
|
32320
|
+
case "#Headers":
|
|
32321
|
+
if (!table.headerRowCount) {
|
|
32322
|
+
return INCORRECT_RANGE_STRING;
|
|
32323
|
+
}
|
|
32324
|
+
rowIndexes.push(tableZone.top);
|
|
32325
|
+
break;
|
|
32326
|
+
case "#Totals":
|
|
32327
|
+
if (!table.totalsRowCount) {
|
|
32328
|
+
return INCORRECT_RANGE_STRING;
|
|
32329
|
+
}
|
|
32330
|
+
rowIndexes.push(tableZone.bottom);
|
|
32331
|
+
break;
|
|
32332
|
+
}
|
|
32310
32333
|
}
|
|
32311
|
-
|
|
32312
|
-
|
|
32313
|
-
|
|
32314
|
-
|
|
32315
|
-
|
|
32316
|
-
|
|
32317
|
-
|
|
32318
|
-
|
|
32319
|
-
|
|
32320
|
-
|
|
32321
|
-
|
|
32322
|
-
|
|
32323
|
-
|
|
32324
|
-
|
|
32325
|
-
|
|
32326
|
-
|
|
32327
|
-
|
|
32328
|
-
if (!table.headerRowCount) {
|
|
32329
|
-
isReferencedZoneValid = false;
|
|
32330
|
-
}
|
|
32331
|
-
break;
|
|
32332
|
-
case "#Totals":
|
|
32333
|
-
refZone.top = refZone.bottom = tableZone.bottom;
|
|
32334
|
-
if (!table.totalsRowCount) {
|
|
32335
|
-
isReferencedZoneValid = false;
|
|
32334
|
+
else {
|
|
32335
|
+
const columns = part
|
|
32336
|
+
.split(":")
|
|
32337
|
+
.map((part) => part.trim())
|
|
32338
|
+
.map(removeBrackets);
|
|
32339
|
+
if (colIndexes.length) {
|
|
32340
|
+
return INCORRECT_RANGE_STRING;
|
|
32341
|
+
}
|
|
32342
|
+
const colRelativeIndex = table.cols.findIndex((col) => col.name === columns[0]);
|
|
32343
|
+
if (colRelativeIndex === -1) {
|
|
32344
|
+
return INCORRECT_RANGE_STRING;
|
|
32345
|
+
}
|
|
32346
|
+
colIndexes.push(colRelativeIndex + tableZone.left);
|
|
32347
|
+
if (columns[1]) {
|
|
32348
|
+
const colRelativeIndex2 = table.cols.findIndex((col) => col.name === columns[1]);
|
|
32349
|
+
if (colRelativeIndex2 === -1) {
|
|
32350
|
+
return INCORRECT_RANGE_STRING;
|
|
32336
32351
|
}
|
|
32337
|
-
|
|
32352
|
+
colIndexes.push(colRelativeIndex2 + tableZone.left);
|
|
32353
|
+
}
|
|
32338
32354
|
}
|
|
32339
|
-
const colRef = refElements[1].slice(1, refElements[1].length - 1);
|
|
32340
|
-
const colRelativeIndex = table.cols.findIndex((col) => col.name === colRef);
|
|
32341
|
-
refZone.left = refZone.right = colRelativeIndex + tableZone.left;
|
|
32342
32355
|
}
|
|
32343
|
-
if (!
|
|
32356
|
+
if (!areKeywordsCompatible(foundKeywords)) {
|
|
32344
32357
|
return INCORRECT_RANGE_STRING;
|
|
32345
32358
|
}
|
|
32346
|
-
|
|
32359
|
+
if (rowIndexes.length === 0) {
|
|
32360
|
+
const top = table.headerRowCount ? tableZone.top + table.headerRowCount : tableZone.top;
|
|
32361
|
+
const bottom = table.totalsRowCount
|
|
32362
|
+
? tableZone.bottom - table.totalsRowCount
|
|
32363
|
+
: tableZone.bottom;
|
|
32364
|
+
rowIndexes.push(top, bottom);
|
|
32365
|
+
}
|
|
32366
|
+
if (colIndexes.length === 0) {
|
|
32367
|
+
colIndexes.push(tableZone.left, tableZone.right);
|
|
32368
|
+
}
|
|
32369
|
+
const refZone = {
|
|
32370
|
+
top: Math.min(...rowIndexes),
|
|
32371
|
+
left: Math.min(...colIndexes),
|
|
32372
|
+
bottom: Math.max(...rowIndexes),
|
|
32373
|
+
right: Math.max(...colIndexes),
|
|
32374
|
+
};
|
|
32375
|
+
return sheetPrefix + zoneToXc(refZone);
|
|
32376
|
+
}
|
|
32377
|
+
function removeBrackets(str) {
|
|
32378
|
+
return str.startsWith("[") && str.endsWith("]") ? str.slice(1, str.length - 1) : str;
|
|
32379
|
+
}
|
|
32380
|
+
function areKeywordsCompatible(keywords) {
|
|
32381
|
+
if (keywords.length < 2) {
|
|
32382
|
+
return true;
|
|
32383
|
+
}
|
|
32384
|
+
else if (keywords.length > 2) {
|
|
32385
|
+
return false;
|
|
32386
|
+
}
|
|
32387
|
+
else if (keywords.includes("#Data") && keywords.includes("#Totals")) {
|
|
32388
|
+
return true;
|
|
32389
|
+
}
|
|
32390
|
+
else if (keywords.includes("#Headers") && keywords.includes("#Data")) {
|
|
32391
|
+
return true;
|
|
32392
|
+
}
|
|
32393
|
+
return false;
|
|
32347
32394
|
}
|
|
32348
32395
|
|
|
32349
32396
|
// -------------------------------------
|
|
@@ -33896,7 +33943,7 @@
|
|
|
33896
33943
|
* a breaking change is made in the way the state is handled, and an upgrade
|
|
33897
33944
|
* function should be defined
|
|
33898
33945
|
*/
|
|
33899
|
-
const CURRENT_VERSION = 14;
|
|
33946
|
+
const CURRENT_VERSION = 14.5;
|
|
33900
33947
|
const INITIAL_SHEET_ID = "Sheet1";
|
|
33901
33948
|
/**
|
|
33902
33949
|
* This function tries to load anything that could look like a valid
|
|
@@ -42405,6 +42452,9 @@
|
|
|
42405
42452
|
// Export
|
|
42406
42453
|
// ---------------------------------------------------------------------------
|
|
42407
42454
|
exportForExcel(data) {
|
|
42455
|
+
for (const sheet of data.sheets) {
|
|
42456
|
+
sheet.formulaSpillRanges = {};
|
|
42457
|
+
}
|
|
42408
42458
|
for (const position of this.evaluator.getEvaluatedPositions()) {
|
|
42409
42459
|
const evaluatedCell = this.evaluator.getEvaluatedCell(position);
|
|
42410
42460
|
const xc = toXC(position.col, position.row);
|
|
@@ -42416,8 +42466,9 @@
|
|
|
42416
42466
|
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
42417
42467
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
42418
42468
|
if (formulaCell) {
|
|
42469
|
+
const cell = this.getters.getCell(position);
|
|
42419
42470
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
42420
|
-
isFormula = isExported;
|
|
42471
|
+
isFormula = isExported && cell?.content === formulaCell.content;
|
|
42421
42472
|
if (!isExported) {
|
|
42422
42473
|
// If the cell contains a non-exported formula and that is evaluates to
|
|
42423
42474
|
// nothing* ,we don't export it.
|
|
@@ -42441,6 +42492,14 @@
|
|
|
42441
42492
|
content = !isExported ? newContent : exportedCellData.content;
|
|
42442
42493
|
}
|
|
42443
42494
|
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
|
42495
|
+
const spillCells = this.getSpreadPositionsOf(position);
|
|
42496
|
+
spillCells.push(position);
|
|
42497
|
+
const spillZones = spillCells.map((cell) => positionToZone(cell));
|
|
42498
|
+
const spillZone = union(...spillZones);
|
|
42499
|
+
const spillZoneXc = this.getters.getRangeString(this.getters.getRangeFromZone(position.sheetId, spillZone), position.sheetId);
|
|
42500
|
+
if (spillZoneXc && spillZoneXc !== "#REF") {
|
|
42501
|
+
exportedSheetData.formulaSpillRanges[xc] = spillZoneXc;
|
|
42502
|
+
}
|
|
42444
42503
|
}
|
|
42445
42504
|
}
|
|
42446
42505
|
/**
|
|
@@ -43641,7 +43700,7 @@
|
|
|
43641
43700
|
getRule(cell, cells) {
|
|
43642
43701
|
const rules = autofillRulesRegistry.getAll().sort((a, b) => a.sequence - b.sequence);
|
|
43643
43702
|
const rule = rules.find((rule) => rule.condition(cell, cells));
|
|
43644
|
-
return rule && rule.generateRule(cell, cells);
|
|
43703
|
+
return rule && this.direction && rule.generateRule(cell, cells, this.direction);
|
|
43645
43704
|
}
|
|
43646
43705
|
/**
|
|
43647
43706
|
* Create the generator to be able to autofill the next cells.
|
|
@@ -51311,7 +51370,8 @@
|
|
|
51311
51370
|
? this.getters.getSheetViewVisibleCols()
|
|
51312
51371
|
: this.getters.getSheetViewVisibleRows();
|
|
51313
51372
|
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
51314
|
-
|
|
51373
|
+
let endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
51374
|
+
endIndex = endIndex === -1 ? visibleHeaders.length : endIndex;
|
|
51315
51375
|
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
51316
51376
|
let offset = 0;
|
|
51317
51377
|
for (const i of relevantIndexes) {
|
|
@@ -56110,7 +56170,7 @@
|
|
|
56110
56170
|
`;
|
|
56111
56171
|
}
|
|
56112
56172
|
|
|
56113
|
-
function addFormula(cell) {
|
|
56173
|
+
function addFormula(cell, formulaSpillRange) {
|
|
56114
56174
|
const formula = cell.content;
|
|
56115
56175
|
if (!formula) {
|
|
56116
56176
|
return { attrs: [], node: escapeXml `` };
|
|
@@ -56119,10 +56179,17 @@
|
|
|
56119
56179
|
if (type === undefined) {
|
|
56120
56180
|
return { attrs: [], node: escapeXml `` };
|
|
56121
56181
|
}
|
|
56122
|
-
const attrs = [
|
|
56182
|
+
const attrs = [
|
|
56183
|
+
["cm", "1"],
|
|
56184
|
+
["t", type],
|
|
56185
|
+
];
|
|
56123
56186
|
const XlsxFormula = adaptFormulaToExcel(formula);
|
|
56124
56187
|
const exportedValue = adaptFormulaValueToExcel(cell.value);
|
|
56125
|
-
|
|
56188
|
+
// We treat all formulas as array formulas (a simple formula
|
|
56189
|
+
// is an array formula that spills on only one cell) to avoid
|
|
56190
|
+
// trying to detect spilling sub-formulas which is not a trivial task.
|
|
56191
|
+
let node;
|
|
56192
|
+
node = escapeXml /*xml*/ `<f t="array" ref="${formulaSpillRange}">${XlsxFormula}</f><v>${exportedValue}</v>`;
|
|
56126
56193
|
return { attrs, node };
|
|
56127
56194
|
}
|
|
56128
56195
|
function addContent(content, sharedStrings, forceString = false) {
|
|
@@ -56934,7 +57001,7 @@
|
|
|
56934
57001
|
let cellNode = escapeXml ``;
|
|
56935
57002
|
// Either formula or static value inside the cell
|
|
56936
57003
|
if (cell.isFormula) {
|
|
56937
|
-
const res = addFormula(cell);
|
|
57004
|
+
const res = addFormula(cell, sheet.formulaSpillRanges[xc] ?? xc);
|
|
56938
57005
|
if (!res) {
|
|
56939
57006
|
continue;
|
|
56940
57007
|
}
|
|
@@ -57191,6 +57258,30 @@
|
|
|
57191
57258
|
`;
|
|
57192
57259
|
files.push(createXMLFile(parseXML(sheetXml), `xl/worksheets/sheet${sheetIndex}.xml`, "sheet"));
|
|
57193
57260
|
}
|
|
57261
|
+
const sheetMetadataXml = escapeXml /*xml*/ `
|
|
57262
|
+
<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">
|
|
57263
|
+
<metadataTypes count="1">
|
|
57264
|
+
<metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1"
|
|
57265
|
+
pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1"
|
|
57266
|
+
clearComments="1" assign="1" coerce="1" cellMeta="1" />
|
|
57267
|
+
</metadataTypes>
|
|
57268
|
+
<futureMetadata name="XLDAPR" count="1">
|
|
57269
|
+
<bk>
|
|
57270
|
+
<extLst>
|
|
57271
|
+
<ext uri="{${ARRAY_FORMULA_URI}}">
|
|
57272
|
+
<xda:dynamicArrayProperties fDynamic="1" fCollapsed="0" />
|
|
57273
|
+
</ext>
|
|
57274
|
+
</extLst>
|
|
57275
|
+
</bk>
|
|
57276
|
+
</futureMetadata>
|
|
57277
|
+
<cellMetadata count="1">
|
|
57278
|
+
<bk>
|
|
57279
|
+
<rc t="1" v="0" />
|
|
57280
|
+
</bk>
|
|
57281
|
+
</cellMetadata>
|
|
57282
|
+
</metadata>
|
|
57283
|
+
`;
|
|
57284
|
+
files.push(createXMLFile(parseXML(sheetMetadataXml), "xl/metadata.xml", "metadata"));
|
|
57194
57285
|
addRelsToFile(construct.relsFiles, "xl/_rels/workbook.xml.rels", {
|
|
57195
57286
|
type: XLSX_RELATION_TYPE.sharedStrings,
|
|
57196
57287
|
target: "sharedStrings.xml",
|
|
@@ -57199,6 +57290,10 @@
|
|
|
57199
57290
|
type: XLSX_RELATION_TYPE.styles,
|
|
57200
57291
|
target: "styles.xml",
|
|
57201
57292
|
});
|
|
57293
|
+
addRelsToFile(construct.relsFiles, "xl/_rels/workbook.xml.rels", {
|
|
57294
|
+
type: XLSX_RELATION_TYPE.metadata,
|
|
57295
|
+
target: "metadata.xml",
|
|
57296
|
+
});
|
|
57202
57297
|
return files;
|
|
57203
57298
|
}
|
|
57204
57299
|
/**
|
|
@@ -57973,9 +58068,9 @@
|
|
|
57973
58068
|
exports.tokenize = tokenize;
|
|
57974
58069
|
|
|
57975
58070
|
|
|
57976
|
-
__info__.version = "17.0.
|
|
57977
|
-
__info__.date = "2025-
|
|
57978
|
-
__info__.hash = "
|
|
58071
|
+
__info__.version = "17.0.52";
|
|
58072
|
+
__info__.date = "2025-03-07T10:30:04.783Z";
|
|
58073
|
+
__info__.hash = "c19cd9a";
|
|
57979
58074
|
|
|
57980
58075
|
|
|
57981
58076
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|