@odoo/o-spreadsheet 16.0.4 → 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.
@@ -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);
1091
- }
1092
- color = color.replace("#", "").toUpperCase();
1093
- if (color.length === 3 || color.length === 4) {
1094
- color = color.split("").reduce((acc, h) => acc + h + h, "");
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}`;
1095
1106
  }
1096
- if (color.replace(/[a-f0-9]/gi, "") !== "") {
1097
- throw new Error("invalid color");
1107
+ if (!hexColor.match(HEX_MATCH)) {
1108
+ throw new Error(`invalid color input: ${color}`);
1098
1109
  }
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,
@@ -9960,6 +10004,7 @@
9960
10004
  const LINE_HEIGHT = 1.2;
9961
10005
  css /* scss */ `
9962
10006
  div.o-scorecard {
10007
+ font-family: ${DEFAULT_FONT};
9963
10008
  user-select: none;
9964
10009
  background-color: white;
9965
10010
  display: flex;
@@ -19369,6 +19414,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19369
19414
  this.setContent(this.initialContent || "");
19370
19415
  }
19371
19416
  setContent(text, selection, raise) {
19417
+ text = text.replace(/[\r\n]/g, "");
19372
19418
  const isNewCurrentContent = this.currentContent !== text;
19373
19419
  this.currentContent = text;
19374
19420
  if (selection) {
@@ -19698,6 +19744,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19698
19744
  start = 0;
19699
19745
  if (end > this.el.textContent.length)
19700
19746
  end = this.el.textContent.length;
19747
+ if (start > this.el.textContent.length)
19748
+ start = this.el.textContent.length;
19701
19749
  }
19702
19750
  let startNode = this.findChildAtCharacterIndex(start);
19703
19751
  let endNode = this.findChildAtCharacterIndex(end);
@@ -19919,10 +19967,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19919
19967
  padding: 0;
19920
19968
  margin: 0;
19921
19969
  border: 0;
19922
- z-index: ${ComponentsImportance.Composer};
19923
19970
  flex-grow: 1;
19924
19971
  max-height: inherit;
19925
19972
  .o-composer {
19973
+ font-family: ${DEFAULT_FONT};
19926
19974
  caret-color: black;
19927
19975
  padding-left: 3px;
19928
19976
  padding-right: 3px;
@@ -19952,6 +20000,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19952
20000
  .o-topbar-toolbar .o-composer-container:focus-within {
19953
20001
  border: 1px solid ${SELECTION_BORDER_COLOR};
19954
20002
  }
20003
+
20004
+ .o-topbar-toolbar .o-composer-container {
20005
+ z-index: ${ComponentsImportance.TopBarComposer};
20006
+ }
19955
20007
  `;
19956
20008
  class Composer extends owl.Component {
19957
20009
  constructor() {
@@ -20376,7 +20428,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20376
20428
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
20377
20429
  css /* scss */ `
20378
20430
  div.o-grid-composer {
20379
- z-index: ${ComponentsImportance.Composer};
20431
+ z-index: ${ComponentsImportance.GridComposer};
20380
20432
  box-sizing: border-box;
20381
20433
  position: absolute;
20382
20434
  border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
@@ -21206,6 +21258,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
21206
21258
  };
21207
21259
 
21208
21260
  class GridPopover extends owl.Component {
21261
+ constructor() {
21262
+ super(...arguments);
21263
+ this.zIndex = ComponentsImportance.GridPopover;
21264
+ }
21209
21265
  get cellPopover() {
21210
21266
  const popover = this.env.model.getters.getCellPopover(this.props.hoveredCell);
21211
21267
  if (!popover.isOpen) {
@@ -22509,6 +22565,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22509
22565
  }
22510
22566
  }
22511
22567
  onInput(ev) {
22568
+ // the user meant to paste in the sheet, not open the composer with the pasted content
22569
+ if (!ev.isComposing && ev.inputType === "insertFromPaste") {
22570
+ return;
22571
+ }
22512
22572
  if (ev.data) {
22513
22573
  // if the user types a character on the grid, it means he wants to start composing the selected cell with that
22514
22574
  // character
@@ -23724,6 +23784,72 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23724
23784
  });
23725
23785
  }
23726
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
+
23727
23853
  function convertBorders(data, warningManager) {
23728
23854
  const borderArray = data.borders.map((border) => {
23729
23855
  addBorderWarnings(border, warningManager);
@@ -23788,41 +23914,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23788
23914
  }
23789
23915
  return arrayToObject(formats, 1);
23790
23916
  }
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 with 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
- formatValue(0, convertedFormat);
23819
- return convertedFormat;
23820
- }
23821
- catch (e) { }
23822
- }
23823
- warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
23824
- return undefined;
23825
- }
23826
23917
  /**
23827
23918
  * We currently only support only a set of font sizes, we cannot define new font sizes.
23828
23919
  * This function adapts an arbitrary font size to the closest supported font size.
@@ -32005,9 +32096,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32005
32096
  // remove duplicates first to check validity on a reduced
32006
32097
  // set of colors, then normalize to HEX and remove duplicates
32007
32098
  // again
32008
- [...new Set([...usedColors, ...this.customColors])]
32009
- .filter(isColorValid)
32010
- .map((c) => toHex(c).toLowerCase())),
32099
+ [...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
32011
32100
  ]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
32012
32101
  }
32013
32102
  getColorsFromCells(cells) {
@@ -32068,7 +32157,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32068
32157
  return [...chartsColors];
32069
32158
  }
32070
32159
  tryToAddColor(color) {
32071
- const formattedColor = toHex(color).toLowerCase();
32160
+ const formattedColor = toHex(color);
32072
32161
  if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
32073
32162
  this.customColors.add(formattedColor);
32074
32163
  }
@@ -35809,8 +35898,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35809
35898
  this.getters = getters;
35810
35899
  this.sheetId = sheetId;
35811
35900
  this.boundaries = boundaries;
35812
- this.width = sizeInGrid.width;
35813
- this.height = sizeInGrid.height;
35901
+ this.viewportWidth = sizeInGrid.width;
35902
+ this.viewportHeight = sizeInGrid.height;
35814
35903
  this.offsetScrollbarX = offsets.x;
35815
35904
  this.offsetScrollbarY = offsets.y;
35816
35905
  this.canScrollVertically = options.canScrollVertically;
@@ -35821,6 +35910,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35821
35910
  this.adjustViewportOffsetY();
35822
35911
  }
35823
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
+ */
35824
35917
  getMaxSize() {
35825
35918
  const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
35826
35919
  first: this.boundaries.left,
@@ -35832,20 +35925,24 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35832
35925
  });
