@odoo/o-spreadsheet 16.0.5 → 16.0.6

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.
@@ -115,88 +115,88 @@ const LINK_COLOR = "#01666b";
115
115
  const FILTERS_COLOR = "#188038";
116
116
  const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
117
117
  const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
118
- // Color picker
118
+ // Color picker defaults as upper case HEX to match `toHex`helper
119
119
  const COLOR_PICKER_DEFAULTS = [
120
120
  "#000000",
121
121
  "#434343",
122
122
  "#666666",
123
123
  "#999999",
124
- "#b7b7b7",
125
- "#cccccc",
126
- "#d9d9d9",
127
- "#efefef",
128
- "#f3f3f3",
129
- "#ffffff",
124
+ "#B7B7B7",
125
+ "#CCCCCC",
126
+ "#D9D9D9",
127
+ "#EFEFEF",
128
+ "#F3F3F3",
129
+ "#FFFFFF",
130
130
  "#980000",
131
- "#ff0000",
132
- "#ff9900",
133
- "#ffff00",
134
- "#00ff00",
135
- "#00ffff",
136
- "#4a86e8",
137
- "#0000ff",
138
- "#9900ff",
139
- "#ff00ff",
140
- "#e6b8af",
141
- "#f4cccc",
142
- "#fce5cd",
143
- "#fff2cc",
144
- "#d9ead3",
145
- "#d0e0e3",
146
- "#c9daf8",
147
- "#cfe2f3",
148
- "#d9d2e9",
149
- "#ead1dc",
150
- "#dd7e6b",
151
- "#ea9999",
152
- "#f9cb9c",
153
- "#ffe599",
154
- "#b6d7a8",
155
- "#a2c4c9",
156
- "#a4c2f4",
157
- "#9fc5e8",
158
- "#b4a7d6",
159
- "#d5a6bd",
160
- "#cc4125",
161
- "#e06666",
162
- "#f6b26b",
163
- "#ffd966",
164
- "#93c47d",
165
- "#76a5af",
166
- "#6d9eeb",
167
- "#6fa8dc",
168
- "#8e7cc3",
169
- "#c27ba0",
170
- "#a61c00",
171
- "#cc0000",
172
- "#e69138",
173
- "#f1c232",
174
- "#6aa84f",
175
- "#45818e",
176
- "#3c78d8",
177
- "#3d85c6",
178
- "#674ea7",
179
- "#a64d79",
180
- "#85200c",
131
+ "#FF0000",
132
+ "#FF9900",
133
+ "#FFFF00",
134
+ "#00FF00",
135
+ "#00FFFF",
136
+ "#4A86E8",
137
+ "#0000FF",
138
+ "#9900FF",
139
+ "#FF00FF",
140
+ "#E6B8AF",
141
+ "#F4CCCC",
142
+ "#FCE5CD",
143
+ "#FFF2CC",
144
+ "#D9EAD3",
145
+ "#D0E0E3",
146
+ "#C9DAF8",
147
+ "#CFE2F3",
148
+ "#D9D2E9",
149
+ "#EAD1DC",
150
+ "#DD7E6B",
151
+ "#EA9999",
152
+ "#F9CB9C",
153
+ "#FFE599",
154
+ "#B6D7A8",
155
+ "#A2C4C9",
156
+ "#A4C2F4",
157
+ "#9FC5E8",
158
+ "#B4A7D6",
159
+ "#D5A6BD",
160
+ "#CC4125",
161
+ "#E06666",
162
+ "#F6B26B",
163
+ "#FFD966",
164
+ "#93C47D",
165
+ "#76A5AF",
166
+ "#6D9EEB",
167
+ "#6FA8DC",
168
+ "#8E7CC3",
169
+ "#C27BA0",
170
+ "#A61C00",
171
+ "#CC0000",
172
+ "#E69138",
173
+ "#F1C232",
174
+ "#6AA84F",
175
+ "#45818E",
176
+ "#3C78D8",
177
+ "#3D85C6",
178
+ "#674EA7",
179
+ "#A64D79",
180
+ "#85200C",
181
181
  "#990000",
182
- "#b45f06",
183
- "#bf9000",
184
- "#38761d",
185
- "#134f5c",
186
- "#1155cc",
187
- "#0b5394",
188
- "#351c75",
189
- "#741b47",
190
- "#5b0f00",
182
+ "#B45F06",
183
+ "#BF9000",
184
+ "#38761D",
185
+ "#134F5C",
186
+ "#1155CC",
187
+ "#0B5394",
188
+ "#351C75",
189
+ "#741B47",
190
+ "#5B0F00",
191
191
  "#660000",
192
- "#783f04",
193
- "#7f6000",
194
- "#274e13",
195
- "#0c343d",
196
- "#1c4587",
192
+ "#783F04",
193
+ "#7F6000",
194
+ "#274E13",
195
+ "#0C343D",
196
+ "#1C4587",
197
197
  "#073763",
198
- "#20124d",
199
- "#4c1130",
198
+ "#20124D",
199
+ "#4C1130",
200
200
  ];
