@odoo/o-spreadsheet 16.1.6 → 16.1.8

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;
@@ -232,7 +232,7 @@
232
232
  const DEFAULT_BORDER_DESC = ["thin", "#000"];
233
233
  const DEFAULT_FILTER_BORDER_DESC = ["thin", FILTERS_COLOR];
234
234
  // DateTimeRegex
235
- const DATETIME_FORMAT = /[ymd:]/;
235
+ const DATETIME_FORMAT = /[ymdhs:]/;
236
236
  // Ranges
237
237
  const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
238
238
  // Max Number of history steps kept in memory
@@ -269,11 +269,13 @@
269
269
  ComponentsImportance[ComponentsImportance["Highlight"] = 5] = "Highlight";
270
270
  ComponentsImportance[ComponentsImportance["Figure"] = 10] = "Figure";
271
271
  ComponentsImportance[ComponentsImportance["ScrollBar"] = 15] = "ScrollBar";
272
- ComponentsImportance[ComponentsImportance["Dropdown"] = 16] = "Dropdown";
273
- ComponentsImportance[ComponentsImportance["Composer"] = 20] = "Composer";
272
+ ComponentsImportance[ComponentsImportance["GridPopover"] = 19] = "GridPopover";
273
+ ComponentsImportance[ComponentsImportance["GridComposer"] = 20] = "GridComposer";
274
+ ComponentsImportance[ComponentsImportance["Dropdown"] = 21] = "Dropdown";
274
275
  ComponentsImportance[ComponentsImportance["ColorPicker"] = 25] = "ColorPicker";
275
276
  ComponentsImportance[ComponentsImportance["IconPicker"] = 25] = "IconPicker";
276
- ComponentsImportance[ComponentsImportance["Popover"] = 30] = "Popover";
277
+ ComponentsImportance[ComponentsImportance["TopBarComposer"] = 30] = "TopBarComposer";
278
+ ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
277
279
  ComponentsImportance[ComponentsImportance["ChartAnchor"] = 1000] = "ChartAnchor";
278
280
  })(ComponentsImportance || (ComponentsImportance = {}));
279
281
  const DEFAULT_SHEETVIEW_SIZE = 1000;
@@ -1036,6 +1038,8 @@
1036
1038
  return matrix[0].map((_, i) => matrix.map((row) => row[i]));
1037
1039
  }
1038
1040
 
1041
+ const RBA_REGEX = /rgba?\(|\s+|\)/gi;
1042
+ const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/g;
1039
1043
  const colors$1 = [
1040
1044
  "#eb6d00",
1041
1045
  "#0074d9",
@@ -1061,7 +1065,10 @@
1061
1065
  }
1062
1066
  /**
1063
1067
  * Converts any CSS color value to a standardized hex6 value.
1064
- * Accepts: hex3, hex6, hex8 and rgb (rgba is not supported)
1068
+ * Accepts: hex3, hex6, hex8, rgb[1] and rgba[1].
1069
+ *
1070
+ * [1] under the form rgb(r, g, b, a?) or rgba(r, g, b, a?)
1071
+ * with r,g,b ∈ [0, 255] and a ∈ [0, 1]
1065
1072
  *
1066
1073
  * toHex("#ABC")
1067
1074
  * >> "#AABBCC"
@@ -1072,27 +1079,31 @@
1072
1079
  * toHex("rgb(30, 80, 16)")
1073
1080
  * >> "#1E5010"
1074
1081
  *
1082
+ * * toHex("rgb(30, 80, 16, 0.5)")
1083
+ * >> "#1E501080"
1084
+ *
1075
1085
  */