35833
35926
  const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
35834
35927
  const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
35835
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.width, 0);
35928
+ const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
35836
35929
  const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
35837
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.height, 0);
35930
+ const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
35838
35931
  const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
35839
- const width = lastColEnd -
35840
- this.offsetCorrectionX +
35841
- (this.canScrollHorizontally
35842
- ? Math.max(DEFAULT_CELL_WIDTH, Math.min(leftColSize, this.width - lastColSize))
35843
- : 0);
35844
- const height = lastRowEnd -
35845
- this.offsetCorrectionY +
35846
- (this.canScrollVertically
35847
- ? Math.max(DEFAULT_CELL_HEIGHT + 5, Math.min(topRowSize, this.height - lastRowSize))
35848
- : 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
+ }
35849
35946
  return { width, height };
35850
35947
  }
35851
35948
  /**
@@ -35854,7 +35951,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35854
35951
  * It returns -1 if no column is found.
35855
35952
  */
35856
35953
  getColIndex(x, absolute = false) {
35857
- if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.width) {
35954
+ if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
35858
35955
  return -1;
35859
35956
  }
35860
35957
  return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
@@ -35865,7 +35962,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35865
35962
  * It returns -1 if no row is found.
35866
35963
  */
35867
35964
  getRowIndex(y, absolute = false) {
35868
- if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.height) {
35965
+ if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
35869
35966
  return -1;
35870
35967
  }
35871
35968
  return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
