@odoo/o-spreadsheet 16.1.5 → 16.1.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.
- package/dist/o-spreadsheet.cjs.js +294 -181
- package/dist/o-spreadsheet.d.ts +80 -49
- package/dist/o-spreadsheet.esm.js +294 -181
- package/dist/o-spreadsheet.iife.js +294 -181
- package/dist/o-spreadsheet.iife.min.js +239 -237
- package/package.json +3 -3
|
@@ -115,88 +115,88 @@ const LINK_COLOR = "#01666b";
|
|
|
115
115
|
const FILTERS_COLOR = "#188038";
|
|
116
116
|
const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
|
|
117
117
|
const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
|
|
118
|
-
// Color picker
|
|
118
|
+
// Color picker defaults as upper case HEX to match `toHex`helper
|
|
119
119
|
const COLOR_PICKER_DEFAULTS = [
|
|
120
120
|
"#000000",
|
|
121
121
|
"#434343",
|
|
122
122
|
"#666666",
|
|
123
123
|
"#999999",
|
|
124
|
-
"#
|
|
125
|
-
"#
|
|
126
|
-
"#
|
|
127
|
-
"#
|
|
128
|
-
"#
|
|
129
|
-
"#
|
|
124
|
+
"#B7B7B7",
|
|
125
|
+
"#CCCCCC",
|
|
126
|
+
"#D9D9D9",
|
|
127
|
+
"#EFEFEF",
|
|
128
|
+
"#F3F3F3",
|
|
129
|
+
"#FFFFFF",
|
|
130
130
|
"#980000",
|
|
131
|
-
"#
|
|
132
|
-
"#
|
|
133
|
-
"#
|
|
134
|
-
"#
|
|
135
|
-
"#
|
|
136
|
-
"#
|
|
137
|
-
"#
|
|
138
|
-
"#
|
|
139
|
-
"#
|
|
140
|
-
"#
|
|
141
|
-
"#
|
|
142
|
-
"#
|
|
143
|
-
"#
|
|
144
|
-
"#
|
|
145
|
-
"#
|
|
146
|
-
"#
|
|
147
|
-
"#
|
|
148
|
-
"#
|
|
149
|
-
"#
|
|
150
|
-
"#
|
|
151
|
-
"#
|
|
152
|
-
"#
|
|
153
|
-
"#
|
|
154
|
-
"#
|
|
155
|
-
"#
|
|
156
|
-
"#
|
|
157
|
-
"#
|
|
158
|
-
"#
|
|
159
|
-
"#
|
|
160
|
-
"#
|
|
161
|
-
"#
|
|
162
|
-
"#
|
|
163
|
-
"#
|
|
164
|
-
"#
|
|
165
|
-
"#
|
|
166
|
-
"#
|
|
167
|
-
"#
|
|
168
|
-
"#
|
|
169
|
-
"#
|
|
170
|
-
"#
|
|
171
|
-
"#
|
|
172
|
-
"#
|
|
173
|
-
"#
|
|
174
|
-
"#
|
|
175
|
-
"#
|
|
176
|
-
"#
|
|
177
|
-
"#
|
|
178
|
-
"#
|
|
179
|
-
"#
|
|
180
|
-
"#
|
|
131
|
+
"#FF0000",
|
|
132
|
+
"#FF9900",
|
|
133
|
+
"#FFFF00",
|
|
134
|
+
"#00FF00",
|
|
135
|
+
"#00FFFF",
|
|
136
|
+
"#4A86E8",
|
|
137
|
+
"#0000FF",
|
|
138
|
+
"#9900FF",
|
|
139
|
+
"#FF00FF",
|
|
140
|
+
"#E6B8AF",
|
|
141
|
+
"#F4CCCC",
|
|
142
|
+
"#FCE5CD",
|
|
143
|
+
"#FFF2CC",
|
|
144
|
+
"#D9EAD3",
|
|
145
|
+
"#D0E0E3",
|
|
146
|
+
"#C9DAF8",
|
|
147
|
+
"#CFE2F3",
|
|
148
|
+
"#D9D2E9",
|
|
149
|
+
"#EAD1DC",
|
|
150
|
+
"#DD7E6B",
|
|
151
|
+
"#EA9999",
|
|
152
|
+
"#F9CB9C",
|
|
153
|
+
"#FFE599",
|
|
154
|
+
"#B6D7A8",
|
|
155
|
+
"#A2C4C9",
|
|
156
|
+
"#A4C2F4",
|
|
157
|
+
"#9FC5E8",
|
|
158
|
+
"#B4A7D6",
|
|
159
|
+
"#D5A6BD",
|
|
160
|
+
"#CC4125",
|
|
161
|
+
"#E06666",
|
|
162
|
+
"#F6B26B",
|
|
163
|
+
"#FFD966",
|
|
164
|
+
"#93C47D",
|
|
165
|
+
"#76A5AF",
|
|
166
|
+
"#6D9EEB",
|
|
167
|
+
"#6FA8DC",
|
|
168
|
+
"#8E7CC3",
|
|
169
|
+
"#C27BA0",
|
|
170
|
+
"#A61C00",
|
|
171
|
+
"#CC0000",
|
|
172
|
+
"#E69138",
|
|
173
|
+
"#F1C232",
|
|
174
|
+
"#6AA84F",
|
|
175
|
+
"#45818E",
|
|
176
|
+
"#3C78D8",
|
|
177
|
+
"#3D85C6",
|
|
178
|
+
"#674EA7",
|
|
179
|
+
"#A64D79",
|
|
180
|
+
"#85200C",
|
|
181
181
|
"#990000",
|
|
182
|
-
"#
|
|
183
|
-
"#
|
|
184
|
-
"#
|
|
185
|
-
"#
|
|
186
|
-
"#
|
|
187
|
-
"#
|
|
188
|
-
"#
|
|
189
|
-
"#
|
|
190
|
-
"#
|
|
182
|
+
"#B45F06",
|
|
183
|
+
"#BF9000",
|
|
184
|
+
"#38761D",
|
|
185
|
+
"#134F5C",
|
|
186
|
+
"#1155CC",
|
|
187
|
+
"#0B5394",
|
|
188
|
+
"#351C75",
|
|
189
|
+
"#741B47",
|
|
190
|
+
"#5B0F00",
|
|
191
191
|
"#660000",
|
|
192
|
-
"#
|
|
193
|
-
"#
|
|
194
|
-
"#
|
|
195
|
-
"#
|
|
196
|
-
"#
|
|
192
|
+
"#783F04",
|
|
193
|
+
"#7F6000",
|
|
194
|
+
"#274E13",
|
|
195
|
+
"#0C343D",
|
|
196
|
+
"#1C4587",
|
|
197
197
|
"#073763",
|
|
198
|
-
"#
|
|
199
|
-
"#
|
|
198
|
+
"#20124D",
|
|
199
|
+
"#4C1130",
|
|
200
200
|
];
|
|
201
201
|
// Dimensions
|
|
202
202
|
const MIN_ROW_HEIGHT = 10;
|
|
@@ -235,7 +235,7 @@ const DEFAULT_FONT = "'Roboto', arial";
|
|
|
235
235
|
const DEFAULT_BORDER_DESC = ["thin", "#000"];
|
|
236
236
|
const DEFAULT_FILTER_BORDER_DESC = ["thin", FILTERS_COLOR];
|
|
237
237
|
// DateTimeRegex
|
|
238
|
-
const DATETIME_FORMAT = /[
|
|
238
|
+
const DATETIME_FORMAT = /[ymdhs:]/;
|
|
239
239
|
// Ranges
|
|
240
240
|
const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
|
|
241
241
|
// Max Number of history steps kept in memory
|
|
@@ -272,11 +272,13 @@ var ComponentsImportance;
|
|
|
272
272
|
ComponentsImportance[ComponentsImportance["Highlight"] = 5] = "Highlight";
|
|
273
273
|
ComponentsImportance[ComponentsImportance["Figure"] = 10] = "Figure";
|
|
274
274
|
ComponentsImportance[ComponentsImportance["ScrollBar"] = 15] = "ScrollBar";
|
|
275
|
-
ComponentsImportance[ComponentsImportance["
|
|
276
|
-
ComponentsImportance[ComponentsImportance["
|
|
275
|
+
ComponentsImportance[ComponentsImportance["GridPopover"] = 19] = "GridPopover";
|
|
276
|
+
ComponentsImportance[ComponentsImportance["GridComposer"] = 20] = "GridComposer";
|
|
277
|
+
ComponentsImportance[ComponentsImportance["Dropdown"] = 21] = "Dropdown";
|
|
277
278
|
ComponentsImportance[ComponentsImportance["ColorPicker"] = 25] = "ColorPicker";
|
|
278
279
|
ComponentsImportance[ComponentsImportance["IconPicker"] = 25] = "IconPicker";
|
|
279
|
-
ComponentsImportance[ComponentsImportance["
|
|
280
|
+
ComponentsImportance[ComponentsImportance["TopBarComposer"] = 30] = "TopBarComposer";
|
|
281
|
+
ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
|
|
280
282
|
ComponentsImportance[ComponentsImportance["ChartAnchor"] = 1000] = "ChartAnchor";
|
|
281
283
|
})(ComponentsImportance || (ComponentsImportance = {}));
|
|
282
284
|
const DEFAULT_SHEETVIEW_SIZE = 1000;
|
|
@@ -1039,6 +1041,8 @@ function transpose2dArray(matrix) {
|
|
|
1039
1041
|
return matrix[0].map((_, i) => matrix.map((row) => row[i]));
|
|
1040
1042
|
}
|
|
1041
1043
|
|
|
1044
|
+
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
1045
|
+
const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/g;
|
|
1042
1046
|
const colors$1 = [
|
|
1043
1047
|
"#eb6d00",
|
|
1044
1048
|
"#0074d9",
|
|
@@ -1064,7 +1068,10 @@ function colorNumberString(color) {
|
|
|
1064
1068
|
}
|
|
1065
1069
|
/**
|
|
1066
1070
|
* Converts any CSS color value to a standardized hex6 value.
|
|
1067
|
-
* Accepts: hex3, hex6, hex8 and
|
|
1071
|
+
* Accepts: hex3, hex6, hex8, rgb[1] and rgba[1].
|
|
1072
|
+
*
|
|
1073
|
+
* [1] under the form rgb(r, g, b, a?) or rgba(r, g, b, a?)
|
|
1074
|
+
* with r,g,b ∈ [0, 255] and a ∈ [0, 1]
|
|
1068
1075
|
*
|
|
1069
1076
|
* toHex("#ABC")
|
|
1070
1077
|
* >> "#AABBCC"
|
|
@@ -1075,27 +1082,31 @@ function colorNumberString(color) {
|
|
|
1075
1082
|
* toHex("rgb(30, 80, 16)")
|
|
1076
1083
|
* >> "#1E5010"
|
|
1077
1084
|
*
|
|
1085
|
+
* * toHex("rgb(30, 80, 16, 0.5)")
|
|
1086
|
+
* >> "#1E501080"
|
|
1087
|
+
*
|
|
1078
1088
|
*/
|
|
1079
1089
|
function toHex(color) {
|
|
1080
|
-
|
|
1081
|
-
|
|
1090
|
+
let hexColor = color;
|
|
1091
|
+
if (color.startsWith("rgb")) {
|
|
1092
|
+
hexColor = rgbaStringToHex(color);
|
|
1082
1093
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1094
|
+
else {
|
|
1095
|
+
hexColor = color.replace("#", "").toUpperCase();
|
|
1096
|
+
if (hexColor.length === 3 || hexColor.length === 4) {
|
|
1097
|
+
hexColor = hexColor.split("").reduce((acc, h) => acc + h + h, "");
|
|
1098
|
+
}
|
|
1099
|
+
hexColor = `#${hexColor}`;
|
|
1089
1100
|
}
|
|
1090
|
-
if (
|
|
1091
|
-
throw new Error(
|
|
1101
|
+
if (!hexColor.match(HEX_MATCH)) {
|
|
1102
|
+
throw new Error(`invalid color input: ${color}`);
|
|
1092
1103
|
}
|
|
1093
|
-
return
|
|
1104
|
+
return hexColor;
|
|
1094
1105
|
}
|
|
1095
1106
|
function isColorValid(color) {
|
|
1096
1107
|
try {
|
|
1097
|
-
|
|
1098
|
-
return
|
|
1108
|
+
toHex(color);
|
|
1109
|
+
return true;
|
|
1099
1110
|
}
|
|
1100
1111
|
catch (error) {
|
|
1101
1112
|
return false;
|
|
@@ -1128,15 +1139,29 @@ function relativeLuminance(color) {
|
|
|
1128
1139
|
/**
|
|
1129
1140
|
* Convert a CSS rgb color string to a standardized hex6 color value.
|
|
1130
1141
|
*
|
|
1131
|
-
*
|
|
1142
|
+
* rgbaStringToHex("rgb(30, 80, 16)")
|
|
1132
1143
|
* >> "#1E5010"
|
|
1144
|
+
*
|
|
1145
|
+
* rgbaStringToHex("rgba(30, 80, 16, 0.5)")
|
|
1146
|
+
* >> "#1E501080"
|
|
1147
|
+
*
|
|
1148
|
+
* DOES NOT SUPPORT NON INTEGER RGB VALUES
|
|
1133
1149
|
*/
|
|
1134
|
-
function
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1150
|
+
function rgbaStringToHex(color) {
|
|
1151
|
+
const stringVals = color.replace(RBA_REGEX, "").split(",");
|
|
1152
|
+
let alphaHex = 255;
|
|
1153
|
+
if (stringVals.length !== 3 && stringVals.length !== 4) {
|
|
1154
|
+
throw new Error("invalid color");
|
|
1155
|
+
}
|
|
1156
|
+
else if (stringVals.length === 4) {
|
|
1157
|
+
const alpha = parseFloat(stringVals.pop() || "1");
|
|
1158
|
+
alphaHex = Math.round((alpha || 1) * 255);
|
|
1159
|
+
}
|
|
1160
|
+
const vals = stringVals.map((val) => parseInt(val, 10));
|
|
1161
|
+
if (alphaHex !== 255) {
|
|
1162
|
+
vals.push(alphaHex);
|
|
1163
|
+
}
|
|
1164
|
+
return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
|
|
1140
1165
|
}
|
|
1141
1166
|
/**
|
|
1142
1167
|
* RGBA to HEX representation (#RRGGBBAA).
|
|
@@ -1158,7 +1183,7 @@ function rgbaToHex(rgba) {
|
|
|
1158
1183
|
a = "0" + a;
|
|
1159
1184
|
if (a === "ff")
|
|
1160
1185
|
a = "";
|
|
1161
|
-
return "#" + r + g + b + a;
|
|
1186
|
+
return ("#" + r + g + b + a).toUpperCase();
|
|
1162
1187
|
}
|
|
1163
1188
|
/**
|
|
1164
1189
|
* Color string to RGBA representation
|
|
@@ -1279,6 +1304,9 @@ function rgbaToHSLA(rgba) {
|
|
|
1279
1304
|
s = +(s * 100).toFixed(1);
|
|
1280
1305
|
l = +(l * 100).toFixed(1);
|
|
1281
1306
|
return { a: rgba.a, h, s, l };
|
|
1307
|
+
}
|
|
1308
|
+
function isSameColor(color1, color2) {
|
|
1309
|
+
return isColorValid(color1) && isColorValid(color2) && toHex(color1) === toHex(color2);
|
|
1282
1310
|
}
|
|
1283
1311
|
|
|
1284
1312
|
/** Reference of a cell (eg. A1, $B$5) */
|
|
@@ -1430,7 +1458,7 @@ function scrollDelay(value) {
|
|
|
1430
1458
|
* formula, commas are used to separate arguments
|
|
1431
1459
|
* - it does not support % symbol, in formulas % is an operator
|
|
1432
1460
|
*/
|
|
1433
|
-
const formulaNumberRegexp =
|
|
1461
|
+
const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
|
|
1434
1462
|
const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
|
|
1435
1463
|
const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
|
|
1436
1464
|
const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -3025,6 +3053,7 @@ const CHART_PADDING_RATIO = 0.02;
|
|
|
3025
3053
|
const LINE_HEIGHT = 1.2;
|
|
3026
3054
|
css /* scss */ `
|
|
3027
3055
|
div.o-scorecard {
|
|
3056
|
+
font-family: ${DEFAULT_FONT};
|
|
3028
3057
|
user-select: none;
|
|
3029
3058
|
background-color: white;
|
|
3030
3059
|
display: flex;
|
|
@@ -5649,6 +5678,11 @@ class Popover extends owl.Component {
|
|
|
5649
5678
|
this.currentPosition = newPosition;
|
|
5650
5679
|
});
|
|
5651
5680
|
}
|
|
5681
|
+
get popoverStyle() {
|
|
5682
|
+
return cssPropertiesToCss({
|
|
5683
|
+
"z-index": `${this.props.zIndex}`,
|
|
5684
|
+
});
|
|
5685
|
+
}
|
|
5652
5686
|
}
|
|
5653
5687
|
Popover.template = "o-spreadsheet-Popover";
|
|
5654
5688
|
Popover.defaultProps = {
|
|
@@ -5657,6 +5691,7 @@ Popover.defaultProps = {
|
|
|
5657
5691
|
onMouseWheel: () => { },
|
|
5658
5692
|
onPopoverMoved: () => { },
|
|
5659
5693
|
onPopoverHidden: () => { },
|
|
5694
|
+
zIndex: ComponentsImportance.Popover,
|
|
5660
5695
|
};
|
|
5661
5696
|
Popover.props = {
|
|
5662
5697
|
anchorRect: Object,
|
|
@@ -5668,6 +5703,7 @@ Popover.props = {
|
|
|
5668
5703
|
onMouseWheel: { type: Function, optional: true },
|
|
5669
5704
|
onPopoverHidden: { type: Function, optional: true },
|
|
5670
5705
|
onPopoverMoved: { type: Function, optional: true },
|
|
5706
|
+
zIndex: { type: Number, optional: true },
|
|
5671
5707
|
slots: Object,
|
|
5672
5708
|
};
|
|
5673
5709
|
class PopoverPositionContext {
|
|
@@ -16525,6 +16561,7 @@ class EditionPlugin extends UIPlugin {
|
|
|
16525
16561
|
this.setContent(this.initialContent || "");
|
|
16526
16562
|
}
|
|
16527
16563
|
setContent(text, selection, raise) {
|
|
16564
|
+
text = text.replace(/[\r\n]/g, "");
|
|
16528
16565
|
const isNewCurrentContent = this.currentContent !== text;
|
|
16529
16566
|
this.currentContent = text;
|
|
16530
16567
|
if (selection) {
|
|
@@ -16809,6 +16846,8 @@ class ContentEditableHelper {
|
|
|
16809
16846
|
start = 0;
|
|
16810
16847
|
if (end > this.el.textContent.length)
|
|
16811
16848
|
end = this.el.textContent.length;
|
|
16849
|
+
if (start > this.el.textContent.length)
|
|
16850
|
+
start = this.el.textContent.length;
|
|
16812
16851
|
}
|
|
16813
16852
|
let startNode = this.findChildAtCharacterIndex(start);
|
|
16814
16853
|
let endNode = this.findChildAtCharacterIndex(end);
|
|
@@ -17035,10 +17074,10 @@ css /* scss */ `
|
|
|
17035
17074
|
padding: 0;
|
|
17036
17075
|
margin: 0;
|
|
17037
17076
|
border: 0;
|
|
17038
|
-
z-index: ${ComponentsImportance.Composer};
|
|
17039
17077
|
flex-grow: 1;
|
|
17040
17078
|
max-height: inherit;
|
|
17041
17079
|
.o-composer {
|
|
17080
|
+
font-family: ${DEFAULT_FONT};
|
|
17042
17081
|
caret-color: black;
|
|
17043
17082
|
padding-left: 3px;
|
|
17044
17083
|
padding-right: 3px;
|
|
@@ -17073,6 +17112,10 @@ css /* scss */ `
|
|
|
17073
17112
|
.o-topbar-toolbar .o-composer-container:focus-within {
|
|
17074
17113
|
border: 1px solid ${SELECTION_BORDER_COLOR};
|
|
17075
17114
|
}
|
|
17115
|
+
|
|
17116
|
+
.o-topbar-toolbar .o-composer-container {
|
|
17117
|
+
z-index: ${ComponentsImportance.TopBarComposer};
|
|
17118
|
+
}
|
|
17076
17119
|
`;
|
|
17077
17120
|
class Composer extends owl.Component {
|
|
17078
17121
|
constructor() {
|
|
@@ -17521,7 +17564,7 @@ const SCROLLBAR_HIGHT = 15;
|
|
|
17521
17564
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
17522
17565
|
css /* scss */ `
|
|
17523
17566
|
div.o-grid-composer {
|
|
17524
|
-
z-index: ${ComponentsImportance.
|
|
17567
|
+
z-index: ${ComponentsImportance.GridComposer};
|
|
17525
17568
|
box-sizing: border-box;
|
|
17526
17569
|
position: absolute;
|
|
17527
17570
|
border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
|
|
@@ -20057,6 +20100,9 @@ class ColorPicker extends owl.Component {
|
|
|
20057
20100
|
const { display, background, left, top } = this.state.style;
|
|
20058
20101
|
return `display:${display};${display === "block" ? `background-color:${background};left:${left};top:${top};` : ""}`;
|
|
20059
20102
|
}
|
|
20103
|
+
isSameColor(color1, color2) {
|
|
20104
|
+
return isSameColor(color1, color2);
|
|
20105
|
+
}
|
|
20060
20106
|
}
|
|
20061
20107
|
ColorPicker.template = "o-spreadsheet-ColorPicker";
|
|
20062
20108
|
ColorPicker.defaultProps = {
|
|
@@ -20201,6 +20247,12 @@ class GaugeChartDesignPanel extends owl.Component {
|
|
|
20201
20247
|
const cancelledReasons = [...(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.reasons) || [])];
|
|
20202
20248
|
return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
|
|
20203
20249
|
}
|
|
20250
|
+
onClick(ev) {
|
|
20251
|
+
this.state.openedMenu = undefined;
|
|
20252
|
+
}
|
|
20253
|
+
setup() {
|
|
20254
|
+
owl.useExternalListener(window, "click", this.onClick);
|
|
20255
|
+
}
|
|
20204
20256
|
updateBackgroundColor(color) {
|
|
20205
20257
|
this.state.openedMenu = undefined;
|
|
20206
20258
|
this.props.updateChart({
|
|
@@ -20384,6 +20436,12 @@ class ScorecardChartDesignPanel extends owl.Component {
|
|
|
20384
20436
|
openedColorPicker: undefined,
|
|
20385
20437
|
});
|
|
20386
20438
|
}
|
|
20439
|
+
onClick(ev) {
|
|
20440
|
+
this.state.openedColorPicker = undefined;
|
|
20441
|
+
}
|
|
20442
|
+
setup() {
|
|
20443
|
+
owl.useExternalListener(window, "click", this.onClick);
|
|
20444
|
+
}
|
|
20387
20445
|
updateTitle(ev) {
|
|
20388
20446
|
this.props.updateChart({
|
|
20389
20447
|
title: ev.target.value,
|
|
@@ -22287,6 +22345,9 @@ class GridOverlay extends owl.Component {
|
|
|
22287
22345
|
owl.onMounted(() => {
|
|
22288
22346
|
resizeObserver.observe(this.gridOverlayEl);
|
|
22289
22347
|
});
|
|
22348
|
+
owl.onWillUnmount(() => {
|
|
22349
|
+
resizeObserver.disconnect();
|
|
22350
|
+
});
|
|
22290
22351
|
useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
|
|
22291
22352
|
const { scrollY } = this.env.model.getters.getActiveSheetDOMScrollInfo();
|
|
22292
22353
|
return scrollY > 0;
|
|
@@ -22343,6 +22404,10 @@ GridOverlay.props = {
|
|
|
22343
22404
|
};
|
|
22344
22405
|
|
|
22345
22406
|
class GridPopover extends owl.Component {
|
|
22407
|
+
constructor() {
|
|
22408
|
+
super(...arguments);
|
|
22409
|
+
this.zIndex = ComponentsImportance.GridPopover;
|
|
22410
|
+
}
|
|
22346
22411
|
get cellPopover() {
|
|
22347
22412
|
const popover = this.env.model.getters.getCellPopover(this.props.hoveredCell);
|
|
22348
22413
|
if (!popover.isOpen) {
|
|
@@ -23707,6 +23772,10 @@ class Grid extends owl.Component {
|
|
|
23707
23772
|
}
|
|
23708
23773
|
}
|
|
23709
23774
|
onInput(ev) {
|
|
23775
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
23776
|
+
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
23777
|
+
return;
|
|
23778
|
+
}
|
|
23710
23779
|
if (ev.data) {
|
|
23711
23780
|
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
23712
23781
|
// character
|
|
@@ -24556,6 +24625,70 @@ function fixXlsxUnicode(str) {
|
|
|
24556
24625
|
});
|
|
24557
24626
|
}
|
|
24558
24627
|
|
|
24628
|
+
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;
|
|
24629
|
+
/**
|
|
24630
|
+
* Convert excel format to o_spreadsheet format
|
|
24631
|
+
*
|
|
24632
|
+
* Excel format are defined in openXML §18.8.31
|
|
24633
|
+
*/
|
|
24634
|
+
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
24635
|
+
var _a, _b, _c;
|
|
24636
|
+
if (numFmtId === 0) {
|
|
24637
|
+
return undefined;
|
|
24638
|
+
}
|
|
24639
|
+
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
24640
|
+
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
|
|
24641
|
+
if (format) {
|
|
24642
|
+
try {
|
|
24643
|
+
let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
|
|
24644
|
+
convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
24645
|
+
convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
|
|
24646
|
+
// Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
|
|
24647
|
+
const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
24648
|
+
const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
|
|
24649
|
+
if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
|
|
24650
|
+
throw new Error("Multiple escaped blocks in format");
|
|
24651
|
+
}
|
|
24652
|
+
convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
|
|
24653
|
+
convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM
|
|
24654
|
+
convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
|
|
24655
|
+
convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
|
|
24656
|
+
convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters
|
|
24657
|
+
if (isXlsxDateFormat(convertedFormat)) {
|
|
24658
|
+
convertedFormat = convertDateFormat$1(convertedFormat);
|
|
24659
|
+
}
|
|
24660
|
+
if (isFormatSupported(convertedFormat)) {
|
|
24661
|
+
return convertedFormat;
|
|
24662
|
+
}
|
|
24663
|
+
}
|
|
24664
|
+
catch (e) { }
|
|
24665
|
+
}
|
|
24666
|
+
warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
|
|
24667
|
+
return undefined;
|
|
24668
|
+
}
|
|
24669
|
+
function isFormatSupported(format) {
|
|
24670
|
+
try {
|
|
24671
|
+
formatValue(0, format);
|
|
24672
|
+
return true;
|
|
24673
|
+
}
|
|
24674
|
+
catch (e) {
|
|
24675
|
+
return false;
|
|
24676
|
+
}
|
|
24677
|
+
}
|
|
24678
|
+
function isXlsxDateFormat(format) {
|
|
24679
|
+
return format.match(XLSX_DATE_FORMAT_REGEX) !== null;
|
|
24680
|
+
}
|
|
24681
|
+
function convertDateFormat$1(format) {
|
|
24682
|
+
// Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML,
|
|
24683
|
+
// but can still occur and are supported by Excel/Google sheets
|
|
24684
|
+
format = format.toLowerCase();
|
|
24685
|
+
format = format.replace(/mmmmm/g, "mmm");
|
|
24686
|
+
format = format.replace(/am\/pm|a\/m/g, "a");
|
|
24687
|
+
format = format.replace(/hhhh/g, "hh");
|
|
24688
|
+
format = format.replace(/\bh\b/g, "hh");
|
|
24689
|
+
return format;
|
|
24690
|
+
}
|
|
24691
|
+
|
|
24559
24692
|
function convertBorders(data, warningManager) {
|
|
24560
24693
|
const borderArray = data.borders.map((border) => {
|
|
24561
24694
|
addBorderWarnings(border, warningManager);
|
|
@@ -24620,41 +24753,6 @@ function convertFormats(data, warningManager) {
|
|
|
24620
24753
|
}
|
|
24621
24754
|
return arrayToObject(formats, 1);
|
|
24622
24755
|
}
|
|
24623
|
-
/**
|
|
24624
|
-
* Convert excel format to o_spreadsheet format
|
|
24625
|
-
*
|
|
24626
|
-
* Excel format are defined in openXML §18.8.31
|
|
24627
|
-
*/
|
|
24628
|
-
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
24629
|
-
var _a, _b, _c;
|
|
24630
|
-
if (numFmtId === 0) {
|
|
24631
|
-
return undefined;
|
|
24632
|
-
}
|
|
24633
|
-
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
24634
|
-
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
|
|
24635
|
-
if (format) {
|
|
24636
|
-
try {
|
|
24637
|
-
let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
|
|
24638
|
-
convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
24639
|
-
convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
|
|
24640
|
-
// Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
|
|
24641
|
-
const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
24642
|
-
const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
|
|
24643
|
-
if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
|
|
24644
|
-
throw new Error("Multiple escaped blocks in format");
|
|
24645
|
-
}
|
|
24646
|
-
convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
|
|
24647
|
-
convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore with of next char for align purposes. Not supported ATM
|
|
24648
|
-
convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
|
|
24649
|
-
convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
|
|
24650
|
-
formatValue(0, convertedFormat);
|
|
24651
|
-
return convertedFormat;
|
|
24652
|
-
}
|
|
24653
|
-
catch (e) { }
|
|
24654
|
-
}
|
|
24655
|
-
warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
|
|
24656
|
-
return undefined;
|
|
24657
|
-
}
|
|
24658
24756
|
/**
|
|
24659
24757
|
* We currently only support only a set of font sizes, we cannot define new font sizes.
|
|
24660
24758
|
* This function adapts an arbitrary font size to the closest supported font size.
|
|
@@ -30519,6 +30617,7 @@ class RangeAdapter {
|
|
|
30519
30617
|
}
|
|
30520
30618
|
else if (range.zone[start] >= min && range.zone[end] <= max) {
|
|
30521
30619
|
changeType = "REMOVE";
|
|
30620
|
+
newRange = range.clone({ ...this.getInvalidRange() });
|
|
30522
30621
|
}
|
|
30523
30622
|
else if (range.zone[start] <= max && range.zone[end] >= max) {
|
|
30524
30623
|
const toRemove = max - range.zone[start] + 1;
|
|
@@ -30584,8 +30683,10 @@ class RangeAdapter {
|
|
|
30584
30683
|
return { changeType: "NONE" };
|
|
30585
30684
|
}
|
|
30586
30685
|
const invalidSheetName = this.getters.getSheetName(cmd.sheetId);
|
|
30587
|
-
|
|
30588
|
-
|
|
30686
|
+
range = range.clone({
|
|
30687
|
+
...this.getInvalidRange(),
|
|
30688
|
+
invalidSheetName,
|
|
30689
|
+
});
|
|
30589
30690
|
return { changeType: "REMOVE", range };
|
|
30590
30691
|
}, cmd.sheetId);
|
|
30591
30692
|
break;
|
|
@@ -30845,6 +30946,15 @@ class RangeAdapter {
|
|
|
30845
30946
|
}
|
|
30846
30947
|
return str;
|
|
30847
30948
|
}
|
|
30949
|
+
getInvalidRange() {
|
|
30950
|
+
return {
|
|
30951
|
+
parts: [],
|
|
30952
|
+
prefixSheet: false,
|
|
30953
|
+
zone: { left: -1, top: -1, right: -1, bottom: -1 },
|
|
30954
|
+
sheetId: "",
|
|
30955
|
+
invalidXc: INCORRECT_RANGE_STRING,
|
|
30956
|
+
};
|
|
30957
|
+
}
|
|
30848
30958
|
}
|
|
30849
30959
|
RangeAdapter.getters = [
|
|
30850
30960
|
"getRangeString",
|
|
@@ -31809,9 +31919,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
31809
31919
|
// remove duplicates first to check validity on a reduced
|
|
31810
31920
|
// set of colors, then normalize to HEX and remove duplicates
|
|
31811
31921
|
// again
|
|
31812
|
-
[...new Set([...usedColors, ...this.customColors])]
|
|
31813
|
-
.filter(isColorValid)
|
|
31814
|
-
.map((c) => toHex(c).toLowerCase())),
|
|
31922
|
+
[...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
|
|
31815
31923
|
]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
|
|
31816
31924
|
}
|
|
31817
31925
|
getColorsFromCells(cells) {
|
|
@@ -31872,7 +31980,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
31872
31980
|
return [...chartsColors];
|
|
31873
31981
|
}
|
|
31874
31982
|
tryToAddColor(color) {
|
|
31875
|
-
const formattedColor = toHex(color)
|
|
31983
|
+
const formattedColor = toHex(color);
|
|
31876
31984
|
if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
|
|
31877
31985
|
this.customColors.add(formattedColor);
|
|
31878
31986
|
}
|
|
@@ -32877,8 +32985,8 @@ class InternalViewport {
|
|
|
32877
32985
|
this.getters = getters;
|
|
32878
32986
|
this.sheetId = sheetId;
|
|
32879
32987
|
this.boundaries = boundaries;
|
|
32880
|
-
this.
|
|
32881
|
-
this.
|
|
32988
|
+
this.viewportWidth = sizeInGrid.width;
|
|
32989
|
+
this.viewportHeight = sizeInGrid.height;
|
|
32882
32990
|
this.offsetScrollbarX = offsets.x;
|
|
32883
32991
|
this.offsetScrollbarY = offsets.y;
|
|
32884
32992
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -32889,6 +32997,10 @@ class InternalViewport {
|
|
|
32889
32997
|
this.adjustViewportOffsetY();
|
|
32890
32998
|
}
|
|
32891
32999
|
// PUBLIC
|
|
33000
|
+
/** Returns the maximum size (in Pixels) of the viewport relative to its allocated client size
|
|
33001
|
+
* When the viewport grid size is smaller than its client width (resp. height), it will return
|
|
33002
|
+
* the client width (resp. height).
|
|
33003
|
+
*/
|
|
32892
33004
|
getMaxSize() {
|
|
32893
33005
|
const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
|
|
32894
33006
|
first: this.boundaries.left,
|
|
@@ -32900,20 +33012,24 @@ class InternalViewport {
|
|
|
32900
33012
|
});
|
|
32901
33013
|
const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
|
|
32902
33014
|
const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
|
|
32903
|
-
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.
|
|
33015
|
+
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
|
|
32904
33016
|
const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
|
|
32905
|
-
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.
|
|
33017
|
+
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
|
|
32906
33018
|
const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
|
|
32907
|
-
|
|
32908
|
-
|
|
32909
|
-
(
|
|
32910
|
-
|
|
32911
|
-
|
|
32912
|
-
|
|
32913
|
-
|
|
32914
|
-
|
|
32915
|
-
|
|
32916
|
-
|
|
33019
|
+
let width = lastColEnd - this.offsetCorrectionX;
|
|
33020
|
+
if (this.canScrollHorizontally) {
|
|
33021
|
+
width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
|
|
33022
|
+
Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
|
|
33023
|
+
);
|
|
33024
|
+
width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
|
|
33025
|
+
}
|
|
33026
|
+
let height = lastRowEnd - this.offsetCorrectionY;
|
|
33027
|
+
if (this.canScrollVertically) {
|
|
33028
|
+
height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
|
|
33029
|
+
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
33030
|
+
);
|
|
33031
|
+
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
33032
|
+
}
|
|
32917
33033
|
return { width, height };
|
|
32918
33034
|
}
|
|
32919
33035
|
/**
|
|
@@ -32922,7 +33038,7 @@ class InternalViewport {
|
|
|
32922
33038
|
* It returns -1 if no column is found.
|
|
32923
33039
|
*/
|
|
32924
33040
|
getColIndex(x, absolute = false) {
|
|
32925
|
-
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.
|
|
33041
|
+
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
|
|
32926
33042
|
return -1;
|
|
32927
33043
|
}
|
|
32928
33044
|
return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
|
|
@@ -32933,7 +33049,7 @@ class InternalViewport {
|
|
|
32933
33049
|
* It returns -1 if no row is found.
|
|
32934
33050
|
*/
|
|
32935
33051
|
getRowIndex(y, absolute = false) {
|
|
32936
|
-
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.
|
|
33052
|
+
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
|
|
32937
33053
|
return -1;
|
|
32938
33054
|
}
|
|
32939
33055
|
return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
|
|
@@ -32960,7 +33076,7 @@ class InternalViewport {
|
|
|
32960
33076
|
adjustPositionX(col) {
|
|
32961
33077
|
const sheetId = this.sheetId;
|
|
32962
33078
|
const { start, end } = this.getters.getColDimensions(sheetId, col);
|
|
32963
|
-
while (end > this.offsetX + this.offsetCorrectionX + this.
|
|
33079
|
+
while (end > this.offsetX + this.offsetCorrectionX + this.viewportWidth &&
|
|
32964
33080
|
this.offsetX + this.offsetCorrectionX < start) {
|
|
32965
33081
|
this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
|
|
32966
33082
|
this.offsetScrollbarX = this.offsetX;
|
|
@@ -32982,7 +33098,7 @@ class InternalViewport {
|
|
|
32982
33098
|
adjustPositionY(row) {
|
|
32983
33099
|
const sheetId = this.sheetId;
|
|
32984
33100
|
while (this.getters.getRowDimensions(sheetId, row).end >
|
|
32985
|
-
this.offsetY + this.
|
|
33101
|
+
this.offsetY + this.viewportHeight + this.offsetCorrectionY &&
|
|
32986
33102
|
this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
|
|
32987
33103
|
this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
|
|
32988
33104
|
this.offsetScrollbarY = this.offsetY;
|
|
@@ -33020,8 +33136,8 @@ class InternalViewport {
|
|
|
33020
33136
|
const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
|
|
33021
33137
|
this.offsetCorrectionX;
|
|
33022
33138
|
const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
|
|
33023
|
-
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.
|
|
33024
|
-
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.
|
|
33139
|
+
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
|
|
33140
|
+
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
|
|
33025
33141
|
return {
|
|
33026
33142
|
x,
|
|
33027
33143
|
y,
|
|
@@ -33084,12 +33200,12 @@ class InternalViewport {
|
|
|
33084
33200
|
adjustViewportOffsetX() {
|
|
33085
33201
|
if (this.canScrollHorizontally) {
|
|
33086
33202
|
const { width: viewportWidth } = this.getMaxSize();
|
|
33087
|
-
if (this.
|
|
33088
|
-
this.offsetScrollbarX = Math.max(0, viewportWidth - this.
|
|
33203
|
+
if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
|
|
33204
|
+
this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
|
|
33089
33205
|
}
|
|
33090
33206
|
}
|
|
33091
33207
|
this.left = this.getColIndex(this.offsetScrollbarX, true);
|
|
33092
|
-
this.right = this.getColIndex(this.offsetScrollbarX + this.
|
|
33208
|
+
this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
|
|
33093
33209
|
if (this.right === -1) {
|
|
33094
33210
|
this.right = this.boundaries.right;
|
|
33095
33211
|
}
|
|
@@ -33101,12 +33217,12 @@ class InternalViewport {
|
|
|
33101
33217
|
adjustViewportOffsetY() {
|
|
33102
33218
|
if (this.canScrollVertically) {
|
|
33103
33219
|
const { height: paneHeight } = this.getMaxSize();
|
|
33104
|
-
if (this.
|
|
33105
|
-
this.offsetScrollbarY = Math.max(0, paneHeight - this.
|
|
33220
|
+
if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
|
|
33221
|
+
this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
|
|
33106
33222
|
}
|
|
33107
33223
|
}
|
|
33108
33224
|
this.top = this.getRowIndex(this.offsetScrollbarY, true);
|
|
33109
|
-
this.bottom = this.getRowIndex(this.offsetScrollbarY + this.
|
|
33225
|
+
this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
|
|
33110
33226
|
if (this.bottom === -1) {
|
|
33111
33227
|
this.bottom = this.boundaries.bottom;
|
|
33112
33228
|
}
|
|
@@ -33117,7 +33233,7 @@ class InternalViewport {
|
|
|
33117
33233
|
adjustViewportZoneX() {
|
|
33118
33234
|
const sheetId = this.sheetId;
|
|
33119
33235
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
33120
|
-
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.
|
|
33236
|
+
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
33121
33237
|
if (this.right === -1) {
|
|
33122
33238
|
this.right = this.getters.getNumberCols(sheetId) - 1;
|
|
33123
33239
|
}
|
|
@@ -33130,7 +33246,7 @@ class InternalViewport {
|
|
|
33130
33246
|
adjustViewportZoneY() {
|
|
33131
33247
|
const sheetId = this.sheetId;
|
|
33132
33248
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
33133
|
-
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.
|
|
33249
|
+
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
33134
33250
|
if (this.bottom === -1) {
|
|
33135
33251
|
this.bottom = this.getters.getNumberRows(sheetId) - 1;
|
|
33136
33252
|
}
|
|
@@ -33392,8 +33508,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
33392
33508
|
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
33393
33509
|
}
|
|
33394
33510
|
/**
|
|
33395
|
-
* Return the main viewport maximum size
|
|
33396
|
-
* with some bottom and right padding.
|
|
33511
|
+
* Return the main viewport maximum size relative to the client size.
|
|
33397
33512
|
*/
|
|
33398
33513
|
getMainViewportRect() {
|
|
33399
33514
|
const sheetId = this.getters.getActiveSheetId();
|
|
@@ -33409,8 +33524,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
33409
33524
|
const { width, height } = this.getMainViewportRect();
|
|
33410
33525
|
const viewport = this.getMainInternalViewport(sheetId);
|
|
33411
33526
|
return {
|
|
33412
|
-
maxOffsetX: Math.max(0, width - viewport.
|
|
33413
|
-
maxOffsetY: Math.max(0, height - viewport.
|
|
33527
|
+
maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
|
|
33528
|
+
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
33414
33529
|
};
|
|
33415
33530
|
}
|
|
33416
33531
|
getColRowOffsetInViewport(dimension, referenceIndex, index) {
|
|
@@ -39894,6 +40009,7 @@ class TopBar extends owl.Component {
|
|
|
39894
40009
|
this.state.menuState.parentMenu = menu;
|
|
39895
40010
|
this.isSelectingMenu = true;
|
|
39896
40011
|
this.openedEl = ev.target;
|
|
40012
|
+
this.env.model.dispatch("STOP_EDITION");
|
|
39897
40013
|
}
|
|
39898
40014
|
closeMenus() {
|
|
39899
40015
|
this.state.activeTool = "";
|
|
@@ -40113,9 +40229,6 @@ css /* scss */ `
|
|
|
40113
40229
|
color: #333;
|
|
40114
40230
|
}
|
|
40115
40231
|
|
|
40116
|
-
* {
|
|
40117
|
-
font-family: "Roboto", "RobotoDraft", Helvetica, Arial, sans-serif;
|
|
40118
|
-
}
|
|
40119
40232
|
&,
|
|
40120
40233
|
*,
|
|
40121
40234
|
*:before,
|
|
@@ -43911,6 +44024,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
43911
44024
|
exports.tokenize = tokenize;
|
|
43912
44025
|
|
|
43913
44026
|
|
|
43914
|
-
__info__.version = '16.1.
|
|
43915
|
-
__info__.date = '2023-
|
|
43916
|
-
__info__.hash = '
|
|
44027
|
+
__info__.version = '16.1.7';
|
|
44028
|
+
__info__.date = '2023-04-13T08:29:52.140Z';
|
|
44029
|
+
__info__.hash = '3141a6d';
|