1076
1086
  function toHex(color) {
1077
- if (color.includes("rgba")) {
1078
- throw new Error(`rgba() conversion currently not supported: ${color}`);
1087
+ let hexColor = color;
1088
+ if (color.startsWith("rgb")) {
1089
+ hexColor = rgbaStringToHex(color);
1079
1090
  }
1080
- if (color.includes("rgb")) {
1081
- return rgbToHex6(color);
1091
+ else {
1092
+ hexColor = color.replace("#", "").toUpperCase();
1093
+ if (hexColor.length === 3 || hexColor.length === 4) {
1094
+ hexColor = hexColor.split("").reduce((acc, h) => acc + h + h, "");
1095
+ }
1096
+ hexColor = `#${hexColor}`;
1082
1097
  }
1083
- color = color.replace("#", "").toUpperCase();
1084
- if (color.length === 3 || color.length === 4) {
1085
- color = color.split("").reduce((acc, h) => acc + h + h, "");
1098
+ if (!hexColor.match(HEX_MATCH)) {
1099
+ throw new Error(`invalid color input: ${color}`);
1086
1100
  }
1087
- if (color.replace(/[a-f0-9]/gi, "") !== "") {
1088
- throw new Error("invalid color");
1089
- }
1090
- return "#" + color;
1101
+ return hexColor;
1091
1102
  }
1092
1103
  function isColorValid(color) {
1093
1104
  try {
1094
- const { r, g, b, a } = colorToRGBA(color);
1095
- return (isColorValueValid(r) && isColorValueValid(g) && isColorValueValid(b) && isColorValueValid(a));
1105
+ toHex(color);
1106
+ return true;
1096
1107
  }
1097
1108
  catch (error) {
1098
1109
  return false;
@@ -1125,15 +1136,29 @@
1125
1136
  /**
1126
1137
  * Convert a CSS rgb color string to a standardized hex6 color value.
1127
1138
  *
1128
- * rgbToHex6("rgb(30, 80, 16)")
1139
+ * rgbaStringToHex("rgb(30, 80, 16)")
1129
1140
  * >> "#1E5010"
1141
+ *
1142
+ * rgbaStringToHex("rgba(30, 80, 16, 0.5)")
1143
+ * >> "#1E501080"
1144
+ *
1145
+ * DOES NOT SUPPORT NON INTEGER RGB VALUES
1130
1146
  */
1131
- function rgbToHex6(color) {
1132
- return ("#" +
1133
- concat(color
1134
- .slice(4, -1)
1135
- .split(",")
1136
- .map((valueString) => parseInt(valueString, 10).toString(16).padStart(2, "0"))).toUpperCase());
1147
+ function rgbaStringToHex(color) {
1148
+ const stringVals = color.replace(RBA_REGEX, "").split(",");
1149
+ let alphaHex = 255;
1150
+ if (stringVals.length !== 3 && stringVals.length !== 4) {
1151
+ throw new Error("invalid color");
1152
+ }
1153
+ else if (stringVals.length === 4) {
1154
+ const alpha = parseFloat(stringVals.pop() || "1");
1155
+ alphaHex = Math.round((alpha || 1) * 255);
1156
+ }
1157
+ const vals = stringVals.map((val) => parseInt(val, 10));
1158
+ if (alphaHex !== 255) {
1159
+ vals.push(alphaHex);
1160
+ }
1161
+ return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
1137
1162
  }
1138
1163
  /**
1139
1164
  * RGBA to HEX representation (#RRGGBBAA).
@@ -1155,7 +1180,7 @@
1155
1180
  a = "0" + a;
1156
1181
  if (a === "ff")
1157
1182
  a = "";
1158
- return "#" + r + g + b + a;
1183
+ return ("#" + r + g + b + a).toUpperCase();
1159
1184
  }
1160
1185
  /**
1161
1186
  * Color string to RGBA representation
@@ -1276,6 +1301,9 @@
1276
1301
  s = +(s * 100).toFixed(1);
1277
1302
  l = +(l * 100).toFixed(1);
1278
1303
  return { a: rgba.a, h, s, l };
1304
+ }
1305
+ function isSameColor(color1, color2) {
1306
+ return isColorValid(color1) && isColorValid(color2) && toHex(color1) === toHex(color2);
1279
1307
  }
1280
1308
 
1281
1309
  /** Reference of a cell (eg. A1, $B$5) */
@@ -1427,7 +1455,7 @@
1427
1455
  * formula, commas are used to separate arguments
1428
1456
  * - it does not support % symbol, in formulas % is an operator
1429
1457
  */
1430
- const formulaNumberRegexp = /^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+/;
1458
+ const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
1431
1459
  const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
1432
1460
  const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
1433
1461
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -3022,6 +3050,7 @@
3022
3050
  const LINE_HEIGHT = 1.2;
3023
3051
  css /* scss */ `
3024
3052
  div.o-scorecard {
3053
+ font-family: ${DEFAULT_FONT};
3025
3054
  user-select: none;
3026
3055
  background-color: white;
3027
3056
  display: flex;
@@ -5646,6 +5675,11 @@
5646
5675
  this.currentPosition = newPosition;
5647
5676
  });
5648
5677
  }
5678
+ get popoverStyle() {
5679
+ return cssPropertiesToCss({
5680
+ "z-index": `${this.props.zIndex}`,
5681
+ });
5682
+ }
5649
5683
  }
5650
5684
  Popover.template = "o-spreadsheet-Popover";
5651
5685
  Popover.defaultProps = {
@@ -5654,6 +5688,7 @@
5654
5688
  onMouseWheel: () => { },
5655
5689
  onPopoverMoved: () => { },
5656
5690
  onPopoverHidden: () => { },
5691
+ zIndex: ComponentsImportance.Popover,
5657
5692
  };
5658
5693
  Popover.props = {
5659
5694
  anchorRect: Object,
@@ -5665,6 +5700,7 @@
5665
5700
  onMouseWheel: { type: Function, optional: true },
5666
5701
  onPopoverHidden: { type: Function, optional: true },
5667
5702
  onPopoverMoved: { type: Function, optional: true },
5703
+ zIndex: { type: Number, optional: true },
5668
5704
  slots: Object,
5669
5705
  };
5670
5706
  class PopoverPositionContext {
@@ -17035,10 +17071,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
17035
17071
  padding: 0;
17036
17072
  margin: 0;
17037
17073
  border: 0;
17038
- z-index: ${ComponentsImportance.Composer};
17039
17074
  flex-grow: 1;
17040
17075
  max-height: inherit;
17041
17076
  .o-composer {
17077
+ font-family: ${DEFAULT_FONT};
17042
17078
  caret-color: black;
17043
17079
  padding-left: 3px;
17044
17080
  padding-right: 3px;
@@ -17073,6 +17109,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
17073
17109
  .o-topbar-toolbar .o-composer-container:focus-within {
17074
17110
  border: 1px solid ${SELECTION_BORDER_COLOR};
17075
17111
  }
17112
+
17113
+ .o-topbar-toolbar .o-composer-container {
17114
+ z-index: ${ComponentsImportance.TopBarComposer};
17115
+ }
17076
17116
  `;
17077
17117
  class Composer extends owl.Component {
17078
17118
  constructor() {
@@ -17521,7 +17561,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
17521
17561
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
17522
17562
  css /* scss */ `
17523
17563
  div.o-grid-composer {
17524
- z-index: ${ComponentsImportance.Composer};
17564
+ z-index: ${ComponentsImportance.GridComposer};
17525
17565
  box-sizing: border-box;
17526
17566
  position: absolute;
17527
17567
  border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
@@ -20057,6 +20097,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20057
20097
  const { display, background, left, top } = this.state.style;
20058
20098
  return `display:${display};${display === "block" ? `background-color:${background};left:${left};top:${top};` : ""}`;
20059
20099
  }
20100
+ isSameColor(color1, color2) {
20101
+ return isSameColor(color1, color2);
20102
+ }
20060
20103
  }
20061
20104
  ColorPicker.template = "o-spreadsheet-ColorPicker";
20062
20105
  ColorPicker.defaultProps = {
@@ -20201,6 +20244,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20201
20244
  const cancelledReasons = [...(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.reasons) || [])];
20202
20245
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
20203
20246
  }
20247
+ onClick(ev) {
20248
+ this.state.openedMenu = undefined;
20249
+ }
20250
+ setup() {
20251
+ owl.useExternalListener(window, "click", this.onClick);
20252
+ }
20204
20253
  updateBackgroundColor(color) {
20205
20254
  this.state.openedMenu = undefined;
20206
20255
  this.props.updateChart({
@@ -20384,6 +20433,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20384
20433
  openedColorPicker: undefined,
20385
20434
  });
20386
20435
  }
20436
+ onClick(ev) {
20437
+ this.state.openedColorPicker = undefined;
20438
+ }
20439
+ setup() {
20440
+ owl.useExternalListener(window, "click", this.onClick);
20441
+ }
20387
20442
  updateTitle(ev) {
20388
20443
  this.props.updateChart({
20389
20444
  title: ev.target.value,
@@ -22346,6 +22401,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22346
22401
  };
22347
22402
 
22348
22403
  class GridPopover extends owl.Component {
22404
+ constructor() {
22405
+ super(...arguments);
22406
+ this.zIndex = ComponentsImportance.GridPopover;
22407
+ }
22349
22408
  get cellPopover() {
22350
22409
  const popover = this.env.model.getters.getCellPopover(this.props.hoveredCell);
22351
22410
  if (!popover.isOpen) {
@@ -24563,6 +24622,70 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
24563
24622
  });
24564
24623
  }
24565
24624
 
24625
+ 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;
24626
+ /**
24627
+ * Convert excel format to o_spreadsheet format
24628
+ *
24629
+ * Excel format are defined in openXML §18.8.31
24630
+ */
24631
+ function convertXlsxFormat(numFmtId, formats, warningManager) {
24632
+ var _a, _b, _c;
24633
+ if (numFmtId === 0) {
24634
+ return undefined;
24635
+ }
24636
+ // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
24637
+ let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
24638
+ if (format) {
24639
+ try {
24640
+ let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
24641
+ convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
24642
+ convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
24643
+ // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
24644
+ const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
24645
+ const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
24646
+ if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
24647
+ throw new Error("Multiple escaped blocks in format");
24648
+ }
24649
+ convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
24650
+ convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM
24651
+ convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
24652
+ convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
24653
+ convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters
24654
+ if (isXlsxDateFormat(convertedFormat)) {
24655
+ convertedFormat = convertDateFormat$1(convertedFormat);
24656
+ }
24657
+ if (isFormatSupported(convertedFormat)) {
24658
+ return convertedFormat;
24659
+ }
24660
+ }
24661
+ catch (e) { }
24662
+ }
24663
+ warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
24664
+ return undefined;
24665
+ }
24666
+ function isFormatSupported(format) {
24667
+ try {
24668
+ formatValue(0, format);
24669
+ return true;
24670
+ }
24671
+ catch (e) {
24672
+ return false;
24673
+ }
24674
+ }
24675
+ function isXlsxDateFormat(format) {
24676
+ return format.match(XLSX_DATE_FORMAT_REGEX) !== null;
24677
+ }
24678
+ function convertDateFormat$1(format) {
24679
+ // Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML,
24680
+ // but can still occur and are supported by Excel/Google sheets
24681
+ format = format.toLowerCase();
24682
+ format = format.replace(/mmmmm/g, "mmm");
24683
+ format = format.replace(/am\/pm|a\/m/g, "a");
24684
+ format = format.replace(/hhhh/g, "hh");
24685
+ format = format.replace(/\bh\b/g, "hh");
24686
+ return format;
24687
+ }
24688
+
24566
24689
  function convertBorders(data, warningManager) {
24567
24690
  const borderArray = data.borders.map((border) => {
24568
24691
  addBorderWarnings(border, warningManager);
@@ -24627,41 +24750,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
24627
24750
  }
24628
24751
  return arrayToObject(formats, 1);
24629
24752
  }
24630
- /**
24631
- * Convert excel format to o_spreadsheet format
24632
- *
24633
- * Excel format are defined in openXML §18.8.31
24634
- */
24635
- function convertXlsxFormat(numFmtId, formats, warningManager) {
24636
- var _a, _b, _c;
24637
- if (numFmtId === 0) {
24638
- return undefined;
24639
- }
24640
- // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
24641
- let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
24642
- if (format) {
24643
- try {
24644
- let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
24645
- convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
24646
- convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
24647
- // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
24648
- const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
24649
- const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
24650
- if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
24651
- throw new Error("Multiple escaped blocks in format");
24652
- }
24653
- convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
24654
- convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore with of next char for align purposes. Not supported ATM
24655
- convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
24656
- convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
24657
- formatValue(0, convertedFormat);
24658
- return convertedFormat;
24659
- }
24660
- catch (e) { }
24661
- }
24662
- warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
24663
- return undefined;
24664
- }
24665
24753
  /**
24666
24754
  * We currently only support only a set of font sizes, we cannot define new font sizes.
24667
24755
  * This function adapts an arbitrary font size to the closest supported font size.
@@ -31828,9 +31916,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31828
31916
  // remove duplicates first to check validity on a reduced
31829
31917
  // set of colors, then normalize to HEX and remove duplicates
31830
31918
  // again
31831
- [...new Set([...usedColors, ...this.customColors])]
31832
- .filter(isColorValid)
31833
- .map((c) => toHex(c).toLowerCase())),
31919
+ [...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
31834
31920
  ]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
31835
31921
  }
31836
31922
  getColorsFromCells(cells) {
@@ -31891,7 +31977,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31891
31977
  return [...chartsColors];
31892
31978
  }
31893
31979
  tryToAddColor(color) {
31894
- const formattedColor = toHex(color).toLowerCase();
31980
+ const formattedColor = toHex(color);
31895
31981
  if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
31896
31982
  this.customColors.add(formattedColor);
31897
31983
  }
@@ -32896,8 +32982,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32896
32982
  this.getters = getters;
32897
32983
  this.sheetId = sheetId;
32898
32984
  this.boundaries = boundaries;
32899
- this.width = sizeInGrid.width;
32900
- this.height = sizeInGrid.height;
32985
+ this.viewportWidth = sizeInGrid.width;
32986
+ this.viewportHeight = sizeInGrid.height;
32901
32987
  this.offsetScrollbarX = offsets.x;
32902
32988
  this.offsetScrollbarY = offsets.y;
32903
32989
  this.canScrollVertically = options.canScrollVertically;
@@ -32908,6 +32994,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32908
32994
  this.adjustViewportOffsetY();
32909
32995
  }
32910
32996
  // PUBLIC
32997
+ /** Returns the maximum size (in Pixels) of the viewport relative to its allocated client size
32998
+ * When the viewport grid size is smaller than its client width (resp. height), it will return
32999
+ * the client width (resp. height).
33000
+ */
32911
33001
  getMaxSize() {
32912
33002
  const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
32913
33003
  first: this.boundaries.left,
@@ -32919,20 +33009,24 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32919
33009
  });
32920
33010
  const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
32921
33011
  const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
32922
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.width, 0);
33012
+ const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
32923
33013
  const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
32924
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.height, 0);
33014
+ const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
32925
33015
  const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
32926
- const width = lastColEnd -
32927
- this.offsetCorrectionX +
32928
- (this.canScrollHorizontally
32929
- ? Math.max(DEFAULT_CELL_WIDTH, Math.min(leftColSize, this.width - lastColSize))
32930
- : 0);
32931
- const height = lastRowEnd -
32932
- this.offsetCorrectionY +
32933
- (this.canScrollVertically
32934
- ? Math.max(DEFAULT_CELL_HEIGHT + 5, Math.min(topRowSize, this.height - lastRowSize))
32935
- : 0);
33016
+ let width = lastColEnd - this.offsetCorrectionX;
33017
+ if (this.canScrollHorizontally) {
33018
+ width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
33019
+ Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
33020
+ );
33021
+ width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
33022
+ }
33023
+ let height = lastRowEnd - this.offsetCorrectionY;
33024
+ if (this.canScrollVertically) {
33025
+ height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
33026
+ Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
33027
+ );
33028
+ height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
33029
+ }
32936
33030
  return { width, height };
32937
33031
  }
32938
33032
  /**
@@ -32941,7 +33035,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32941
33035
  * It returns -1 if no column is found.
32942
33036
  */
32943
33037
  getColIndex(x, absolute = false) {
32944
- if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.width) {
33038
+ if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
32945
33039
  return -1;
32946
33040
  }
32947
33041
  return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
@@ -32952,7 +33046,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32952
33046
  * It returns -1 if no row is found.
32953
33047
  */
32954
33048
  getRowIndex(y, absolute = false) {
32955
- if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.height) {
33049
+ if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
32956
33050
  return -1;
32957
33051
  }
32958
33052
  return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
@@ -32976,48 +33070,66 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32976
33070
  this.adjustPositionY(row);
32977
33071
  }
32978
33072
  }
32979
- adjustPositionX(col) {
33073
+ adjustPositionX(targetCol) {
32980
33074
  const sheetId = this.sheetId;
32981
- const { start, end } = this.getters.getColDimensions(sheetId, col);
32982
- while (end > this.offsetX + this.offsetCorrectionX + this.width &&
32983
- this.offsetX + this.offsetCorrectionX < start) {
32984
- this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
32985
- this.offsetScrollbarX = this.offsetX;
32986
- this.adjustViewportZoneX();
32987
- }
32988
- while (col < this.left) {
32989
- let leftCol;
32990
- for (leftCol = this.left; leftCol >= 0; leftCol--) {
32991
- if (!this.getters.isColHidden(sheetId, leftCol)) {
33075
+ const { end } = this.getters.getColDimensions(sheetId, targetCol);
33076
+ const maxCol = this.getters.getNumberCols(sheetId);
33077
+ if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
33078
+ for (let col = this.left; this.offsetX + this.offsetCorrectionX + this.viewportWidth < end; col++) {
33079
+ if (col > maxCol) {
32992
33080
  break;
32993
33081
  }
33082
+ if (this.getters.isColHidden(sheetId, col)) {
33083
+ continue;
33084
+ }
33085
+ this.offsetX = this.getters.getColDimensions(sheetId, col).end - this.offsetCorrectionX;
33086
+ this.offsetScrollbarX = this.offsetX;
33087
+ this.adjustViewportZoneX();
33088
+ }
33089
+ }
33090
+ else if (this.left > targetCol) {
33091
+ for (let col = this.left; col >= targetCol; col--) {
33092
+ if (col < 0) {
33093
+ break;
33094
+ }
33095
+ if (this.getters.isColHidden(sheetId, col)) {
33096
+ continue;
33097
+ }
33098
+ this.offsetX = this.getters.getColDimensions(sheetId, col).start - this.offsetCorrectionX;
33099
+ this.offsetScrollbarX = this.offsetX;
33100
+ this.adjustViewportZoneX();
32994
33101
  }
32995
- this.offsetX =
32996
- this.getters.getColDimensions(sheetId, leftCol - 1).start - this.offsetCorrectionX;
32997
- this.offsetScrollbarX = this.offsetX;
32998
- this.adjustViewportZoneX();
32999
33102
  }
33000
33103
  }
33001
- adjustPositionY(row) {
33104
+ adjustPositionY(targetRow) {
33002
33105
  const sheetId = this.sheetId;
33003
- while (this.getters.getRowDimensions(sheetId, row).end >
33004
- this.offsetY + this.height + this.offsetCorrectionY &&
33005
- this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
33006
- this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
33007
- this.offsetScrollbarY = this.offsetY;
33008
- this.adjustViewportZoneY();
33009
- }
33010
- while (row < this.top) {
33011
- let topRow;
33012
- for (topRow = this.top; topRow >= 0; topRow--) {
33013
- if (!this.getters.isRowHidden(sheetId, topRow)) {
33106
+ const { end } = this.getters.getRowDimensions(sheetId, targetRow);
33107
+ const maxRow = this.getters.getNumberRows(sheetId);
33108
+ if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
33109
+ for (let row = this.top; this.offsetY + this.viewportHeight + this.offsetCorrectionY < end; row++) {
33110
+ if (row > maxRow) {
33111
+ break;
33112
+ }
33113
+ if (this.getters.isRowHidden(sheetId, row)) {
33114
+ continue;
33115
+ }
33116
+ this.offsetY = this.getters.getRowDimensions(sheetId, row).end - this.offsetCorrectionY;
33117
+ this.offsetScrollbarY = this.offsetY;
33118
+ this.adjustViewportZoneY();
33119
+ }
33120
+ }
33121
+ else if (this.top > targetRow) {
33122
+ for (let row = this.top; row >= targetRow; row--) {
33123
+ if (row < 0) {
33014
33124
  break;
33015
33125
  }
33126
+ if (this.getters.isRowHidden(sheetId, row)) {
33127
+ continue;
33128
+ }
33129
+ this.offsetY = this.getters.getRowDimensions(sheetId, row).start - this.offsetCorrectionY;
33130
+ this.offsetScrollbarY = this.offsetY;
33131
+ this.adjustViewportZoneY();
33016
33132
  }
33017
- this.offsetY =
33018
- this.getters.getRowDimensions(sheetId, topRow - 1).start - this.offsetCorrectionY;
33019
- this.offsetScrollbarY = this.offsetY;
33020
- this.adjustViewportZoneY();
33021
33133
  }
33022
33134
  }
33023
33135
  setViewportOffset(offsetX, offsetY) {
@@ -33039,8 +33151,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33039
33151
  const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
33040
33152
  this.offsetCorrectionX;
33041
33153
  const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
33042
- const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.width);
33043
- const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.height);
33154
+ const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
33155
+ const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
33044
33156
  return {
33045
33157
  x,
33046
33158
  y,
@@ -33103,12 +33215,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33103
33215
  adjustViewportOffsetX() {
33104
33216
  if (this.canScrollHorizontally) {
33105
33217
  const { width: viewportWidth } = this.getMaxSize();
33106
- if (this.width + this.offsetScrollbarX > viewportWidth) {
33107
- this.offsetScrollbarX = Math.max(0, viewportWidth - this.width);
33218
+ if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
33219
+ this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
33108
33220
  }
33109
33221
  }
33110
33222
  this.left = this.getColIndex(this.offsetScrollbarX, true);
33111
- this.right = this.getColIndex(this.offsetScrollbarX + this.width, true);
33223
+ this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
33112
33224
  if (this.right === -1) {
33113
33225
  this.right = this.boundaries.right;
33114
33226
  }
@@ -33120,12 +33232,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33120
33232
  adjustViewportOffsetY() {
33121
33233
  if (this.canScrollVertically) {
33122
33234
  const { height: paneHeight } = this.getMaxSize();
33123
- if (this.height + this.offsetScrollbarY > paneHeight) {
33124
- this.offsetScrollbarY = Math.max(0, paneHeight - this.height);
33235
+ if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
33236
+ this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
33125
33237
  }
33126
33238
  }
33127
33239
  this.top = this.getRowIndex(this.offsetScrollbarY, true);
33128
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.width, true);
33240
+ this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
33129
33241
  if (this.bottom === -1) {
33130
33242
  this.bottom = this.boundaries.bottom;
33131
33243
  }
@@ -33136,7 +33248,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33136
33248
  adjustViewportZoneX() {
33137
33249
  const sheetId = this.sheetId;
33138
33250
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
33139
- this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.width, this.left));
33251
+ this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
33140
33252
  if (this.right === -1) {
33141
33253
  this.right = this.getters.getNumberCols(sheetId) - 1;
33142
33254
  }
@@ -33149,7 +33261,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33149
33261
  adjustViewportZoneY() {
33150
33262
  const sheetId = this.sheetId;
33151
33263
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
33152
- this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.height, this.top));
33264
+ this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
33153
33265
  if (this.bottom === -1) {
33154
33266
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
33155
33267
  }
@@ -33411,8 +33523,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33411
33523
  return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
33412
33524
  }
33413
33525
  /**
33414
- * Return the main viewport maximum size. That is the zone dimension
33415
- * with some bottom and right padding.
33526
+ * Return the main viewport maximum size relative to the client size.
33416
33527
  */
33417
33528
  getMainViewportRect() {
33418
33529
  const sheetId = this.getters.getActiveSheetId();
@@ -33428,8 +33539,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33428
33539
  const { width, height } = this.getMainViewportRect();
33429
33540
  const viewport = this.getMainInternalViewport(sheetId);
33430
33541
  return {
33431
- maxOffsetX: Math.max(0, width - viewport.width + 1),
33432
- maxOffsetY: Math.max(0, height - viewport.height + 1),
33542
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
33543
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
33433
33544
  };
33434
33545
  }
33435
33546
  getColRowOffsetInViewport(dimension, referenceIndex, index) {
@@ -40133,9 +40244,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
40133
40244
  color: #333;
40134
40245
  }
40135
40246
 
40136
- * {
40137
- font-family: "Roboto", "RobotoDraft", Helvetica, Arial, sans-serif;
40138
- }
40139
40247
  &,
40140
40248
  *,
40141
40249
  *:before,
@@ -43933,9 +44041,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43933
44041
  Object.defineProperty(exports, '__esModule', { value: true });
43934
44042
 
43935
44043
 
43936
- __info__.version = '16.1.6';
43937
- __info__.date = '2023-03-23T11:36:48.524Z';
43938
- __info__.hash = '3bad828';
44044
+ __info__.version = '16.1.8';
44045
+ __info__.date = '2023-04-14T12:46:41.355Z';
44046
+ __info__.hash = '4399770';
43939
44047
 
43940
44048
 
43941
44049
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);