@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.
@@ -112,88 +112,88 @@
112
112
  const FILTERS_COLOR = "#188038";
113
113
  const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
114
114
  const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
115
- // Color picker
115
+ // Color picker defaults as upper case HEX to match `toHex`helper
116
116
  const COLOR_PICKER_DEFAULTS = [
117
117
  "#000000",
118
118
  "#434343",
119
119
  "#666666",
120
120
  "#999999",
121
- "#b7b7b7",
122
- "#cccccc",
123
- "#d9d9d9",
124
- "#efefef",
125
- "#f3f3f3",
126
- "#ffffff",
121
+ "#B7B7B7",
122
+ "#CCCCCC",
123
+ "#D9D9D9",
124
+ "#EFEFEF",
125
+ "#F3F3F3",
126
+ "#FFFFFF",
127
127
  "#980000",
128
- "#ff0000",
129
- "#ff9900",
130
- "#ffff00",
131
- "#00ff00",
132
- "#00ffff",
133
- "#4a86e8",
134
- "#0000ff",
135
- "#9900ff",
136
- "#ff00ff",
137
- "#e6b8af",
138
- "#f4cccc",
139
- "#fce5cd",
140
- "#fff2cc",
141
- "#d9ead3",
142
- "#d0e0e3",
143
- "#c9daf8",
144
- "#cfe2f3",
145
- "#d9d2e9",
146
- "#ead1dc",
147
- "#dd7e6b",
148
- "#ea9999",
149
- "#f9cb9c",
150
- "#ffe599",
151
- "#b6d7a8",
152
- "#a2c4c9",
153
- "#a4c2f4",
154
- "#9fc5e8",
155
- "#b4a7d6",
156
- "#d5a6bd",
157
- "#cc4125",
158
- "#e06666",
159
- "#f6b26b",
160
- "#ffd966",
161
- "#93c47d",
162
- "#76a5af",
163
- "#6d9eeb",
164
- "#6fa8dc",
165
- "#8e7cc3",
166
- "#c27ba0",
167
- "#a61c00",
168
- "#cc0000",
169
- "#e69138",
170
- "#f1c232",
171
- "#6aa84f",
172
- "#45818e",
173
- "#3c78d8",
174
- "#3d85c6",
175
- "#674ea7",
176
- "#a64d79",
177
- "#85200c",
128
+ "#FF0000",
129
+ "#FF9900",
130
+ "#FFFF00",
131
+ "#00FF00",
132
+ "#00FFFF",
133
+ "#4A86E8",
134
+ "#0000FF",
135
+ "#9900FF",
136
+ "#FF00FF",
137
+ "#E6B8AF",
138
+ "#F4CCCC",
139
+ "#FCE5CD",
140
+ "#FFF2CC",
141
+ "#D9EAD3",
142
+ "#D0E0E3",
143
+ "#C9DAF8",
144
+ "#CFE2F3",
145
+ "#D9D2E9",
146
+ "#EAD1DC",
147
+ "#DD7E6B",
148
+ "#EA9999",
149
+ "#F9CB9C",
150
+ "#FFE599",
151
+ "#B6D7A8",
152
+ "#A2C4C9",
153
+ "#A4C2F4",
154
+ "#9FC5E8",
155
+ "#B4A7D6",
156
+ "#D5A6BD",
157
+ "#CC4125",
158
+ "#E06666",
159
+ "#F6B26B",
160
+ "#FFD966",
161
+ "#93C47D",
162
+ "#76A5AF",
163
+ "#6D9EEB",
164
+ "#6FA8DC",
165
+ "#8E7CC3",
166
+ "#C27BA0",
167
+ "#A61C00",
168
+ "#CC0000",
169
+ "#E69138",
170
+ "#F1C232",
171
+ "#6AA84F",
172
+ "#45818E",
173
+ "#3C78D8",
174
+ "#3D85C6",
175
+ "#674EA7",
176
+ "#A64D79",
177
+ "#85200C",
178
178
  "#990000",
179
- "#b45f06",
180
- "#bf9000",
181
- "#38761d",
182
- "#134f5c",
183
- "#1155cc",
184
- "#0b5394",
185
- "#351c75",
186
- "#741b47",
187
- "#5b0f00",
179
+ "#B45F06",
180
+ "#BF9000",
181
+ "#38761D",
182
+ "#134F5C",
183
+ "#1155CC",
184
+ "#0B5394",
185
+ "#351C75",
186
+ "#741B47",
187
+ "#5B0F00",
188
188
  "#660000",
189
- "#783f04",
190
- "#7f6000",
191
- "#274e13",
192
- "#0c343d",
193
- "#1c4587",
189
+ "#783F04",
190
+ "#7F6000",
191
+ "#274E13",
192
+ "#0C343D",
193
+ "#1C4587",
194
194
  "#073763",
195
- "#20124d",
196
- "#4c1130",
195
+ "#20124D",
196
+ "#4C1130",
197
197
  ];
