@odoo/o-spreadsheet 16.0.5 → 16.0.7

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);
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}`;
1094
1109
  }
1095
- color = color.replace("#", "").toUpperCase();
1096
- if (color.length === 3 || color.length === 4) {
1097
- color = color.split("").reduce((acc, h) => acc + h + h, "");
1110
+ if (!hexColor.match(HEX_MATCH)) {
1111
+ throw new Error(`invalid color input: ${color}`);
1098
1112
  }
1099
- if (color.replace(/[a-f0-9]/gi, "") !== "") {
1100
- throw new Error("invalid color");
1101
- }
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);
@@ -35901,48 +35989,66 @@ class InternalViewport {
35901
35989
  this.adjustPositionY(row);
35902
35990
  }
35903
35991
  }
35904
- adjustPositionX(col) {
35992
+ adjustPositionX(targetCol) {
35905
35993
  const sheetId = this.sheetId;
35906
- const { start, end } = this.getters.getColDimensions(sheetId, col);
35907
- while (end > this.offsetX + this.offsetCorrectionX + this.width &&
35908
- this.offsetX + this.offsetCorrectionX < start) {
35909
- this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
35910
- this.offsetScrollbarX = this.offsetX;
35911
- this.adjustViewportZoneX();
35912
- }
35913
- while (col < this.left) {
35914
- let leftCol;
35915
- for (leftCol = this.left; leftCol >= 0; leftCol--) {
35916
- if (!this.getters.isColHidden(sheetId, leftCol)) {
35994
+ const { end } = this.getters.getColDimensions(sheetId, targetCol);
35995
+ const maxCol = this.getters.getNumberCols(sheetId);
35996
+ if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
35997
+ for (let col = this.left; this.offsetX + this.offsetCorrectionX + this.viewportWidth < end; col++) {
35998
+ if (col > maxCol) {
35917
35999
  break;
35918
36000
  }
36001
+ if (this.getters.isColHidden(sheetId, col)) {
36002
+ continue;
36003
+ }
36004
+ this.offsetX = this.getters.getColDimensions(sheetId, col).end - this.offsetCorrectionX;
36005
+ this.offsetScrollbarX = this.offsetX;
36006
+ this.adjustViewportZoneX();
36007
+ }
36008
+ }
36009
+ else if (this.left > targetCol) {
36010
+ for (let col = this.left; col >= targetCol; col--) {
36011
+ if (col < 0) {
36012
+ break;
36013
+ }
36014
+ if (this.getters.isColHidden(sheetId, col)) {
36015
+ continue;
36016
+ }
36017
+ this.offsetX = this.getters.getColDimensions(sheetId, col).start - this.offsetCorrectionX;
36018
+ this.offsetScrollbarX = this.offsetX;
36019
+ this.adjustViewportZoneX();
35919
36020
  }
35920
- this.offsetX =
35921
- this.getters.getColDimensions(sheetId, leftCol - 1).start - this.offsetCorrectionX;
35922
- this.offsetScrollbarX = this.offsetX;
35923
- this.adjustViewportZoneX();
35924
36021
  }
35925
36022
  }
35926
- adjustPositionY(row) {
36023
+ adjustPositionY(targetRow) {
35927
36024
  const sheetId = this.sheetId;
35928
- while (this.getters.getRowDimensions(sheetId, row).end >
35929
- this.offsetY + this.height + this.offsetCorrectionY &&
35930
- this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
35931
- this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
35932
- this.offsetScrollbarY = this.offsetY;
35933
- this.adjustViewportZoneY();
35934
- }
35935
- while (row < this.top) {
35936
- let topRow;
35937
- for (topRow = this.top; topRow >= 0; topRow--) {
35938
- if (!this.getters.isRowHidden(sheetId, topRow)) {
36025
+ const { end } = this.getters.getRowDimensions(sheetId, targetRow);
36026
+ const maxRow = this.getters.getNumberRows(sheetId);
36027
+ if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
36028
+ for (let row = this.top; this.offsetY + this.viewportHeight + this.offsetCorrectionY < end; row++) {
36029
+ if (row > maxRow) {
35939
36030
  break;
35940
36031
  }
36032
+ if (this.getters.isRowHidden(sheetId, row)) {
36033
+ continue;
36034
+ }
36035
+ this.offsetY = this.getters.getRowDimensions(sheetId, row).end - this.offsetCorrectionY;
36036
+ this.offsetScrollbarY = this.offsetY;
36037
+ this.adjustViewportZoneY();
36038
+ }
36039
+ }
36040
+ else if (this.top > targetRow) {
36041
+ for (let row = this.top; row >= targetRow; row--) {
36042
+ if (row < 0) {
36043
+ break;
36044
+ }
36045
+ if (this.getters.isRowHidden(sheetId, row)) {
36046
+ continue;
36047
+ }
36048
+ this.offsetY = this.getters.getRowDimensions(sheetId, row).start - this.offsetCorrectionY;
36049
+ this.offsetScrollbarY = this.offsetY;
36050
+ this.adjustViewportZoneY();
35941
36051
  }
35942
- this.offsetY =
35943
- this.getters.getRowDimensions(sheetId, topRow - 1).start - this.offsetCorrectionY;
35944
- this.offsetScrollbarY = this.offsetY;
35945
- this.adjustViewportZoneY();
35946
36052
  }
35947
36053
  }
35948
36054
  setViewportOffset(offsetX, offsetY) {
@@ -35964,8 +36070,8 @@ class InternalViewport {
35964
36070
  const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
35965
36071
  this.offsetCorrectionX;
35966
36072
  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);
36073
+ const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
36074
+ const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
35969
36075
  return {
35970
36076
  x,
35971
36077
  y,
@@ -36028,12 +36134,12 @@ class InternalViewport {
36028
36134
  adjustViewportOffsetX() {
36029
36135
  if (this.canScrollHorizontally) {
36030
36136
  const { width: viewportWidth } = this.getMaxSize();
36031
- if (this.width + this.offsetScrollbarX > viewportWidth) {
36032
- this.offsetScrollbarX = Math.max(0, viewportWidth - this.width);
36137
+ if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
36138
+ this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
36033
36139
  }
36034
36140
  }
36035
36141
  this.left = this.getColIndex(this.offsetScrollbarX, true);
36036
- this.right = this.getColIndex(this.offsetScrollbarX + this.width, true);
36142
+ this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
36037
36143
  if (this.right === -1) {
36038
36144
  this.right = this.boundaries.right;
36039
36145
  }
@@ -36045,12 +36151,12 @@ class InternalViewport {
36045
36151
  adjustViewportOffsetY() {
36046
36152
  if (this.canScrollVertically) {
36047
36153
  const { height: paneHeight } = this.getMaxSize();
36048
- if (this.height + this.offsetScrollbarY > paneHeight) {
36049
- this.offsetScrollbarY = Math.max(0, paneHeight - this.height);
36154
+ if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
36155
+ this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
36050
36156
  }
36051
36157
  }
36052
36158
  this.top = this.getRowIndex(this.offsetScrollbarY, true);
36053
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.width, true);
36159
+ this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
36054
36160
  if (this.bottom === -1) {
36055
36161
  this.bottom = this.boundaries.bottom;
36056
36162
  }
@@ -36061,7 +36167,7 @@ class InternalViewport {
36061
36167
  adjustViewportZoneX() {
36062
36168
  const sheetId = this.sheetId;
36063
36169
  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));
36170
+ this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
36065
36171
  if (this.right === -1) {
36066
36172
  this.right = this.getters.getNumberCols(sheetId) - 1;
36067
36173
  }
@@ -36074,7 +36180,7 @@ class InternalViewport {
36074
36180
  adjustViewportZoneY() {
36075
36181
  const sheetId = this.sheetId;
36076
36182
  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));
36183
+ this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
36078
36184
  if (this.bottom === -1) {
36079
36185
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
36080
36186
  }
@@ -36333,8 +36439,7 @@ class SheetViewPlugin extends UIPlugin {
36333
36439
  return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
36334
36440
  }
36335
36441
  /**
36336
- * Return the main viewport maximum size. That is the zone dimension
36337
- * with some bottom and right padding.
36442
+ * Return the main viewport maximum size relative to the client size.
36338
36443
  */
36339
36444
  getMainViewportRect() {
36340
36445
  const sheetId = this.getters.getActiveSheetId();
@@ -36350,8 +36455,8 @@ class SheetViewPlugin extends UIPlugin {
36350
36455
  const { width, height } = this.getMainViewportRect();
36351
36456
  const viewport = this.getMainInternalViewport(sheetId);
36352
36457
  return {
36353
- maxOffsetX: Math.max(0, width - viewport.width + 1),
36354
- maxOffsetY: Math.max(0, height - viewport.height + 1),
36458
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
36459
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
36355
36460
  };
36356
36461
  }
36357
36462
  getColRowOffsetInViewport(dimension, referenceIndex, index) {
@@ -42489,6 +42594,6 @@ exports.setTranslationMethod = setTranslationMethod;
42489
42594
  exports.tokenize = tokenize;
42490
42595
 
42491
42596
 
42492
- __info__.version = '16.0.5';
42493
- __info__.date = '2023-03-23T11:35:22.974Z';
42494
- __info__.hash = '53150ef';
42597
+ __info__.version = '16.0.7';
42598
+ __info__.date = '2023-04-14T12:46:24.076Z';
42599
+ __info__.hash = '2b4831d';