@odoo/o-spreadsheet 17.0.16 → 17.0.18
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 +149 -100
- package/dist/o-spreadsheet.d.ts +3 -0
- package/dist/o-spreadsheet.esm.js +149 -100
- package/dist/o-spreadsheet.iife.js +149 -100
- package/dist/o-spreadsheet.iife.min.js +260 -260
- package/dist/o_spreadsheet.xml +7 -6
- package/package.json +2 -2
|
@@ -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 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.18
|
|
6
|
+
* @date 2024-04-10T13:28:23.664Z
|
|
7
|
+
* @hash 6294758
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -559,7 +559,7 @@ function getItemId(item, itemsDic) {
|
|
|
559
559
|
}
|
|
560
560
|
// Generate new Id if the item didn't exist in the dictionary
|
|
561
561
|
const ids = Object.keys(itemsDic);
|
|
562
|
-
const maxId = ids.length === 0 ? 0 :
|
|
562
|
+
const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
|
|
563
563
|
itemsDic[maxId + 1] = item;
|
|
564
564
|
return maxId + 1;
|
|
565
565
|
}
|
|
@@ -650,7 +650,7 @@ function deepEquals(o1, o2) {
|
|
|
650
650
|
if (typeof o1 !== typeof o2)
|
|
651
651
|
return false;
|
|
652
652
|
if (typeof o1 !== "object")
|
|
653
|
-
return
|
|
653
|
+
return false;
|
|
654
654
|
// Objects can have different keys if the values are undefined
|
|
655
655
|
for (const key in o2) {
|
|
656
656
|
if (!(key in o1) && o2[key] !== undefined) {
|
|
@@ -776,6 +776,34 @@ function isNumberBetween(value, min, max) {
|
|
|
776
776
|
}
|
|
777
777
|
return value >= min && value <= max;
|
|
778
778
|
}
|
|
779
|
+
/**
|
|
780
|
+
* Alternative to Math.max that works with large arrays.
|
|
781
|
+
* Typically useful for arrays bigger than 100k elements.
|
|
782
|
+
*/
|
|
783
|
+
function largeMax(array) {
|
|
784
|
+
let len = array.length;
|
|
785
|
+
if (len < 100000)
|
|
786
|
+
return Math.max(...array);
|
|
787
|
+
let max = -Infinity;
|
|
788
|
+
while (len--) {
|
|
789
|
+
max = array[len] > max ? array[len] : max;
|
|
790
|
+
}
|
|
791
|
+
return max;
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Alternative to Math.min that works with large arrays.
|
|
795
|
+
* Typically useful for arrays bigger than 100k elements.
|
|
796
|
+
*/
|
|
797
|
+
function largeMin(array) {
|
|
798
|
+
let len = array.length;
|
|
799
|
+
if (len < 100000)
|
|
800
|
+
return Math.min(...array);
|
|
801
|
+
let min = +Infinity;
|
|
802
|
+
while (len--) {
|
|
803
|
+
min = array[len] < min ? array[len] : min;
|
|
804
|
+
}
|
|
805
|
+
return min;
|
|
806
|
+
}
|
|
779
807
|
|
|
780
808
|
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
781
809
|
const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
|
|
@@ -4422,8 +4450,9 @@ function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
|
4422
4450
|
* Get the default height of the cell given its style.
|
|
4423
4451
|
*/
|
|
4424
4452
|
function getDefaultCellHeight(ctx, cell, colSize) {
|
|
4425
|
-
if (!cell || !cell.content)
|
|
4453
|
+
if (!cell || (!cell.isFormula && !cell.content)) {
|
|
4426
4454
|
return DEFAULT_CELL_HEIGHT;
|
|
4455
|
+
}
|
|
4427
4456
|
const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
|
|
4428
4457
|
const numberOfLines = cell.isFormula
|
|
4429
4458
|
? 1
|
|
@@ -8326,10 +8355,10 @@ function aggregateDataForLabels(labels, datasets) {
|
|
|
8326
8355
|
}
|
|
8327
8356
|
}
|
|
8328
8357
|
return {
|
|
8329
|
-
labels:
|
|
8358
|
+
labels: Array.from(labelSet),
|
|
8330
8359
|
dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
|
|
8331
8360
|
...dataset,
|
|
8332
|
-
data:
|
|
8361
|
+
data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
|
|
8333
8362
|
})),
|
|
8334
8363
|
};
|
|
8335
8364
|
}
|
|
@@ -8380,7 +8409,7 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale })
|
|
|
8380
8409
|
const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
|
|
8381
8410
|
// tooltipItem.parsed.y can be an object or a number for pie charts
|
|
8382
8411
|
const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
|
|
8383
|
-
const toolTipFormat = !format && yLabel
|
|
8412
|
+
const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
|
|
8384
8413
|
const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
|
|
8385
8414
|
return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
|
|
8386
8415
|
},
|
|
@@ -8666,7 +8695,10 @@ function getBarConfiguration(chart, labels, localeFormat) {
|
|
|
8666
8695
|
if (isNaN(value))
|
|
8667
8696
|
return value;
|
|
8668
8697
|
const { locale, format } = localeFormat;
|
|
8669
|
-
return formatValue(value, {
|
|
8698
|
+
return formatValue(value, {
|
|
8699
|
+
locale,
|
|
8700
|
+
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
8701
|
+
});
|
|
8670
8702
|
},
|
|
8671
8703
|
},
|
|
8672
8704
|
},
|
|
@@ -9080,7 +9112,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
|
|
|
9080
9112
|
return undefined;
|
|
9081
9113
|
}
|
|
9082
9114
|
const labelsTimestamps = labelDates.map((date) => date.getTime());
|
|
9083
|
-
const period =
|
|
9115
|
+
const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
|
|
9084
9116
|
const minUnit = getFormatMinDisplayUnit(format);
|
|
9085
9117
|
if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
|
|
9086
9118
|
return "second";
|
|
@@ -9317,7 +9349,10 @@ function getLineConfiguration(chart, labels, localeFormat) {
|
|
|
9317
9349
|
if (isNaN(value))
|
|
9318
9350
|
return value;
|
|
9319
9351
|
const { locale, format } = localeFormat;
|
|
9320
|
-
return formatValue(value, {
|
|
9352
|
+
return formatValue(value, {
|
|
9353
|
+
locale,
|
|
9354
|
+
format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
|
|
9355
|
+
});
|
|
9321
9356
|
},
|
|
9322
9357
|
},
|
|
9323
9358
|
},
|
|
@@ -9544,7 +9579,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
|
|
|
9544
9579
|
const percentage = calculatePercentage(data, dataIndex);
|
|
9545
9580
|
const xLabel = tooltipItem.label || tooltipItem.dataset.label;
|
|
9546
9581
|
const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
|
|
9547
|
-
const toolTipFormat = !format && yLabel
|
|
9582
|
+
const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
|
|
9548
9583
|
const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
|
|
9549
9584
|
return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
|
|
9550
9585
|
};
|
|
@@ -9552,7 +9587,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
|
|
|
9552
9587
|
}
|
|
9553
9588
|
function getPieColors(colors, dataSetsValues) {
|
|
9554
9589
|
const pieColors = [];
|
|
9555
|
-
const maxLength =
|
|
9590
|
+
const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
|
|
9556
9591
|
for (let i = 0; i <= maxLength; i++) {
|
|
9557
9592
|
pieColors.push(colors.next());
|
|
9558
9593
|
}
|
|
@@ -10454,8 +10489,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
|
|
|
10454
10489
|
let last;
|
|
10455
10490
|
const activesRows = env.model.getters.getActiveRows();
|
|
10456
10491
|
if (activesRows.size !== 0) {
|
|
10457
|
-
first =
|
|
10458
|
-
last =
|
|
10492
|
+
first = largeMin([...activesRows]);
|
|
10493
|
+
last = largeMax([...activesRows]);
|
|
10459
10494
|
}
|
|
10460
10495
|
else {
|
|
10461
10496
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -10483,8 +10518,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
|
|
|
10483
10518
|
let last;
|
|
10484
10519
|
const activeCols = env.model.getters.getActiveCols();
|
|
10485
10520
|
if (activeCols.size !== 0) {
|
|
10486
|
-
first =
|
|
10487
|
-
last =
|
|
10521
|
+
first = largeMin([...activeCols]);
|
|
10522
|
+
last = largeMax([...activeCols]);
|
|
10488
10523
|
}
|
|
10489
10524
|
else {
|
|
10490
10525
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -10512,8 +10547,8 @@ const REMOVE_ROWS_NAME = (env) => {
|
|
|
10512
10547
|
let last;
|
|
10513
10548
|
const activesRows = env.model.getters.getActiveRows();
|
|
10514
10549
|
if (activesRows.size !== 0) {
|
|
10515
|
-
first =
|
|
10516
|
-
last =
|
|
10550
|
+
first = largeMin([...activesRows]);
|
|
10551
|
+
last = largeMax([...activesRows]);
|
|
10517
10552
|
}
|
|
10518
10553
|
else {
|
|
10519
10554
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -10554,8 +10589,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
|
|
|
10554
10589
|
let last;
|
|
10555
10590
|
const activeCols = env.model.getters.getActiveCols();
|
|
10556
10591
|
if (activeCols.size !== 0) {
|
|
10557
|
-
first =
|
|
10558
|
-
last =
|
|
10592
|
+
first = largeMin([...activeCols]);
|
|
10593
|
+
last = largeMax([...activeCols]);
|
|
10559
10594
|
}
|
|
10560
10595
|
else {
|
|
10561
10596
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -10596,7 +10631,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
|
|
|
10596
10631
|
let row;
|
|
10597
10632
|
let quantity;
|
|
10598
10633
|
if (activeRows.size) {
|
|
10599
|
-
row =
|
|
10634
|
+
row = largeMin([...activeRows]);
|
|
10600
10635
|
quantity = activeRows.size;
|
|
10601
10636
|
}
|
|
10602
10637
|
else {
|
|
@@ -10617,7 +10652,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
|
|
|
10617
10652
|
let row;
|
|
10618
10653
|
let quantity;
|
|
10619
10654
|
if (activeRows.size) {
|
|
10620
|
-
row =
|
|
10655
|
+
row = largeMax([...activeRows]);
|
|
10621
10656
|
quantity = activeRows.size;
|
|
10622
10657
|
}
|
|
10623
10658
|
else {
|
|
@@ -10638,7 +10673,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
|
|
|
10638
10673
|
let column;
|
|
10639
10674
|
let quantity;
|
|
10640
10675
|
if (activeCols.size) {
|
|
10641
|
-
column =
|
|
10676
|
+
column = largeMin([...activeCols]);
|
|
10642
10677
|
quantity = activeCols.size;
|
|
10643
10678
|
}
|
|
10644
10679
|
else {
|
|
@@ -10659,7 +10694,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
|
|
|
10659
10694
|
let column;
|
|
10660
10695
|
let quantity;
|
|
10661
10696
|
if (activeCols.size) {
|
|
10662
|
-
column =
|
|
10697
|
+
column = largeMax([...activeCols]);
|
|
10663
10698
|
quantity = activeCols.size;
|
|
10664
10699
|
}
|
|
10665
10700
|
else {
|
|
@@ -26929,6 +26964,11 @@ class Composer extends owl.Component {
|
|
|
26929
26964
|
}
|
|
26930
26965
|
}
|
|
26931
26966
|
}
|
|
26967
|
+
onContextMenu(ev) {
|
|
26968
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
26969
|
+
this.props.onInputContextMenu?.(ev);
|
|
26970
|
+
}
|
|
26971
|
+
}
|
|
26932
26972
|
// ---------------------------------------------------------------------------
|
|
26933
26973
|
// Private
|
|
26934
26974
|
// ---------------------------------------------------------------------------
|
|
@@ -27166,6 +27206,7 @@ Composer.props = {
|
|
|
27166
27206
|
onComposerCellFocused: { type: Function, optional: true },
|
|
27167
27207
|
onComposerContentFocused: Function,
|
|
27168
27208
|
isDefaultFocus: { type: Boolean, optional: true },
|
|
27209
|
+
onInputContextMenu: { type: Function, optional: true },
|
|
27169
27210
|
};
|
|
27170
27211
|
|
|
27171
27212
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
@@ -27241,6 +27282,7 @@ class GridComposer extends owl.Component {
|
|
|
27241
27282
|
isDefaultFocus: true,
|
|
27242
27283
|
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
27243
27284
|
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
27285
|
+
onInputContextMenu: this.props.onInputContextMenu,
|
|
27244
27286
|
};
|
|
27245
27287
|
}
|
|
27246
27288
|
get containerStyle() {
|
|
@@ -27329,6 +27371,7 @@ GridComposer.props = {
|
|
|
27329
27371
|
onComposerContentFocused: Function,
|
|
27330
27372
|
gridDims: Object,
|
|
27331
27373
|
onComposerCellFocused: Function,
|
|
27374
|
+
onInputContextMenu: Function,
|
|
27332
27375
|
};
|
|
27333
27376
|
|
|
27334
27377
|
const CSS$1 = css /* scss */ `
|
|
@@ -31282,29 +31325,12 @@ function convertWidthFromExcel(width) {
|
|
|
31282
31325
|
return width;
|
|
31283
31326
|
return Math.round((width / WIDTH_FACTOR) * 100) / 100;
|
|
31284
31327
|
}
|
|
31285
|
-
function convertBorderDescr(descr) {
|
|
31286
|
-
if (!descr) {
|
|
31287
|
-
return undefined;
|
|
31288
|
-
}
|
|
31289
|
-
return {
|
|
31290
|
-
style: descr.style,
|
|
31291
|
-
color: { rgb: descr.color },
|
|
31292
|
-
};
|
|
31293
|
-
}
|
|
31294
31328
|
function extractStyle(cell, data) {
|
|
31295
31329
|
let style = {};
|
|
31296
31330
|
if (cell.style) {
|
|
31297
31331
|
style = data.styles[cell.style];
|
|
31298
31332
|
}
|
|
31299
31333
|
const format = extractFormat(cell, data);
|
|
31300
|
-
const exportedBorder = {};
|
|
31301
|
-
if (cell.border) {
|
|
31302
|
-
const border = data.borders[cell.border];
|
|
31303
|
-
exportedBorder.left = convertBorderDescr(border.left);
|
|
31304
|
-
exportedBorder.right = convertBorderDescr(border.right);
|
|
31305
|
-
exportedBorder.bottom = convertBorderDescr(border.bottom);
|
|
31306
|
-
exportedBorder.top = convertBorderDescr(border.top);
|
|
31307
|
-
}
|
|
31308
31334
|
const styles = {
|
|
31309
31335
|
font: {
|
|
31310
31336
|
size: style?.fontSize || DEFAULT_FONT_SIZE,
|
|
@@ -31318,7 +31344,7 @@ function extractStyle(cell, data) {
|
|
|
31318
31344
|
}
|
|
31319
31345
|
: { reservedAttribute: "none" },
|
|
31320
31346
|
numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
|
|
31321
|
-
border:
|
|
31347
|
+
border: cell.border || 0,
|
|
31322
31348
|
alignment: {
|
|
31323
31349
|
horizontal: style.align,
|
|
31324
31350
|
vertical: style.verticalAlign
|
|
@@ -31340,15 +31366,12 @@ function extractFormat(cell, data) {
|
|
|
31340
31366
|
return undefined;
|
|
31341
31367
|
}
|
|
31342
31368
|
function normalizeStyle(construct, styles) {
|
|
31343
|
-
const { id: fontId } = pushElement(styles["font"], construct.fonts);
|
|
31344
|
-
const { id: fillId } = pushElement(styles["fill"], construct.fills);
|
|
31345
|
-
const { id: borderId } = pushElement(styles["border"], construct.borders);
|
|
31346
31369
|
// Normalize this
|
|
31347
31370
|
const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
|
|
31348
31371
|
const style = {
|
|
31349
|
-
fontId,
|
|
31350
|
-
fillId,
|
|
31351
|
-
borderId,
|
|
31372
|
+
fontId: pushElement(styles.font, construct.fonts),
|
|
31373
|
+
fillId: pushElement(styles.fill, construct.fills),
|
|
31374
|
+
borderId: styles.border,
|
|
31352
31375
|
numFmtId,
|
|
31353
31376
|
alignment: {
|
|
31354
31377
|
vertical: styles.alignment.vertical,
|
|
@@ -31356,8 +31379,7 @@ function normalizeStyle(construct, styles) {
|
|
|
31356
31379
|
wrapText: styles.alignment.wrapText,
|
|
31357
31380
|
},
|
|
31358
31381
|
};
|
|
31359
|
-
|
|
31360
|
-
return id;
|
|
31382
|
+
return pushElement(style, construct.styles);
|
|
31361
31383
|
}
|
|
31362
31384
|
function convertFormat(format, numFmtStructure) {
|
|
31363
31385
|
if (!format) {
|
|
@@ -31365,8 +31387,7 @@ function convertFormat(format, numFmtStructure) {
|
|
|
31365
31387
|
}
|
|
31366
31388
|
let formatId = XLSX_FORMAT_MAP[format.format];
|
|
31367
31389
|
if (!formatId) {
|
|
31368
|
-
|
|
31369
|
-
formatId = id + FIRST_NUMFMT_ID;
|
|
31390
|
+
formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
|
|
31370
31391
|
}
|
|
31371
31392
|
return formatId;
|
|
31372
31393
|
}
|
|
@@ -31391,20 +31412,15 @@ function addRelsToFile(relsFiles, path, rel) {
|
|
|
31391
31412
|
return id;
|
|
31392
31413
|
}
|
|
31393
31414
|
function pushElement(property, propertyList) {
|
|
31394
|
-
|
|
31395
|
-
|
|
31396
|
-
|
|
31415
|
+
let len = propertyList.length;
|
|
31416
|
+
const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
|
|
31417
|
+
for (let i = 0; i < len; i++) {
|
|
31418
|
+
if (operator(property, propertyList[i])) {
|
|
31419
|
+
return i;
|
|
31397
31420
|
}
|
|
31398
31421
|
}
|
|
31399
|
-
|
|
31400
|
-
|
|
31401
|
-
propertyList.push(property);
|
|
31402
|
-
elemId = propertyList.length - 1;
|
|
31403
|
-
}
|
|
31404
|
-
return {
|
|
31405
|
-
id: elemId,
|
|
31406
|
-
list: propertyList,
|
|
31407
|
-
};
|
|
31422
|
+
propertyList[propertyList.length] = property;
|
|
31423
|
+
return propertyList.length - 1;
|
|
31408
31424
|
}
|
|
31409
31425
|
const chartIds = [];
|
|
31410
31426
|
/**
|
|
@@ -31856,7 +31872,7 @@ function convertHyperlink(link, cellValue, warningManager) {
|
|
|
31856
31872
|
function getSheetDims(sheet) {
|
|
31857
31873
|
const dims = [0, 0];
|
|
31858
31874
|
for (let row of sheet.rows) {
|
|
31859
|
-
dims[0] = Math.max(dims[0],
|
|
31875
|
+
dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
|
|
31860
31876
|
dims[1] = Math.max(dims[1], row.index);
|
|
31861
31877
|
}
|
|
31862
31878
|
dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
|
|
@@ -32125,7 +32141,25 @@ function parseXML(xmlString, mimeType = "text/xml") {
|
|
|
32125
32141
|
}
|
|
32126
32142
|
return document;
|
|
32127
32143
|
}
|
|
32128
|
-
function
|
|
32144
|
+
function convertBorderDescr(descr) {
|
|
32145
|
+
if (!descr) {
|
|
32146
|
+
return undefined;
|
|
32147
|
+
}
|
|
32148
|
+
return {
|
|
32149
|
+
style: descr.style,
|
|
32150
|
+
color: { rgb: descr.color },
|
|
32151
|
+
};
|
|
32152
|
+
}
|
|
32153
|
+
function getDefaultXLSXStructure(data) {
|
|
32154
|
+
const xlsxBorders = Object.values(data.borders).map((border) => {
|
|
32155
|
+
return {
|
|
32156
|
+
left: convertBorderDescr(border.left),
|
|
32157
|
+
right: convertBorderDescr(border.right),
|
|
32158
|
+
bottom: convertBorderDescr(border.bottom),
|
|
32159
|
+
top: convertBorderDescr(border.top),
|
|
32160
|
+
};
|
|
32161
|
+
});
|
|
32162
|
+
const borders = [{}, ...xlsxBorders];
|
|
32129
32163
|
return {
|
|
32130
32164
|
relsFiles: [],
|
|
32131
32165
|
sharedStrings: [],
|
|
@@ -32148,7 +32182,7 @@ function getDefaultXLSXStructure() {
|
|
|
32148
32182
|
},
|
|
32149
32183
|
],
|
|
32150
32184
|
fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
|
|
32151
|
-
borders
|
|
32185
|
+
borders,
|
|
32152
32186
|
numFmts: [],
|
|
32153
32187
|
dxfs: [],
|
|
32154
32188
|
};
|
|
@@ -36746,6 +36780,9 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
36746
36780
|
if (newRule.criterion.type === "isBoolean") {
|
|
36747
36781
|
this.setCenterStyleToBooleanCells(newRule);
|
|
36748
36782
|
}
|
|
36783
|
+
else if (newRule.criterion.type === "isValueInList") {
|
|
36784
|
+
newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
|
|
36785
|
+
}
|
|
36749
36786
|
const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
|
|
36750
36787
|
const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
|
|
36751
36788
|
if (ruleIndex !== -1) {
|
|
@@ -37331,7 +37368,17 @@ class FiltersPlugin extends CorePlugin {
|
|
|
37331
37368
|
}
|
|
37332
37369
|
}
|
|
37333
37370
|
exportForExcel(data) {
|
|
37334
|
-
|
|
37371
|
+
for (const sheet of data.sheets) {
|
|
37372
|
+
for (const filterTable of this.getFilterTables(sheet.id)) {
|
|
37373
|
+
if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
|
|
37374
|
+
continue;
|
|
37375
|
+
}
|
|
37376
|
+
sheet.filterTables.push({
|
|
37377
|
+
range: zoneToXc(filterTable.zone),
|
|
37378
|
+
filters: [],
|
|
37379
|
+
});
|
|
37380
|
+
}
|
|
37381
|
+
}
|
|
37335
37382
|
}
|
|
37336
37383
|
}
|
|
37337
37384
|
|
|
@@ -37472,7 +37519,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
37472
37519
|
if (hiddenElements.size >= elements) {
|
|
37473
37520
|
return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
|
|
37474
37521
|
}
|
|
37475
|
-
else if (
|
|
37522
|
+
else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
|
|
37476
37523
|
return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
|
|
37477
37524
|
}
|
|
37478
37525
|
else {
|
|
@@ -38287,8 +38334,8 @@ class RangeAdapter {
|
|
|
38287
38334
|
let newRange = range;
|
|
38288
38335
|
let changeType = "NONE";
|
|
38289
38336
|
for (let group of groups) {
|
|
38290
|
-
const min =
|
|
38291
|
-
const max =
|
|
38337
|
+
const min = largeMin(group);
|
|
38338
|
+
const max = largeMax(group);
|
|
38292
38339
|
if (range.zone[start] <= min && min <= range.zone[end]) {
|
|
38293
38340
|
const toRemove = Math.min(range.zone[end], max) - min + 1;
|
|
38294
38341
|
changeType = "RESIZE";
|
|
@@ -38711,8 +38758,8 @@ class SheetPlugin extends CorePlugin {
|
|
|
38711
38758
|
}
|
|
38712
38759
|
return "Success" /* CommandResult.Success */;
|
|
38713
38760
|
case "REMOVE_COLUMNS_ROWS": {
|
|
38714
|
-
const min =
|
|
38715
|
-
const max =
|
|
38761
|
+
const min = largeMin(cmd.elements);
|
|
38762
|
+
const max = largeMax(cmd.elements);
|
|
38716
38763
|
if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
|
|
38717
38764
|
return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
|
|
38718
38765
|
}
|
|
@@ -41060,7 +41107,9 @@ class Evaluator {
|
|
|
41060
41107
|
this.blockedArrayFormulas = new Set();
|
|
41061
41108
|
this.spreadingRelations = new SpreadingRelation();
|
|
41062
41109
|
this.formulaDependencies = lazy(() => {
|
|
41063
|
-
const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
|
|
41110
|
+
const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
|
|
41111
|
+
.filter((range) => !range.invalidSheetName && !range.invalidXc)
|
|
41112
|
+
.map((range) => ({
|
|
41064
41113
|
data: positionId,
|
|
41065
41114
|
boundingBox: {
|
|
41066
41115
|
zone: range.zone,
|
|
@@ -42044,13 +42093,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
42044
42093
|
.map((cell) => cell.value);
|
|
42045
42094
|
switch (threshold.type) {
|
|
42046
42095
|
case "value":
|
|
42047
|
-
const result = functionName === "max" ?
|
|
42096
|
+
const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
|
|
42048
42097
|
return result;
|
|
42049
42098
|
case "number":
|
|
42050
42099
|
return Number(threshold.value);
|
|
42051
42100
|
case "percentage":
|
|
42052
|
-
const min =
|
|
42053
|
-
const max =
|
|
42101
|
+
const min = largeMin(rangeValues);
|
|
42102
|
+
const max = largeMax(rangeValues);
|
|
42054
42103
|
const delta = max - min;
|
|
42055
42104
|
return min + (delta * Number(threshold.value)) / 100;
|
|
42056
42105
|
case "percentile":
|
|
@@ -43102,13 +43151,13 @@ class AutomaticSumPlugin extends UIPlugin {
|
|
|
43102
43151
|
const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
|
|
43103
43152
|
const cellPositions = range(end, -1, -1);
|
|
43104
43153
|
const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
|
|
43105
|
-
const maxValidPosition =
|
|
43154
|
+
const maxValidPosition = largeMax(invalidCells);
|
|
43106
43155
|
const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
|
|
43107
43156
|
const firstSequence = numberSequences[0] || [];
|
|
43108
|
-
if (
|
|
43157
|
+
if (largeMax(firstSequence) < maxValidPosition) {
|
|
43109
43158
|
return Infinity;
|
|
43110
43159
|
}
|
|
43111
|
-
return
|
|
43160
|
+
return largeMin(firstSequence);
|
|
43112
43161
|
}
|
|
43113
43162
|
shouldFindData(sheetId, zone) {
|
|
43114
43163
|
return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
|
|
@@ -45512,7 +45561,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
45512
45561
|
* column of the current viewport
|
|
45513
45562
|
*/
|
|
45514
45563
|
getColDimensionsInViewport(sheetId, col) {
|
|
45515
|
-
const left =
|
|
45564
|
+
const left = largeMin(this.getters.getSheetViewVisibleCols());
|
|
45516
45565
|
const start = this.getters.getColRowOffsetInViewport("COL", left, col);
|
|
45517
45566
|
const size = this.getters.getColSize(sheetId, col);
|
|
45518
45567
|
const isColHidden = this.getters.isColHidden(sheetId, col);
|
|
@@ -45527,7 +45576,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
45527
45576
|
* of the current viewport
|
|
45528
45577
|
*/
|
|
45529
45578
|
getRowDimensionsInViewport(sheetId, row) {
|
|
45530
|
-
const top =
|
|
45579
|
+
const top = largeMin(this.getters.getSheetViewVisibleRows());
|
|
45531
45580
|
const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
|
|
45532
45581
|
const size = this.getters.getRowSize(sheetId, row);
|
|
45533
45582
|
const isRowHidden = this.getters.isRowHidden(sheetId, row);
|
|
@@ -46991,7 +47040,7 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
46991
47040
|
getColMaxWidth(sheetId, index) {
|
|
46992
47041
|
const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
|
|
46993
47042
|
const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
|
|
46994
|
-
return Math.max(0,
|
|
47043
|
+
return Math.max(0, largeMax(sizes));
|
|
46995
47044
|
}
|
|
46996
47045
|
/**
|
|
46997
47046
|
* Check that any "sheetId" in the command matches an existing
|
|
@@ -47756,7 +47805,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
|
|
|
47756
47805
|
}
|
|
47757
47806
|
getPasteZone(target) {
|
|
47758
47807
|
const height = this.values.length;
|
|
47759
|
-
const width =
|
|
47808
|
+
const width = largeMax(this.values.map((a) => a.length));
|
|
47760
47809
|
const { left: activeCol, top: activeRow } = target[0];
|
|
47761
47810
|
return {
|
|
47762
47811
|
top: activeRow,
|
|
@@ -48793,11 +48842,11 @@ class EditionPlugin extends UIPlugin {
|
|
|
48793
48842
|
}
|
|
48794
48843
|
else {
|
|
48795
48844
|
const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
|
|
48796
|
-
values = this.getters
|
|
48845
|
+
values = Array.from(new Set(this.getters
|
|
48797
48846
|
.getRangeValues(range)
|
|
48798
48847
|
.filter(isNotNull)
|
|
48799
48848
|
.map((value) => value.toString())
|
|
48800
|
-
.filter((val) => val !== "");
|
|
48849
|
+
.filter((val) => val !== "")));
|
|
48801
48850
|
}
|
|
48802
48851
|
const composerContent = this.getCurrentContent();
|
|
48803
48852
|
if (composerContent && composerContent !== this.getInitialComposerContent()) {
|
|
@@ -51254,12 +51303,14 @@ class BottomBarSheet extends owl.Component {
|
|
|
51254
51303
|
this.editionState = "initializing";
|
|
51255
51304
|
}
|
|
51256
51305
|
stopEdition() {
|
|
51257
|
-
|
|
51306
|
+
const input = this.sheetNameRef.el;
|
|
51307
|
+
if (!this.state.isEditing || !input)
|
|
51258
51308
|
return;
|
|
51259
51309
|
this.state.isEditing = false;
|
|
51260
51310
|
this.editionState = "initializing";
|
|
51261
|
-
|
|
51311
|
+
input.blur();
|
|
51262
51312
|
const inputValue = this.getInputContent() || "";
|
|
51313
|
+
input.innerText = inputValue;
|
|
51263
51314
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
51264
51315
|
}
|
|
51265
51316
|
cancelEdition() {
|
|
@@ -51553,7 +51604,7 @@ class BottomBar extends owl.Component {
|
|
|
51553
51604
|
this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
|
|
51554
51605
|
}
|
|
51555
51606
|
onSheetMouseDown(sheetId, event) {
|
|
51556
|
-
if (event.button !== 0)
|
|
51607
|
+
if (event.button !== 0 || this.env.model.getters.isReadonly())
|
|
51557
51608
|
return;
|
|
51558
51609
|
this.closeMenu();
|
|
51559
51610
|
const visibleSheets = this.getVisibleSheets();
|
|
@@ -55058,7 +55109,7 @@ function addLineChart(chart) {
|
|
|
55058
55109
|
}
|
|
55059
55110
|
function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
|
|
55060
55111
|
const colors = new ChartColors();
|
|
55061
|
-
const maxLength =
|
|
55112
|
+
const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
|
|
55062
55113
|
const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
|
|
55063
55114
|
const dataSetsNodes = [];
|
|
55064
55115
|
for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
|
|
@@ -55196,8 +55247,7 @@ function addContent(content, sharedStrings, forceString = false) {
|
|
|
55196
55247
|
attrs.push(["t", "b"]);
|
|
55197
55248
|
}
|
|
55198
55249
|
else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
|
|
55199
|
-
|
|
55200
|
-
value = id.toString();
|
|
55250
|
+
value = pushElement(content, sharedStrings);
|
|
55201
55251
|
attrs.push(["t", "s"]);
|
|
55202
55252
|
}
|
|
55203
55253
|
return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
|
|
@@ -55322,8 +55372,7 @@ function addCellIsRule(cf, rule, dxfs) {
|
|
|
55322
55372
|
if (rule.style.fillColor) {
|
|
55323
55373
|
dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
|
|
55324
55374
|
}
|
|
55325
|
-
|
|
55326
|
-
ruleAttributes.push(["dxfId", id]);
|
|
55375
|
+
ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
|
|
55327
55376
|
return escapeXml /*xml*/ `
|
|
55328
55377
|
<conditionalFormatting sqref="${cf.ranges.join(" ")}">
|
|
55329
55378
|
<cfRule ${formatAttributes(ruleAttributes)}>
|
|
@@ -56132,7 +56181,7 @@ function addSheetViews(sheet) {
|
|
|
56132
56181
|
*/
|
|
56133
56182
|
function getXLSX(data) {
|
|
56134
56183
|
const files = [];
|
|
56135
|
-
const construct = getDefaultXLSXStructure();
|
|
56184
|
+
const construct = getDefaultXLSXStructure(data);
|
|
56136
56185
|
files.push(createWorkbook(data, construct));
|
|
56137
56186
|
files.push(...createWorksheets(data, construct));
|
|
56138
56187
|
files.push(createStylesSheet(construct));
|
|
@@ -57012,6 +57061,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
57012
57061
|
exports.tokenize = tokenize;
|
|
57013
57062
|
|
|
57014
57063
|
|
|
57015
|
-
__info__.version = "17.0.
|
|
57016
|
-
__info__.date = "2024-
|
|
57017
|
-
__info__.hash = "
|
|
57064
|
+
__info__.version = "17.0.18";
|
|
57065
|
+
__info__.date = "2024-04-10T13:28:23.664Z";
|
|
57066
|
+
__info__.hash = "6294758";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -7207,6 +7207,7 @@ interface ComposerProps {
|
|
|
7207
7207
|
delimitation?: DOMDimension;
|
|
7208
7208
|
onComposerContentFocused: () => void;
|
|
7209
7209
|
onComposerCellFocused?: (content: String) => void;
|
|
7210
|
+
onInputContextMenu?: (event: MouseEvent) => void;
|
|
7210
7211
|
isDefaultFocus?: boolean;
|
|
7211
7212
|
}
|
|
7212
7213
|
interface ComposerState$1 {
|
|
@@ -7280,6 +7281,7 @@ declare class Composer extends Component<ComposerProps, SpreadsheetChildEnv> {
|
|
|
7280
7281
|
onMousedown(ev: MouseEvent): void;
|
|
7281
7282
|
onClick(): void;
|
|
7282
7283
|
onDblClick(): void;
|
|
7284
|
+
onContextMenu(ev: MouseEvent): void;
|
|
7283
7285
|
private processContent;
|
|
7284
7286
|
/**
|
|
7285
7287
|
* Get the HTML content corresponding to the current composer token, divided by lines.
|
|
@@ -7461,6 +7463,7 @@ interface Props$5 {
|
|
|
7461
7463
|
onComposerContentFocused: () => void;
|
|
7462
7464
|
onComposerCellFocused: () => void;
|
|
7463
7465
|
gridDims: DOMDimension;
|
|
7466
|
+
onInputContextMenu: (event: MouseEvent) => void;
|
|
7464
7467
|
}
|
|
7465
7468
|
/**
|
|
7466
7469
|
* This component is a composer which positions itself on the grid at the anchor cell.
|