@odoo/o-spreadsheet 16.4.27 → 16.4.29
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 +145 -113
- package/dist/o-spreadsheet.d.ts +3 -5
- package/dist/o-spreadsheet.esm.js +145 -113
- package/dist/o-spreadsheet.iife.js +145 -113
- package/dist/o-spreadsheet.iife.min.js +254 -254
- package/dist/o_spreadsheet.xml +6 -5
- package/package.json +2 -2
|
@@ -526,7 +526,7 @@ function getItemId(item, itemsDic) {
|
|
|
526
526
|
}
|
|
527
527
|
// Generate new Id if the item didn't exist in the dictionary
|
|
528
528
|
const ids = Object.keys(itemsDic);
|
|
529
|
-
const maxId = ids.length === 0 ? 0 :
|
|
529
|
+
const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
|
|
530
530
|
itemsDic[maxId + 1] = item;
|
|
531
531
|
return maxId + 1;
|
|
532
532
|
}
|
|
@@ -617,7 +617,7 @@ function deepEquals(o1, o2) {
|
|
|
617
617
|
if (typeof o1 !== typeof o2)
|
|
618
618
|
return false;
|
|
619
619
|
if (typeof o1 !== "object")
|
|
620
|
-
return
|
|
620
|
+
return false;
|
|
621
621
|
// Objects can have different keys if the values are undefined
|
|
622
622
|
const keys = new Set();
|
|
623
623
|
Object.keys(o1).forEach((key) => keys.add(key));
|
|
@@ -742,6 +742,34 @@ function insertItemsAtIndex(array, items, index) {
|
|
|
742
742
|
const newArray = [...array];
|
|
743
743
|
newArray.splice(index, 0, ...items);
|
|
744
744
|
return newArray;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Alternative to Math.max that works with large arrays.
|
|
748
|
+
* Typically useful for arrays bigger than 100k elements.
|
|
749
|
+
*/
|
|
750
|
+
function largeMax(array) {
|
|
751
|
+
let len = array.length;
|
|
752
|
+
if (len < 100000)
|
|
753
|
+
return Math.max(...array);
|
|
754
|
+
let max = -Infinity;
|
|
755
|
+
while (len--) {
|
|
756
|
+
max = array[len] > max ? array[len] : max;
|
|
757
|
+
}
|
|
758
|
+
return max;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Alternative to Math.min that works with large arrays.
|
|
762
|
+
* Typically useful for arrays bigger than 100k elements.
|
|
763
|
+
*/
|
|
764
|
+
function largeMin(array) {
|
|
765
|
+
let len = array.length;
|
|
766
|
+
if (len < 100000)
|
|
767
|
+
return Math.min(...array);
|
|
768
|
+
let min = +Infinity;
|
|
769
|
+
while (len--) {
|
|
770
|
+
min = array[len] < min ? array[len] : min;
|
|
771
|
+
}
|
|
772
|
+
return min;
|
|
745
773
|
}
|
|
746
774
|
|
|
747
775
|
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
@@ -15773,6 +15801,7 @@ class LinkEditor extends owl.Component {
|
|
|
15773
15801
|
this.save();
|
|
15774
15802
|
}
|
|
15775
15803
|
ev.stopPropagation();
|
|
15804
|
+
ev.preventDefault();
|
|
15776
15805
|
break;
|
|
15777
15806
|
case "Escape":
|
|
15778
15807
|
this.cancel();
|
|
@@ -16338,10 +16367,10 @@ function aggregateDataForLabels(labels, datasets) {
|
|
|
16338
16367
|
}
|
|
16339
16368
|
}
|
|
16340
16369
|
return {
|
|
16341
|
-
labels:
|
|
16370
|
+
labels: Array.from(labelSet),
|
|
16342
16371
|
dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
|
|
16343
16372
|
...dataset,
|
|
16344
|
-
data:
|
|
16373
|
+
data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
|
|
16345
16374
|
})),
|
|
16346
16375
|
};
|
|
16347
16376
|
}
|
|
@@ -17062,7 +17091,7 @@ function getBestTimeUnitForScale(labels, format, locale) {
|
|
|
17062
17091
|
return undefined;
|
|
17063
17092
|
}
|
|
17064
17093
|
const labelsTimestamps = labelDates.map((date) => date.getTime());
|
|
17065
|
-
const period =
|
|
17094
|
+
const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
|
|
17066
17095
|
const minUnit = getFormatMinDisplayUnit(format);
|
|
17067
17096
|
if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
|
|
17068
17097
|
return "second";
|
|
@@ -17504,7 +17533,7 @@ function getPieConfiguration(chart, labels, localeFormat) {
|
|
|
17504
17533
|
}
|
|
17505
17534
|
function getPieColors(colors, dataSetsValues) {
|
|
17506
17535
|
const pieColors = [];
|
|
17507
|
-
const maxLength =
|
|
17536
|
+
const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
|
|
17508
17537
|
for (let i = 0; i <= maxLength; i++) {
|
|
17509
17538
|
pieColors.push(colors.next());
|
|
17510
17539
|
}
|
|
@@ -18321,8 +18350,8 @@ const DELETE_CONTENT_ROWS_NAME = (env) => {
|
|
|
18321
18350
|
let last;
|
|
18322
18351
|
const activesRows = env.model.getters.getActiveRows();
|
|
18323
18352
|
if (activesRows.size !== 0) {
|
|
18324
|
-
first =
|
|
18325
|
-
last =
|
|
18353
|
+
first = largeMin([...activesRows]);
|
|
18354
|
+
last = largeMax([...activesRows]);
|
|
18326
18355
|
}
|
|
18327
18356
|
else {
|
|
18328
18357
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -18350,8 +18379,8 @@ const DELETE_CONTENT_COLUMNS_NAME = (env) => {
|
|
|
18350
18379
|
let last;
|
|
18351
18380
|
const activeCols = env.model.getters.getActiveCols();
|
|
18352
18381
|
if (activeCols.size !== 0) {
|
|
18353
|
-
first =
|
|
18354
|
-
last =
|
|
18382
|
+
first = largeMin([...activeCols]);
|
|
18383
|
+
last = largeMax([...activeCols]);
|
|
18355
18384
|
}
|
|
18356
18385
|
else {
|
|
18357
18386
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -18379,8 +18408,8 @@ const REMOVE_ROWS_NAME = (env) => {
|
|
|
18379
18408
|
let last;
|
|
18380
18409
|
const activesRows = env.model.getters.getActiveRows();
|
|
18381
18410
|
if (activesRows.size !== 0) {
|
|
18382
|
-
first =
|
|
18383
|
-
last =
|
|
18411
|
+
first = largeMin([...activesRows]);
|
|
18412
|
+
last = largeMax([...activesRows]);
|
|
18384
18413
|
}
|
|
18385
18414
|
else {
|
|
18386
18415
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -18421,8 +18450,8 @@ const REMOVE_COLUMNS_NAME = (env) => {
|
|
|
18421
18450
|
let last;
|
|
18422
18451
|
const activeCols = env.model.getters.getActiveCols();
|
|
18423
18452
|
if (activeCols.size !== 0) {
|
|
18424
|
-
first =
|
|
18425
|
-
last =
|
|
18453
|
+
first = largeMin([...activeCols]);
|
|
18454
|
+
last = largeMax([...activeCols]);
|
|
18426
18455
|
}
|
|
18427
18456
|
else {
|
|
18428
18457
|
const zone = env.model.getters.getSelectedZones()[0];
|
|
@@ -18463,7 +18492,7 @@ const INSERT_ROWS_BEFORE_ACTION = (env) => {
|
|
|
18463
18492
|
let row;
|
|
18464
18493
|
let quantity;
|
|
18465
18494
|
if (activeRows.size) {
|
|
18466
|
-
row =
|
|
18495
|
+
row = largeMin([...activeRows]);
|
|
18467
18496
|
quantity = activeRows.size;
|
|
18468
18497
|
}
|
|
18469
18498
|
else {
|
|
@@ -18484,7 +18513,7 @@ const INSERT_ROWS_AFTER_ACTION = (env) => {
|
|
|
18484
18513
|
let row;
|
|
18485
18514
|
let quantity;
|
|
18486
18515
|
if (activeRows.size) {
|
|
18487
|
-
row =
|
|
18516
|
+
row = largeMax([...activeRows]);
|
|
18488
18517
|
quantity = activeRows.size;
|
|
18489
18518
|
}
|
|
18490
18519
|
else {
|
|
@@ -18505,7 +18534,7 @@ const INSERT_COLUMNS_BEFORE_ACTION = (env) => {
|
|
|
18505
18534
|
let column;
|
|
18506
18535
|
let quantity;
|
|
18507
18536
|
if (activeCols.size) {
|
|
18508
|
-
column =
|
|
18537
|
+
column = largeMin([...activeCols]);
|
|
18509
18538
|
quantity = activeCols.size;
|
|
18510
18539
|
}
|
|
18511
18540
|
else {
|
|
@@ -18526,7 +18555,7 @@ const INSERT_COLUMNS_AFTER_ACTION = (env) => {
|
|
|
18526
18555
|
let column;
|
|
18527
18556
|
let quantity;
|
|
18528
18557
|
if (activeCols.size) {
|
|
18529
|
-
column =
|
|
18558
|
+
column = largeMax([...activeCols]);
|
|
18530
18559
|
quantity = activeCols.size;
|
|
18531
18560
|
}
|
|
18532
18561
|
else {
|
|
@@ -24438,6 +24467,11 @@ class Composer extends owl.Component {
|
|
|
24438
24467
|
}
|
|
24439
24468
|
}
|
|
24440
24469
|
}
|
|
24470
|
+
onContextMenu(ev) {
|
|
24471
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
24472
|
+
this.props.onInputContextMenu?.(ev);
|
|
24473
|
+
}
|
|
24474
|
+
}
|
|
24441
24475
|
// ---------------------------------------------------------------------------
|
|
24442
24476
|
// Private
|
|
24443
24477
|
// ---------------------------------------------------------------------------
|
|
@@ -24662,6 +24696,7 @@ Composer.props = {
|
|
|
24662
24696
|
onComposerCellFocused: { type: Function, optional: true },
|
|
24663
24697
|
onComposerContentFocused: Function,
|
|
24664
24698
|
isDefaultFocus: { type: Boolean, optional: true },
|
|
24699
|
+
onInputContextMenu: { type: Function, optional: true },
|
|
24665
24700
|
};
|
|
24666
24701
|
|
|
24667
24702
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
@@ -24738,6 +24773,7 @@ class GridComposer extends owl.Component {
|
|
|
24738
24773
|
isDefaultFocus: true,
|
|
24739
24774
|
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
24740
24775
|
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
24776
|
+
onInputContextMenu: this.props.onInputContextMenu,
|
|
24741
24777
|
};
|
|
24742
24778
|
}
|
|
24743
24779
|
get containerStyle() {
|
|
@@ -24826,6 +24862,7 @@ GridComposer.props = {
|
|
|
24826
24862
|
onComposerContentFocused: Function,
|
|
24827
24863
|
gridDims: Object,
|
|
24828
24864
|
onComposerCellFocused: Function,
|
|
24865
|
+
onInputContextMenu: Function,
|
|
24829
24866
|
};
|
|
24830
24867
|
|
|
24831
24868
|
const CSS$1 = css /* scss */ `
|
|
@@ -27175,8 +27212,8 @@ class Grid extends owl.Component {
|
|
|
27175
27212
|
else if (this.env.model.getters.getActiveRows().has(row)) {
|
|
27176
27213
|
type = "ROW";
|
|
27177
27214
|
}
|
|
27178
|
-
const { x, y, width
|
|
27179
|
-
this.toggleContextMenu(type, x + width, y +
|
|
27215
|
+
const { x, y, width } = this.env.model.getters.getVisibleRect(lastZone);
|
|
27216
|
+
this.toggleContextMenu(type, this.canvasPosition.x + x + width, this.canvasPosition.y + y);
|
|
27180
27217
|
}
|
|
27181
27218
|
onCellRightClicked(col, row, { x, y }) {
|
|
27182
27219
|
const zones = this.env.model.getters.getSelectedZones();
|
|
@@ -28466,29 +28503,12 @@ function convertWidthFromExcel(width) {
|
|
|
28466
28503
|
return width;
|
|
28467
28504
|
return Math.round((width / WIDTH_FACTOR) * 100) / 100;
|
|
28468
28505
|
}
|
|
28469
|
-
function convertBorderDescr(descr) {
|
|
28470
|
-
if (!descr) {
|
|
28471
|
-
return undefined;
|
|
28472
|
-
}
|
|
28473
|
-
return {
|
|
28474
|
-
style: descr.style,
|
|
28475
|
-
color: { rgb: descr.color },
|
|
28476
|
-
};
|
|
28477
|
-
}
|
|
28478
28506
|
function extractStyle(cell, data) {
|
|
28479
28507
|
let style = {};
|
|
28480
28508
|
if (cell.style) {
|
|
28481
28509
|
style = data.styles[cell.style];
|
|
28482
28510
|
}
|
|
28483
28511
|
const format = extractFormat(cell, data);
|
|
28484
|
-
const exportedBorder = {};
|
|
28485
|
-
if (cell.border) {
|
|
28486
|
-
const border = data.borders[cell.border];
|
|
28487
|
-
exportedBorder.left = convertBorderDescr(border.left);
|
|
28488
|
-
exportedBorder.right = convertBorderDescr(border.right);
|
|
28489
|
-
exportedBorder.bottom = convertBorderDescr(border.bottom);
|
|
28490
|
-
exportedBorder.top = convertBorderDescr(border.top);
|
|
28491
|
-
}
|
|
28492
28512
|
const styles = {
|
|
28493
28513
|
font: {
|
|
28494
28514
|
size: style?.fontSize || DEFAULT_FONT_SIZE,
|
|
@@ -28502,7 +28522,7 @@ function extractStyle(cell, data) {
|
|
|
28502
28522
|
}
|
|
28503
28523
|
: { reservedAttribute: "none" },
|
|
28504
28524
|
numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
|
|
28505
|
-
border:
|
|
28525
|
+
border: cell.border || 0,
|
|
28506
28526
|
alignment: {
|
|
28507
28527
|
horizontal: style.align,
|
|
28508
28528
|
vertical: style.verticalAlign
|
|
@@ -28524,15 +28544,12 @@ function extractFormat(cell, data) {
|
|
|
28524
28544
|
return undefined;
|
|
28525
28545
|
}
|
|
28526
28546
|
function normalizeStyle(construct, styles) {
|
|
28527
|
-
const { id: fontId } = pushElement(styles["font"], construct.fonts);
|
|
28528
|
-
const { id: fillId } = pushElement(styles["fill"], construct.fills);
|
|
28529
|
-
const { id: borderId } = pushElement(styles["border"], construct.borders);
|
|
28530
28547
|
// Normalize this
|
|
28531
28548
|
const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
|
|
28532
28549
|
const style = {
|
|
28533
|
-
fontId,
|
|
28534
|
-
fillId,
|
|
28535
|
-
borderId,
|
|
28550
|
+
fontId: pushElement(styles.font, construct.fonts),
|
|
28551
|
+
fillId: pushElement(styles.fill, construct.fills),
|
|
28552
|
+
borderId: styles.border,
|
|
28536
28553
|
numFmtId,
|
|
28537
28554
|
alignment: {
|
|
28538
28555
|
vertical: styles.alignment.vertical,
|
|
@@ -28540,8 +28557,7 @@ function normalizeStyle(construct, styles) {
|
|
|
28540
28557
|
wrapText: styles.alignment.wrapText,
|
|
28541
28558
|
},
|
|
28542
28559
|
};
|
|
28543
|
-
|
|
28544
|
-
return id;
|
|
28560
|
+
return pushElement(style, construct.styles);
|
|
28545
28561
|
}
|
|
28546
28562
|
function convertFormat(format, numFmtStructure) {
|
|
28547
28563
|
if (!format) {
|
|
@@ -28549,8 +28565,7 @@ function convertFormat(format, numFmtStructure) {
|
|
|
28549
28565
|
}
|
|
28550
28566
|
let formatId = XLSX_FORMAT_MAP[format.format];
|
|
28551
28567
|
if (!formatId) {
|
|
28552
|
-
|
|
28553
|
-
formatId = id + FIRST_NUMFMT_ID;
|
|
28568
|
+
formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
|
|
28554
28569
|
}
|
|
28555
28570
|
return formatId;
|
|
28556
28571
|
}
|
|
@@ -28575,20 +28590,15 @@ function addRelsToFile(relsFiles, path, rel) {
|
|
|
28575
28590
|
return id;
|
|
28576
28591
|
}
|
|
28577
28592
|
function pushElement(property, propertyList) {
|
|
28578
|
-
|
|
28579
|
-
|
|
28580
|
-
|
|
28593
|
+
let len = propertyList.length;
|
|
28594
|
+
const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
|
|
28595
|
+
for (let i = 0; i < len; i++) {
|
|
28596
|
+
if (operator(property, propertyList[i])) {
|
|
28597
|
+
return i;
|
|
28581
28598
|
}
|
|
28582
28599
|
}
|
|
28583
|
-
|
|
28584
|
-
|
|
28585
|
-
propertyList.push(property);
|
|
28586
|
-
elemId = propertyList.length - 1;
|
|
28587
|
-
}
|
|
28588
|
-
return {
|
|
28589
|
-
id: elemId,
|
|
28590
|
-
list: propertyList,
|
|
28591
|
-
};
|
|
28600
|
+
propertyList[propertyList.length] = property;
|
|
28601
|
+
return propertyList.length - 1;
|
|
28592
28602
|
}
|
|
28593
28603
|
const chartIds = [];
|
|
28594
28604
|
/**
|
|
@@ -29040,7 +29050,7 @@ function convertHyperlink(link, cellValue, warningManager) {
|
|
|
29040
29050
|
function getSheetDims(sheet) {
|
|
29041
29051
|
const dims = [0, 0];
|
|
29042
29052
|
for (let row of sheet.rows) {
|
|
29043
|
-
dims[0] = Math.max(dims[0],
|
|
29053
|
+
dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
|
|
29044
29054
|
dims[1] = Math.max(dims[1], row.index);
|
|
29045
29055
|
}
|
|
29046
29056
|
dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
|
|
@@ -29309,7 +29319,25 @@ function parseXML(xmlString, mimeType = "text/xml") {
|
|
|
29309
29319
|
}
|
|
29310
29320
|
return document;
|
|
29311
29321
|
}
|
|
29312
|
-
function
|
|
29322
|
+
function convertBorderDescr(descr) {
|
|
29323
|
+
if (!descr) {
|
|
29324
|
+
return undefined;
|
|
29325
|
+
}
|
|
29326
|
+
return {
|
|
29327
|
+
style: descr.style,
|
|
29328
|
+
color: { rgb: descr.color },
|
|
29329
|
+
};
|
|
29330
|
+
}
|
|
29331
|
+
function getDefaultXLSXStructure(data) {
|
|
29332
|
+
const xlsxBorders = Object.values(data.borders).map((border) => {
|
|
29333
|
+
return {
|
|
29334
|
+
left: convertBorderDescr(border.left),
|
|
29335
|
+
right: convertBorderDescr(border.right),
|
|
29336
|
+
bottom: convertBorderDescr(border.bottom),
|
|
29337
|
+
top: convertBorderDescr(border.top),
|
|
29338
|
+
};
|
|
29339
|
+
});
|
|
29340
|
+
const borders = [{}, ...xlsxBorders];
|
|
29313
29341
|
return {
|
|
29314
29342
|
relsFiles: [],
|
|
29315
29343
|
sharedStrings: [],
|
|
@@ -29332,7 +29360,7 @@ function getDefaultXLSXStructure() {
|
|
|
29332
29360
|
},
|
|
29333
29361
|
],
|
|
29334
29362
|
fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
|
|
29335
|
-
borders
|
|
29363
|
+
borders,
|
|
29336
29364
|
numFmts: [],
|
|
29337
29365
|
dxfs: [],
|
|
29338
29366
|
};
|
|
@@ -33397,7 +33425,17 @@ class FiltersPlugin extends CorePlugin {
|
|
|
33397
33425
|
}
|
|
33398
33426
|
}
|
|
33399
33427
|
exportForExcel(data) {
|
|
33400
|
-
|
|
33428
|
+
for (const sheet of data.sheets) {
|
|
33429
|
+
for (const filterTable of this.getFilterTables(sheet.id)) {
|
|
33430
|
+
if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
|
|
33431
|
+
continue;
|
|
33432
|
+
}
|
|
33433
|
+
sheet.filterTables.push({
|
|
33434
|
+
range: zoneToXc(filterTable.zone),
|
|
33435
|
+
filters: [],
|
|
33436
|
+
});
|
|
33437
|
+
}
|
|
33438
|
+
}
|
|
33401
33439
|
}
|
|
33402
33440
|
}
|
|
33403
33441
|
|
|
@@ -33537,7 +33575,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
33537
33575
|
if (hiddenElements.size >= elements) {
|
|
33538
33576
|
return 69 /* CommandResult.TooManyHiddenElements */;
|
|
33539
33577
|
}
|
|
33540
|
-
else if (
|
|
33578
|
+
else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
|
|
33541
33579
|
return 89 /* CommandResult.InvalidHeaderIndex */;
|
|
33542
33580
|
}
|
|
33543
33581
|
else {
|
|
@@ -34331,8 +34369,8 @@ class RangeAdapter {
|
|
|
34331
34369
|
let newRange = range;
|
|
34332
34370
|
let changeType = "NONE";
|
|
34333
34371
|
for (let group of groups) {
|
|
34334
|
-
const min =
|
|
34335
|
-
const max =
|
|
34372
|
+
const min = largeMin(group);
|
|
34373
|
+
const max = largeMax(group);
|
|
34336
34374
|
if (range.zone[start] <= min && min <= range.zone[end]) {
|
|
34337
34375
|
const toRemove = Math.min(range.zone[end], max) - min + 1;
|
|
34338
34376
|
changeType = "RESIZE";
|
|
@@ -34759,7 +34797,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
34759
34797
|
const elements = cmd.dimension === "COL"
|
|
34760
34798
|
? this.getNumberCols(cmd.sheetId)
|
|
34761
34799
|
: this.getNumberRows(cmd.sheetId);
|
|
34762
|
-
if (
|
|
34800
|
+
if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
|
|
34763
34801
|
return 89 /* CommandResult.InvalidHeaderIndex */;
|
|
34764
34802
|
}
|
|
34765
34803
|
else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
|
|
@@ -36691,7 +36729,9 @@ class Evaluator {
|
|
|
36691
36729
|
this.blockedArrayFormulas = new Set();
|
|
36692
36730
|
this.spreadingRelations = new SpreadingRelation();
|
|
36693
36731
|
this.formulaDependencies = lazy(() => {
|
|
36694
|
-
const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
|
|
36732
|
+
const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
|
|
36733
|
+
.filter((range) => !range.invalidSheetName && !range.invalidXc)
|
|
36734
|
+
.map((range) => ({
|
|
36695
36735
|
data: positionId,
|
|
36696
36736
|
boundingBox: {
|
|
36697
36737
|
zone: range.zone,
|
|
@@ -37635,13 +37675,13 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
37635
37675
|
.map((cell) => cell.value);
|
|
37636
37676
|
switch (threshold.type) {
|
|
37637
37677
|
case "value":
|
|
37638
|
-
const result = functionName === "max" ?
|
|
37678
|
+
const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
|
|
37639
37679
|
return result;
|
|
37640
37680
|
case "number":
|
|
37641
37681
|
return Number(threshold.value);
|
|
37642
37682
|
case "percentage":
|
|
37643
|
-
const min =
|
|
37644
|
-
const max =
|
|
37683
|
+
const min = largeMin(rangeValues);
|
|
37684
|
+
const max = largeMax(rangeValues);
|
|
37645
37685
|
const delta = max - min;
|
|
37646
37686
|
return min + (delta * Number(threshold.value)) / 100;
|
|
37647
37687
|
case "percentile":
|
|
@@ -38524,13 +38564,13 @@ class AutomaticSumPlugin extends UIPlugin {
|
|
|
38524
38564
|
const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
|
|
38525
38565
|
const cellPositions = range(end, -1, -1);
|
|
38526
38566
|
const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
|
|
38527
|
-
const maxValidPosition =
|
|
38567
|
+
const maxValidPosition = largeMax(invalidCells);
|
|
38528
38568
|
const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
|
|
38529
38569
|
const firstSequence = numberSequences[0] || [];
|
|
38530
|
-
if (
|
|
38570
|
+
if (largeMax(firstSequence) < maxValidPosition) {
|
|
38531
38571
|
return Infinity;
|
|
38532
38572
|
}
|
|
38533
|
-
return
|
|
38573
|
+
return largeMin(firstSequence);
|
|
38534
38574
|
}
|
|
38535
38575
|
shouldFindData(sheetId, zone) {
|
|
38536
38576
|
return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
|
|
@@ -40119,7 +40159,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
40119
40159
|
* column of the current viewport
|
|
40120
40160
|
*/
|
|
40121
40161
|
getColDimensionsInViewport(sheetId, col) {
|
|
40122
|
-
const left =
|
|
40162
|
+
const left = largeMin(this.getters.getSheetViewVisibleCols());
|
|
40123
40163
|
const start = this.getters.getColRowOffsetInViewport("COL", left, col);
|
|
40124
40164
|
const size = this.getters.getColSize(sheetId, col);
|
|
40125
40165
|
const isColHidden = this.getters.isColHidden(sheetId, col);
|
|
@@ -40134,7 +40174,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
40134
40174
|
* of the current viewport
|
|
40135
40175
|
*/
|
|
40136
40176
|
getRowDimensionsInViewport(sheetId, row) {
|
|
40137
|
-
const top =
|
|
40177
|
+
const top = largeMin(this.getters.getSheetViewVisibleRows());
|
|
40138
40178
|
const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
|
|
40139
40179
|
const size = this.getters.getRowSize(sheetId, row);
|
|
40140
40180
|
const isRowHidden = this.getters.isRowHidden(sheetId, row);
|
|
@@ -41631,7 +41671,7 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
41631
41671
|
getColMaxWidth(sheetId, index) {
|
|
41632
41672
|
const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
|
|
41633
41673
|
const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
|
|
41634
|
-
return Math.max(0,
|
|
41674
|
+
return Math.max(0, largeMax(sizes));
|
|
41635
41675
|
}
|
|
41636
41676
|
/**
|
|
41637
41677
|
* Check that any "sheetId" in the command matches an existing
|
|
@@ -42933,7 +42973,7 @@ class ClipboardOsState extends ClipboardCellsAbstractState {
|
|
|
42933
42973
|
}
|
|
42934
42974
|
getPasteZone(target) {
|
|
42935
42975
|
const height = this.values.length;
|
|
42936
|
-
const width =
|
|
42976
|
+
const width = largeMax(this.values.map((a) => a.length));
|
|
42937
42977
|
const { left: activeCol, top: activeRow } = target[0];
|
|
42938
42978
|
return {
|
|
42939
42979
|
top: activeRow,
|
|
@@ -45226,13 +45266,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
45226
45266
|
}
|
|
45227
45267
|
}
|
|
45228
45268
|
handleEvent(event) {
|
|
45269
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
45229
45270
|
if (event.options.scrollIntoView) {
|
|
45230
45271
|
let { col, row } = findCellInNewZone(event.previousAnchor.zone, event.anchor.zone);
|
|
45231
45272
|
if (event.mode === "updateAnchor") {
|
|
45232
45273
|
const oldZone = event.previousAnchor.zone;
|
|
45233
45274
|
const newZone = event.anchor.zone;
|
|
45234
45275
|
// altering a zone should not move the viewport in a dimension that wasn't changed
|
|
45235
|
-
const { top, bottom, left, right } = this.
|
|
45276
|
+
const { top, bottom, left, right } = this.getMainInternalViewport(sheetId);
|
|
45236
45277
|
if (oldZone.left === newZone.left && oldZone.right === newZone.right) {
|
|
45237
45278
|
col = left > col || col > right ? left : col;
|
|
45238
45279
|
}
|
|
@@ -45240,7 +45281,6 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
45240
45281
|
row = top > row || row > bottom ? top : row;
|
|
45241
45282
|
}
|
|
45242
45283
|
}
|
|
45243
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
45244
45284
|
col = Math.min(col, this.getters.getNumberCols(sheetId) - 1);
|
|
45245
45285
|
row = Math.min(row, this.getters.getNumberRows(sheetId) - 1);
|
|
45246
45286
|
this.refreshViewport(this.getters.getActiveSheetId(), { col, row });
|
|
@@ -45266,16 +45306,16 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
45266
45306
|
this.setSheetViewOffset(cmd.offsetX, cmd.offsetY);
|
|
45267
45307
|
break;
|
|
45268
45308
|
case "SHIFT_VIEWPORT_DOWN":
|
|
45269
|
-
const { top } = this.getActiveMainViewport();
|
|
45270
45309
|
const sheetId = this.getters.getActiveSheetId();
|
|
45271
|
-
const
|
|
45272
|
-
this.
|
|
45310
|
+
const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
|
|
45311
|
+
const topRowDims = this.getters.getRowDimensions(sheetId, top);
|
|
45312
|
+
this.shiftVertically(topRowDims.start + viewportHeight - offsetCorrectionY);
|
|
45273
45313
|
break;
|
|
45274
45314
|
case "SHIFT_VIEWPORT_UP": {
|
|
45275
|
-
const { top } = this.getActiveMainViewport();
|
|
45276
45315
|
const sheetId = this.getters.getActiveSheetId();
|
|
45277
|
-
const
|
|
45278
|
-
this.
|
|
45316
|
+
const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
|
|
45317
|
+
const topRowDims = this.getters.getRowDimensions(sheetId, top);
|
|
45318
|
+
this.shiftVertically(topRowDims.end - offsetCorrectionY - viewportHeight);
|
|
45279
45319
|
break;
|
|
45280
45320
|
}
|
|
45281
45321
|
case "REMOVE_COLUMNS_ROWS":
|
|
@@ -45637,17 +45677,6 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
45637
45677
|
const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
|
|
45638
45678
|
Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
|
|
45639
45679
|
}
|
|
45640
|
-
/**
|
|
45641
|
-
* Clip the vertical offset within the allowed range.
|
|
45642
|
-
* Not above the sheet, nor below the sheet.
|
|
45643
|
-
*/
|
|
45644
|
-
clipOffsetY(offsetY) {
|
|
45645
|
-
const { height } = this.getMainViewportRect();
|
|
45646
|
-
const maxOffset = height - this.sheetViewHeight;
|
|
45647
|
-
offsetY = Math.min(offsetY, maxOffset);
|
|
45648
|
-
offsetY = Math.max(offsetY, 0);
|
|
45649
|
-
return offsetY;
|
|
45650
|
-
}
|
|
45651
45680
|
getViewportOffset(sheetId) {
|
|
45652
45681
|
return {
|
|
45653
45682
|
x: this.viewports[sheetId]?.bottomRight.offsetScrollbarX || 0,
|
|
@@ -45703,12 +45732,15 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
45703
45732
|
* viewport top.
|
|
45704
45733
|
*/
|
|
45705
45734
|
shiftVertically(offset) {
|
|
45706
|
-
const
|
|
45735
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
45736
|
+
const { top } = this.getMainInternalViewport(sheetId);
|
|
45707
45737
|
const { scrollX } = this.getActiveSheetScrollInfo();
|
|
45708
45738
|
this.setSheetViewOffset(scrollX, offset);
|
|
45709
45739
|
const { anchor } = this.getters.getSelection();
|
|
45710
|
-
|
|
45711
|
-
|
|
45740
|
+
if (anchor.cell.row >= this.getters.getPaneDivisions(sheetId).ySplit) {
|
|
45741
|
+
const deltaRow = this.getMainInternalViewport(sheetId).top - top;
|
|
45742
|
+
this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
|
|
45743
|
+
}
|
|
45712
45744
|
}
|
|
45713
45745
|
getVisibleFigures() {
|
|
45714
45746
|
const sheetId = this.getters.getActiveSheetId();
|
|
@@ -46154,12 +46186,14 @@ class BottomBarSheet extends owl.Component {
|
|
|
46154
46186
|
this.editionState = "initializing";
|
|
46155
46187
|
}
|
|
46156
46188
|
stopEdition() {
|
|
46157
|
-
|
|
46189
|
+
const input = this.sheetNameRef.el;
|
|
46190
|
+
if (!this.state.isEditing || !input)
|
|
46158
46191
|
return;
|
|
46159
46192
|
this.state.isEditing = false;
|
|
46160
46193
|
this.editionState = "initializing";
|
|
46161
|
-
|
|
46194
|
+
input.blur();
|
|
46162
46195
|
const inputValue = this.getInputContent() || "";
|
|
46196
|
+
input.innerText = inputValue;
|
|
46163
46197
|
interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
|
|
46164
46198
|
}
|
|
46165
46199
|
cancelEdition() {
|
|
@@ -46621,7 +46655,7 @@ class BottomBar extends owl.Component {
|
|
|
46621
46655
|
this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
|
|
46622
46656
|
}
|
|
46623
46657
|
onSheetMouseDown(sheetId, event) {
|
|
46624
|
-
if (event.button !== 0)
|
|
46658
|
+
if (event.button !== 0 || this.env.model.getters.isReadonly())
|
|
46625
46659
|
return;
|
|
46626
46660
|
this.closeMenu();
|
|
46627
46661
|
const mouseX = event.clientX;
|
|
@@ -49825,7 +49859,7 @@ function addLineChart(chart) {
|
|
|
49825
49859
|
}
|
|
49826
49860
|
function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
|
|
49827
49861
|
const colors = new ChartColors();
|
|
49828
|
-
const maxLength =
|
|
49862
|
+
const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
|
|
49829
49863
|
const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
|
|
49830
49864
|
const dataSetsNodes = [];
|
|
49831
49865
|
for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
|
|
@@ -49963,8 +49997,7 @@ function addContent(content, sharedStrings, forceString = false) {
|
|
|
49963
49997
|
attrs.push(["t", "b"]);
|
|
49964
49998
|
}
|
|
49965
49999
|
else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
|
|
49966
|
-
|
|
49967
|
-
value = id.toString();
|
|
50000
|
+
value = pushElement(content, sharedStrings);
|
|
49968
50001
|
attrs.push(["t", "s"]);
|
|
49969
50002
|
}
|
|
49970
50003
|
return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
|
|
@@ -50089,8 +50122,7 @@ function addCellIsRule(cf, rule, dxfs) {
|
|
|
50089
50122
|
if (rule.style.fillColor) {
|
|
50090
50123
|
dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
|
|
50091
50124
|
}
|
|
50092
|
-
|
|
50093
|
-
ruleAttributes.push(["dxfId", id]);
|
|
50125
|
+
ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
|
|
50094
50126
|
return escapeXml /*xml*/ `
|
|
50095
50127
|
<conditionalFormatting sqref="${cf.ranges.join(" ")}">
|
|
50096
50128
|
<cfRule ${formatAttributes(ruleAttributes)}>
|
|
@@ -50899,7 +50931,7 @@ function addSheetViews(sheet) {
|
|
|
50899
50931
|
*/
|
|
50900
50932
|
function getXLSX(data) {
|
|
50901
50933
|
const files = [];
|
|
50902
|
-
const construct = getDefaultXLSXStructure();
|
|
50934
|
+
const construct = getDefaultXLSXStructure(data);
|
|
50903
50935
|
files.push(createWorkbook(data, construct));
|
|
50904
50936
|
files.push(...createWorksheets(data, construct));
|
|
50905
50937
|
files.push(createStylesSheet(construct));
|
|
@@ -51754,6 +51786,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
51754
51786
|
exports.tokenize = tokenize;
|
|
51755
51787
|
|
|
51756
51788
|
|
|
51757
|
-
__info__.version = '16.4.
|
|
51758
|
-
__info__.date = '2024-
|
|
51759
|
-
__info__.hash = '
|
|
51789
|
+
__info__.version = '16.4.29';
|
|
51790
|
+
__info__.date = '2024-04-10T12:19:13.935Z';
|
|
51791
|
+
__info__.hash = 'c022445';
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -4819,11 +4819,6 @@ declare class SheetViewPlugin extends UIPlugin {
|
|
|
4819
4819
|
private resizeSheetView;
|
|
4820
4820
|
private recomputeViewports;
|
|
4821
4821
|
private setSheetViewOffset;
|
|
4822
|
-
/**
|
|
4823
|
-
* Clip the vertical offset within the allowed range.
|
|
4824
|
-
* Not above the sheet, nor below the sheet.
|
|
4825
|
-
*/
|
|
4826
|
-
private clipOffsetY;
|
|
4827
4822
|
private getViewportOffset;
|
|
4828
4823
|
private resetViewports;
|
|
4829
4824
|
/**
|
|
@@ -6689,6 +6684,7 @@ interface ComposerProps {
|
|
|
6689
6684
|
delimitation?: DOMDimension;
|
|
6690
6685
|
onComposerContentFocused: () => void;
|
|
6691
6686
|
onComposerCellFocused?: (content: String) => void;
|
|
6687
|
+
onInputContextMenu?: (event: MouseEvent) => void;
|
|
6692
6688
|
isDefaultFocus?: boolean;
|
|
6693
6689
|
}
|
|
6694
6690
|
interface ComposerState$1 {
|
|
@@ -6759,6 +6755,7 @@ declare class Composer extends Component<ComposerProps, SpreadsheetChildEnv> {
|
|
|
6759
6755
|
onMousedown(ev: MouseEvent): void;
|
|
6760
6756
|
onClick(): void;
|
|
6761
6757
|
onDblClick(): void;
|
|
6758
|
+
onContextMenu(ev: MouseEvent): void;
|
|
6762
6759
|
private processContent;
|
|
6763
6760
|
/**
|
|
6764
6761
|
* Get the HTML content corresponding to the current composer token, divided by lines.
|
|
@@ -6937,6 +6934,7 @@ interface Props$5 {
|
|
|
6937
6934
|
onComposerContentFocused: () => void;
|
|
6938
6935
|
onComposerCellFocused: () => void;
|
|
6939
6936
|
gridDims: DOMDimension;
|
|
6937
|
+
onInputContextMenu: (event: MouseEvent) => void;
|
|
6940
6938
|
}
|
|
6941
6939
|
/**
|
|
6942
6940
|
* This component is a composer which positions itself on the grid at the anchor cell.
|