@odoo/o-spreadsheet 18.0.7 → 18.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +240 -92
- package/dist/o-spreadsheet.d.ts +23 -2
- package/dist/o-spreadsheet.esm.js +240 -92
- package/dist/o-spreadsheet.iife.js +240 -92
- package/dist/o-spreadsheet.iife.min.js +349 -346
- package/dist/o_spreadsheet.xml +14 -9
- package/package.json +3 -3
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.0.
|
|
6
|
-
* @date
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.9
|
|
6
|
+
* @date 2025-01-14T11:33:47.429Z
|
|
7
|
+
* @hash 0c5220e
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -787,6 +787,7 @@ function removeFalsyAttributes(obj) {
|
|
|
787
787
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
788
788
|
*/
|
|
789
789
|
const whiteSpaceSpecialCharacters = [
|
|
790
|
+
" ",
|
|
790
791
|
"\t",
|
|
791
792
|
"\f",
|
|
792
793
|
"\v",
|
|
@@ -801,17 +802,15 @@ const whiteSpaceSpecialCharacters = [
|
|
|
801
802
|
String.fromCharCode(parseInt("3000", 16)),
|
|
802
803
|
String.fromCharCode(parseInt("feff", 16)),
|
|
803
804
|
];
|
|
804
|
-
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|")
|
|
805
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|"), "g");
|
|
806
|
+
const newLineRegexp = /(\r\n|\r)/g;
|
|
805
807
|
/**
|
|
806
|
-
* Replace all
|
|
807
|
-
* different newlines types by \n.
|
|
808
|
+
* Replace all different newlines characters by \n
|
|
808
809
|
*/
|
|
809
|
-
function
|
|
810
|
+
function replaceNewLines(text) {
|
|
810
811
|
if (!text)
|
|
811
812
|
return "";
|
|
812
|
-
|
|
813
|
-
return text;
|
|
814
|
-
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
813
|
+
return text.replace(newLineRegexp, NEWLINE);
|
|
815
814
|
}
|
|
816
815
|
/**
|
|
817
816
|
* Determine if the numbers are consecutive.
|
|
@@ -3543,6 +3542,7 @@ exports.CommandResult = void 0;
|
|
|
3543
3542
|
CommandResult["SheetIsHidden"] = "SheetIsHidden";
|
|
3544
3543
|
CommandResult["InvalidTableResize"] = "InvalidTableResize";
|
|
3545
3544
|
CommandResult["PivotIdNotFound"] = "PivotIdNotFound";
|
|
3545
|
+
CommandResult["PivotInError"] = "PivotInError";
|
|
3546
3546
|
CommandResult["EmptyName"] = "EmptyName";
|
|
3547
3547
|
CommandResult["ValueCellIsInvalidFormula"] = "ValueCellIsInvalidFormula";
|
|
3548
3548
|
CommandResult["InvalidDefinition"] = "InvalidDefinition";
|
|
@@ -6294,7 +6294,7 @@ class BorderClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
6294
6294
|
const POSTFIX_UNARY_OPERATORS = ["%"];
|
|
6295
6295
|
const OPERATORS = "+,-,*,/,:,=,<>,>=,>,<=,<,^,&".split(",").concat(POSTFIX_UNARY_OPERATORS);
|
|
6296
6296
|
function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
6297
|
-
str =
|
|
6297
|
+
str = replaceNewLines(str);
|
|
6298
6298
|
const chars = new TokenizingChars(str);
|
|
6299
6299
|
const result = [];
|
|
6300
6300
|
while (!chars.isOver()) {
|
|
@@ -6441,12 +6441,12 @@ function tokenizeSpace(chars) {
|
|
|
6441
6441
|
if (length) {
|
|
6442
6442
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
6443
6443
|
}
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
chars.shift();
|
|
6444
|
+
let spaces = "";
|
|
6445
|
+
while (chars.current && chars.current.match(whiteSpaceRegexp)) {
|
|
6446
|
+
spaces += chars.shift();
|
|
6447
6447
|
}
|
|
6448
|
-
if (
|
|
6449
|
-
return { type: "SPACE", value:
|
|
6448
|
+
if (spaces) {
|
|
6449
|
+
return { type: "SPACE", value: spaces };
|
|
6450
6450
|
}
|
|
6451
6451
|
return null;
|
|
6452
6452
|
}
|
|
@@ -9389,9 +9389,9 @@ function getTrendDatasetForBarChart(config, dataset) {
|
|
|
9389
9389
|
if (!newValues.length) {
|
|
9390
9390
|
return;
|
|
9391
9391
|
}
|
|
9392
|
-
return getFullTrendingLineDataSet(dataset, config, newValues);
|
|
9392
|
+
return getFullTrendingLineDataSet(dataset, config, newValues, newLabels);
|
|
9393
9393
|
}
|
|
9394
|
-
function getFullTrendingLineDataSet(dataset, config, data) {
|
|
9394
|
+
function getFullTrendingLineDataSet(dataset, config, data, labels) {
|
|
9395
9395
|
const defaultBorderColor = colorToRGBA(dataset.backgroundColor);
|
|
9396
9396
|
defaultBorderColor.a = 1;
|
|
9397
9397
|
const borderColor = config.color || lightenColor(rgbaToHex(defaultBorderColor), 0.5);
|
|
@@ -9400,7 +9400,7 @@ function getFullTrendingLineDataSet(dataset, config, data) {
|
|
|
9400
9400
|
xAxisID: TREND_LINE_XAXIS_ID,
|
|
9401
9401
|
yAxisID: dataset.yAxisID,
|
|
9402
9402
|
label: dataset.label ? _t("Trend line for %s", dataset.label) : "",
|
|
9403
|
-
data,
|
|
9403
|
+
data: data.map((v, i) => ({ x: labels[i], y: v })),
|
|
9404
9404
|
order: -1,
|
|
9405
9405
|
showLine: true,
|
|
9406
9406
|
pointRadius: 0,
|
|
@@ -19571,6 +19571,17 @@ const TEXT = {
|
|
|
19571
19571
|
},
|
|
19572
19572
|
isExported: true,
|
|
19573
19573
|
};
|
|
19574
|
+
// -----------------------------------------------------------------------------
|
|
19575
|
+
// VALUE
|
|
19576
|
+
// -----------------------------------------------------------------------------
|
|
19577
|
+
const VALUE = {
|
|
19578
|
+
description: _t("Converts a string to a numeric value."),
|
|
19579
|
+
args: [arg("value (number)", _t("the string to be converted"))],
|
|
19580
|
+
compute: function (value) {
|
|
19581
|
+
return toNumber(value, this.locale);
|
|
19582
|
+
},
|
|
19583
|
+
isExported: true,
|
|
19584
|
+
};
|
|
19574
19585
|
|
|
19575
19586
|
var text = /*#__PURE__*/Object.freeze({
|
|
19576
19587
|
__proto__: null,
|
|
@@ -19593,7 +19604,8 @@ var text = /*#__PURE__*/Object.freeze({
|
|
|
19593
19604
|
TEXT: TEXT,
|
|
19594
19605
|
TEXTJOIN: TEXTJOIN,
|
|
19595
19606
|
TRIM: TRIM,
|
|
19596
|
-
UPPER: UPPER
|
|
19607
|
+
UPPER: UPPER,
|
|
19608
|
+
VALUE: VALUE
|
|
19597
19609
|
});
|
|
19598
19610
|
|
|
19599
19611
|
// -----------------------------------------------------------------------------
|
|
@@ -19857,14 +19869,11 @@ autoCompleteProviders.add("functions", {
|
|
|
19857
19869
|
});
|
|
19858
19870
|
|
|
19859
19871
|
class DOMFocusableElementStore {
|
|
19860
|
-
mutators = ["setFocusableElement"
|
|
19872
|
+
mutators = ["setFocusableElement"];
|
|
19861
19873
|
focusableElement = undefined;
|
|
19862
19874
|
setFocusableElement(element) {
|
|
19863
19875
|
this.focusableElement = element;
|
|
19864
19876
|
}
|
|
19865
|
-
focus() {
|
|
19866
|
-
this.focusableElement?.focus();
|
|
19867
|
-
}
|
|
19868
19877
|
}
|
|
19869
19878
|
|
|
19870
19879
|
/**
|
|
@@ -20829,7 +20838,7 @@ class Composer extends owl.Component {
|
|
|
20829
20838
|
if (document.activeElement === this.contentHelper.el &&
|
|
20830
20839
|
this.props.composerStore.editionMode === "inactive" &&
|
|
20831
20840
|
!this.props.isDefaultFocus) {
|
|
20832
|
-
this.DOMFocusableElementStore.focus();
|
|
20841
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
20833
20842
|
}
|
|
20834
20843
|
});
|
|
20835
20844
|
owl.useEffect(() => {
|
|
@@ -24413,7 +24422,7 @@ function extractStyle(cell, data) {
|
|
|
24413
24422
|
vertical: style.verticalAlign
|
|
24414
24423
|
? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
|
|
24415
24424
|
: undefined,
|
|
24416
|
-
wrapText: style.wrapping === "wrap" || undefined,
|
|
24425
|
+
wrapText: style.wrapping === "wrap" || cell.content?.includes(NEWLINE) ? true : undefined,
|
|
24417
24426
|
},
|
|
24418
24427
|
};
|
|
24419
24428
|
styles.font["strike"] = !!style?.strikethrough || undefined;
|
|
@@ -24636,7 +24645,7 @@ function convertFigure(figure, id, sheetData) {
|
|
|
24636
24645
|
return undefined;
|
|
24637
24646
|
}
|
|
24638
24647
|
function isChartData(data) {
|
|
24639
|
-
return "dataSets" in data;
|
|
24648
|
+
return "dataSets" in data && data.dataSets.length > 0;
|
|
24640
24649
|
}
|
|
24641
24650
|
function isImageData(data) {
|
|
24642
24651
|
return "imageSrc" in data;
|
|
@@ -24875,9 +24884,8 @@ function convertRows(sheet, numberOfRows, headerGroups) {
|
|
|
24875
24884
|
}
|
|
24876
24885
|
return rows;
|
|
24877
24886
|
}
|
|
24878
|
-
/** Remove newlines (\n) in shared strings, We do not support them */
|
|
24879
24887
|
function convertSharedStrings(xlsxSharedStrings) {
|
|
24880
|
-
return xlsxSharedStrings.map(
|
|
24888
|
+
return xlsxSharedStrings.map(replaceNewLines);
|
|
24881
24889
|
}
|
|
24882
24890
|
function convertCells(sheet, data, sheetDims, warningManager) {
|
|
24883
24891
|
const cells = {};
|
|
@@ -25978,15 +25986,10 @@ class XlsxMiscExtractor extends XlsxBaseExtractor {
|
|
|
25978
25986
|
getSharedStrings() {
|
|
25979
25987
|
return this.mapOnElements({ parent: this.rootFile.file.xml, query: "si" }, (ssElement) => {
|
|
25980
25988
|
// Shared string can either be a simple text, or a rich text (text with formatting, possibly in multiple parts)
|
|
25981
|
-
if (ssElement.children[0].tagName === "t") {
|
|
25982
|
-
return this.extractTextContent(ssElement) || "";
|
|
25983
|
-
}
|
|
25984
25989
|
// We don't support rich text formatting, we'll only extract the text
|
|
25985
|
-
|
|
25986
|
-
return this.
|
|
25987
|
-
|
|
25988
|
-
}).join("");
|
|
25989
|
-
}
|
|
25990
|
+
return this.mapOnElements({ parent: ssElement, query: "t" }, (textElement) => {
|
|
25991
|
+
return this.extractTextContent(textElement) || "";
|
|
25992
|
+
}).join("");
|
|
25990
25993
|
});
|
|
25991
25994
|
}
|
|
25992
25995
|
}
|
|
@@ -28339,7 +28342,7 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
28339
28342
|
// then using the classical aggregation method to sum the values.
|
|
28340
28343
|
data.fill(1);
|
|
28341
28344
|
}
|
|
28342
|
-
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(),
|
|
28345
|
+
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
|
|
28343
28346
|
continue;
|
|
28344
28347
|
}
|
|
28345
28348
|
datasetValues.push({ data, label });
|
|
@@ -28915,12 +28918,12 @@ function getTrendDatasetForLineChart(config, dataset, axisType, locale) {
|
|
|
28915
28918
|
}
|
|
28916
28919
|
const numberOfStep = 5 * labels.length;
|
|
28917
28920
|
const step = (xmax - xmin) / numberOfStep;
|
|
28918
|
-
const
|
|
28919
|
-
const
|
|
28920
|
-
if (!
|
|
28921
|
+
const trendLabels = range(xmin, xmax + step / 2, step);
|
|
28922
|
+
const trendValues = interpolateData(config, filteredValues, filteredLabels, trendLabels);
|
|
28923
|
+
if (!trendValues.length) {
|
|
28921
28924
|
return;
|
|
28922
28925
|
}
|
|
28923
|
-
return getFullTrendingLineDataSet(dataset, config,
|
|
28926
|
+
return getFullTrendingLineDataSet(dataset, config, trendValues, trendLabels);
|
|
28924
28927
|
}
|
|
28925
28928
|
function createLineOrScatterChartRuntime(chart, getters) {
|
|
28926
28929
|
const axisType = getChartAxisType(chart, getters);
|
|
@@ -29037,8 +29040,16 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29037
29040
|
config.options.scales.x.type = "linear";
|
|
29038
29041
|
config.options.scales.x.ticks.callback = (value) => formatValue(value, { format: labelFormat, locale });
|
|
29039
29042
|
config.options.plugins.tooltip.callbacks.label = (tooltipItem) => {
|
|
29040
|
-
|
|
29041
|
-
let label
|
|
29043
|
+
let dataSetPoint;
|
|
29044
|
+
let label;
|
|
29045
|
+
if (tooltipItem.dataset.xAxisID === TREND_LINE_XAXIS_ID) {
|
|
29046
|
+
dataSetPoint = dataSetsValues[tooltipItem.datasetIndex].data[tooltipItem.dataIndex].y;
|
|
29047
|
+
label = "";
|
|
29048
|
+
}
|
|
29049
|
+
else {
|
|
29050
|
+
dataSetPoint = dataSetsValues[tooltipItem.datasetIndex].data[tooltipItem.dataIndex];
|
|
29051
|
+
label = labelValues.values[tooltipItem.dataIndex];
|
|
29052
|
+
}
|
|
29042
29053
|
if (isNumber(label, locale)) {
|
|
29043
29054
|
label = toNumber(label, locale);
|
|
29044
29055
|
}
|
|
@@ -29109,16 +29120,18 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
29109
29120
|
}
|
|
29110
29121
|
}
|
|
29111
29122
|
if (trendDatasets.length) {
|
|
29112
|
-
/* We add a second x axis here to draw the trend lines, with the labels length being
|
|
29113
|
-
* set so that the second axis points match the classical x axis
|
|
29114
|
-
*/
|
|
29115
29123
|
config.options.scales[TREND_LINE_XAXIS_ID] = {
|
|
29116
29124
|
...xAxis,
|
|
29117
|
-
type: "category",
|
|
29118
|
-
labels: range(0, maxLength).map((x) => x.toString()),
|
|
29119
|
-
offset: false,
|
|
29120
29125
|
display: false,
|
|
29121
29126
|
};
|
|
29127
|
+
if (axisType === "category" || axisType === "time") {
|
|
29128
|
+
/* We add a second x axis here to draw the trend lines, with the labels length being
|
|
29129
|
+
* set so that the second axis points match the classical x axis
|
|
29130
|
+
*/
|
|
29131
|
+
config.options.scales[TREND_LINE_XAXIS_ID]["type"] = "category";
|
|
29132
|
+
config.options.scales[TREND_LINE_XAXIS_ID]["labels"] = range(0, maxLength).map((x) => x.toString());
|
|
29133
|
+
config.options.scales[TREND_LINE_XAXIS_ID]["offset"] = false;
|
|
29134
|
+
}
|
|
29122
29135
|
/* These datasets must be inserted after the original datasets to ensure the way we
|
|
29123
29136
|
* distinguish the originals and trendLine datasets after
|
|
29124
29137
|
*/
|
|
@@ -29609,7 +29622,11 @@ function createGaugeChartRuntime(chart, getters) {
|
|
|
29609
29622
|
colors.push(chartColors.upperColor);
|
|
29610
29623
|
return {
|
|
29611
29624
|
background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
|
|
29612
|
-
title:
|
|
29625
|
+
title: {
|
|
29626
|
+
...chart.title,
|
|
29627
|
+
// chart titles are extracted from .json files and they are translated at runtime here
|
|
29628
|
+
text: _t(chart.title.text ?? ""),
|
|
29629
|
+
},
|
|
29613
29630
|
minValue: {
|
|
29614
29631
|
value: minValue,
|
|
29615
29632
|
label: formatValue(minValue, { locale, format }),
|
|
@@ -34290,12 +34307,20 @@ function fontSizeMenuBuilder() {
|
|
|
34290
34307
|
});
|
|
34291
34308
|
}
|
|
34292
34309
|
function isAutomaticFormatSelected(env) {
|
|
34293
|
-
const
|
|
34294
|
-
|
|
34310
|
+
const activePosition = env.model.getters.getActivePosition();
|
|
34311
|
+
const pivotCell = env.model.getters.getPivotCellFromPosition(activePosition);
|
|
34312
|
+
if (pivotCell.type === "VALUE") {
|
|
34313
|
+
return !env.model.getters.getEvaluatedCell(activePosition).format;
|
|
34314
|
+
}
|
|
34315
|
+
return !env.model.getters.getCell(activePosition)?.format;
|
|
34295
34316
|
}
|
|
34296
34317
|
function isFormatSelected(env, format) {
|
|
34297
|
-
const
|
|
34298
|
-
|
|
34318
|
+
const activePosition = env.model.getters.getActivePosition();
|
|
34319
|
+
const pivotCell = env.model.getters.getPivotCellFromPosition(activePosition);
|
|
34320
|
+
if (pivotCell.type === "VALUE") {
|
|
34321
|
+
return env.model.getters.getEvaluatedCell(activePosition).format === format;
|
|
34322
|
+
}
|
|
34323
|
+
return env.model.getters.getCell(activePosition)?.format === format;
|
|
34299
34324
|
}
|
|
34300
34325
|
function isFontSizeSelected(env, fontSize) {
|
|
34301
34326
|
const currentFontSize = env.model.getters.getCurrentStyle().fontSize || DEFAULT_FONT_SIZE;
|
|
@@ -39890,6 +39915,9 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
39890
39915
|
return [this.state.rules.dataBar.rangeValues || ""];
|
|
39891
39916
|
}
|
|
39892
39917
|
updateDataBarColor(color) {
|
|
39918
|
+
if (!isColorValid(color)) {
|
|
39919
|
+
return;
|
|
39920
|
+
}
|
|
39893
39921
|
this.state.rules.dataBar.color = Number.parseInt(color.substr(1), 16);
|
|
39894
39922
|
}
|
|
39895
39923
|
onDataBarRangeUpdate(ranges) {
|
|
@@ -39975,6 +40003,10 @@ css /* scss */ `
|
|
|
39975
40003
|
border: 1px solid #d8dadd;
|
|
39976
40004
|
color: #374151;
|
|
39977
40005
|
}
|
|
40006
|
+
|
|
40007
|
+
table {
|
|
40008
|
+
table-layout: fixed;
|
|
40009
|
+
}
|
|
39978
40010
|
}
|
|
39979
40011
|
`;
|
|
39980
40012
|
class CustomCurrencyPanel extends owl.Component {
|
|
@@ -42210,16 +42242,21 @@ class TextInput extends owl.Component {
|
|
|
42210
42242
|
}
|
|
42211
42243
|
this.inputRef.el?.blur();
|
|
42212
42244
|
}
|
|
42213
|
-
|
|
42214
|
-
|
|
42215
|
-
if (
|
|
42216
|
-
|
|
42217
|
-
|
|
42218
|
-
|
|
42219
|
-
|
|
42220
|
-
|
|
42221
|
-
|
|
42222
|
-
|
|
42245
|
+
onMouseDown(ev) {
|
|
42246
|
+
// Stop the event if the input is not focused, we handle everything in onMouseUp
|
|
42247
|
+
if (ev.target !== document.activeElement) {
|
|
42248
|
+
ev.preventDefault();
|
|
42249
|
+
ev.stopPropagation();
|
|
42250
|
+
}
|
|
42251
|
+
}
|
|
42252
|
+
onMouseUp(ev) {
|
|
42253
|
+
const target = ev.target;
|
|
42254
|
+
if (target !== document.activeElement) {
|
|
42255
|
+
target.focus();
|
|
42256
|
+
target.select();
|
|
42257
|
+
ev.preventDefault();
|
|
42258
|
+
ev.stopPropagation();
|
|
42259
|
+
}
|
|
42223
42260
|
}
|
|
42224
42261
|
}
|
|
42225
42262
|
|
|
@@ -42697,7 +42734,16 @@ class PivotTitleSection extends owl.Component {
|
|
|
42697
42734
|
newPivotId,
|
|
42698
42735
|
newSheetId,
|
|
42699
42736
|
});
|
|
42700
|
-
|
|
42737
|
+
let text;
|
|
42738
|
+
if (result.isSuccessful) {
|
|
42739
|
+
text = _t("Pivot duplicated.");
|
|
42740
|
+
}
|
|
42741
|
+
else if (result.isCancelledBecause("PivotInError" /* CommandResult.PivotInError */)) {
|
|
42742
|
+
text = _t("Cannot duplicate a pivot in error.");
|
|
42743
|
+
}
|
|
42744
|
+
else {
|
|
42745
|
+
text = _t("Pivot duplication failed.");
|
|
42746
|
+
}
|
|
42701
42747
|
const type = result.isSuccessful ? "success" : "danger";
|
|
42702
42748
|
this.env.notifyUser({
|
|
42703
42749
|
text,
|
|
@@ -43995,7 +44041,9 @@ class PivotSidePanelStore extends SpreadsheetStore {
|
|
|
43995
44041
|
pivot: this.draft,
|
|
43996
44042
|
});
|
|
43997
44043
|
this.draft = null;
|
|
43998
|
-
if (!this.alreadyNotified &&
|
|
44044
|
+
if (!this.alreadyNotified &&
|
|
44045
|
+
!this.isDynamicPivotInViewport() &&
|
|
44046
|
+
this.isStaticPivotInViewport()) {
|
|
43999
44047
|
const formulaId = this.getters.getPivotFormulaId(this.pivotId);
|
|
44000
44048
|
const pivotExample = `=PIVOT(${formulaId})`;
|
|
44001
44049
|
this.alreadyNotified = true;
|
|
@@ -44062,6 +44110,18 @@ class PivotSidePanelStore extends SpreadsheetStore {
|
|
|
44062
44110
|
}
|
|
44063
44111
|
return false;
|
|
44064
44112
|
}
|
|
44113
|
+
isStaticPivotInViewport() {
|
|
44114
|
+
for (const position of this.getters.getVisibleCellPositions()) {
|
|
44115
|
+
const cell = this.getters.getCell(position);
|
|
44116
|
+
if (cell?.isFormula) {
|
|
44117
|
+
const pivotFunction = getFirstPivotFunction(cell.compiledFormula.tokens);
|
|
44118
|
+
if (pivotFunction && pivotFunction.functionName !== "PIVOT") {
|
|
44119
|
+
return true;
|
|
44120
|
+
}
|
|
44121
|
+
}
|
|
44122
|
+
}
|
|
44123
|
+
return false;
|
|
44124
|
+
}
|
|
44065
44125
|
addDefaultDateTimeGranularity(fields, definition) {
|
|
44066
44126
|
const { columns, rows } = definition;
|
|
44067
44127
|
const columnsWithGranularity = deepCopy(columns);
|
|
@@ -45194,6 +45254,7 @@ css /* scss */ `
|
|
|
45194
45254
|
}
|
|
45195
45255
|
}
|
|
45196
45256
|
`;
|
|
45257
|
+
const DEFAULT_TABLE_STYLE_COLOR = "#3C78D8";
|
|
45197
45258
|
class TableStyleEditorPanel extends owl.Component {
|
|
45198
45259
|
static template = "o-spreadsheet-TableStyleEditorPanel";
|
|
45199
45260
|
static components = { Section, RoundColorPicker, TableStylePreview };
|
|
@@ -45212,7 +45273,7 @@ class TableStyleEditorPanel extends owl.Component {
|
|
|
45212
45273
|
: null;
|
|
45213
45274
|
return {
|
|
45214
45275
|
pickerOpened: false,
|
|
45215
|
-
primaryColor: editedStyle?.primaryColor ||
|
|
45276
|
+
primaryColor: editedStyle?.primaryColor || DEFAULT_TABLE_STYLE_COLOR,
|
|
45216
45277
|
selectedTemplateName: editedStyle?.templateName || "lightColoredText",
|
|
45217
45278
|
styleName: editedStyle?.displayName || this.env.model.getters.getNewCustomTableStyleName(),
|
|
45218
45279
|
};
|
|
@@ -45221,7 +45282,7 @@ class TableStyleEditorPanel extends owl.Component {
|
|
|
45221
45282
|
this.state.pickerOpened = !this.state.pickerOpened;
|
|
45222
45283
|
}
|
|
45223
45284
|
onColorPicked(color) {
|
|
45224
|
-
this.state.primaryColor = color;
|
|
45285
|
+
this.state.primaryColor = isColorValid(color) ? color : DEFAULT_TABLE_STYLE_COLOR;
|
|
45225
45286
|
this.state.pickerOpened = false;
|
|
45226
45287
|
}
|
|
45227
45288
|
onTemplatePicked(templateName) {
|
|
@@ -46838,6 +46899,7 @@ class FiguresContainer extends owl.Component {
|
|
|
46838
46899
|
draggedFigure: undefined,
|
|
46839
46900
|
horizontalSnap: undefined,
|
|
46840
46901
|
verticalSnap: undefined,
|
|
46902
|
+
cancelDnd: undefined,
|
|
46841
46903
|
});
|
|
46842
46904
|
setup() {
|
|
46843
46905
|
owl.onMounted(() => {
|
|
@@ -46850,12 +46912,28 @@ class FiguresContainer extends owl.Component {
|
|
|
46850
46912
|
// new rendering
|
|
46851
46913
|
this.render();
|
|
46852
46914
|
});
|
|
46915
|
+
owl.onWillUpdateProps(() => {
|
|
46916
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
46917
|
+
const draggedFigureId = this.dnd.draggedFigure?.id;
|
|
46918
|
+
if (draggedFigureId && !this.env.model.getters.getFigure(sheetId, draggedFigureId)) {
|
|
46919
|
+
if (this.dnd.cancelDnd) {
|
|
46920
|
+
this.dnd.cancelDnd();
|
|
46921
|
+
}
|
|
46922
|
+
this.dnd.draggedFigure = undefined;
|
|
46923
|
+
this.dnd.horizontalSnap = undefined;
|
|
46924
|
+
this.dnd.verticalSnap = undefined;
|
|
46925
|
+
this.dnd.cancelDnd = undefined;
|
|
46926
|
+
}
|
|
46927
|
+
});
|
|
46853
46928
|
}
|
|
46854
46929
|
getVisibleFigures() {
|
|
46855
46930
|
const visibleFigures = this.env.model.getters.getVisibleFigures();
|
|
46856
46931
|
if (this.dnd.draggedFigure &&
|
|
46857
46932
|
!visibleFigures.some((figure) => figure.id === this.dnd.draggedFigure?.id)) {
|
|
46858
|
-
|
|
46933
|
+
const draggedFigure = this.env.model.getters.getFigure(this.env.model.getters.getActiveSheetId(), this.dnd.draggedFigure?.id);
|
|
46934
|
+
if (draggedFigure) {
|
|
46935
|
+
visibleFigures.push(draggedFigure);
|
|
46936
|
+
}
|
|
46859
46937
|
}
|
|
46860
46938
|
return visibleFigures;
|
|
46861
46939
|
}
|
|
@@ -46974,7 +47052,7 @@ class FiguresContainer extends owl.Component {
|
|
|
46974
47052
|
this.dnd.verticalSnap = undefined;
|
|
46975
47053
|
this.env.model.dispatch("UPDATE_FIGURE", { sheetId, id: figure.id, x, y });
|
|
46976
47054
|
};
|
|
46977
|
-
startDnd(onMouseMove, onMouseUp);
|
|
47055
|
+
this.dnd.cancelDnd = startDnd(onMouseMove, onMouseUp);
|
|
46978
47056
|
}
|
|
46979
47057
|
/**
|
|
46980
47058
|
* Initialize the resize of a figure with mouse movements
|
|
@@ -47022,7 +47100,7 @@ class FiguresContainer extends owl.Component {
|
|
|
47022
47100
|
this.dnd.horizontalSnap = undefined;
|
|
47023
47101
|
this.dnd.verticalSnap = undefined;
|
|
47024
47102
|
};
|
|
47025
|
-
startDnd(onMouseMove, onMouseUp);
|
|
47103
|
+
this.dnd.cancelDnd = startDnd(onMouseMove, onMouseUp);
|
|
47026
47104
|
}
|
|
47027
47105
|
getOtherFigures(figId) {
|
|
47028
47106
|
return this.getVisibleFigures().filter((f) => f.id !== figId);
|
|
@@ -49430,7 +49508,7 @@ class Grid extends owl.Component {
|
|
|
49430
49508
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
49431
49509
|
owl.useEffect(() => {
|
|
49432
49510
|
if (!this.sidePanel.isOpen) {
|
|
49433
|
-
this.DOMFocusableElementStore.focus();
|
|
49511
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
49434
49512
|
}
|
|
49435
49513
|
}, () => [this.sidePanel.isOpen]);
|
|
49436
49514
|
}
|
|
@@ -49634,7 +49712,7 @@ class Grid extends owl.Component {
|
|
|
49634
49712
|
focusDefaultElement() {
|
|
49635
49713
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
49636
49714
|
this.composerFocusStore.activeComposer.editionMode === "inactive") {
|
|
49637
|
-
this.DOMFocusableElementStore.focus();
|
|
49715
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
49638
49716
|
}
|
|
49639
49717
|
}
|
|
49640
49718
|
get gridEl() {
|
|
@@ -50198,10 +50276,34 @@ class BordersPlugin extends CorePlugin {
|
|
|
50198
50276
|
const elements = [...cmd.elements].sort((a, b) => b - a);
|
|
50199
50277
|
for (const group of groupConsecutive(elements)) {
|
|
50200
50278
|
if (cmd.dimension === "COL") {
|
|
50201
|
-
|
|
50279
|
+
if (group[0] >= this.getters.getNumberCols(cmd.sheetId)) {
|
|
50280
|
+
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
50281
|
+
this.history.update("borders", cmd.sheetId, group[0] + 1, row, "vertical", undefined);
|
|
50282
|
+
}
|
|
50283
|
+
}
|
|
50284
|
+
if (group[group.length - 1] === 0) {
|
|
50285
|
+
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
50286
|
+
this.history.update("borders", cmd.sheetId, 0, row, "vertical", undefined);
|
|
50287
|
+
}
|
|
50288
|
+
}
|
|
50289
|
+
const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
50290
|
+
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
50291
|
+
this.shiftBordersHorizontally(cmd.sheetId, group[0] + 1, -group.length);
|
|
50202
50292
|
}
|
|
50203
50293
|
else {
|
|
50204
|
-
|
|
50294
|
+
if (group[0] >= this.getters.getNumberRows(cmd.sheetId)) {
|
|
50295
|
+
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
50296
|
+
this.history.update("borders", cmd.sheetId, col, group[0] + 1, "horizontal", undefined);
|
|
50297
|
+
}
|
|
50298
|
+
}
|
|
50299
|
+
if (group[group.length - 1] === 0) {
|
|
50300
|
+
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
50301
|
+
this.history.update("borders", cmd.sheetId, col, 0, "horizontal", undefined);
|
|
50302
|
+
}
|
|
50303
|
+
}
|
|
50304
|
+
const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
50305
|
+
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
50306
|
+
this.shiftBordersVertically(cmd.sheetId, group[0] + 1, -group.length);
|
|
50205
50307
|
}
|
|
50206
50308
|
}
|
|
50207
50309
|
break;
|
|
@@ -50508,6 +50610,18 @@ class BordersPlugin extends CorePlugin {
|
|
|
50508
50610
|
}
|
|
50509
50611
|
}
|
|
50510
50612
|
}
|
|
50613
|
+
/**
|
|
50614
|
+
* Remove the borders inside of a zone
|
|
50615
|
+
*/
|
|
50616
|
+
clearInsideBorders(sheetId, zones) {
|
|
50617
|
+
for (let zone of zones) {
|
|
50618
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
50619
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
50620
|
+
this.history.update("borders", sheetId, col, row, undefined);
|
|
50621
|
+
}
|
|
50622
|
+
}
|
|
50623
|
+
}
|
|
50624
|
+
}
|
|
50511
50625
|
/**
|
|
50512
50626
|
* Add a border to the existing one to a cell
|
|
50513
50627
|
*/
|
|
@@ -51175,7 +51289,7 @@ class CellPlugin extends CorePlugin {
|
|
|
51175
51289
|
const before = this.getters.getCell({ sheetId, col, row });
|
|
51176
51290
|
const hasContent = "content" in after || "formula" in after;
|
|
51177
51291
|
// Compute the new cell properties
|
|
51178
|
-
const afterContent = hasContent ?
|
|
51292
|
+
const afterContent = hasContent ? replaceNewLines(after?.content) : before?.content || "";
|
|
51179
51293
|
let style;
|
|
51180
51294
|
if (after.style !== undefined) {
|
|
51181
51295
|
style = after.style || undefined;
|
|
@@ -54087,6 +54201,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
54087
54201
|
};
|
|
54088
54202
|
}
|
|
54089
54203
|
getUnboundedZone(sheetId, zone) {
|
|
54204
|
+
if (zone.bottom === undefined || zone.right === undefined) {
|
|
54205
|
+
return zone;
|
|
54206
|
+
}
|
|
54090
54207
|
const isFullRow = zone.left === 0 && zone.right === this.getNumberCols(sheetId) - 1;
|
|
54091
54208
|
const isFullCol = zone.top === 0 && zone.bottom === this.getNumberRows(sheetId) - 1;
|
|
54092
54209
|
return {
|
|
@@ -61132,6 +61249,9 @@ class Session extends EventBus {
|
|
|
61132
61249
|
}
|
|
61133
61250
|
}
|
|
61134
61251
|
this.acknowledge(message);
|
|
61252
|
+
if (message.type === "REMOTE_REVISION" && message.clientId === this.clientId) {
|
|
61253
|
+
return;
|
|
61254
|
+
}
|
|
61135
61255
|
this.trigger("collaborative-event-received");
|
|
61136
61256
|
}
|
|
61137
61257
|
onClientMoved(message) {
|
|
@@ -61575,7 +61695,7 @@ class FormatPlugin extends UIPlugin {
|
|
|
61575
61695
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
61576
61696
|
const position = { sheetId, col, row };
|
|
61577
61697
|
const pivotCell = this.getters.getPivotCellFromPosition(position);
|
|
61578
|
-
if (
|
|
61698
|
+
if (this.isSpilledPivotValueFormula(position, pivotCell)) {
|
|
61579
61699
|
measurePositions.push(position);
|
|
61580
61700
|
const pivotId = this.getters.getPivotIdFromPosition(position) || "";
|
|
61581
61701
|
measuresByPivotId[pivotId] ??= new Set();
|
|
@@ -61612,6 +61732,10 @@ class FormatPlugin extends UIPlugin {
|
|
|
61612
61732
|
format,
|
|
61613
61733
|
});
|
|
61614
61734
|
}
|
|
61735
|
+
isSpilledPivotValueFormula(position, pivotCell) {
|
|
61736
|
+
const cell = this.getters.getCell(position);
|
|
61737
|
+
return pivotCell.type === "VALUE" && !cell?.isFormula;
|
|
61738
|
+
}
|
|
61615
61739
|
/**
|
|
61616
61740
|
* This function allows to adjust the quantity of decimal places after a decimal
|
|
61617
61741
|
* point on cells containing number value. It does this by changing the cells
|
|
@@ -61742,6 +61866,19 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
61742
61866
|
|
|
61743
61867
|
class InsertPivotPlugin extends UIPlugin {
|
|
61744
61868
|
static getters = [];
|
|
61869
|
+
allowDispatch(cmd) {
|
|
61870
|
+
switch (cmd.type) {
|
|
61871
|
+
case "DUPLICATE_PIVOT_IN_NEW_SHEET":
|
|
61872
|
+
if (!this.getters.isExistingPivot(cmd.pivotId)) {
|
|
61873
|
+
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
61874
|
+
}
|
|
61875
|
+
if (!this.getters.getPivot(cmd.pivotId).isValid()) {
|
|
61876
|
+
return "PivotInError" /* CommandResult.PivotInError */;
|
|
61877
|
+
}
|
|
61878
|
+
break;
|
|
61879
|
+
}
|
|
61880
|
+
return "Success" /* CommandResult.Success */;
|
|
61881
|
+
}
|
|
61745
61882
|
handle(cmd) {
|
|
61746
61883
|
switch (cmd.type) {
|
|
61747
61884
|
case "INSERT_NEW_PIVOT":
|
|
@@ -65000,6 +65137,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65000
65137
|
break;
|
|
65001
65138
|
case "DELETE_SHEET":
|
|
65002
65139
|
this.cleanViewports();
|
|
65140
|
+
this.sheetsWithDirtyViewports.delete(cmd.sheetId);
|
|
65003
65141
|
break;
|
|
65004
65142
|
case "ACTIVATE_SHEET":
|
|
65005
65143
|
this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
|
|
@@ -65969,11 +66107,6 @@ class BottomBarSheet extends owl.Component {
|
|
|
65969
66107
|
editionState = "initializing";
|
|
65970
66108
|
DOMFocusableElementStore;
|
|
65971
66109
|
setup() {
|
|
65972
|
-
owl.onMounted(() => {
|
|
65973
|
-
if (this.isSheetActive) {
|
|
65974
|
-
this.scrollToSheet();
|
|
65975
|
-
}
|
|
65976
|
-
});
|
|
65977
66110
|
owl.onPatched(() => {
|
|
65978
66111
|
if (this.sheetNameRef.el && this.state.isEditing && this.editionState === "initializing") {
|
|
65979
66112
|
this.editionState = "editing";
|
|
@@ -65982,6 +66115,11 @@ class BottomBarSheet extends owl.Component {
|
|
|
65982
66115
|
});
|
|
65983
66116
|
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
65984
66117
|
owl.useExternalListener(window, "click", () => (this.state.pickerOpened = false));
|
|
66118
|
+
owl.useEffect((sheetId) => {
|
|
66119
|
+
if (this.props.sheetId === sheetId) {
|
|
66120
|
+
this.scrollToSheet();
|
|
66121
|
+
}
|
|
66122
|
+
}, () => [this.env.model.getters.getActiveSheetId()]);
|
|
65985
66123
|
}
|
|
65986
66124
|
focusInputAndSelectContent() {
|
|
65987
66125
|
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
@@ -65993,7 +66131,10 @@ class BottomBarSheet extends owl.Component {
|
|
|
65993
66131
|
}
|
|
65994
66132
|
}
|
|
65995
66133
|
scrollToSheet() {
|
|
65996
|
-
this.sheetDivRef.el?.scrollIntoView?.(
|
|
66134
|
+
this.sheetDivRef.el?.scrollIntoView?.({
|
|
66135
|
+
behavior: "smooth",
|
|
66136
|
+
inline: "nearest",
|
|
66137
|
+
});
|
|
65997
66138
|
}
|
|
65998
66139
|
onFocusOut() {
|
|
65999
66140
|
if (this.state.isEditing && this.editionState !== "initializing") {
|
|
@@ -66023,11 +66164,11 @@ class BottomBarSheet extends owl.Component {
|
|
|
66023
66164
|
if (ev.key === "Enter") {
|
|
66024
66165
|
ev.preventDefault();
|
|
66025
66166
|
this.stopEdition();
|
|
66026
|
-
this.DOMFocusableElementStore.focus();
|
|
66167
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
66027
66168
|
}
|
|
66028
66169
|
if (ev.key === "Escape") {
|
|
66029
66170
|
this.cancelEdition();
|
|
66030
|
-
this.DOMFocusableElementStore.focus();
|
|
66171
|
+
this.DOMFocusableElementStore.focusableElement?.focus();
|
|
66031
66172
|
}
|
|
66032
66173
|
}
|
|
66033
66174
|
onMouseEventSheetName(ev) {
|
|
@@ -67398,7 +67539,6 @@ css /* scss */ `
|
|
|
67398
67539
|
height: fit-content;
|
|
67399
67540
|
margin-top: -1px;
|
|
67400
67541
|
border: 1px solid;
|
|
67401
|
-
z-index: ${ComponentsImportance.TopBarComposer};
|
|
67402
67542
|
font-family: ${DEFAULT_FONT};
|
|
67403
67543
|
|
|
67404
67544
|
.o-composer:empty:not(:focus):not(.active)::before {
|
|
@@ -67456,6 +67596,7 @@ class TopBarComposer extends owl.Component {
|
|
|
67456
67596
|
}
|
|
67457
67597
|
return cssPropertiesToCss({
|
|
67458
67598
|
"border-color": SELECTION_BORDER_COLOR,
|
|
67599
|
+
"z-index": String(ComponentsImportance.TopBarComposer),
|
|
67459
67600
|
});
|
|
67460
67601
|
}
|
|
67461
67602
|
onFocus(selection) {
|
|
@@ -71651,7 +71792,12 @@ function createSharedStrings(strings) {
|
|
|
71651
71792
|
["count", strings.length],
|
|
71652
71793
|
["uniqueCount", strings.length],
|
|
71653
71794
|
];
|
|
71654
|
-
const stringNodes = strings.map((string) =>
|
|
71795
|
+
const stringNodes = strings.map((string) => {
|
|
71796
|
+
if (string.trim() !== string) {
|
|
71797
|
+
return escapeXml /*xml*/ `<si><t xml:space="preserve">${string}</t></si>`;
|
|
71798
|
+
}
|
|
71799
|
+
return escapeXml /*xml*/ `<si><t>${string}</t></si>`;
|
|
71800
|
+
});
|
|
71655
71801
|
const xml = escapeXml /*xml*/ `
|
|
71656
71802
|
<sst ${formatAttributes(namespaces)}>
|
|
71657
71803
|
${joinXmlNodes(stringNodes)}
|
|
@@ -71896,7 +72042,7 @@ class Model extends EventBus {
|
|
|
71896
72042
|
// events
|
|
71897
72043
|
this.setupSessionEvents();
|
|
71898
72044
|
this.joinSession();
|
|
71899
|
-
if (config.snapshotRequested) {
|
|
72045
|
+
if (config.snapshotRequested || (data["[Content_Types].xml"] && !this.getters.isReadonly())) {
|
|
71900
72046
|
const startSnapshot = performance.now();
|
|
71901
72047
|
console.debug("Snapshot requested");
|
|
71902
72048
|
this.session.snapshot(this.exportData());
|
|
@@ -72394,6 +72540,8 @@ const helpers = {
|
|
|
72394
72540
|
splitReference,
|
|
72395
72541
|
formatTickValue,
|
|
72396
72542
|
sanitizeSheetName,
|
|
72543
|
+
isNumber,
|
|
72544
|
+
isDateTime,
|
|
72397
72545
|
};
|
|
72398
72546
|
const links = {
|
|
72399
72547
|
isMarkdownLink,
|
|
@@ -72529,6 +72677,6 @@ exports.tokenColors = tokenColors;
|
|
|
72529
72677
|
exports.tokenize = tokenize;
|
|
72530
72678
|
|
|
72531
72679
|
|
|
72532
|
-
__info__.version = "18.0.
|
|
72533
|
-
__info__.date = "
|
|
72534
|
-
__info__.hash = "
|
|
72680
|
+
__info__.version = "18.0.9";
|
|
72681
|
+
__info__.date = "2025-01-14T11:33:47.429Z";
|
|
72682
|
+
__info__.hash = "0c5220e";
|