@@ -35892,7 +35989,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35892
35989
  adjustPositionX(col) {
35893
35990
  const sheetId = this.sheetId;
35894
35991
  const { start, end } = this.getters.getColDimensions(sheetId, col);
35895
- while (end > this.offsetX + this.offsetCorrectionX + this.width &&
35992
+ while (end > this.offsetX + this.offsetCorrectionX + this.viewportWidth &&
35896
35993
  this.offsetX + this.offsetCorrectionX < start) {
35897
35994
  this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
35898
35995
  this.offsetScrollbarX = this.offsetX;
@@ -35914,7 +36011,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35914
36011
  adjustPositionY(row) {
35915
36012
  const sheetId = this.sheetId;
35916
36013
  while (this.getters.getRowDimensions(sheetId, row).end >
35917
- this.offsetY + this.height + this.offsetCorrectionY &&
36014
+ this.offsetY + this.viewportHeight + this.offsetCorrectionY &&
35918
36015
  this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
35919
36016
  this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
35920
36017
  this.offsetScrollbarY = this.offsetY;
@@ -35952,8 +36049,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35952
36049
  const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
35953
36050
  this.offsetCorrectionX;
35954
36051
  const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
35955
- const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.width);
35956
- const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.height);
36052
+ const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
36053
+ const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
35957
36054
  return {
35958
36055
  x,
35959
36056
  y,
@@ -36016,12 +36113,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36016
36113
  adjustViewportOffsetX() {
36017
36114
  if (this.canScrollHorizontally) {
36018
36115
  const { width: viewportWidth } = this.getMaxSize();
36019
- if (this.width + this.offsetScrollbarX > viewportWidth) {
36020
- this.offsetScrollbarX = Math.max(0, viewportWidth - this.width);
36116
+ if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
36117
+ this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
36021
36118
  }
36022
36119
  }
36023
36120
  this.left = this.getColIndex(this.offsetScrollbarX, true);
36024
- this.right = this.getColIndex(this.offsetScrollbarX + this.width, true);
36121
+ this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
36025
36122
  if (this.right === -1) {
36026
36123
  this.right = this.boundaries.right;
36027
36124
  }
@@ -36033,12 +36130,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36033
36130
  adjustViewportOffsetY() {
36034
36131
  if (this.canScrollVertically) {
36035
36132
  const { height: paneHeight } = this.getMaxSize();
36036
- if (this.height + this.offsetScrollbarY > paneHeight) {
36037
- this.offsetScrollbarY = Math.max(0, paneHeight - this.height);
36133
+ if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
36134
+ this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
36038
36135
  }
36039
36136
  }
36040
36137
  this.top = this.getRowIndex(this.offsetScrollbarY, true);
36041
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.width, true);
36138
+ this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
36042
36139
  if (this.bottom === -1) {
36043
36140
  this.bottom = this.boundaries.bottom;
36044
36141
  }
@@ -36049,7 +36146,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36049
36146
  adjustViewportZoneX() {
36050
36147
  const sheetId = this.sheetId;
36051
36148
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
36052
- this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.width, this.left));
36149
+ this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
36053
36150
  if (this.right === -1) {
36054
36151
  this.right = this.getters.getNumberCols(sheetId) - 1;
36055
36152
  }
@@ -36062,7 +36159,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36062
36159
  adjustViewportZoneY() {
36063
36160
  const sheetId = this.sheetId;
36064
36161
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
36065
- this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.height, this.top));
36162
+ this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
36066
36163
  if (this.bottom === -1) {
36067
36164
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
36068
36165
  }
@@ -36321,8 +36418,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36321
36418
  return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
36322
36419
  }
36323
36420
  /**
36324
- * Return the main viewport maximum size. That is the zone dimension
36325
- * with some bottom and right padding.
36421
+ * Return the main viewport maximum size relative to the client size.
36326
36422
  */
36327
36423
  getMainViewportRect() {
36328
36424
  const sheetId = this.getters.getActiveSheetId();
@@ -36338,8 +36434,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
36338
36434
  const { width, height } = this.getMainViewportRect();
36339
36435
  const viewport = this.getMainInternalViewport(sheetId);
36340
36436
  return {
36341
- maxOffsetX: Math.max(0, width - viewport.width + 1),
36342
- maxOffsetY: Math.max(0, height - viewport.height + 1),
36437
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
36438
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
36343
36439
  };
36344
36440
  }
36345
36441
  getColRowOffsetInViewport(dimension, referenceIndex, index) {
@@ -38356,9 +38452,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
38356
38452
  color: #333;
38357
38453
  }
38358
38454
 
38359
- * {
38360
- font-family: "Roboto", "RobotoDraft", Helvetica, Arial, sans-serif;
38361
- }
38362
38455
  &,
38363
38456
  *,
38364
38457
  *:before,
@@ -39534,6 +39627,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39534
39627
  }
39535
39628
  else if (range.zone[start] >= min && range.zone[end] <= max) {
39536
39629
  changeType = "REMOVE";
39630
+ newRange = range.clone({ ...this.getInvalidRange() });
39537
39631
  }
39538
39632
  else if (range.zone[start] <= max && range.zone[end] >= max) {
39539
39633
  const toRemove = max - range.zone[start] + 1;
@@ -39599,8 +39693,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39599
39693
  return { changeType: "NONE" };
39600
39694
  }
39601
39695
  const invalidSheetName = this.getters.getSheetName(cmd.sheetId);
39602
- const sheetId = "";
39603
- range = range.clone({ sheetId, invalidSheetName });
39696
+ range = range.clone({
39697
+ ...this.getInvalidRange(),
39698
+ invalidSheetName,
39699
+ });
39604
39700
  return { changeType: "REMOVE", range };
39605
39701
  }, cmd.sheetId);
39606
39702
  break;
@@ -39864,6 +39960,15 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39864
39960
  }
39865
39961
  return str;
39866
39962
  }
39963
+ getInvalidRange() {
39964
+ return {
39965
+ parts: [],
39966
+ prefixSheet: false,
39967
+ zone: { left: -1, top: -1, right: -1, bottom: -1 },
39968
+ sheetId: "",
39969
+ invalidXc: INCORRECT_RANGE_STRING,
39970
+ };
39971
+ }
39867
39972
  }
39868
39973
  RangeAdapter.getters = [
39869
39974
  "getRangeString",
@@ -42470,9 +42575,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42470
42575
  Object.defineProperty(exports, '__esModule', { value: true });
42471
42576
 
42472
42577
 
42473
- __info__.version = '16.0.4';
42474
- __info__.date = '2023-03-16T12:11:01.007Z';
42475
- __info__.hash = 'ebbb1f0';
42578
+ __info__.version = '16.0.6';
42579
+ __info__.date = '2023-04-13T08:30:26.954Z';
42580
+ __info__.hash = '8d60b5c';
42476
42581
 
42477
42582
 
42478
42583
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);