201
201
  // Dimensions
202
202
  const MIN_ROW_HEIGHT = 10;
@@ -234,7 +234,7 @@ const DEFAULT_FONT = "'Roboto', arial";
234
234
  const DEFAULT_BORDER_DESC = ["thin", "#000"];
235
235
  const DEFAULT_FILTER_BORDER_DESC = ["thin", FILTERS_COLOR];
236
236
  // DateTimeRegex
237
- const DATETIME_FORMAT = /[ymd:]/;
237
+ const DATETIME_FORMAT = /[ymdhs:]/;
238
238
  // Ranges
239
239
  const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
240
240
  // Max Number of history steps kept in memory
@@ -270,11 +270,13 @@ var ComponentsImportance;
270
270
  ComponentsImportance[ComponentsImportance["Highlight"] = 5] = "Highlight";
271
271
  ComponentsImportance[ComponentsImportance["Figure"] = 10] = "Figure";
272
272
  ComponentsImportance[ComponentsImportance["ScrollBar"] = 15] = "ScrollBar";
273
- ComponentsImportance[ComponentsImportance["Dropdown"] = 16] = "Dropdown";
274
- ComponentsImportance[ComponentsImportance["Composer"] = 20] = "Composer";
273
+ ComponentsImportance[ComponentsImportance["GridPopover"] = 19] = "GridPopover";
274
+ ComponentsImportance[ComponentsImportance["GridComposer"] = 20] = "GridComposer";
275
+ ComponentsImportance[ComponentsImportance["Dropdown"] = 21] = "Dropdown";
275
276
  ComponentsImportance[ComponentsImportance["ColorPicker"] = 25] = "ColorPicker";
276
277
  ComponentsImportance[ComponentsImportance["IconPicker"] = 25] = "IconPicker";
277
- ComponentsImportance[ComponentsImportance["Popover"] = 30] = "Popover";
278
+ ComponentsImportance[ComponentsImportance["TopBarComposer"] = 30] = "TopBarComposer";
279
+ ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
278
280
  ComponentsImportance[ComponentsImportance["ChartAnchor"] = 1000] = "ChartAnchor";
279
281
  })(ComponentsImportance || (ComponentsImportance = {}));
280
282
  const DEFAULT_SHEETVIEW_SIZE = 1000;
@@ -1043,6 +1045,8 @@ function transpose2dArray(matrix) {
1043
1045
  return matrix[0].map((_, i) => matrix.map((row) => row[i]));
1044
1046
  }
1045
1047
 