198
198
  // Dimensions
199
199
  const MIN_ROW_HEIGHT = 10;
@@ -231,7 +231,7 @@
231
231
  const DEFAULT_BORDER_DESC = ["thin", "#000"];
232
232
  const DEFAULT_FILTER_BORDER_DESC = ["thin", FILTERS_COLOR];
233
233
  // DateTimeRegex
234
- const DATETIME_FORMAT = /[ymd:]/;
234
+ const DATETIME_FORMAT = /[ymdhs:]/;
235
235
  // Ranges
236
236
  const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
237
237
  // Max Number of history steps kept in memory
@@ -267,11 +267,13 @@
267
267
  ComponentsImportance[ComponentsImportance["Highlight"] = 5] = "Highlight";
268
268
  ComponentsImportance[ComponentsImportance["Figure"] = 10] = "Figure";
269
269
  ComponentsImportance[ComponentsImportance["ScrollBar"] = 15] = "ScrollBar";
270
- ComponentsImportance[ComponentsImportance["Dropdown"] = 16] = "Dropdown";
271
- ComponentsImportance[ComponentsImportance["Composer"] = 20] = "Composer";
270
+ ComponentsImportance[ComponentsImportance["GridPopover"] = 19] = "GridPopover";
271
+ ComponentsImportance[ComponentsImportance["GridComposer"] = 20] = "GridComposer";
272
+ ComponentsImportance[ComponentsImportance["Dropdown"] = 21] = "Dropdown";
272
273
  ComponentsImportance[ComponentsImportance["ColorPicker"] = 25] = "ColorPicker";
273
274
  ComponentsImportance[ComponentsImportance["IconPicker"] = 25] = "IconPicker";
274
- ComponentsImportance[ComponentsImportance["Popover"] = 30] = "Popover";
275
+ ComponentsImportance[ComponentsImportance["TopBarComposer"] = 30] = "TopBarComposer";
276
+ ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
275
277
  ComponentsImportance[ComponentsImportance["ChartAnchor"] = 1000] = "ChartAnchor";
276
278
  })(ComponentsImportance || (ComponentsImportance = {}));
277
279
  const DEFAULT_SHEETVIEW_SIZE = 1000;
@@ -1040,6 +1042,8 @@
1040
1042
  return matrix[0].map((_, i) => matrix.map((row) => row[i]));
1041
1043
  }
1042
1044
 
1045
+ const RBA_REGEX = /rgba?\(|\s+|\)/gi;
1046
+ const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/g;
1043
1047
  const colors$1 = [
1044
1048
  "#eb6d00",
1045
1049
  "#0074d9",
@@ -1070,7 +1074,10 @@
1070
1074
  }
1071
1075
  /**
1072
1076
  * Converts any CSS color value to a standardized hex6 value.
1073
- * Accepts: hex3, hex6, hex8 and rgb (rgba is not supported)
1077
+ * Accepts: hex3, hex6, hex8, rgb[1] and rgba[1].
1078
+ *
1079
+ * [1] under the form rgb(r, g, b, a?) or rgba(r, g, b, a?)
1080
+ * with r,g,b ∈ [0, 255] and a ∈ [0, 1]
1074
1081
  *
1075
1082
  * toHex("#ABC")
1076
1083
  * >> "#AABBCC"
@@ -1081,27 +1088,31 @@
1081
1088
  * toHex("rgb(30, 80, 16)")
1082
1089
  * >> "#1E5010"
1083
1090
  *
1091
+ * * toHex("rgb(30, 80, 16, 0.5)")
1092
+ * >> "#1E501080"
1093
+ *
1084
1094
  */
