@odoo/o-spreadsheet 16.4.14 → 16.4.16
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 +200 -166
- package/dist/o-spreadsheet.d.ts +18 -27
- package/dist/o-spreadsheet.esm.js +200 -166
- package/dist/o-spreadsheet.iife.js +200 -166
- package/dist/o-spreadsheet.iife.min.js +249 -249
- package/dist/o_spreadsheet.xml +6 -7
- package/package.json +1 -1
|
@@ -301,13 +301,6 @@ const NEWLINE = "\n";
|
|
|
301
301
|
const FONT_SIZES = [6, 7, 8, 9, 10, 11, 12, 14, 18, 24, 36];
|
|
302
302
|
|
|
303
303
|
//------------------------------------------------------------------------------
|
|
304
|
-
/**
|
|
305
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
306
|
-
* is ordered.
|
|
307
|
-
*/
|
|
308
|
-
function stringify(obj) {
|
|
309
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
310
|
-
}
|
|
311
304
|
/**
|
|
312
305
|
* Remove quotes from a quoted string
|
|
313
306
|
* ```js
|
|
@@ -527,7 +520,7 @@ function isObjectEmptyRecursive(argument) {
|
|
|
527
520
|
*/
|
|
528
521
|
function getItemId(item, itemsDic) {
|
|
529
522
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
530
|
-
if (
|
|
523
|
+
if (deepEquals(value, item)) {
|
|
531
524
|
return parseInt(key, 10);
|
|
532
525
|
}
|
|
533
526
|
}
|
|
@@ -672,8 +665,7 @@ function transpose2dArray(matrix, callback = (val) => val) {
|
|
|
672
665
|
*
|
|
673
666
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
674
667
|
*/
|
|
675
|
-
const
|
|
676
|
-
" ",
|
|
668
|
+
const whiteSpaceSpecialCharacters = [
|
|
677
669
|
"\t",
|
|
678
670
|
"\f",
|
|
679
671
|
"\v",
|
|
@@ -688,8 +680,7 @@ const whiteSpaceCharacters = [
|
|
|
688
680
|
String.fromCharCode(parseInt("3000", 16)),
|
|
689
681
|
String.fromCharCode(parseInt("feff", 16)),
|
|
690
682
|
];
|
|
691
|
-
const whiteSpaceRegexp = new RegExp(
|
|
692
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
683
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
693
684
|
/**
|
|
694
685
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
695
686
|
* different newlines types by \n.
|
|
@@ -697,9 +688,9 @@ const newLineRegex = /\r\n|\r|\n/g;
|
|
|
697
688
|
function replaceSpecialSpaces(text) {
|
|
698
689
|
if (!text)
|
|
699
690
|
return "";
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
return text;
|
|
691
|
+
if (!whiteSpaceRegexp.test(text))
|
|
692
|
+
return text;
|
|
693
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
703
694
|
}
|
|
704
695
|
/**
|
|
705
696
|
* Determine if the numbers are consecutive.
|
|
@@ -2347,8 +2338,10 @@ function convertInternalFormatToFormat(internalFormat) {
|
|
|
2347
2338
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
2348
2339
|
// Same as above, but matches the exact string (nothing before or after)
|
|
2349
2340
|
const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
|
|
2350
|
-
/** Reference of a column header (eg. A, AB) */
|
|
2351
|
-
const colHeader = new RegExp(
|
|
2341
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
2342
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
2343
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
2344
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
2352
2345
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
2353
2346
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
2354
2347
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -2378,6 +2371,9 @@ function isRowReference(xc) {
|
|
|
2378
2371
|
function isColHeader(str) {
|
|
2379
2372
|
return colHeader.test(str);
|
|
2380
2373
|
}
|
|
2374
|
+
function isRowHeader(str) {
|
|
2375
|
+
return rowHeader.test(str);
|
|
2376
|
+
}
|
|
2381
2377
|
/**
|
|
2382
2378
|
* Return true if the given xc is the reference of a single cell,
|
|
2383
2379
|
* without any specified sheet (e.g. A1)
|
|
@@ -3050,18 +3046,10 @@ class RangeImpl {
|
|
|
3050
3046
|
if (isFullCol) {
|
|
3051
3047
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
3052
3048
|
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
3053
|
-
if (zone.left === zone.right) {
|
|
3054
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
3055
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
3056
|
-
}
|
|
3057
3049
|
}
|
|
3058
3050
|
if (isFullRow) {
|
|
3059
3051
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
3060
3052
|
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
3061
|
-
if (zone.top === zone.bottom) {
|
|
3062
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
3063
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
3064
|
-
}
|
|
3065
3053
|
}
|
|
3066
3054
|
return parts;
|
|
3067
3055
|
}
|
|
@@ -4269,6 +4257,7 @@ exports.CommandResult = void 0;
|
|
|
4269
4257
|
CommandResult[CommandResult["NoActiveSheet"] = 94] = "NoActiveSheet";
|
|
4270
4258
|
CommandResult[CommandResult["InvalidLocale"] = 95] = "InvalidLocale";
|
|
4271
4259
|
CommandResult[CommandResult["AlreadyInPaintingFormatMode"] = 96] = "AlreadyInPaintingFormatMode";
|
|
4260
|
+
CommandResult[CommandResult["NoChanges"] = 97] = "NoChanges";
|
|
4272
4261
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
4273
4262
|
|
|
4274
4263
|
const borderStyles = ["thin", "medium", "thick", "dashed", "dotted"];
|
|
@@ -4358,12 +4347,12 @@ function toString(value) {
|
|
|
4358
4347
|
}
|
|
4359
4348
|
}
|
|
4360
4349
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
4361
|
-
function normalizeString(str) {
|
|
4350
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
4362
4351
|
return str
|
|
4363
4352
|
.toLowerCase()
|
|
4364
4353
|
.normalize("NFD")
|
|
4365
4354
|
.replace(/[\u0300-\u036f]/g, "");
|
|
4366
|
-
}
|
|
4355
|
+
});
|
|
4367
4356
|
/**
|
|
4368
4357
|
* Normalize a value.
|
|
4369
4358
|
* If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
|
|
@@ -5649,6 +5638,9 @@ function* iterateChildren(el) {
|
|
|
5649
5638
|
}
|
|
5650
5639
|
function getOpenedMenus() {
|
|
5651
5640
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5641
|
+
}
|
|
5642
|
+
function isMacOS() {
|
|
5643
|
+
return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
|
|
5652
5644
|
}
|
|
5653
5645
|
|
|
5654
5646
|
/**
|
|
@@ -14174,7 +14166,7 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
|
14174
14166
|
return result;
|
|
14175
14167
|
}
|
|
14176
14168
|
function tokenizeDebugger(chars) {
|
|
14177
|
-
if (chars.current
|
|
14169
|
+
if (chars.current === "?") {
|
|
14178
14170
|
chars.shift();
|
|
14179
14171
|
return { type: "DEBUGGER", value: "?" };
|
|
14180
14172
|
}
|
|
@@ -14185,7 +14177,7 @@ const misc = {
|
|
|
14185
14177
|
")": "RIGHT_PAREN",
|
|
14186
14178
|
};
|
|
14187
14179
|
function tokenizeMisc(chars) {
|
|
14188
|
-
if (chars.current
|
|
14180
|
+
if (chars.current in misc) {
|
|
14189
14181
|
const value = chars.shift();
|
|
14190
14182
|
const type = misc[value];
|
|
14191
14183
|
return { type, value };
|
|
@@ -14193,7 +14185,7 @@ function tokenizeMisc(chars) {
|
|
|
14193
14185
|
return null;
|
|
14194
14186
|
}
|
|
14195
14187
|
function tokenizeArgsSeparator(chars, locale) {
|
|
14196
|
-
if (chars.current
|
|
14188
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
14197
14189
|
const value = chars.shift();
|
|
14198
14190
|
const type = "ARG_SEPARATOR";
|
|
14199
14191
|
return { type, value };
|
|
@@ -14218,14 +14210,13 @@ function tokenizeNumber(chars, locale) {
|
|
|
14218
14210
|
return null;
|
|
14219
14211
|
}
|
|
14220
14212
|
function tokenizeString(chars) {
|
|
14221
|
-
if (chars.current
|
|
14213
|
+
if (chars.current === '"') {
|
|
14222
14214
|
const startChar = chars.shift();
|
|
14223
14215
|
let letters = startChar;
|
|
14224
|
-
while (chars.current()
|
|
14225
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
14216
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
14226
14217
|
letters += chars.shift();
|
|
14227
14218
|
}
|
|
14228
|
-
if (chars.current
|
|
14219
|
+
if (chars.current === '"') {
|
|
14229
14220
|
letters += chars.shift();
|
|
14230
14221
|
}
|
|
14231
14222
|
return {
|
|
@@ -14252,14 +14243,14 @@ function tokenizeSymbol(chars) {
|
|
|
14252
14243
|
let result = "";
|
|
14253
14244
|
// there are two main cases to manage: either something which starts with
|
|
14254
14245
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
14255
|
-
if (chars.current
|
|
14246
|
+
if (chars.current === "'") {
|
|
14256
14247
|
let lastChar = chars.shift();
|
|
14257
14248
|
result += lastChar;
|
|
14258
|
-
while (chars.current
|
|
14249
|
+
while (chars.current) {
|
|
14259
14250
|
lastChar = chars.shift();
|
|
14260
14251
|
result += lastChar;
|
|
14261
14252
|
if (lastChar === "'") {
|
|
14262
|
-
if (chars.current
|
|
14253
|
+
if (chars.current && chars.current === "'") {
|
|
14263
14254
|
lastChar = chars.shift();
|
|
14264
14255
|
result += lastChar;
|
|
14265
14256
|
}
|
|
@@ -14275,7 +14266,7 @@ function tokenizeSymbol(chars) {
|
|
|
14275
14266
|
};
|
|
14276
14267
|
}
|
|
14277
14268
|
}
|
|
14278
|
-
while (chars.current
|
|
14269
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
14279
14270
|
result += chars.shift();
|
|
14280
14271
|
}
|
|
14281
14272
|
if (result.length) {
|
|
@@ -14290,14 +14281,14 @@ function tokenizeSymbol(chars) {
|
|
|
14290
14281
|
}
|
|
14291
14282
|
function tokenizeSpace(chars) {
|
|
14292
14283
|
let length = 0;
|
|
14293
|
-
while (chars.current
|
|
14284
|
+
while (chars.current === NEWLINE) {
|
|
14294
14285
|
length++;
|
|
14295
14286
|
chars.shift();
|
|
14296
14287
|
}
|
|
14297
14288
|
if (length) {
|
|
14298
14289
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
14299
14290
|
}
|
|
14300
|
-
while (chars.current
|
|
14291
|
+
while (chars.current === " ") {
|
|
14301
14292
|
length++;
|
|
14302
14293
|
chars.shift();
|
|
14303
14294
|
}
|
|
@@ -14316,17 +14307,20 @@ function tokenizeInvalidRange(chars) {
|
|
|
14316
14307
|
class TokenizingChars {
|
|
14317
14308
|
text;
|
|
14318
14309
|
currentIndex = 0;
|
|
14310
|
+
current;
|
|
14319
14311
|
constructor(text) {
|
|
14320
14312
|
this.text = text;
|
|
14321
|
-
|
|
14322
|
-
current() {
|
|
14323
|
-
return this.text[this.currentIndex];
|
|
14313
|
+
this.current = text[0];
|
|
14324
14314
|
}
|
|
14325
14315
|
shift() {
|
|
14326
|
-
|
|
14316
|
+
const current = this.current;
|
|
14317
|
+
const next = this.text[++this.currentIndex];
|
|
14318
|
+
this.current = next;
|
|
14319
|
+
return current;
|
|
14327
14320
|
}
|
|
14328
14321
|
advanceBy(length) {
|
|
14329
14322
|
this.currentIndex += length;
|
|
14323
|
+
this.current = this.text[this.currentIndex];
|
|
14330
14324
|
}
|
|
14331
14325
|
isOver() {
|
|
14332
14326
|
return this.currentIndex >= this.text.length;
|
|
@@ -14703,7 +14697,7 @@ const machine = {
|
|
|
14703
14697
|
SPACE: goTo(State.RightRef),
|
|
14704
14698
|
NUMBER: goTo(State.Found),
|
|
14705
14699
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
14706
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
14700
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
14707
14701
|
},
|
|
14708
14702
|
[State.RightColumnRef]: {
|
|
14709
14703
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -14714,6 +14708,7 @@ const machine = {
|
|
|
14714
14708
|
SPACE: goTo(State.RightRowRef),
|
|
14715
14709
|
NUMBER: goTo(State.Found),
|
|
14716
14710
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
14711
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
14717
14712
|
},
|
|
14718
14713
|
[State.Found]: {},
|
|
14719
14714
|
};
|
|
@@ -16871,7 +16866,7 @@ function createGaugeChartRuntime(chart, getters) {
|
|
|
16871
16866
|
});
|
|
16872
16867
|
return {
|
|
16873
16868
|
chartJsConfig: config,
|
|
16874
|
-
background: getters.
|
|
16869
|
+
background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
|
|
16875
16870
|
};
|
|
16876
16871
|
}
|
|
16877
16872
|
|
|
@@ -17595,7 +17590,7 @@ function createScorecardChartRuntime(chart, getters) {
|
|
|
17595
17590
|
};
|
|
17596
17591
|
baselineCell = getters.getEvaluatedCell(baselinePosition);
|
|
17597
17592
|
}
|
|
17598
|
-
const background = getters.
|
|
17593
|
+
const { background, fontColor } = getters.getStyleOfSingleCellChart(chart.background, chart.keyValue);
|
|
17599
17594
|
const locale = getters.getLocale();
|
|
17600
17595
|
return {
|
|
17601
17596
|
title: _t(chart.title),
|
|
@@ -17604,7 +17599,7 @@ function createScorecardChartRuntime(chart, getters) {
|
|
|
17604
17599
|
baselineArrow: getBaselineArrowDirection(baselineCell, keyValueCell, chart.baselineMode),
|
|
17605
17600
|
baselineColor: getBaselineColor(baselineCell, chart.baselineMode, keyValueCell, chart.baselineColorUp, chart.baselineColorDown),
|
|
17606
17601
|
baselineDescr: chart.baselineDescr ? _t(chart.baselineDescr) : "",
|
|
17607
|
-
fontColor
|
|
17602
|
+
fontColor,
|
|
17608
17603
|
background,
|
|
17609
17604
|
baselineStyle: chart.baselineMode !== "percentage" && baseline
|
|
17610
17605
|
? getters.getCellStyle({
|
|
@@ -25620,6 +25615,7 @@ class AbstractResizer extends owl.Component {
|
|
|
25620
25615
|
draggerShadowThickness: 0,
|
|
25621
25616
|
delta: 0,
|
|
25622
25617
|
base: 0,
|
|
25618
|
+
position: "before",
|
|
25623
25619
|
});
|
|
25624
25620
|
_computeHandleDisplay(ev) {
|
|
25625
25621
|
const position = this._getEvOffset(ev);
|
|
@@ -25744,11 +25740,13 @@ class AbstractResizer extends owl.Component {
|
|
|
25744
25740
|
this.state.draggerLinePosition = dimensions.start;
|
|
25745
25741
|
this.state.draggerShadowPosition = dimensions.start;
|
|
25746
25742
|
this.state.base = elementIndex;
|
|
25743
|
+
this.state.position = "before";
|
|
25747
25744
|
}
|
|
25748
25745
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
25749
25746
|
this.state.draggerLinePosition = dimensions.end;
|
|
25750
25747
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
25751
|
-
this.state.base = elementIndex
|
|
25748
|
+
this.state.base = elementIndex;
|
|
25749
|
+
this.state.position = "after";
|
|
25752
25750
|
}
|
|
25753
25751
|
else {
|
|
25754
25752
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -25931,6 +25929,7 @@ class ColResizer extends AbstractResizer {
|
|
|
25931
25929
|
dimension: "COL",
|
|
25932
25930
|
base: this.state.base,
|
|
25933
25931
|
elements,
|
|
25932
|
+
position: this.state.position,
|
|
25934
25933
|
});
|
|
25935
25934
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
25936
25935
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -26104,6 +26103,7 @@ class RowResizer extends AbstractResizer {
|
|
|
26104
26103
|
dimension: "ROW",
|
|
26105
26104
|
base: this.state.base,
|
|
26106
26105
|
elements,
|
|
26106
|
+
position: this.state.position,
|
|
26107
26107
|
});
|
|
26108
26108
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
26109
26109
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -26211,8 +26211,8 @@ function useWheelHandler(handler) {
|
|
|
26211
26211
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
26212
26212
|
}
|
|
26213
26213
|
const onMouseWheel = (ev) => {
|
|
26214
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
26215
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
26214
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
26215
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
26216
26216
|
handler(deltaX, deltaY);
|
|
26217
26217
|
};
|
|
26218
26218
|
return onMouseWheel;
|
|
@@ -31170,6 +31170,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
31170
31170
|
// ---------------------------------------------------------------------------
|
|
31171
31171
|
// Command Handling
|
|
31172
31172
|
// ---------------------------------------------------------------------------
|
|
31173
|
+
allowDispatch(cmd) {
|
|
31174
|
+
switch (cmd.type) {
|
|
31175
|
+
case "SET_BORDER":
|
|
31176
|
+
return this.checkBordersUnchanged(cmd);
|
|
31177
|
+
default:
|
|
31178
|
+
return 0 /* CommandResult.Success */;
|
|
31179
|
+
}
|
|
31180
|
+
}
|
|
31173
31181
|
handle(cmd) {
|
|
31174
31182
|
switch (cmd.type) {
|
|
31175
31183
|
case "ADD_MERGE":
|
|
@@ -31589,6 +31597,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
31589
31597
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
31590
31598
|
}
|
|
31591
31599
|
}
|
|
31600
|
+
checkBordersUnchanged(cmd) {
|
|
31601
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
31602
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
31603
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
31604
|
+
return 97 /* CommandResult.NoChanges */;
|
|
31605
|
+
}
|
|
31606
|
+
return 0 /* CommandResult.Success */;
|
|
31607
|
+
}
|
|
31592
31608
|
// ---------------------------------------------------------------------------
|
|
31593
31609
|
// Import/Export
|
|
31594
31610
|
// ---------------------------------------------------------------------------
|
|
@@ -31625,7 +31641,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
31625
31641
|
*/
|
|
31626
31642
|
function getBorderId(border) {
|
|
31627
31643
|
for (let [key, value] of Object.entries(borders)) {
|
|
31628
|
-
if (
|
|
31644
|
+
if (deepEquals(value, border)) {
|
|
31629
31645
|
return parseInt(key, 10);
|
|
31630
31646
|
}
|
|
31631
31647
|
}
|
|
@@ -31696,8 +31712,9 @@ class CellPlugin extends CorePlugin {
|
|
|
31696
31712
|
allowDispatch(cmd) {
|
|
31697
31713
|
switch (cmd.type) {
|
|
31698
31714
|
case "UPDATE_CELL":
|
|
31715
|
+
return this.checkCellOutOfSheet(cmd);
|
|
31699
31716
|
case "CLEAR_CELL":
|
|
31700
|
-
return this.
|
|
31717
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
31701
31718
|
default:
|
|
31702
31719
|
return 0 /* CommandResult.Success */;
|
|
31703
31720
|
}
|
|
@@ -31856,14 +31873,9 @@ class CellPlugin extends CorePlugin {
|
|
|
31856
31873
|
*/
|
|
31857
31874
|
getCellById(cellId) {
|
|
31858
31875
|
// this must be as fast as possible
|
|
31859
|
-
|
|
31860
|
-
|
|
31861
|
-
|
|
31862
|
-
if (cell) {
|
|
31863
|
-
return cell;
|
|
31864
|
-
}
|
|
31865
|
-
}
|
|
31866
|
-
return undefined;
|
|
31876
|
+
const position = this.getters.getCellPosition(cellId);
|
|
31877
|
+
const sheet = this.cells[position.sheetId];
|
|
31878
|
+
return sheet[cellId];
|
|
31867
31879
|
}
|
|
31868
31880
|
/*
|
|
31869
31881
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -32089,13 +32101,23 @@ class CellPlugin extends CorePlugin {
|
|
|
32089
32101
|
dependencies: [],
|
|
32090
32102
|
};
|
|
32091
32103
|
}
|
|
32092
|
-
checkCellOutOfSheet(
|
|
32104
|
+
checkCellOutOfSheet(cmd) {
|
|
32105
|
+
const { sheetId, col, row } = cmd;
|
|
32093
32106
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
32094
32107
|
if (!sheet)
|
|
32095
32108
|
return 28 /* CommandResult.InvalidSheetId */;
|
|
32096
32109
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
32097
32110
|
return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 19 /* CommandResult.TargetOutOfSheet */;
|
|
32098
32111
|
}
|
|
32112
|
+
checkUselessClearCell(cmd) {
|
|
32113
|
+
const cell = this.getters.getCell(cmd);
|
|
32114
|
+
if (!cell)
|
|
32115
|
+
return 97 /* CommandResult.NoChanges */;
|
|
32116
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
32117
|
+
return 97 /* CommandResult.NoChanges */;
|
|
32118
|
+
}
|
|
32119
|
+
return 0 /* CommandResult.Success */;
|
|
32120
|
+
}
|
|
32099
32121
|
}
|
|
32100
32122
|
class FormulaCellWithDependencies {
|
|
32101
32123
|
id;
|
|
@@ -34528,7 +34550,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
34528
34550
|
const elements = cmd.dimension === "COL"
|
|
34529
34551
|
? this.getNumberCols(cmd.sheetId)
|
|
34530
34552
|
: this.getNumberRows(cmd.sheetId);
|
|
34531
|
-
if (cmd.base < 0 || cmd.base
|
|
34553
|
+
if (cmd.base < 0 || cmd.base >= elements) {
|
|
34532
34554
|
return 88 /* CommandResult.InvalidHeaderIndex */;
|
|
34533
34555
|
}
|
|
34534
34556
|
else if (cmd.quantity <= 0) {
|
|
@@ -35164,10 +35186,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
35164
35186
|
// begin with the end.
|
|
35165
35187
|
rows.sort((a, b) => b - a);
|
|
35166
35188
|
for (let group of groupConsecutive(rows)) {
|
|
35189
|
+
// indexes are sorted in the descending order
|
|
35190
|
+
const from = group[group.length - 1];
|
|
35191
|
+
const to = group[0];
|
|
35167
35192
|
// Move the cells.
|
|
35168
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
35169
|
-
// Effectively delete the
|
|
35170
|
-
|
|
35193
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
35194
|
+
// Effectively delete the rows
|
|
35195
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
35171
35196
|
}
|
|
35172
35197
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
35173
35198
|
if (count) {
|
|
@@ -35189,8 +35214,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
35189
35214
|
this.addEmptyRows(sheet, quantity);
|
|
35190
35215
|
// Move the cells.
|
|
35191
35216
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
35192
|
-
// Recompute the left-right/top-bottom.
|
|
35193
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
35194
35217
|
if (index < sheet.panes.ySplit) {
|
|
35195
35218
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
35196
35219
|
}
|
|
@@ -35291,35 +35314,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
35291
35314
|
}
|
|
35292
35315
|
}
|
|
35293
35316
|
}
|
|
35294
|
-
updateRowsStructureOnDeletion(
|
|
35317
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
35295
35318
|
const rows = [];
|
|
35296
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
35319
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
35297
35320
|
for (let i in sheet.rows) {
|
|
35298
|
-
|
|
35321
|
+
const row = Number(i);
|
|
35322
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
35299
35323
|
continue;
|
|
35300
35324
|
}
|
|
35301
35325
|
rows.push({
|
|
35302
|
-
cells: cellsQueue.
|
|
35326
|
+
cells: cellsQueue.pop(),
|
|
35303
35327
|
});
|
|
35304
35328
|
}
|
|
35305
35329
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
35306
35330
|
}
|
|
35307
|
-
/**
|
|
35308
|
-
* Update the rows of the sheet after an addition:
|
|
35309
|
-
* - Rename the rows
|
|
35310
|
-
*
|
|
35311
|
-
* @param sheet Sheet on which the deletion occurs
|
|
35312
|
-
* @param addedRow Index of the added row
|
|
35313
|
-
* @param rowsToAdd Number of the rows to add
|
|
35314
|
-
*/
|
|
35315
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
35316
|
-
const rows = [];
|
|
35317
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
35318
|
-
sheet.rows.forEach(() => rows.push({
|
|
35319
|
-
cells: cellsQueue.shift(),
|
|
35320
|
-
}));
|
|
35321
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
35322
|
-
}
|
|
35323
35331
|
/**
|
|
35324
35332
|
* Add empty rows at the end of the rows
|
|
35325
35333
|
*
|
|
@@ -35435,6 +35443,7 @@ class CompilationParametersBuilder {
|
|
|
35435
35443
|
getters;
|
|
35436
35444
|
computeCell;
|
|
35437
35445
|
evalContext;
|
|
35446
|
+
rangeCache = {};
|
|
35438
35447
|
constructor(context, getters, computeCell) {
|
|
35439
35448
|
this.getters = getters;
|
|
35440
35449
|
this.computeCell = computeCell;
|
|
@@ -35482,10 +35491,13 @@ class CompilationParametersBuilder {
|
|
|
35482
35491
|
if (evaluatedCell === undefined) {
|
|
35483
35492
|
return { value: null, format: this.getters.getCell(position)?.format };
|
|
35484
35493
|
}
|
|
35494
|
+
if (evaluatedCell.type === CellValueType.error) {
|
|
35495
|
+
throw evaluatedCell.error;
|
|
35496
|
+
}
|
|
35485
35497
|
return evaluatedCell;
|
|
35486
35498
|
}
|
|
35487
35499
|
getEvaluatedCellIfNotEmpty(position) {
|
|
35488
|
-
const evaluatedCell = this.
|
|
35500
|
+
const evaluatedCell = this.computeCell(position);
|
|
35489
35501
|
if (evaluatedCell.type === CellValueType.empty) {
|
|
35490
35502
|
const cell = this.getters.getCell(position);
|
|
35491
35503
|
if (!cell || (!cell.isFormula && cell.content === "")) {
|
|
@@ -35494,13 +35506,6 @@ class CompilationParametersBuilder {
|
|
|
35494
35506
|
}
|
|
35495
35507
|
return evaluatedCell;
|
|
35496
35508
|
}
|
|
35497
|
-
getEvaluatedCell(position) {
|
|
35498
|
-
const evaluatedCell = this.computeCell(position);
|
|
35499
|
-
if (evaluatedCell.type === CellValueType.error) {
|
|
35500
|
-
throw evaluatedCell.error;
|
|
35501
|
-
}
|
|
35502
|
-
return evaluatedCell;
|
|
35503
|
-
}
|
|
35504
35509
|
/**
|
|
35505
35510
|
* Return the values of the cell(s) used in reference, but always in the format of a range even
|
|
35506
35511
|
* if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
|
|
@@ -35520,25 +35525,40 @@ class CompilationParametersBuilder {
|
|
|
35520
35525
|
if (!_zone) {
|
|
35521
35526
|
return { value: [[]], format: [[]] };
|
|
35522
35527
|
}
|
|
35528
|
+
const { top, left, bottom, right } = zone;
|
|
35529
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
35530
|
+
if (cacheKey in this.rangeCache) {
|
|
35531
|
+
const result = this.rangeCache[cacheKey];
|
|
35532
|
+
if (result instanceof EvaluationError) {
|
|
35533
|
+
throw result;
|
|
35534
|
+
}
|
|
35535
|
+
return result;
|
|
35536
|
+
}
|
|
35523
35537
|
const height = _zone.bottom - _zone.top + 1;
|
|
35524
35538
|
const width = _zone.right - _zone.left + 1;
|
|
35525
|
-
const value = Array
|
|
35526
|
-
const format = Array
|
|
35539
|
+
const value = new Array(width);
|
|
35540
|
+
const format = new Array(width);
|
|
35527
35541
|
// Performance issue: nested loop is faster than a map here
|
|
35528
35542
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
35543
|
+
const colIndex = col - _zone.left;
|
|
35544
|
+
value[colIndex] = new Array(height);
|
|
35545
|
+
format[colIndex] = new Array(height);
|
|
35529
35546
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
35530
|
-
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId
|
|
35531
|
-
if (evaluatedCell) {
|
|
35532
|
-
|
|
35533
|
-
|
|
35534
|
-
|
|
35535
|
-
|
|
35536
|
-
|
|
35537
|
-
|
|
35547
|
+
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId, col, row });
|
|
35548
|
+
if (evaluatedCell?.type === CellValueType.error) {
|
|
35549
|
+
this.rangeCache[cacheKey] = evaluatedCell.error;
|
|
35550
|
+
throw evaluatedCell.error;
|
|
35551
|
+
}
|
|
35552
|
+
const rowIndex = row - _zone.top;
|
|
35553
|
+
value[colIndex][rowIndex] = evaluatedCell?.value;
|
|
35554
|
+
if (evaluatedCell?.format !== undefined) {
|
|
35555
|
+
format[colIndex][rowIndex] = evaluatedCell.format;
|
|
35538
35556
|
}
|
|
35539
35557
|
}
|
|
35540
35558
|
}
|
|
35541
|
-
|
|
35559
|
+
const result = { value, format };
|
|
35560
|
+
this.rangeCache[cacheKey] = result;
|
|
35561
|
+
return result;
|
|
35542
35562
|
}
|
|
35543
35563
|
}
|
|
35544
35564
|
|
|
@@ -35736,6 +35756,7 @@ class Evaluator {
|
|
|
35736
35756
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
35737
35757
|
}
|
|
35738
35758
|
updateCompilationParameters() {
|
|
35759
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
35739
35760
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
35740
35761
|
}
|
|
35741
35762
|
evaluateCells(positions) {
|
|
@@ -35779,6 +35800,15 @@ class Evaluator {
|
|
|
35779
35800
|
this.evaluatedCells = new Map();
|
|
35780
35801
|
this.evaluate(this.getAllCells());
|
|
35781
35802
|
}
|
|
35803
|
+
evaluateFormula(sheetId, formulaString) {
|
|
35804
|
+
const compiledFormula = compile(formulaString);
|
|
35805
|
+
const ranges = [];
|
|
35806
|
+
for (let xc of compiledFormula.dependencies) {
|
|
35807
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
35808
|
+
}
|
|
35809
|
+
this.updateCompilationParameters();
|
|
35810
|
+
return compiledFormula.execute(ranges, ...this.compilationParams).value;
|
|
35811
|
+
}
|
|
35782
35812
|
getAllCells() {
|
|
35783
35813
|
const positionIds = new JetSet();
|
|
35784
35814
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -35805,6 +35835,7 @@ class Evaluator {
|
|
|
35805
35835
|
this.nextPositionsToUpdate = cells;
|
|
35806
35836
|
let currentIteration = 0;
|
|
35807
35837
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
35838
|
+
this.updateCompilationParameters();
|
|
35808
35839
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
35809
35840
|
this.nextPositionsToUpdate.clear();
|
|
35810
35841
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -36189,7 +36220,6 @@ class PositionBitsEncoder {
|
|
|
36189
36220
|
// of other cells depending on it, at the next iteration.
|
|
36190
36221
|
//#endregion
|
|
36191
36222
|
class EvaluationPlugin extends UIPlugin {
|
|
36192
|
-
config;
|
|
36193
36223
|
static getters = [
|
|
36194
36224
|
"evaluateFormula",
|
|
36195
36225
|
"getRangeFormattedValues",
|
|
@@ -36201,12 +36231,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36201
36231
|
];
|
|
36202
36232
|
shouldRebuildDependenciesGraph = true;
|
|
36203
36233
|
evaluator;
|
|
36204
|
-
compilationParams;
|
|
36205
36234
|
positionsToUpdate = [];
|
|
36206
36235
|
constructor(config) {
|
|
36207
36236
|
super(config);
|
|
36208
|
-
this.config = config;
|
|
36209
|
-
this.compilationParams = this.getCompilationParameters();
|
|
36210
36237
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
36211
36238
|
}
|
|
36212
36239
|
// ---------------------------------------------------------------------------
|
|
@@ -36231,10 +36258,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36231
36258
|
case "EVALUATE_CELLS":
|
|
36232
36259
|
this.evaluator.evaluateAllCells();
|
|
36233
36260
|
break;
|
|
36234
|
-
case "UPDATE_LOCALE":
|
|
36235
|
-
this.compilationParams = this.getCompilationParameters();
|
|
36236
|
-
this.evaluator.updateCompilationParameters();
|
|
36237
|
-
break;
|
|
36238
36261
|
}
|
|
36239
36262
|
}
|
|
36240
36263
|
finalize() {
|
|
@@ -36252,12 +36275,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36252
36275
|
// Getters
|
|
36253
36276
|
// ---------------------------------------------------------------------------
|
|
36254
36277
|
evaluateFormula(sheetId, formulaString) {
|
|
36255
|
-
|
|
36256
|
-
const ranges = [];
|
|
36257
|
-
for (let xc of compiledFormula.dependencies) {
|
|
36258
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
36259
|
-
}
|
|
36260
|
-
return compiledFormula.execute(ranges, ...this.compilationParams).value;
|
|
36278
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
36261
36279
|
}
|
|
36262
36280
|
/**
|
|
36263
36281
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -36356,9 +36374,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36356
36374
|
}
|
|
36357
36375
|
return undefined;
|
|
36358
36376
|
}
|
|
36359
|
-
getCompilationParameters() {
|
|
36360
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
36361
|
-
}
|
|
36362
36377
|
}
|
|
36363
36378
|
function isBadExpression(formula) {
|
|
36364
36379
|
try {
|
|
@@ -36523,7 +36538,7 @@ class CustomColorsPlugin extends UIPlugin {
|
|
|
36523
36538
|
}
|
|
36524
36539
|
|
|
36525
36540
|
class EvaluationChartPlugin extends UIPlugin {
|
|
36526
|
-
static getters = ["getChartRuntime", "
|
|
36541
|
+
static getters = ["getChartRuntime", "getStyleOfSingleCellChart"];
|
|
36527
36542
|
charts = {};
|
|
36528
36543
|
createRuntimeChart = chartRuntimeFactory(this.getters);
|
|
36529
36544
|
handle(cmd) {
|
|
@@ -36561,25 +36576,26 @@ class EvaluationChartPlugin extends UIPlugin {
|
|
|
36561
36576
|
return this.charts[figureId];
|
|
36562
36577
|
}
|
|
36563
36578
|
/**
|
|
36564
|
-
* Get the background
|
|
36565
|
-
* of the chart. In order of priority, it will return :
|
|
36566
|
-
*
|
|
36567
|
-
* - the chart background color if one is defined
|
|
36568
|
-
* - the fill color of the cell if one is defined
|
|
36569
|
-
* - the fill color of the cell from conditional formats if one is defined
|
|
36570
|
-
* - the default chart color if no other color is defined
|
|
36579
|
+
* Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
|
|
36571
36580
|
*/
|
|
36572
|
-
|
|
36581
|
+
getStyleOfSingleCellChart(chartBackground, mainRange) {
|
|
36573
36582
|
if (chartBackground)
|
|
36574
|
-
return chartBackground;
|
|
36583
|
+
return { background: chartBackground, fontColor: chartFontColor(chartBackground) };
|
|
36575
36584
|
if (!mainRange) {
|
|
36576
|
-
return
|
|
36585
|
+
return {
|
|
36586
|
+
background: BACKGROUND_CHART_COLOR,
|
|
36587
|
+
fontColor: chartFontColor(BACKGROUND_CHART_COLOR),
|
|
36588
|
+
};
|
|
36577
36589
|
}
|
|
36578
36590
|
const col = mainRange.zone.left;
|
|
36579
36591
|
const row = mainRange.zone.top;
|
|
36580
36592
|
const sheetId = mainRange.sheetId;
|
|
36581
36593
|
const style = this.getters.getCellComputedStyle({ sheetId, col, row });
|
|
36582
|
-
|
|
36594
|
+
const background = style.fillColor || BACKGROUND_CHART_COLOR;
|
|
36595
|
+
return {
|
|
36596
|
+
background,
|
|
36597
|
+
fontColor: style.textColor || chartFontColor(background),
|
|
36598
|
+
};
|
|
36583
36599
|
}
|
|
36584
36600
|
}
|
|
36585
36601
|
|
|
@@ -37278,19 +37294,21 @@ class AutofillPlugin extends UIPlugin {
|
|
|
37278
37294
|
let col = zone.left;
|
|
37279
37295
|
let row = zone.bottom;
|
|
37280
37296
|
if (col > 0) {
|
|
37281
|
-
let
|
|
37282
|
-
while (
|
|
37297
|
+
let leftPosition = { sheetId, col: col - 1, row };
|
|
37298
|
+
while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
|
|
37299
|
+
this.getters.getCell(leftPosition)?.content) {
|
|
37283
37300
|
row += 1;
|
|
37284
|
-
|
|
37301
|
+
leftPosition = { sheetId, col: col - 1, row };
|
|
37285
37302
|
}
|
|
37286
37303
|
}
|
|
37287
37304
|
if (row === zone.bottom) {
|
|
37288
37305
|
col = zone.right;
|
|
37289
37306
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
37290
|
-
let
|
|
37291
|
-
while (
|
|
37307
|
+
let rightPosition = { sheetId, col: col + 1, row };
|
|
37308
|
+
while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
|
|
37309
|
+
this.getters.getCell(rightPosition)?.content) {
|
|
37292
37310
|
row += 1;
|
|
37293
|
-
|
|
37311
|
+
rightPosition = { sheetId, col: col + 1, row };
|
|
37294
37312
|
}
|
|
37295
37313
|
}
|
|
37296
37314
|
}
|
|
@@ -40208,6 +40226,9 @@ class SelectionInputsManagerPlugin extends UIPlugin {
|
|
|
40208
40226
|
// Other
|
|
40209
40227
|
// ---------------------------------------------------------------------------
|
|
40210
40228
|
initInput(id, initialRanges, inputHasSingleRange = false) {
|
|
40229
|
+
if (this.inputs[id]) {
|
|
40230
|
+
this.unfocus();
|
|
40231
|
+
}
|
|
40211
40232
|
this.inputs[id] = new SelectionInputPlugin(this.config, initialRanges, inputHasSingleRange);
|
|
40212
40233
|
if (initialRanges.length === 0) {
|
|
40213
40234
|
const input = this.inputs[id];
|
|
@@ -42075,8 +42096,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
42075
42096
|
this.lastPasteState = this.state;
|
|
42076
42097
|
if (this.paintFormatStatus === "oneOff") {
|
|
42077
42098
|
this.paintFormatStatus = "inactive";
|
|
42078
|
-
this.status = "invisible";
|
|
42079
42099
|
}
|
|
42100
|
+
this.status = "invisible";
|
|
42080
42101
|
break;
|
|
42081
42102
|
case "CLEAN_CLIPBOARD_HIGHLIGHT":
|
|
42082
42103
|
this.status = "invisible";
|
|
@@ -42323,6 +42344,10 @@ function setXcToReferenceType(xc, referenceType) {
|
|
|
42323
42344
|
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
42324
42345
|
case "colrow":
|
|
42325
42346
|
indexOfNumber = xc.search(/[0-9]/);
|
|
42347
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
42348
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
42349
|
+
return "$" + xc;
|
|
42350
|
+
}
|
|
42326
42351
|
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
42327
42352
|
return "$" + xc;
|
|
42328
42353
|
case "none":
|
|
@@ -43738,7 +43763,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
43738
43763
|
sheetId: cmd.sheetId,
|
|
43739
43764
|
base: cmd.base,
|
|
43740
43765
|
quantity: thickness,
|
|
43741
|
-
position:
|
|
43766
|
+
position: cmd.position,
|
|
43742
43767
|
});
|
|
43743
43768
|
const isCol = cmd.dimension === "COL";
|
|
43744
43769
|
const start = cmd.elements[0];
|
|
@@ -43755,12 +43780,13 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
43755
43780
|
},
|
|
43756
43781
|
];
|
|
43757
43782
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
43783
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
43758
43784
|
const pasteTarget = [
|
|
43759
43785
|
{
|
|
43760
|
-
left: isCol ?
|
|
43761
|
-
right: isCol ?
|
|
43762
|
-
top: !isCol ?
|
|
43763
|
-
bottom: !isCol ?
|
|
43786
|
+
left: isCol ? base : 0,
|
|
43787
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
43788
|
+
top: !isCol ? base : 0,
|
|
43789
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
43764
43790
|
},
|
|
43765
43791
|
];
|
|
43766
43792
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -43797,6 +43823,11 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
43797
43823
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
43798
43824
|
return 2 /* CommandResult.WillRemoveExistingMerge */;
|
|
43799
43825
|
}
|
|
43826
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
43827
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
43828
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
43829
|
+
return 88 /* CommandResult.InvalidHeaderIndex */;
|
|
43830
|
+
}
|
|
43800
43831
|
return 0 /* CommandResult.Success */;
|
|
43801
43832
|
}
|
|
43802
43833
|
//-------------------------------------------
|
|
@@ -47893,9 +47924,9 @@ function revertChanges(revisions) {
|
|
|
47893
47924
|
* Apply the changes of the given HistoryChange to the state
|
|
47894
47925
|
*/
|
|
47895
47926
|
function applyChange(change, target) {
|
|
47896
|
-
let val = change.
|
|
47897
|
-
|
|
47898
|
-
for (let pathIndex =
|
|
47927
|
+
let val = change.path[0];
|
|
47928
|
+
const key = change.path[change.path.length - 1];
|
|
47929
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
47899
47930
|
const p = change.path[pathIndex];
|
|
47900
47931
|
if (val[p] === undefined) {
|
|
47901
47932
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -48576,13 +48607,14 @@ class StateObserver {
|
|
|
48576
48607
|
}
|
|
48577
48608
|
addChange(...args) {
|
|
48578
48609
|
const val = args.pop();
|
|
48579
|
-
const
|
|
48610
|
+
const root = args[0];
|
|
48580
48611
|
let value = root;
|
|
48581
|
-
let key =
|
|
48582
|
-
|
|
48583
|
-
|
|
48612
|
+
let key = args[args.length - 1];
|
|
48613
|
+
const pathLength = args.length - 2;
|
|
48614
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
48615
|
+
const p = args[pathIndex];
|
|
48584
48616
|
if (value[p] === undefined) {
|
|
48585
|
-
const nextPath =
|
|
48617
|
+
const nextPath = args[pathIndex + 1];
|
|
48586
48618
|
value[p] = createEmptyStructure(nextPath);
|
|
48587
48619
|
}
|
|
48588
48620
|
value = value[p];
|
|
@@ -48591,8 +48623,7 @@ class StateObserver {
|
|
|
48591
48623
|
return;
|
|
48592
48624
|
}
|
|
48593
48625
|
this.changes.push({
|
|
48594
|
-
|
|
48595
|
-
path,
|
|
48626
|
+
path: args,
|
|
48596
48627
|
before: value[key],
|
|
48597
48628
|
after: val,
|
|
48598
48629
|
});
|
|
@@ -50442,19 +50473,22 @@ class Model extends EventBus {
|
|
|
50442
50473
|
* Check if the given command is allowed by all the plugins and the history.
|
|
50443
50474
|
*/
|
|
50444
50475
|
checkDispatchAllowed(command) {
|
|
50445
|
-
|
|
50446
|
-
|
|
50476
|
+
const results = isCoreCommand(command)
|
|
50477
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
50478
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
50479
|
+
if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
|
|
50480
|
+
return new DispatchResult(results.flat());
|
|
50447
50481
|
}
|
|
50448
|
-
return
|
|
50482
|
+
return DispatchResult.Success;
|
|
50449
50483
|
}
|
|
50450
50484
|
checkDispatchAllowedCoreCommand(command) {
|
|
50451
50485
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
50452
50486
|
results.push(this.range.allowDispatch(command));
|
|
50453
|
-
return
|
|
50487
|
+
return results;
|
|
50454
50488
|
}
|
|
50455
50489
|
checkDispatchAllowedLocalCommand(command) {
|
|
50456
50490
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
50457
|
-
return
|
|
50491
|
+
return results;
|
|
50458
50492
|
}
|
|
50459
50493
|
finalize() {
|
|
50460
50494
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -50778,6 +50812,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
50778
50812
|
exports.tokenize = tokenize;
|
|
50779
50813
|
|
|
50780
50814
|
|
|
50781
|
-
__info__.version = '16.4.
|
|
50782
|
-
__info__.date = '2023-
|
|
50783
|
-
__info__.hash = '
|
|
50815
|
+
__info__.version = '16.4.16';
|
|
50816
|
+
__info__.date = '2023-12-05T09:37:14.210Z';
|
|
50817
|
+
__info__.hash = '1abbb92';
|