1048
+ const RBA_REGEX = /rgba?\(|\s+|\)/gi;
1049
+ const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/g;
1046
1050
  const colors$1 = [
1047
1051
  "#eb6d00",
1048
1052
  "#0074d9",
@@ -1073,7 +1077,10 @@ function getNextColor() {
1073
1077
  }
1074
1078
  /**
1075
1079
  * Converts any CSS color value to a standardized hex6 value.
1076
- * Accepts: hex3, hex6, hex8 and rgb (rgba is not supported)
1080
+ * Accepts: hex3, hex6, hex8, rgb[1] and rgba[1].
1081
+ *
1082
+ * [1] under the form rgb(r, g, b, a?) or rgba(r, g, b, a?)
1083
+ * with r,g,b ∈ [0, 255] and a ∈ [0, 1]
1077
1084
  *
1078
1085
  * toHex("#ABC")
1079
1086
  * >> "#AABBCC"
@@ -1084,27 +1091,31 @@ function getNextColor() {
1084
1091
  * toHex("rgb(30, 80, 16)")
1085
1092
  * >> "#1E5010"
1086
1093
  *
1094
+ * * toHex("rgb(30, 80, 16, 0.5)")
1095
+ * >> "#1E501080"
1096
+ *
1087
1097
  */
1088
1098
  function toHex(color) {
1089
- if (color.includes("rgba")) {
1090
- throw new Error(`rgba() conversion currently not supported: ${color}`);
1099
+ let hexColor = color;
1100
+ if (color.startsWith("rgb")) {
1101
+ hexColor = rgbaStringToHex(color);
1091
1102
  }
1092
- if (color.includes("rgb")) {
1093
- return rgbToHex6(color);
1094
- }
1095
- color = color.replace("#", "").toUpperCase();
1096
- if (color.length === 3 || color.length === 4) {
1097
- color = color.split("").reduce((acc, h) => acc + h + h, "");
1103
+ else {
1104
+ hexColor = color.replace("#", "").toUpperCase();
1105
+ if (hexColor.length === 3 || hexColor.length === 4) {
1106
+ hexColor = hexColor.split("").reduce((acc, h) => acc + h + h, "");
1107
+ }
1108
+ hexColor = `#${hexColor}`;
1098
1109
  }
1099
- if (color.replace(/[a-f0-9]/gi, "") !== "") {
1100
- throw new Error("invalid color");
1110
+ if (!hexColor.match(HEX_MATCH)) {
1111
+ throw new Error(`invalid color input: ${color}`);
1101
1112
  }
1102
- return "#" + color;
1113
+ return hexColor;
1103
1114
  }
1104
1115
  function isColorValid(color) {
1105
1116
  try {
1106
- const { r, g, b, a } = colorToRGBA(color);
1107
- return (isColorValueValid(r) && isColorValueValid(g) && isColorValueValid(b) && isColorValueValid(a));
1117
+ toHex(color);
1118
+ return true;
1108
1119
  }
1109
1120
  catch (error) {
1110
1121
  return false;
@@ -1137,15 +1148,29 @@ function relativeLuminance(color) {
1137
1148
  /**
1138
1149
  * Convert a CSS rgb color string to a standardized hex6 color value.
1139
1150
  *
1140
- * rgbToHex6("rgb(30, 80, 16)")
1151
+ * rgbaStringToHex("rgb(30, 80, 16)")
1141
1152
  * >> "#1E5010"
1153
+ *
1154
+ * rgbaStringToHex("rgba(30, 80, 16, 0.5)")
1155
+ * >> "#1E501080"
1156
+ *
1157
+ * DOES NOT SUPPORT NON INTEGER RGB VALUES
1142
1158
  */
1143
- function rgbToHex6(color) {
1144
- return ("#" +
1145
- concat(color
1146
- .slice(4, -1)
1147
- .split(",")
1148
- .map((valueString) => parseInt(valueString, 10).toString(16).padStart(2, "0"))).toUpperCase());
1159
+ function rgbaStringToHex(color) {
1160
+ const stringVals = color.replace(RBA_REGEX, "").split(",");
1161
+ let alphaHex = 255;
1162
+ if (stringVals.length !== 3 && stringVals.length !== 4) {
1163
+ throw new Error("invalid color");
1164
+ }
1165
+ else if (stringVals.length === 4) {
1166
+ const alpha = parseFloat(stringVals.pop() || "1");
1167
+ alphaHex = Math.round((alpha || 1) * 255);
1168
+ }
1169
+ const vals = stringVals.map((val) => parseInt(val, 10));
1170
+ if (alphaHex !== 255) {
1171
+ vals.push(alphaHex);
1172
+ }
1173
+ return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
1149
1174
  }
1150
1175
  /**
1151
1176
  * RGBA to HEX representation (#RRGGBBAA).
@@ -1167,7 +1192,7 @@ function rgbaToHex(rgba) {
1167
1192
  a = "0" + a;
1168
1193
  if (a === "ff")
1169
1194
  a = "";
1170
- return "#" + r + g + b + a;
1195
+ return ("#" + r + g + b + a).toUpperCase();
1171
1196
  }
1172
1197
  /**
1173
1198
  * Color string to RGBA representation
@@ -1288,6 +1313,9 @@ function rgbaToHSLA(rgba) {
1288
1313
  s = +(s * 100).toFixed(1);
1289
1314
  l = +(l * 100).toFixed(1);
1290
1315
  return { a: rgba.a, h, s, l };
1316
+ }
1317
+ function isSameColor(color1, color2) {
1318
+ return isColorValid(color1) && isColorValid(color2) && toHex(color1) === toHex(color2);
1291
1319
  }
1292
1320
 
1293
1321
  /** Reference of a cell (eg. A1, $B$5) */
@@ -1846,7 +1874,7 @@ function convertInternalFormatToFormat(internalFormat) {
1846
1874
  * formula, commas are used to separate arguments
1847
1875
  * - it does not support % symbol, in formulas % is an operator
1848
1876
  */
1849
- const formulaNumberRegexp = /^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+/;
1877
+ const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
1850
1878
  const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
1851
1879
  const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
1852
1880
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -3826,7 +3854,7 @@ class Popover extends owl.Component {
3826
3854
  const shadow = maxHeight !== 0 ? "box-shadow: 1px 2px 5px 2px rgb(51 51 51 / 15%);" : "";
3827
3855
  return `
3828
3856
  position: absolute;
3829
- z-index: ${ComponentsImportance.Popover};
3857
+ z-index: ${this.props.zIndex};
3830
3858
  ${verticalPosition}px;
3831
3859
  ${horizontalPosition}px;
3832
3860
  ${height}px;
@@ -3870,6 +3898,7 @@ Popover.defaultProps = {
3870
3898
  verticalOffset: 0,
3871
3899
  marginTop: 0,
3872
3900
  onMouseWheel: () => { },
3901
+ zIndex: ComponentsImportance.Popover,
3873
3902
  };
3874
3903
 
3875
3904
  //------------------------------------------------------------------------------
@@ -8432,6 +8461,9 @@ class ColorPicker extends owl.Component {
8432
8461
  const { display, background, left, top } = this.state.style;
8433
8462
  return `display:${display};${display === "block" ? `background-color:${background};left:${left};top:${top};` : ""}`;
8434
8463
  }
8464
+ isSameColor(color1, color2) {
8465
+ return isSameColor(color1, color2);
8466
+ }
8435
8467
  }
8436
8468
  ColorPicker.template = "o-spreadsheet-ColorPicker";
8437
8469
 
@@ -8557,6 +8589,12 @@ class GaugeChartDesignPanel extends owl.Component {
8557
8589
  const cancelledReasons = [...(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.reasons) || [])];
8558
8590
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
8559
8591
  }
8592
+ onClick(ev) {
8593
+ this.state.openedMenu = undefined;
8594
+ }
8595
+ setup() {
8596
+ owl.useExternalListener(window, "click", this.onClick);
8597
+ }
8560
8598
  updateBackgroundColor(color) {
8561
8599
  this.state.openedMenu = undefined;
8562
8600
  this.props.updateChart({
@@ -8725,6 +8763,12 @@ class ScorecardChartDesignPanel extends owl.Component {
8725
8763
  openedColorPicker: undefined,
8726
8764
  });
8727
8765
  }
8766
+ onClick(ev) {
8767
+ this.state.openedColorPicker = undefined;
8768
+ }
8769
+ setup() {
8770
+ owl.useExternalListener(window, "click", this.onClick);
8771
+ }
8728
8772
  updateTitle(ev) {
8729
8773
  this.props.updateChart({
8730
8774
  title: ev.target.value,
@@ -19926,7 +19970,6 @@ css /* scss */ `
19926
19970
  padding: 0;
19927
19971
  margin: 0;
19928
19972
  border: 0;
19929
- z-index: ${ComponentsImportance.Composer};
19930
19973
  flex-grow: 1;
19931
19974
  max-height: inherit;
19932
19975
  .o-composer {
@@ -19960,6 +20003,10 @@ css /* scss */ `
19960
20003
  .o-topbar-toolbar .o-composer-container:focus-within {
19961
20004
  border: 1px solid ${SELECTION_BORDER_COLOR};
19962
20005
  }
20006
+
20007
+ .o-topbar-toolbar .o-composer-container {
20008
+ z-index: ${ComponentsImportance.TopBarComposer};
20009
+ }
19963
20010
  `;
19964
20011
  class Composer extends owl.Component {
19965
20012
  constructor() {
@@ -20384,7 +20431,7 @@ const SCROLLBAR_HIGHT = 15;
20384
20431
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
20385
20432
  css /* scss */ `
20386
20433
  div.o-grid-composer {
20387
- z-index: ${ComponentsImportance.Composer};
20434
+ z-index: ${ComponentsImportance.GridComposer};
20388
20435
  box-sizing: border-box;
20389
20436
  position: absolute;
20390
20437
  border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
@@ -21214,6 +21261,10 @@ GridOverlay.defaultProps = {
21214
21261
  };
21215
21262
 
21216
21263
  class GridPopover extends owl.Component {
21264
+ constructor() {
21265
+ super(...arguments);
21266
+ this.zIndex = ComponentsImportance.GridPopover;
21267
+ }
21217
21268
  get cellPopover() {
21218
21269
  const popover = this.env.model.getters.getCellPopover(this.props.hoveredCell);
21219
21270
  if (!popover.isOpen) {
@@ -23736,6 +23787,72 @@ function fixXlsxUnicode(str) {
23736
23787
  });
23737
23788
  }
23738
23789
 
23790
+ const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
23791
+ /**
23792
+ * Convert excel format to o_spreadsheet format
23793
+ *
23794
+ * Excel format are defined in openXML §18.8.31
23795
+ */
23796
+ function convertXlsxFormat(numFmtId, formats, warningManager) {
23797
+ var _a, _b, _c;
23798
+ if (numFmtId === 0) {
23799
+ return undefined;
23800
+ }
23801
+ // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
23802
+ let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
23803
+ if (format) {
23804
+ try {
23805
+ let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
23806
+ convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
23807
+ convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
23808
+ // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
23809
+ const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
23810
+ const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
23811
+ if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
23812
+ throw new Error("Multiple escaped blocks in format");
23813
+ }
23814
+ convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
23815
+ convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM
23816
+ convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
23817
+ convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
23818
+ convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters
23819
+ if (isXlsxDateFormat(convertedFormat)) {
23820
+ convertedFormat = convertDateFormat$1(convertedFormat);
23821
+ }
23822
+ if (isFormatSupported(convertedFormat)) {
23823
+ return convertedFormat;
23824
+ }
23825
+ }
23826
+ catch (e) { }
23827
+ }
23828
+ warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
23829
+ return undefined;
23830
+ }
23831
+ function isFormatSupported(format) {
23832
+ try {
23833
+ formatValue(0, format);
23834
+ return true;
23835
+ }
23836
+ catch (e) {
23837
+ return false;
23838
+ }
23839
+ }
23840
+ function isXlsxDateFormat(format) {
23841
+ return format.match(XLSX_DATE_FORMAT_REGEX) !== null;
23842
+ }
23843
+ function convertDateFormat$1(format) {
23844
+ // Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML,
23845
+ // but can still occur and are supported by Excel/Google sheets
23846
+ format = format.toLowerCase();
23847
+ format = format.replace(/mmmmm|mmmm|mmm/g, "mm");
23848
+ format = format.replace(/dddd|ddd/g, "dd");
23849
+ format = format.replace(/am\/pm|a\/m/g, "a");
23850
+ format = format.replace(/\byy\b/g, "yyyy");
23851
+ format = format.replace(/hhhh/g, "hh");
23852
+ format = format.replace(/\bh\b/g, "hh");
23853
+ return format;
23854
+ }
23855
+
23739
23856
  function convertBorders(data, warningManager) {
23740
23857
  const borderArray = data.borders.map((border) => {
23741
23858
  addBorderWarnings(border, warningManager);
@@ -23800,41 +23917,6 @@ function convertFormats(data, warningManager) {
23800
23917
  }
23801
23918
  return arrayToObject(formats, 1);
23802
23919
  }
23803
- /**
23804
- * Convert excel format to o_spreadsheet format
23805
- *
23806
- * Excel format are defined in openXML §18.8.31
23807
- */
23808
- function convertXlsxFormat(numFmtId, formats, warningManager) {
23809
- var _a, _b, _c;
23810
- if (numFmtId === 0) {
23811
- return undefined;
23812
- }
23813
- // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
23814
- let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
23815
- if (format) {
23816
- try {
23817
- let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
23818
- convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
23819
- convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
23820
- // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
23821
- const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
23822
- const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
23823
- if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
23824
- throw new Error("Multiple escaped blocks in format");
23825
- }
23826
- convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
23827
- convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore with of next char for align purposes. Not supported ATM
23828
- convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
23829
- convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
23830
- formatValue(0, convertedFormat);
23831
- return convertedFormat;
23832
- }
23833
- catch (e) { }
23834
- }
23835
- warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
23836
- return undefined;
23837
- }
23838
23920
  /**
23839
23921
  * We currently only support only a set of font sizes, we cannot define new font sizes.
23840
23922
  * This function adapts an arbitrary font size to the closest supported font size.
@@ -32017,9 +32099,7 @@ class CustomColorsPlugin extends UIPlugin {
32017
32099
  // remove duplicates first to check validity on a reduced
32018
32100
  // set of colors, then normalize to HEX and remove duplicates
32019
32101
  // again
32020
- [...new Set([...usedColors, ...this.customColors])]
32021
- .filter(isColorValid)
32022
- .map((c) => toHex(c).toLowerCase())),
32102
+ [...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
32023
32103
  ]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
32024
32104
  }
32025
32105
  getColorsFromCells(cells) {
@@ -32080,7 +32160,7 @@ class CustomColorsPlugin extends UIPlugin {
32080
32160
  return [...chartsColors];
32081
32161
  }
32082
32162
  tryToAddColor(color) {
32083
- const formattedColor = toHex(color).toLowerCase();
32163
+ const formattedColor = toHex(color);
32084
32164
  if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
32085
32165
  this.customColors.add(formattedColor);
32086
32166
  }
@@ -35821,8 +35901,8 @@ class InternalViewport {
35821
35901
  this.getters = getters;
35822
35902
  this.sheetId = sheetId;
35823
35903
  this.boundaries = boundaries;
35824
- this.width = sizeInGrid.width;
35825
- this.height = sizeInGrid.height;
35904
+ this.viewportWidth = sizeInGrid.width;
35905
+ this.viewportHeight = sizeInGrid.height;
35826
35906
  this.offsetScrollbarX = offsets.x;
35827
35907
  this.offsetScrollbarY = offsets.y;
35828
35908
  this.canScrollVertically = options.canScrollVertically;
@@ -35833,6 +35913,10 @@ class InternalViewport {
35833
35913
  this.adjustViewportOffsetY();
35834
35914
  }
35835
35915
  // PUBLIC
35916
+ /** Returns the maximum size (in Pixels) of the viewport relative to its allocated client size
35917
+ * When the viewport grid size is smaller than its client width (resp. height), it will return
35918
+ * the client width (resp. height).
35919
+ */
35836
35920
  getMaxSize() {
35837
35921
  const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
35838
35922
  first: this.boundaries.left,
@@ -35844,20 +35928,24 @@ class InternalViewport {
35844
35928
  });
35845
35929
  const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
35846
35930
  const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
35847
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.width, 0);
35931
+ const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
35848
35932
  const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
35849
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.height, 0);
35933
+ const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
35850
35934
  const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
35851
- const width = lastColEnd -
35852
- this.offsetCorrectionX +
35853
- (this.canScrollHorizontally
35854
- ? Math.max(DEFAULT_CELL_WIDTH, Math.min(leftColSize, this.width - lastColSize))
35855
- : 0);
35856
- const height = lastRowEnd -
35857
- this.offsetCorrectionY +
35858
- (this.canScrollVertically
35859
- ? Math.max(DEFAULT_CELL_HEIGHT + 5, Math.min(topRowSize, this.height - lastRowSize))
35860
- : 0);
35935
+ let width = lastColEnd - this.offsetCorrectionX;
35936
+ if (this.canScrollHorizontally) {
35937
+ width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
35938
+ Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
35939
+ );
35940
+ width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
35941
+ }
35942
+ let height = lastRowEnd - this.offsetCorrectionY;
35943
+ if (this.canScrollVertically) {
35944
+ height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
35945
+ Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
35946
+ );
35947
+ height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
35948
+ }
35861
35949
  return { width, height };
35862
35950
  }
35863
35951
  /**
@@ -35866,7 +35954,7 @@ class InternalViewport {
35866
35954
  * It returns -1 if no column is found.
35867
35955
  */
35868
35956
  getColIndex(x, absolute = false) {
35869
- if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.width) {
35957
+ if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
35870
35958
  return -1;
35871
35959
  }
35872
35960
  return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
@@ -35877,7 +35965,7 @@ class InternalViewport {
35877
35965
  * It returns -1 if no row is found.
35878
35966
  */
35879
35967
  getRowIndex(y, absolute = false) {
35880
- if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.height) {
35968
+ if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
35881
35969
  return -1;
35882
35970
  }
35883
35971
  return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
@@ -35904,7 +35992,7 @@ class InternalViewport {
35904
35992
  adjustPositionX(col) {
35905
35993
  const sheetId = this.sheetId;
35906
35994
  const { start, end } = this.getters.getColDimensions(sheetId, col);
35907
- while (end > this.offsetX + this.offsetCorrectionX + this.width &&
35995
+ while (end > this.offsetX + this.offsetCorrectionX + this.viewportWidth &&
35908
35996
  this.offsetX + this.offsetCorrectionX < start) {
35909
35997
  this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
35910
35998
  this.offsetScrollbarX = this.offsetX;
@@ -35926,7 +36014,7 @@ class InternalViewport {
35926
36014
  adjustPositionY(row) {
35927
36015
  const sheetId = this.sheetId;
35928
36016
  while (this.getters.getRowDimensions(sheetId, row).end >
35929
- this.offsetY + this.height + this.offsetCorrectionY &&
36017
+ this.offsetY + this.viewportHeight + this.offsetCorrectionY &&
35930
36018
  this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
35931
36019
  this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
35932
36020
  this.offsetScrollbarY = this.offsetY;
@@ -35964,8 +36052,8 @@ class InternalViewport {
35964
36052
  const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
35965
36053
  this.offsetCorrectionX;
35966
36054
  const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
35967
- const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.width);
35968
- const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.height);
36055
+ const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
36056
+ const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
35969
36057
  return {
35970
36058
  x,
35971
36059
  y,
@@ -36028,12 +36116,12 @@ class InternalViewport {
36028
36116
  adjustViewportOffsetX() {
36029
36117
  if (this.canScrollHorizontally) {
36030
36118
  const { width: viewportWidth } = this.getMaxSize();
36031
- if (this.width + this.offsetScrollbarX > viewportWidth) {
36032
- this.offsetScrollbarX = Math.max(0, viewportWidth - this.width);
36119
+ if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
36120
+ this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
36033
36121
  }
36034
36122
  }
36035
36123
  this.left = this.getColIndex(this.offsetScrollbarX, true);
36036
- this.right = this.getColIndex(this.offsetScrollbarX + this.width, true);
36124
+ this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
36037
36125
  if (this.right === -1) {
36038
36126
  this.right = this.boundaries.right;
36039
36127
  }
@@ -36045,12 +36133,12 @@ class InternalViewport {
36045
36133
  adjustViewportOffsetY() {
36046
36134
  if (this.canScrollVertically) {
36047
36135
  const { height: paneHeight } = this.getMaxSize();
36048
- if (this.height + this.offsetScrollbarY > paneHeight) {
36049
- this.offsetScrollbarY = Math.max(0, paneHeight - this.height);
36136
+ if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
36137
+ this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
36050
36138
  }
36051
36139
  }
36052
36140
  this.top = this.getRowIndex(this.offsetScrollbarY, true);
36053
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.width, true);
36141
+ this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
36054
36142
  if (this.bottom === -1) {
36055
36143
  this.bottom = this.boundaries.bottom;
36056
36144
  }
@@ -36061,7 +36149,7 @@ class InternalViewport {
36061
36149
  adjustViewportZoneX() {
36062
36150
  const sheetId = this.sheetId;
36063
36151
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
36064
- this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.width, this.left));
36152
+ this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
36065
36153
  if (this.right === -1) {
36066
36154
  this.right = this.getters.getNumberCols(sheetId) - 1;
36067
36155
  }
@@ -36074,7 +36162,7 @@ class InternalViewport {
36074
36162
  adjustViewportZoneY() {
36075
36163
  const sheetId = this.sheetId;
36076
36164
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
36077
- this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.height, this.top));
36165
+ this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
36078
36166
  if (this.bottom === -1) {
36079
36167
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
36080
36168
  }
@@ -36333,8 +36421,7 @@ class SheetViewPlugin extends UIPlugin {
36333
36421
  return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
36334
36422
  }
36335
36423
  /**
36336
- * Return the main viewport maximum size. That is the zone dimension
36337
- * with some bottom and right padding.
36424
+ * Return the main viewport maximum size relative to the client size.
36338
36425
  */
36339
36426
  getMainViewportRect() {
36340
36427
  const sheetId = this.getters.getActiveSheetId();
@@ -36350,8 +36437,8 @@ class SheetViewPlugin extends UIPlugin {
36350
36437
  const { width, height } = this.getMainViewportRect();
36351
36438
  const viewport = this.getMainInternalViewport(sheetId);
36352
36439
  return {
36353
- maxOffsetX: Math.max(0, width - viewport.width + 1),
36354
- maxOffsetY: Math.max(0, height - viewport.height + 1),
36440
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
36441
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
36355
36442
  };
36356
36443
  }
36357
36444
  getColRowOffsetInViewport(dimension, referenceIndex, index) {
@@ -42489,6 +42576,6 @@ exports.setTranslationMethod = setTranslationMethod;
42489
42576
  exports.tokenize = tokenize;
42490
42577
 
42491
42578
 
42492
- __info__.version = '16.0.5';
42493
- __info__.date = '2023-03-23T11:35:22.974Z';
42494
- __info__.hash = '53150ef';
42579
+ __info__.version = '16.0.6';
42580
+ __info__.date = '2023-04-13T08:30:26.954Z';
42581
+ __info__.hash = '8d60b5c';