1085
1095
  function toHex(color) {
1086
- if (color.includes("rgba")) {
1087
- throw new Error(`rgba() conversion currently not supported: ${color}`);
1096
+ let hexColor = color;
1097
+ if (color.startsWith("rgb")) {
1098
+ hexColor = rgbaStringToHex(color);
1088
1099
  }
1089
- if (color.includes("rgb")) {
1090
- return rgbToHex6(color);
1100
+ else {
1101
+ hexColor = color.replace("#", "").toUpperCase();
1102
+ if (hexColor.length === 3 || hexColor.length === 4) {
1103
+ hexColor = hexColor.split("").reduce((acc, h) => acc + h + h, "");
1104
+ }
1105
+ hexColor = `#${hexColor}`;
1091
1106
  }
1092
- color = color.replace("#", "").toUpperCase();
1093
- if (color.length === 3 || color.length === 4) {
1094
- color = color.split("").reduce((acc, h) => acc + h + h, "");
1107
+ if (!hexColor.match(HEX_MATCH)) {
1108
+ throw new Error(`invalid color input: ${color}`);
1095
1109
  }
1096
- if (color.replace(/[a-f0-9]/gi, "") !== "") {
1097
- throw new Error("invalid color");
1098
- }
1099
- return "#" + color;
1110
+ return hexColor;
1100
1111
  }
1101
1112
  function isColorValid(color) {
1102
1113
  try {
1103
- const { r, g, b, a } = colorToRGBA(color);
1104
- return (isColorValueValid(r) && isColorValueValid(g) && isColorValueValid(b) && isColorValueValid(a));
1114
+ toHex(color);
1115
+ return true;
1105
1116
  }
1106
1117
  catch (error) {
1107
1118
  return false;
@@ -1134,15 +1145,29 @@
1134
1145
  /**
1135
1146
  * Convert a CSS rgb color string to a standardized hex6 color value.
1136
1147
  *
1137
- * rgbToHex6("rgb(30, 80, 16)")
1148
+ * rgbaStringToHex("rgb(30, 80, 16)")
1138
1149
  * >> "#1E5010"
1150
+ *
1151
+ * rgbaStringToHex("rgba(30, 80, 16, 0.5)")
1152
+ * >> "#1E501080"
1153
+ *
1154
+ * DOES NOT SUPPORT NON INTEGER RGB VALUES
1139
1155
  */
1140
- function rgbToHex6(color) {
1141
- return ("#" +
1142
- concat(color
1143
- .slice(4, -1)
1144
- .split(",")
1145
- .map((valueString) => parseInt(valueString, 10).toString(16).padStart(2, "0"))).toUpperCase());
1156
+ function rgbaStringToHex(color) {
1157
+ const stringVals = color.replace(RBA_REGEX, "").split(",");
1158
+ let alphaHex = 255;
1159
+ if (stringVals.length !== 3 && stringVals.length !== 4) {
1160
+ throw new Error("invalid color");
1161
+ }
1162
+ else if (stringVals.length === 4) {
1163
+ const alpha = parseFloat(stringVals.pop() || "1");
1164
+ alphaHex = Math.round((alpha || 1) * 255);
1165
+ }
1166
+ const vals = stringVals.map((val) => parseInt(val, 10));
1167
+ if (alphaHex !== 255) {
1168
+ vals.push(alphaHex);
1169
+ }
1170
+ return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
1146
1171
  }
1147
1172
  /**
1148
1173
  * RGBA to HEX representation (#RRGGBBAA).
@@ -1164,7 +1189,7 @@
1164
1189
  a = "0" + a;
1165
1190
  if (a === "ff")
1166
1191
  a = "";
1167
- return "#" + r + g + b + a;
1192
+ return ("#" + r + g + b + a).toUpperCase();
1168
1193
  }
1169
1194
  /**
1170
1195
  * Color string to RGBA representation
@@ -1285,6 +1310,9 @@
1285
1310
  s = +(s * 100).toFixed(1);
1286
1311
  l = +(l * 100).toFixed(1);
1287
1312
  return { a: rgba.a, h, s, l };
1313
+ }
1314
+ function isSameColor(color1, color2) {
1315
+ return isColorValid(color1) && isColorValid(color2) && toHex(color1) === toHex(color2);
1288
1316
  }
1289
1317
 
1290
1318
  /** Reference of a cell (eg. A1, $B$5) */
@@ -1843,7 +1871,7 @@
1843
1871
  * formula, commas are used to separate arguments
1844
1872
  * - it does not support % symbol, in formulas % is an operator
1845
1873
  */
1846
- const formulaNumberRegexp = /^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+/;
1874
+ const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
1847
1875
  const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
1848
1876
  const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
1849
1877
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -3823,7 +3851,7 @@
3823
3851
  const shadow = maxHeight !== 0 ? "box-shadow: 1px 2px 5px 2px rgb(51 51 51 / 15%);" : "";
3824
3852
  return `
3825
3853
  position: absolute;
3826
- z-index: ${ComponentsImportance.Popover};
3854
+ z-index: ${this.props.zIndex};
3827
3855
  ${verticalPosition}px;
3828
3856
  ${horizontalPosition}px;
3829
3857
  ${height}px;
@@ -3867,6 +3895,7 @@
3867
3895
  verticalOffset: 0,
3868
3896
  marginTop: 0,
3869
3897
  onMouseWheel: () => { },
3898
+ zIndex: ComponentsImportance.Popover,
3870
3899
  };
3871
3900
 
3872
3901
  //------------------------------------------------------------------------------
@@ -8429,6 +8458,9 @@
8429
8458
  const { display, background, left, top } = this.state.style;
8430
8459
  return `display:${display};${display === "block" ? `background-color:${background};left:${left};top:${top};` : ""}`;
8431
8460
  }
8461
+ isSameColor(color1, color2) {
8462
+ return isSameColor(color1, color2);
8463
+ }
8432
8464
  }
8433
8465
  ColorPicker.template = "o-spreadsheet-ColorPicker";
8434
8466
 
@@ -8554,6 +8586,12 @@
8554
8586
  const cancelledReasons = [...(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.reasons) || [])];
8555
8587
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
8556
8588
  }
8589
+ onClick(ev) {
8590
+ this.state.openedMenu = undefined;
8591
+ }
8592
+ setup() {
8593
+ owl.useExternalListener(window, "click", this.onClick);
8594
+ }
8557
8595
  updateBackgroundColor(color) {
8558
8596
  this.state.openedMenu = undefined;
8559
8597
  this.props.updateChart({
@@ -8722,6 +8760,12 @@
8722
8760
  openedColorPicker: undefined,
8723
8761
  });
8724
8762
  }
8763
+ onClick(ev) {
8764
+ this.state.openedColorPicker = undefined;
8765
+ }
8766
+ setup() {
8767
+ owl.useExternalListener(window, "click", this.onClick);
8768
+ }
8725
8769
  updateTitle(ev) {
8726
8770
  this.props.updateChart({
8727
8771
  title: ev.target.value,
@@ -19923,7 +19967,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19923
19967
  padding: 0;
19924
19968
  margin: 0;
19925
19969
  border: 0;
19926
- z-index: ${ComponentsImportance.Composer};
19927
19970
  flex-grow: 1;
19928
19971
  max-height: inherit;
19929
19972
  .o-composer {
@@ -19957,6 +20000,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19957
20000
  .o-topbar-toolbar .o-composer-container:focus-within {
19958
20001
  border: 1px solid ${SELECTION_BORDER_COLOR};
19959
20002
  }
20003
+
20004
+ .o-topbar-toolbar .o-composer-container {
20005
+ z-index: ${ComponentsImportance.TopBarComposer};
20006
+ }
19960
20007
  `;
19961
20008
  class Composer extends owl.Component {
19962
20009
  constructor() {
@@ -20381,7 +20428,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20381
20428
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
20382
20429
  css /* scss */ `
20383
20430
  div.o-grid-composer {
20384
- z-index: ${ComponentsImportance.Composer};
20431
+ z-index: ${ComponentsImportance.GridComposer};
20385
20432
  box-sizing: border-box;
20386
20433
  position: absolute;
20387
20434
  border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
@@ -21211,6 +21258,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
21211
21258
  };
21212
21259
 
21213
21260
  class GridPopover extends owl.Component {
21261
+ constructor() {
21262
+ super(...arguments);
21263
+ this.zIndex = ComponentsImportance.GridPopover;
21264
+ }
21214
21265
  get cellPopover() {
21215
21266
  const popover = this.env.model.getters.getCellPopover(this.props.hoveredCell);
21216
21267
  if (!popover.isOpen) {
@@ -23733,6 +23784,72 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23733
23784
  });
23734
23785
  }
23735
23786
 
23787
+ 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;
23788
+ /**
23789
+ * Convert excel format to o_spreadsheet format
23790
+ *
23791
+ * Excel format are defined in openXML §18.8.31
23792
+ */
23793
+ function convertXlsxFormat(numFmtId, formats, warningManager) {
23794
+ var _a, _b, _c;
23795
+ if (numFmtId === 0) {
23796
+ return undefined;
23797
+ }
23798
+ // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
23799
+ let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
23800
+ if (format) {
23801
+ try {
23802
+ let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
23803
+ convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
23804
+ convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
23805
+ // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
23806
+ const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
23807
+ const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
23808
+ if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
23809
+ throw new Error("Multiple escaped blocks in format");
23810
+ }
23811
+ convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
23812
+ convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM
23813
+ convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
23814
+ convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
23815
+ convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters
23816
+ if (isXlsxDateFormat(convertedFormat)) {
23817
+ convertedFormat = convertDateFormat$1(convertedFormat);
23818
+ }
23819
+ if (isFormatSupported(convertedFormat)) {
23820
+ return convertedFormat;
23821
+ }
23822
+ }
23823
+ catch (e) { }
23824
+ }
23825
+ warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
23826
+ return undefined;
23827
+ }
23828
+ function isFormatSupported(format) {
23829
+ try {
23830
+ formatValue(0, format);
23831
+ return true;
23832
+ }
23833
+ catch (e) {
23834
+ return false;
23835
+ }
23836
+ }
23837
+ function isXlsxDateFormat(format) {
23838
+ return format.match(XLSX_DATE_FORMAT_REGEX) !== null;
23839
+ }
23840
+ function convertDateFormat$1(format) {
23841
+ // Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML,
23842
+ // but can still occur and are supported by Excel/Google sheets
23843
+ format = format.toLowerCase();
23844
+ format = format.replace(/mmmmm|mmmm|mmm/g, "mm");
23845
+ format = format.replace(/dddd|ddd/g, "dd");
23846
+ format = format.replace(/am\/pm|a\/m/g, "a");
23847
+ format = format.replace(/\byy\b/g, "yyyy");
23848
+ format = format.replace(/hhhh/g, "hh");
23849
+ format = format.replace(/\bh\b/g, "hh");
23850
+ return format;
23851
+ }
23852
+
23736
23853
  function convertBorders(data, warningManager) {
23737
23854
  const borderArray = data.borders.map((border) => {
23738
23855
  addBorderWarnings(border, warningManager);
@@ -23797,41 +23914,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23797
23914
  }
23798
23915
  return arrayToObject(formats, 1);
23799
23916
  }
23800
- /**
23801
- * Convert excel format to o_spreadsheet format
23802
- *
23803
- * Excel format are defined in openXML §18.8.31
23804
- */
23805
- function convertXlsxFormat(numFmtId, formats, warningManager) {
23806
- var _a, _b, _c;
23807
- if (numFmtId === 0) {
23808
- return undefined;
23809
- }
23810
- // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
23811
- let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
23812
- if (format) {
23813
- try {
23814
- let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
23815
- convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
23816
- convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
23817
- // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
23818
- const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
23819
- const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
23820
- if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
23821
- throw new Error("Multiple escaped blocks in format");
23822
- }
23823
- convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
23824
- convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore with of next char for align purposes. Not supported ATM
23825
- convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
23826
- convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
23827
- formatValue(0, convertedFormat);
23828
- return convertedFormat;
23829
- }
23830
- catch (e) { }
23831
- }
23832
- warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
23833
- return undefined;
23834
- }
23835
23917
  /**
23836
23918
  * We currently only support only a set of font sizes, we cannot define new font sizes.
23837
23919
  * This function adapts an arbitrary font size to the closest supported font size.
@@ -32014,9 +32096,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32014
32096
  // remove duplicates first to check validity on a reduced
32015
32097
  // set of colors, then normalize to HEX and remove duplicates
32016
32098
  // again
32017
- [...new Set([...usedColors, ...this.customColors])]
32018
- .filter(isColorValid)
32019
- .map((c) => toHex(c).toLowerCase())),
32099
+ [...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
32020
32100
  ]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
32021
32101
  }
32022
32102
  getColorsFromCells(cells) {
@@ -32077,7 +32157,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32077
32157
  return [...chartsColors];
32078
32158
  }
32079
32159
  tryToAddColor(color) {
32080
- const formattedColor = toHex(color).toLowerCase();
32160
+ const formattedColor = toHex(color);
32081
32161
  if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
32082
32162
  this.customColors.add(formattedColor);
32083
32163
  }
@@ -35818,8 +35898,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35818
35898
  this.getters = getters;
35819
35899
  this.sheetId = sheetId;
35820
35900
  this.boundaries = boundaries;
35821
- this.width = sizeInGrid.width;
35822
- this.height = sizeInGrid.height;
35901
+ this.viewportWidth = sizeInGrid.width;
35902
+ this.viewportHeight = sizeInGrid.height;
35823
35903
  this.offsetScrollbarX = offsets.x;
35824
35904
  this.offsetScrollbarY = offsets.y;
35825
35905
  this.canScrollVertically = options.canScrollVertically;
@@ -35830,6 +35910,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35830
35910
  this.adjustViewportOffsetY();
35831
35911
  }
35832
35912
  // PUBLIC
35913
+ /** Returns the maximum size (in Pixels) of the viewport relative to its allocated client size
35914
+ * When the viewport grid size is smaller than its client width (resp. height), it will return
35915
+ * the client width (resp. height).
35916
+ */
35833
35917
  getMaxSize() {
35834
35918
  const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
35835
35919
  first: this.boundaries.left,
@@ -35841,20 +35925,24 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35841
35925
  });
35842
35926
  const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
35843
35927
  const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
35844
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.width, 0);
35928
+ const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
35845
35929
  const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
35846
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.height, 0);
35930
+ const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
35847
35931
  const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
35848
- const width = lastColEnd -
35849
- this.offsetCorrectionX +
35850
- (this.canScrollHorizontally
35851
- ? Math.max(DEFAULT_CELL_WIDTH, Math.min(leftColSize, this.width - lastColSize))
35852
- : 0);
35853
- const height = lastRowEnd -
35854
- this.offsetCorrectionY +
35855
- (this.canScrollVertically
35856
- ? Math.max(DEFAULT_CELL_HEIGHT + 5, Math.min(topRowSize, this.height - lastRowSize))
35857
- : 0);
35932
+ let width = lastColEnd - this.offsetCorrectionX;
35933
+ if (this.canScrollHorizontally) {
35934
+ width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
35935
+ Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
35936
+ );
35937
+ width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
35938
+ }
35939
+ let height = lastRowEnd - this.offsetCorrectionY;
35940
+ if (this.canScrollVertically) {
35941
+ height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
35942
+ Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
35943
+ );
35944
+ height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
35945
+ }
35858
35946
  return { width, height };
35859
35947
  }
35860
35948
  /**
@@ -35863,7 +35951,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35863
35951
  * It returns -1 if no column is found.
35864
35952
  */
35865
35953
  getColIndex(x, absolute = false) {
35866
- if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.width) {
35954
+ if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
35867
35955
  return -1;
35868
35956
  }
35869
35957
  return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
@@ -35874,7 +35962,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35874
35962
  * It returns -1 if no row is found.
35875
35963
  */
35876
35964
  getRowIndex(y, absolute = false) {
35877
- if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.height) {
35965
+ if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
35878
35966
  return -1;
35879
35967
  }
35880
35968
  return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
@@ -35898,48 +35986,66 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35898
35986
  this.adjustPositionY(row);
35899
35987
  }
35900
35988
  }
35901
- adjustPositionX(col) {
35989
+ adjustPositionX(targetCol) {
35902
35990
  const sheetId = this.sheetId;
35903
- const { start, end } = this.getters.getColDimensions(sheetId, col);
35904
- while (end > this.offsetX + this.offsetCorrectionX + this.width &&
35905
- this.offsetX + this.offsetCorrectionX < start) {
35906
- this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
35907
- this.offsetScrollbarX = this.offsetX;
35908
- this.adjustViewportZoneX();
35909
- }
35910
- while (col < this.left) {
35911
- let leftCol;
35912
- for (leftCol = this.left; leftCol >= 0; leftCol--) {
35913
- if (!this.getters.isColHidden(sheetId, leftCol)) {
35991
+ const { end } = this.getters.getColDimensions(sheetId, targetCol);
35992
+ const maxCol = this.getters.getNumberCols(sheetId);
35993
+ if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
35994
+ for (let col = this.left; this.offsetX + this.offsetCorrectionX + this.viewportWidth < end; col++) {
35995
+ if (col > maxCol) {
35914
35996
  break;
35915
35997
  }
35998
+ if (this.getters.isColHidden(sheetId, col)) {
35999
+ continue;
36000
+ }
36001
+ this.offsetX = this.getters.getColDimensions(sheetId, col).end - this.offsetCorrectionX;
36002
+ this.offsetScrollbarX = this.offsetX;
36003
+ this.adjustViewportZoneX();
36004
+ }
36005
+ }
36006
+ else if (this.left > targetCol) {
36007
+ for (let col = this.left; col >= targetCol; col--) {
36008
+ if (col < 0) {
36009
+ break;
36010
+ }
36011
+ if (this.getters.isColHidden(sheetId, col)) {
36012
+ continue;
36013
+ }
36014
+ this.offsetX = this.getters.getColDimensions(sheetId, col).start - this.offsetCorrectionX;
36015
+ this.offsetScrollbarX = this.offsetX;
36016
+ this.adjustViewportZoneX();
35916
36017
  }
35917
- this.offsetX =
35918
- this.getters.getColDimensions(sheetId, leftCol - 1).start - this.offsetCorrectionX;
35919
- this.offsetScrollbarX = this.offsetX;
35920
- this.adjustViewportZoneX();
35921
36018
  }
35922
36019
  }
35923
- adjustPositionY(row) {
36020
+ adjustPositionY(targetRow) {
35924
36021
  const sheetId = this.sheetId;
35925
- while (this.getters.getRowDimensions(sheetId, row).end >
35926
- this.offsetY + this.height + this.offsetCorrectionY &&
35927
- this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
35928
- this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
35929
- this.offsetScrollbarY = this.offsetY;
35930
- this.adjustViewportZoneY();
35931
- }
35932
- while (row < this.top) {
35933
- let topRow;
35934
- for (topRow = this.top; topRow >= 0; topRow--) {
35935
- if (!this.getters.isRowHidden(sheetId, topRow)) {
36022
+ const { end } = this.getters.getRowDimensions(sheetId, targetRow);
36023
+ const maxRow = this.getters.getNumberRows(sheetId);
36024
+ if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
36025
+ for (let row = this.top; this.offsetY + this.viewportHeight + this.offsetCorrectionY < end; row++) {
36026
+ if (row > maxRow) {
35936
36027
  break;
35937
36028
  }
36029
+ if (this.getters.isRowHidden(sheetId, row)) {
36030
+ continue;
36031
+ }
36032
+ this.offsetY = this.getters.getRowDimensions(sheetId, row).end - this.offsetCorrectionY;
36033
+ this.offsetScrollbarY = this.offsetY;
36034
+ this.adjustViewportZoneY();
36035
+ }
36036
+ }
36037
+ else if (this.top > targetRow) {
36038
+ for (let row = this.top; row >= targetRow; row--) {
36039
+ if (row < 0) {
36040
+ break;
36041
+ }
36042
+ if (this.getters.isRowHidden(sheetId, row)) {
36043
+ continue;
36044
+ }
36045
+ this.offsetY = this.getters.getRowDimensions(sheetId, row).start - this.offsetCorrectionY;
36046
+ this.offsetScrollbarY = this.offsetY;
36047
+ this.adjustViewportZoneY();
35938
36048
  }
35939
- this.offsetY =
35940
- this.getters.getRowDimensions(sheetId, topRow - 1).start - this.offsetCorrectionY;
35941
- this.offsetScrollbarY = this.offsetY;
35942
- this.adjustViewportZoneY();
35943
36049
  }
35944
36050
  }
35945
36051
  setViewportOffset(offsetX, offsetY) {
@@ -35961,8 +36067,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35961
36067
  const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
35962
36068
  this.offsetCorrectionX;
35963
36069
  const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
35964
- const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.width);
35965
- const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.height);
36070
+ const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
36071
+ const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
35966
36072
  return {
35967
36073
  x,
35968
36074
  y,
@@ -36025,12 +36131,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36025
36131
  adjustViewportOffsetX() {
36026
36132
  if (this.canScrollHorizontally) {
36027
36133
  const { width: viewportWidth } = this.getMaxSize();
36028
- if (this.width + this.offsetScrollbarX > viewportWidth) {
36029
- this.offsetScrollbarX = Math.max(0, viewportWidth - this.width);
36134
+ if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
36135
+ this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
36030
36136
  }
36031
36137
  }
36032
36138
  this.left = this.getColIndex(this.offsetScrollbarX, true);
36033
- this.right = this.getColIndex(this.offsetScrollbarX + this.width, true);
36139
+ this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
36034
36140
  if (this.right === -1) {
36035
36141
  this.right = this.boundaries.right;
36036
36142
  }
@@ -36042,12 +36148,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36042
36148
  adjustViewportOffsetY() {
36043
36149
  if (this.canScrollVertically) {
36044
36150
  const { height: paneHeight } = this.getMaxSize();
36045
- if (this.height + this.offsetScrollbarY > paneHeight) {
36046
- this.offsetScrollbarY = Math.max(0, paneHeight - this.height);
36151
+ if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
36152
+ this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
36047
36153
  }
36048
36154
  }
36049
36155
  this.top = this.getRowIndex(this.offsetScrollbarY, true);
36050
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.width, true);
36156
+ this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
36051
36157
  if (this.bottom === -1) {
36052
36158
  this.bottom = this.boundaries.bottom;
36053
36159
  }
@@ -36058,7 +36164,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36058
36164
  adjustViewportZoneX() {
36059
36165
  const sheetId = this.sheetId;
36060
36166
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
36061
- this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.width, this.left));
36167
+ this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
36062
36168
  if (this.right === -1) {
36063
36169
  this.right = this.getters.getNumberCols(sheetId) - 1;
36064
36170
  }
@@ -36071,7 +36177,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36071
36177
  adjustViewportZoneY() {
36072
36178
  const sheetId = this.sheetId;
36073
36179
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
36074
- this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.height, this.top));
36180
+ this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
36075
36181
  if (this.bottom === -1) {
36076
36182
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
36077
36183
  }
@@ -36330,8 +36436,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36330
36436
  return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
36331
36437
  }
36332
36438
  /**
36333
- * Return the main viewport maximum size. That is the zone dimension
36334
- * with some bottom and right padding.
36439
+ * Return the main viewport maximum size relative to the client size.
36335
36440
  */
36336
36441
  getMainViewportRect() {
36337
36442
  const sheetId = this.getters.getActiveSheetId();
@@ -36347,8 +36452,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36347
36452
  const { width, height } = this.getMainViewportRect();
36348
36453
  const viewport = this.getMainInternalViewport(sheetId);
36349
36454
  return {
36350
- maxOffsetX: Math.max(0, width - viewport.width + 1),
36351
- maxOffsetY: Math.max(0, height - viewport.height + 1),
36455
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
36456
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
36352
36457
  };
36353
36458
  }
36354
36459
  getColRowOffsetInViewport(dimension, referenceIndex, index) {
@@ -42488,9 +42593,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42488
42593
  Object.defineProperty(exports, '__esModule', { value: true });
42489
42594
 
42490
42595
 
42491
- __info__.version = '16.0.5';
42492
- __info__.date = '2023-03-23T11:35:22.974Z';
42493
- __info__.hash = '53150ef';
42596
+ __info__.version = '16.0.7';
42597
+ __info__.date = '2023-04-14T12:46:24.076Z';
42598
+ __info__.hash = '2b4831d';
42494
42599
 
42495
42600
 
42496
42601
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);