@odoo/o-spreadsheet 16.3.17 → 16.3.22
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 +318 -196
- package/dist/o-spreadsheet.d.ts +49 -25
- package/dist/o-spreadsheet.esm.js +318 -196
- package/dist/o-spreadsheet.iife.js +318 -196
- package/dist/o-spreadsheet.iife.min.js +256 -256
- package/dist/o_spreadsheet.xml +6 -7
- package/package.json +1 -1
|
@@ -302,15 +302,80 @@ const FONT_SIZES = [6, 7, 8, 9, 10, 11, 12, 14, 18, 24, 36];
|
|
|
302
302
|
// -----------------------------------------------------------------------------
|
|
303
303
|
// Date Type
|
|
304
304
|
// -----------------------------------------------------------------------------
|
|
305
|
+
/**
|
|
306
|
+
* A DateTime object that can be used to manipulate spreadsheet dates.
|
|
307
|
+
* Conceptually, a spreadsheet date is simply a number with a date format,
|
|
308
|
+
* and it is timezone-agnostic.
|
|
309
|
+
* This DateTime object consistently uses UTC time to represent a naive date and time.
|
|
310
|
+
*/
|
|
311
|
+
class DateTime {
|
|
312
|
+
jsDate;
|
|
313
|
+
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
|
|
314
|
+
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
|
|
315
|
+
}
|
|
316
|
+
static fromTimestamp(timestamp) {
|
|
317
|
+
const date = new Date(timestamp);
|
|
318
|
+
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
|
|
319
|
+
}
|
|
320
|
+
static now() {
|
|
321
|
+
const now = new Date();
|
|
322
|
+
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
323
|
+
}
|
|
324
|
+
toString() {
|
|
325
|
+
return this.jsDate.toString();
|
|
326
|
+
}
|
|
327
|
+
toLocaleDateString() {
|
|
328
|
+
return this.jsDate.toLocaleDateString();
|
|
329
|
+
}
|
|
330
|
+
getTime() {
|
|
331
|
+
return this.jsDate.getTime();
|
|
332
|
+
}
|
|
333
|
+
getFullYear() {
|
|
334
|
+
return this.jsDate.getUTCFullYear();
|
|
335
|
+
}
|
|
336
|
+
getMonth() {
|
|
337
|
+
return this.jsDate.getUTCMonth();
|
|
338
|
+
}
|
|
339
|
+
getDate() {
|
|
340
|
+
return this.jsDate.getUTCDate();
|
|
341
|
+
}
|
|
342
|
+
getDay() {
|
|
343
|
+
return this.jsDate.getUTCDay();
|
|
344
|
+
}
|
|
345
|
+
getHours() {
|
|
346
|
+
return this.jsDate.getUTCHours();
|
|
347
|
+
}
|
|
348
|
+
getMinutes() {
|
|
349
|
+
return this.jsDate.getUTCMinutes();
|
|
350
|
+
}
|
|
351
|
+
getSeconds() {
|
|
352
|
+
return this.jsDate.getUTCSeconds();
|
|
353
|
+
}
|
|
354
|
+
setFullYear(year) {
|
|
355
|
+
this.jsDate.setFullYear(year);
|
|
356
|
+
}
|
|
357
|
+
setDate(date) {
|
|
358
|
+
this.jsDate.setUTCDate(date);
|
|
359
|
+
}
|
|
360
|
+
setHours(hours) {
|
|
361
|
+
this.jsDate.setUTCHours(hours);
|
|
362
|
+
}
|
|
363
|
+
setMinutes(minutes) {
|
|
364
|
+
this.jsDate.setUTCMinutes(minutes);
|
|
365
|
+
}
|
|
366
|
+
setSeconds(seconds) {
|
|
367
|
+
this.jsDate.setUTCSeconds(seconds);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
305
370
|
// -----------------------------------------------------------------------------
|
|
306
371
|
// Parsing
|
|
307
372
|
// -----------------------------------------------------------------------------
|
|
308
|
-
const INITIAL_1900_DAY = new
|
|
373
|
+
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
|
|
309
374
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
310
375
|
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
|
|
311
|
-
const CURRENT_YEAR =
|
|
312
|
-
const INITIAL_JS_DAY =
|
|
313
|
-
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
|
|
376
|
+
const CURRENT_YEAR = DateTime.now().getFullYear();
|
|
377
|
+
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
378
|
+
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
314
379
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
315
380
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
316
381
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
@@ -359,7 +424,7 @@ function _parseDateTime(str) {
|
|
|
359
424
|
return {
|
|
360
425
|
value: date.value + time.value,
|
|
361
426
|
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
|
|
362
|
-
jsDate: new
|
|
427
|
+
jsDate: new DateTime(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
|
|
363
428
|
};
|
|
364
429
|
}
|
|
365
430
|
return date || time;
|
|
@@ -376,13 +441,13 @@ function parseDate(str, dateFormat) {
|
|
|
376
441
|
const day = Number(parts[dayIndex]);
|
|
377
442
|
const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
|
|
378
443
|
const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
|
|
379
|
-
const jsDate = new
|
|
444
|
+
const jsDate = new DateTime(year, month - 1, day);
|
|
380
445
|
const sep = str.match(/\/|-|\s/)[0];
|
|
381
446
|
if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
|
|
382
447
|
// invalid date
|
|
383
448
|
return null;
|
|
384
449
|
}
|
|
385
|
-
const delta = jsDate - INITIAL_1900_DAY;
|
|
450
|
+
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
386
451
|
let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
|
|
387
452
|
if (parts[yearIndex]) {
|
|
388
453
|
format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
|
|
@@ -442,7 +507,7 @@ function parseTime(str) {
|
|
|
442
507
|
if (hours >= 24) {
|
|
443
508
|
format = "hhhh:mm:ss";
|
|
444
509
|
}
|
|
445
|
-
const jsDate = new
|
|
510
|
+
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
|
|
446
511
|
return {
|
|
447
512
|
value: hours / 24 + minutes / 1440 + seconds / 86400,
|
|
448
513
|
format: format,
|
|
@@ -456,7 +521,7 @@ function parseTime(str) {
|
|
|
456
521
|
// -----------------------------------------------------------------------------
|
|
457
522
|
function numberToJsDate(value) {
|
|
458
523
|
const truncValue = Math.trunc(value);
|
|
459
|
-
let date =
|
|
524
|
+
let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
|
|
460
525
|
let time = value - truncValue;
|
|
461
526
|
time = time < 0 ? 1 + time : time;
|
|
462
527
|
const hours = Math.round(time * 24);
|
|
@@ -473,7 +538,7 @@ function jsDateToRoundNumber(date) {
|
|
|
473
538
|
}
|
|
474
539
|
/** Return the number of days in the current month of the given date */
|
|
475
540
|
function getDaysInMonth(date) {
|
|
476
|
-
return new
|
|
541
|
+
return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
477
542
|
}
|
|
478
543
|
function isLastDayOfMonth(date) {
|
|
479
544
|
return getDaysInMonth(date) === date.getDate();
|
|
@@ -491,7 +556,7 @@ function addMonthsToDate(date, months, keepEndOfMonth) {
|
|
|
491
556
|
const yStart = date.getFullYear();
|
|
492
557
|
const mStart = date.getMonth();
|
|
493
558
|
const dStart = date.getDate();
|
|
494
|
-
const jsDate = new
|
|
559
|
+
const jsDate = new DateTime(yStart, mStart + months, 1);
|
|
495
560
|
if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
|
|
496
561
|
jsDate.setDate(getDaysInMonth(jsDate));
|
|
497
562
|
}
|
|
@@ -651,13 +716,6 @@ function areTwoDatesWithinOneYear(startDate, endDate) {
|
|
|
651
716
|
}
|
|
652
717
|
|
|
653
718
|
//------------------------------------------------------------------------------
|
|
654
|
-
/**
|
|
655
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
656
|
-
* is ordered.
|
|
657
|
-
*/
|
|
658
|
-
function stringify(obj) {
|
|
659
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
660
|
-
}
|
|
661
719
|
/**
|
|
662
720
|
* Remove quotes from a quoted string
|
|
663
721
|
* ```js
|
|
@@ -887,7 +945,7 @@ function isBoolean(str) {
|
|
|
887
945
|
function isDateTime(str) {
|
|
888
946
|
return parseDateTime(str) !== null;
|
|
889
947
|
}
|
|
890
|
-
const MARKDOWN_LINK_REGEX = /^\[(
|
|
948
|
+
const MARKDOWN_LINK_REGEX = /^\[(.+)\]\((.+)\)$/;
|
|
891
949
|
//link must start with http or https
|
|
892
950
|
//https://stackoverflow.com/a/3809435/4760614
|
|
893
951
|
const WEB_LINK_REGEX = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;
|
|
@@ -956,7 +1014,7 @@ function isObjectEmptyRecursive(argument) {
|
|
|
956
1014
|
*/
|
|
957
1015
|
function getItemId(item, itemsDic) {
|
|
958
1016
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
959
|
-
if (
|
|
1017
|
+
if (deepEquals(value, item)) {
|
|
960
1018
|
return parseInt(key, 10);
|
|
961
1019
|
}
|
|
962
1020
|
}
|
|
@@ -1022,6 +1080,22 @@ function lazy(fn) {
|
|
|
1022
1080
|
lazyValue.map = (callback) => lazy(() => callback(lazyValue()));
|
|
1023
1081
|
return lazyValue;
|
|
1024
1082
|
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Creates a version of the function that's memoized on the value of its first
|
|
1085
|
+
* argument, if any.
|
|
1086
|
+
*/
|
|
1087
|
+
function memoize(func) {
|
|
1088
|
+
const cache = new Map();
|
|
1089
|
+
const funcName = func.name ? func.name + " (memoized)" : "memoized";
|
|
1090
|
+
return {
|
|
1091
|
+
[funcName](...args) {
|
|
1092
|
+
if (!cache.has(args[0])) {
|
|
1093
|
+
cache.set(args[0], func(...args));
|
|
1094
|
+
}
|
|
1095
|
+
return cache.get(args[0]);
|
|
1096
|
+
},
|
|
1097
|
+
}[funcName];
|
|
1098
|
+
}
|
|
1025
1099
|
/**
|
|
1026
1100
|
* Find the next defined value after the given index in an array of strings. If there is no defined value
|
|
1027
1101
|
* after the index, return the closest defined value before the index. Return an empty string if no
|
|
@@ -1940,7 +2014,7 @@ function formatJSTime(jsDate, format) {
|
|
|
1940
2014
|
.map((p) => {
|
|
1941
2015
|
switch (p) {
|
|
1942
2016
|
case "hhhh":
|
|
1943
|
-
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
|
|
2017
|
+
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
|
|
1944
2018
|
return helapsedHours.toString();
|
|
1945
2019
|
case "hh":
|
|
1946
2020
|
return hours.toString().padStart(2, "0");
|
|
@@ -2187,8 +2261,10 @@ function convertInternalFormatToFormat(internalFormat) {
|
|
|
2187
2261
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
2188
2262
|
// Same as above, but matches the exact string (nothing before or after)
|
|
2189
2263
|
const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
|
|
2190
|
-
/** Reference of a column header (eg. A, AB) */
|
|
2191
|
-
const colHeader = new RegExp(
|
|
2264
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
2265
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
2266
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
2267
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
2192
2268
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
2193
2269
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
2194
2270
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -2218,6 +2294,9 @@ function isRowReference(xc) {
|
|
|
2218
2294
|
function isColHeader(str) {
|
|
2219
2295
|
return colHeader.test(str);
|
|
2220
2296
|
}
|
|
2297
|
+
function isRowHeader(str) {
|
|
2298
|
+
return rowHeader.test(str);
|
|
2299
|
+
}
|
|
2221
2300
|
/**
|
|
2222
2301
|
* Return true if the given xc is the reference of a single cell,
|
|
2223
2302
|
* without any specified sheet (e.g. A1)
|
|
@@ -2284,18 +2363,10 @@ class RangeImpl {
|
|
|
2284
2363
|
if (isFullCol) {
|
|
2285
2364
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2286
2365
|
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2287
|
-
if (zone.left === zone.right) {
|
|
2288
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2289
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2290
|
-
}
|
|
2291
2366
|
}
|
|
2292
2367
|
if (isFullRow) {
|
|
2293
2368
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2294
2369
|
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2295
|
-
if (zone.top === zone.bottom) {
|
|
2296
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2297
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2298
|
-
}
|
|
2299
2370
|
}
|
|
2300
2371
|
return parts;
|
|
2301
2372
|
}
|
|
@@ -3694,12 +3765,12 @@ function toString(value) {
|
|
|
3694
3765
|
}
|
|
3695
3766
|
}
|
|
3696
3767
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
3697
|
-
function normalizeString(str) {
|
|
3768
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
3698
3769
|
return str
|
|
3699
3770
|
.toLowerCase()
|
|
3700
3771
|
.normalize("NFD")
|
|
3701
3772
|
.replace(/[\u0300-\u036f]/g, "");
|
|
3702
|
-
}
|
|
3773
|
+
});
|
|
3703
3774
|
/**
|
|
3704
3775
|
* Normalize a value.
|
|
3705
3776
|
* If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
|
|
@@ -4430,6 +4501,7 @@ exports.CommandResult = void 0;
|
|
|
4430
4501
|
CommandResult[CommandResult["SplitWillOverwriteContent"] = 90] = "SplitWillOverwriteContent";
|
|
4431
4502
|
CommandResult[CommandResult["NoSplitSeparatorInSelection"] = 91] = "NoSplitSeparatorInSelection";
|
|
4432
4503
|
CommandResult[CommandResult["NoActiveSheet"] = 92] = "NoActiveSheet";
|
|
4504
|
+
CommandResult[CommandResult["NoChanges"] = 93] = "NoChanges";
|
|
4433
4505
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
4434
4506
|
|
|
4435
4507
|
const borderStyles = ["thin", "medium", "thick", "dashed", "dotted"];
|
|
@@ -5154,6 +5226,7 @@ const FilterMenuPopoverBuilder = {
|
|
|
5154
5226
|
},
|
|
5155
5227
|
};
|
|
5156
5228
|
|
|
5229
|
+
const macRegex = /Mac/i;
|
|
5157
5230
|
/**
|
|
5158
5231
|
* Return true if the event was triggered from
|
|
5159
5232
|
* a child element.
|
|
@@ -5199,6 +5272,17 @@ function setElementScrollTop(el, scroll) {
|
|
|
5199
5272
|
}
|
|
5200
5273
|
function getOpenedMenus() {
|
|
5201
5274
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5275
|
+
}
|
|
5276
|
+
function isMacOS() {
|
|
5277
|
+
return Boolean(macRegex.test(navigator.userAgent));
|
|
5278
|
+
}
|
|
5279
|
+
/**
|
|
5280
|
+
* @param {KeyboardEvent | MouseEvent} ev
|
|
5281
|
+
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
5282
|
+
* On Mac, this is the "meta" or "command" key.
|
|
5283
|
+
*/
|
|
5284
|
+
function isCtrlKey(ev) {
|
|
5285
|
+
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
5202
5286
|
}
|
|
5203
5287
|
|
|
5204
5288
|
/**
|
|
@@ -9585,6 +9669,9 @@ function arg(definition, description = "") {
|
|
|
9585
9669
|
function makeArg(str, description) {
|
|
9586
9670
|
let parts = str.match(ARG_REGEXP);
|
|
9587
9671
|
let name = parts[1].trim();
|
|
9672
|
+
if (!name) {
|
|
9673
|
+
throw new Error(`Function argument definition is missing a name: '${str}'.`);
|
|
9674
|
+
}
|
|
9588
9675
|
let types = [];
|
|
9589
9676
|
let isOptional = false;
|
|
9590
9677
|
let isRepeating = false;
|
|
@@ -12038,7 +12125,7 @@ const DATE = {
|
|
|
12038
12125
|
if (_year < 1900) {
|
|
12039
12126
|
_year += 1900;
|
|
12040
12127
|
}
|
|
12041
|
-
const jsDate = new
|
|
12128
|
+
const jsDate = new DateTime(_year, _month - 1, _day);
|
|
12042
12129
|
const result = jsDateToRoundNumber(jsDate);
|
|
12043
12130
|
assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
|
|
12044
12131
|
return result;
|
|
@@ -12081,7 +12168,7 @@ const DATEDIF = {
|
|
|
12081
12168
|
// See: https://support.microsoft.com/en-us/office/datedif-function-25dba1a4-2812-480b-84dd-8b32a451b35c
|
|
12082
12169
|
let days = jsEndDate.getDate() - jsStartDate.getDate();
|
|
12083
12170
|
if (days < 0) {
|
|
12084
|
-
const monthBeforeEndMonth = new
|
|
12171
|
+
const monthBeforeEndMonth = new DateTime(jsEndDate.getFullYear(), jsEndDate.getMonth() - 1, 1);
|
|
12085
12172
|
const daysInMonthBeforeEndMonth = getDaysInMonth(monthBeforeEndMonth);
|
|
12086
12173
|
days = daysInMonthBeforeEndMonth - Math.abs(days);
|
|
12087
12174
|
}
|
|
@@ -12090,7 +12177,7 @@ const DATEDIF = {
|
|
|
12090
12177
|
if (areTwoDatesWithinOneYear(_startDate, _endDate)) {
|
|
12091
12178
|
return getTimeDifferenceInWholeDays(jsStartDate, jsEndDate);
|
|
12092
12179
|
}
|
|
12093
|
-
const endDateWithinOneYear = new
|
|
12180
|
+
const endDateWithinOneYear = new DateTime(jsStartDate.getFullYear(), jsEndDate.getMonth(), jsEndDate.getDate());
|
|
12094
12181
|
let days = getTimeDifferenceInWholeDays(jsStartDate, endDateWithinOneYear);
|
|
12095
12182
|
if (days < 0) {
|
|
12096
12183
|
endDateWithinOneYear.setFullYear(jsStartDate.getFullYear() + 1);
|
|
@@ -12203,7 +12290,7 @@ const EOMONTH = {
|
|
|
12203
12290
|
const _months = Math.trunc(toNumber(months));
|
|
12204
12291
|
const yStart = _startDate.getFullYear();
|
|
12205
12292
|
const mStart = _startDate.getMonth();
|
|
12206
|
-
const jsDate = new
|
|
12293
|
+
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
|
|
12207
12294
|
return jsDateToRoundNumber(jsDate);
|
|
12208
12295
|
},
|
|
12209
12296
|
isExported: true,
|
|
@@ -12240,17 +12327,17 @@ const ISOWEEKNUM = {
|
|
|
12240
12327
|
// The first week of the year is the week that contains the first
|
|
12241
12328
|
// Thursday of the year.
|
|
12242
12329
|
let firstThursday = 1;
|
|
12243
|
-
while (new
|
|
12330
|
+
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
|
|
12244
12331
|
firstThursday += 1;
|
|
12245
12332
|
}
|
|
12246
|
-
const firstDayOfFirstWeek = new
|
|
12333
|
+
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
|
|
12247
12334
|
// The last week of the year is the week that contains the last Thursday of
|
|
12248
12335
|
// the year.
|
|
12249
12336
|
let lastThursday = 31;
|
|
12250
|
-
while (new
|
|
12337
|
+
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
|
|
12251
12338
|
lastThursday -= 1;
|
|
12252
12339
|
}
|
|
12253
|
-
const lastDayOfLastWeek = new
|
|
12340
|
+
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
|
|
12254
12341
|
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
|
|
12255
12342
|
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
|
|
12256
12343
|
let offsetYear;
|
|
@@ -12276,17 +12363,17 @@ const ISOWEEKNUM = {
|
|
|
12276
12363
|
case 1:
|
|
12277
12364
|
// firstDay is the 1st day of the 1st week of the year after
|
|
12278
12365
|
// firstDay = lastDayOfLastWeek + 1 Day
|
|
12279
|
-
firstDay = new
|
|
12366
|
+
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
|
|
12280
12367
|
break;
|
|
12281
12368
|
case -1:
|
|
12282
12369
|
// firstDay is the 1st day of the 1st week of the previous year.
|
|
12283
12370
|
// The first week of the previous year is the week that contains the
|
|
12284
12371
|
// first Thursday of the previous year.
|
|
12285
12372
|
let firstThursdayPreviousYear = 1;
|
|
12286
|
-
while (new
|
|
12373
|
+
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
|
|
12287
12374
|
firstThursdayPreviousYear += 1;
|
|
12288
12375
|
}
|
|
12289
|
-
firstDay = new
|
|
12376
|
+
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
|
|
12290
12377
|
break;
|
|
12291
12378
|
}
|
|
12292
12379
|
const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
|
|
@@ -12421,8 +12508,8 @@ const NETWORKDAYS_INTL = {
|
|
|
12421
12508
|
});
|
|
12422
12509
|
}
|
|
12423
12510
|
const invertDate = _startDate.getTime() > _endDate.getTime();
|
|
12424
|
-
const stopDate =
|
|
12425
|
-
let stepDate =
|
|
12511
|
+
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
|
|
12512
|
+
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
|
|
12426
12513
|
const timeStopDate = stopDate.getTime();
|
|
12427
12514
|
let timeStepDate = stepDate.getTime();
|
|
12428
12515
|
let netWorkingDay = 0;
|
|
@@ -12446,8 +12533,7 @@ const NOW = {
|
|
|
12446
12533
|
returns: ["DATE"],
|
|
12447
12534
|
computeFormat: () => "m/d/yyyy hh:mm:ss",
|
|
12448
12535
|
compute: function () {
|
|
12449
|
-
let today =
|
|
12450
|
-
today.setMilliseconds(0);
|
|
12536
|
+
let today = DateTime.now();
|
|
12451
12537
|
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
|
|
12452
12538
|
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
|
|
12453
12539
|
return Math.floor(delta / MS_PER_DAY) + time;
|
|
@@ -12517,8 +12603,8 @@ const TODAY = {
|
|
|
12517
12603
|
returns: ["DATE"],
|
|
12518
12604
|
computeFormat: () => "m/d/yyyy",
|
|
12519
12605
|
compute: function () {
|
|
12520
|
-
const today =
|
|
12521
|
-
const jsDate = new
|
|
12606
|
+
const today = DateTime.now();
|
|
12607
|
+
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
|
|
12522
12608
|
return jsDateToRoundNumber(jsDate);
|
|
12523
12609
|
},
|
|
12524
12610
|
isExported: true,
|
|
@@ -12573,10 +12659,10 @@ const WEEKNUM = {
|
|
|
12573
12659
|
}
|
|
12574
12660
|
const y = _date.getFullYear();
|
|
12575
12661
|
let dayStart = 1;
|
|
12576
|
-
let startDayOfFirstWeek = new
|
|
12662
|
+
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12577
12663
|
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
|
|
12578
12664
|
dayStart += 1;
|
|
12579
|
-
startDayOfFirstWeek = new
|
|
12665
|
+
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12580
12666
|
}
|
|
12581
12667
|
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
|
|
12582
12668
|
if (dif < 0) {
|
|
@@ -12630,7 +12716,7 @@ const WORKDAY_INTL = {
|
|
|
12630
12716
|
timesHoliday.add(holiday.getTime());
|
|
12631
12717
|
});
|
|
12632
12718
|
}
|
|
12633
|
-
let stepDate =
|
|
12719
|
+
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
|
|
12634
12720
|
let timeStepDate = stepDate.getTime();
|
|
12635
12721
|
const unitDay = Math.sign(_numDays);
|
|
12636
12722
|
let stepDay = Math.abs(_numDays);
|
|
@@ -12692,7 +12778,7 @@ const MONTH_START = {
|
|
|
12692
12778
|
const _startDate = toJsDate(date);
|
|
12693
12779
|
const yStart = _startDate.getFullYear();
|
|
12694
12780
|
const mStart = _startDate.getMonth();
|
|
12695
|
-
const jsDate = new
|
|
12781
|
+
const jsDate = new DateTime(yStart, mStart, 1);
|
|
12696
12782
|
return jsDateToRoundNumber(jsDate);
|
|
12697
12783
|
},
|
|
12698
12784
|
};
|
|
@@ -12730,7 +12816,7 @@ const QUARTER_START = {
|
|
|
12730
12816
|
compute: function (date) {
|
|
12731
12817
|
const quarter = QUARTER.compute(date);
|
|
12732
12818
|
const year = YEAR.compute(date);
|
|
12733
|
-
const jsDate = new
|
|
12819
|
+
const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
|
|
12734
12820
|
return jsDateToRoundNumber(jsDate);
|
|
12735
12821
|
},
|
|
12736
12822
|
};
|
|
@@ -12745,7 +12831,7 @@ const QUARTER_END = {
|
|
|
12745
12831
|
compute: function (date) {
|
|
12746
12832
|
const quarter = QUARTER.compute(date);
|
|
12747
12833
|
const year = YEAR.compute(date);
|
|
12748
|
-
const jsDate = new
|
|
12834
|
+
const jsDate = new DateTime(year, quarter * 3, 0);
|
|
12749
12835
|
return jsDateToRoundNumber(jsDate);
|
|
12750
12836
|
},
|
|
12751
12837
|
};
|
|
@@ -12759,7 +12845,7 @@ const YEAR_START = {
|
|
|
12759
12845
|
computeFormat: () => "m/d/yyyy",
|
|
12760
12846
|
compute: function (date) {
|
|
12761
12847
|
const year = YEAR.compute(date);
|
|
12762
|
-
const jsDate = new
|
|
12848
|
+
const jsDate = new DateTime(year, 0, 1);
|
|
12763
12849
|
return jsDateToRoundNumber(jsDate);
|
|
12764
12850
|
},
|
|
12765
12851
|
};
|
|
@@ -12773,7 +12859,7 @@ const YEAR_END = {
|
|
|
12773
12859
|
computeFormat: () => "m/d/yyyy",
|
|
12774
12860
|
compute: function (date) {
|
|
12775
12861
|
const year = YEAR.compute(date);
|
|
12776
|
-
const jsDate = new
|
|
12862
|
+
const jsDate = new DateTime(year + 1, 0, 0);
|
|
12777
12863
|
return jsDateToRoundNumber(jsDate);
|
|
12778
12864
|
},
|
|
12779
12865
|
};
|
|
@@ -12821,8 +12907,8 @@ const DEFAULT_DELTA_ARG = 0;
|
|
|
12821
12907
|
const DELTA = {
|
|
12822
12908
|
description: _lt("Compare two numeric values, returning 1 if they're equal."),
|
|
12823
12909
|
args: [
|
|
12824
|
-
arg(" (number)", _lt("The first number to compare.")),
|
|
12825
|
-
arg(` (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12910
|
+
arg("number1 (number)", _lt("The first number to compare.")),
|
|
12911
|
+
arg(`number2 (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12826
12912
|
],
|
|
12827
12913
|
returns: ["NUMBER"],
|
|
12828
12914
|
compute: function (number1, number2 = DEFAULT_DELTA_ARG) {
|
|
@@ -12908,7 +12994,7 @@ function assertDeprecationFactorStrictlyPositive(factor) {
|
|
|
12908
12994
|
function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
|
|
12909
12995
|
const startDate = toJsDate(settlement);
|
|
12910
12996
|
const endDate = toJsDate(maturity);
|
|
12911
|
-
const startDatePlusOneYear =
|
|
12997
|
+
const startDatePlusOneYear = toJsDate(settlement);
|
|
12912
12998
|
startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
|
|
12913
12999
|
assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
|
|
12914
13000
|
}
|
|
@@ -13043,7 +13129,7 @@ const AMORLINC = {
|
|
|
13043
13129
|
arg("salvage (number)", _lt("The value of the asset at the end of depreciation.")),
|
|
13044
13130
|
arg("period (number)", _lt("The single period within life for which to calculate depreciation.")),
|
|
13045
13131
|
arg("rate (number)", _lt("The deprecation rate.")),
|
|
13046
|
-
arg(" (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
13132
|
+
arg("day_count_convention (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
13047
13133
|
],
|
|
13048
13134
|
returns: ["NUMBER"],
|
|
13049
13135
|
compute: function (cost, purchaseDate, firstPeriodEnd, salvage, period, rate, dayCountConvention = DEFAULT_DAY_COUNT_CONVENTION) {
|
|
@@ -16026,8 +16112,8 @@ const MID = {
|
|
|
16026
16112
|
description: _lt("A segment of a string."),
|
|
16027
16113
|
args: [
|
|
16028
16114
|
arg("text (string)", _lt("The string to extract a segment from.")),
|
|
16029
|
-
arg(" (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
16030
|
-
arg(" (number)", _lt("The length of the segment to extract.")),
|
|
16115
|
+
arg("starting_at (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
16116
|
+
arg("extract_length (number)", _lt("The length of the segment to extract.")),
|
|
16031
16117
|
],
|
|
16032
16118
|
returns: ["STRING"],
|
|
16033
16119
|
compute: function (text, starting_at, extract_length) {
|
|
@@ -17696,10 +17782,10 @@ const arrowMap = {
|
|
|
17696
17782
|
function updateSelectionWithArrowKeys(ev, selection) {
|
|
17697
17783
|
const direction = arrowMap[ev.key];
|
|
17698
17784
|
if (ev.shiftKey) {
|
|
17699
|
-
selection.resizeAnchorZone(direction, ev
|
|
17785
|
+
selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
|
|
17700
17786
|
}
|
|
17701
17787
|
else {
|
|
17702
|
-
selection.moveAnchorCell(direction, ev
|
|
17788
|
+
selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
|
|
17703
17789
|
}
|
|
17704
17790
|
}
|
|
17705
17791
|
|
|
@@ -22396,7 +22482,10 @@ class GridOverlay extends owl.Component {
|
|
|
22396
22482
|
return;
|
|
22397
22483
|
}
|
|
22398
22484
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
22399
|
-
this.props.onCellClicked(col, row, {
|
|
22485
|
+
this.props.onCellClicked(col, row, {
|
|
22486
|
+
expandZone: ev.shiftKey,
|
|
22487
|
+
addZone: isCtrlKey(ev),
|
|
22488
|
+
});
|
|
22400
22489
|
}
|
|
22401
22490
|
onDoubleClick(ev) {
|
|
22402
22491
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
@@ -22469,6 +22558,7 @@ class AbstractResizer extends owl.Component {
|
|
|
22469
22558
|
draggerShadowThickness: 0,
|
|
22470
22559
|
delta: 0,
|
|
22471
22560
|
base: 0,
|
|
22561
|
+
position: "before",
|
|
22472
22562
|
});
|
|
22473
22563
|
_computeHandleDisplay(ev) {
|
|
22474
22564
|
const position = this._getEvOffset(ev);
|
|
@@ -22593,11 +22683,13 @@ class AbstractResizer extends owl.Component {
|
|
|
22593
22683
|
this.state.draggerLinePosition = dimensions.start;
|
|
22594
22684
|
this.state.draggerShadowPosition = dimensions.start;
|
|
22595
22685
|
this.state.base = elementIndex;
|
|
22686
|
+
this.state.position = "before";
|
|
22596
22687
|
}
|
|
22597
22688
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
22598
22689
|
this.state.draggerLinePosition = dimensions.end;
|
|
22599
22690
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
22600
|
-
this.state.base = elementIndex
|
|
22691
|
+
this.state.base = elementIndex;
|
|
22692
|
+
this.state.position = "after";
|
|
22601
22693
|
}
|
|
22602
22694
|
else {
|
|
22603
22695
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -22621,7 +22713,7 @@ class AbstractResizer extends owl.Component {
|
|
|
22621
22713
|
this._increaseSelection(index);
|
|
22622
22714
|
}
|
|
22623
22715
|
else {
|
|
22624
|
-
this._selectElement(index, ev
|
|
22716
|
+
this._selectElement(index, isCtrlKey(ev));
|
|
22625
22717
|
}
|
|
22626
22718
|
this.lastSelectedElementIndex = index;
|
|
22627
22719
|
const mouseMoveSelect = (col, row) => {
|
|
@@ -22634,7 +22726,7 @@ class AbstractResizer extends owl.Component {
|
|
|
22634
22726
|
const mouseUpSelect = () => {
|
|
22635
22727
|
this.state.isSelecting = false;
|
|
22636
22728
|
this.lastSelectedElementIndex = null;
|
|
22637
|
-
this.env.model.dispatch(ev
|
|
22729
|
+
this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
|
|
22638
22730
|
this._computeGrabDisplay(ev);
|
|
22639
22731
|
};
|
|
22640
22732
|
dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
|
|
@@ -22780,13 +22872,14 @@ class ColResizer extends AbstractResizer {
|
|
|
22780
22872
|
dimension: "COL",
|
|
22781
22873
|
base: this.state.base,
|
|
22782
22874
|
elements,
|
|
22875
|
+
position: this.state.position,
|
|
22783
22876
|
});
|
|
22784
22877
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
22785
22878
|
this.env.raiseError(MergeErrorMessage);
|
|
22786
22879
|
}
|
|
22787
22880
|
}
|
|
22788
|
-
_selectElement(index,
|
|
22789
|
-
this.env.model.selection.selectColumn(index,
|
|
22881
|
+
_selectElement(index, addDistinctHeader) {
|
|
22882
|
+
this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
22790
22883
|
}
|
|
22791
22884
|
_increaseSelection(index) {
|
|
22792
22885
|
this.env.model.selection.selectColumn(index, "updateAnchor");
|
|
@@ -22953,13 +23046,14 @@ class RowResizer extends AbstractResizer {
|
|
|
22953
23046
|
dimension: "ROW",
|
|
22954
23047
|
base: this.state.base,
|
|
22955
23048
|
elements,
|
|
23049
|
+
position: this.state.position,
|
|
22956
23050
|
});
|
|
22957
23051
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
22958
23052
|
this.env.raiseError(MergeErrorMessage);
|
|
22959
23053
|
}
|
|
22960
23054
|
}
|
|
22961
|
-
_selectElement(index,
|
|
22962
|
-
this.env.model.selection.selectRow(index,
|
|
23055
|
+
_selectElement(index, addDistinctHeader) {
|
|
23056
|
+
this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
22963
23057
|
}
|
|
22964
23058
|
_increaseSelection(index) {
|
|
22965
23059
|
this.env.model.selection.selectRow(index, "updateAnchor");
|
|
@@ -23060,8 +23154,8 @@ function useWheelHandler(handler) {
|
|
|
23060
23154
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
23061
23155
|
}
|
|
23062
23156
|
const onMouseWheel = (ev) => {
|
|
23063
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
23064
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
23157
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
23158
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
23065
23159
|
handler(deltaX, deltaY);
|
|
23066
23160
|
};
|
|
23067
23161
|
return onMouseWheel;
|
|
@@ -23763,8 +23857,8 @@ class Grid extends owl.Component {
|
|
|
23763
23857
|
// ---------------------------------------------------------------------------
|
|
23764
23858
|
// Zone selection with mouse
|
|
23765
23859
|
// ---------------------------------------------------------------------------
|
|
23766
|
-
onCellClicked(col, row, {
|
|
23767
|
-
if (
|
|
23860
|
+
onCellClicked(col, row, { addZone, expandZone }) {
|
|
23861
|
+
if (addZone) {
|
|
23768
23862
|
this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
|
|
23769
23863
|
}
|
|
23770
23864
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
@@ -23773,10 +23867,10 @@ class Grid extends owl.Component {
|
|
|
23773
23867
|
if (this.env.model.getters.getEditionMode() === "editing") {
|
|
23774
23868
|
this.env.model.dispatch("STOP_EDITION");
|
|
23775
23869
|
}
|
|
23776
|
-
if (
|
|
23870
|
+
if (expandZone) {
|
|
23777
23871
|
this.env.model.selection.setAnchorCorner(col, row);
|
|
23778
23872
|
}
|
|
23779
|
-
else if (
|
|
23873
|
+
else if (addZone) {
|
|
23780
23874
|
this.env.model.selection.addCellToSelection(col, row);
|
|
23781
23875
|
}
|
|
23782
23876
|
else {
|
|
@@ -23838,9 +23932,7 @@ class Grid extends owl.Component {
|
|
|
23838
23932
|
return;
|
|
23839
23933
|
}
|
|
23840
23934
|
let keyDownString = "";
|
|
23841
|
-
if (ev
|
|
23842
|
-
keyDownString += "CTRL+";
|
|
23843
|
-
if (ev.metaKey)
|
|
23935
|
+
if (isCtrlKey(ev))
|
|
23844
23936
|
keyDownString += "CTRL+";
|
|
23845
23937
|
if (ev.altKey)
|
|
23846
23938
|
keyDownString += "ALT+";
|
|
@@ -25748,7 +25840,7 @@ const machine = {
|
|
|
25748
25840
|
SPACE: goTo(State.RightRef),
|
|
25749
25841
|
NUMBER: goTo(State.Found),
|
|
25750
25842
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
25751
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
25843
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
25752
25844
|
},
|
|
25753
25845
|
[State.RightColumnRef]: {
|
|
25754
25846
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -25759,6 +25851,7 @@ const machine = {
|
|
|
25759
25851
|
SPACE: goTo(State.RightRowRef),
|
|
25760
25852
|
NUMBER: goTo(State.Found),
|
|
25761
25853
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
25854
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
25762
25855
|
},
|
|
25763
25856
|
[State.Found]: {},
|
|
25764
25857
|
};
|
|
@@ -28995,6 +29088,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
28995
29088
|
// ---------------------------------------------------------------------------
|
|
28996
29089
|
// Command Handling
|
|
28997
29090
|
// ---------------------------------------------------------------------------
|
|
29091
|
+
allowDispatch(cmd) {
|
|
29092
|
+
switch (cmd.type) {
|
|
29093
|
+
case "SET_BORDER":
|
|
29094
|
+
return this.checkBordersUnchanged(cmd);
|
|
29095
|
+
default:
|
|
29096
|
+
return 0 /* CommandResult.Success */;
|
|
29097
|
+
}
|
|
29098
|
+
}
|
|
28998
29099
|
handle(cmd) {
|
|
28999
29100
|
switch (cmd.type) {
|
|
29000
29101
|
case "ADD_MERGE":
|
|
@@ -29414,6 +29515,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
29414
29515
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
29415
29516
|
}
|
|
29416
29517
|
}
|
|
29518
|
+
checkBordersUnchanged(cmd) {
|
|
29519
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
29520
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
29521
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
29522
|
+
return 93 /* CommandResult.NoChanges */;
|
|
29523
|
+
}
|
|
29524
|
+
return 0 /* CommandResult.Success */;
|
|
29525
|
+
}
|
|
29417
29526
|
// ---------------------------------------------------------------------------
|
|
29418
29527
|
// Import/Export
|
|
29419
29528
|
// ---------------------------------------------------------------------------
|
|
@@ -29450,7 +29559,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
29450
29559
|
*/
|
|
29451
29560
|
function getBorderId(border) {
|
|
29452
29561
|
for (let [key, value] of Object.entries(borders)) {
|
|
29453
|
-
if (
|
|
29562
|
+
if (deepEquals(value, border)) {
|
|
29454
29563
|
return parseInt(key, 10);
|
|
29455
29564
|
}
|
|
29456
29565
|
}
|
|
@@ -29521,8 +29630,9 @@ class CellPlugin extends CorePlugin {
|
|
|
29521
29630
|
allowDispatch(cmd) {
|
|
29522
29631
|
switch (cmd.type) {
|
|
29523
29632
|
case "UPDATE_CELL":
|
|
29633
|
+
return this.checkCellOutOfSheet(cmd);
|
|
29524
29634
|
case "CLEAR_CELL":
|
|
29525
|
-
return this.
|
|
29635
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
29526
29636
|
default:
|
|
29527
29637
|
return 0 /* CommandResult.Success */;
|
|
29528
29638
|
}
|
|
@@ -29681,14 +29791,9 @@ class CellPlugin extends CorePlugin {
|
|
|
29681
29791
|
*/
|
|
29682
29792
|
getCellById(cellId) {
|
|
29683
29793
|
// this must be as fast as possible
|
|
29684
|
-
|
|
29685
|
-
|
|
29686
|
-
|
|
29687
|
-
if (cell) {
|
|
29688
|
-
return cell;
|
|
29689
|
-
}
|
|
29690
|
-
}
|
|
29691
|
-
return undefined;
|
|
29794
|
+
const position = this.getters.getCellPosition(cellId);
|
|
29795
|
+
const sheet = this.cells[position.sheetId];
|
|
29796
|
+
return sheet[cellId];
|
|
29692
29797
|
}
|
|
29693
29798
|
/*
|
|
29694
29799
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -29925,13 +30030,23 @@ class CellPlugin extends CorePlugin {
|
|
|
29925
30030
|
dependencies: [],
|
|
29926
30031
|
};
|
|
29927
30032
|
}
|
|
29928
|
-
checkCellOutOfSheet(
|
|
30033
|
+
checkCellOutOfSheet(cmd) {
|
|
30034
|
+
const { sheetId, col, row } = cmd;
|
|
29929
30035
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
29930
30036
|
if (!sheet)
|
|
29931
30037
|
return 27 /* CommandResult.InvalidSheetId */;
|
|
29932
30038
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
29933
30039
|
return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 18 /* CommandResult.TargetOutOfSheet */;
|
|
29934
30040
|
}
|
|
30041
|
+
checkUselessClearCell(cmd) {
|
|
30042
|
+
const cell = this.getters.getCell(cmd);
|
|
30043
|
+
if (!cell)
|
|
30044
|
+
return 93 /* CommandResult.NoChanges */;
|
|
30045
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
30046
|
+
return 93 /* CommandResult.NoChanges */;
|
|
30047
|
+
}
|
|
30048
|
+
return 0 /* CommandResult.Success */;
|
|
30049
|
+
}
|
|
29935
30050
|
}
|
|
29936
30051
|
|
|
29937
30052
|
class ChartPlugin extends CorePlugin {
|
|
@@ -32412,7 +32527,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
32412
32527
|
const elements = cmd.dimension === "COL"
|
|
32413
32528
|
? this.getNumberCols(cmd.sheetId)
|
|
32414
32529
|
: this.getNumberRows(cmd.sheetId);
|
|
32415
|
-
if (cmd.base < 0 || cmd.base
|
|
32530
|
+
if (cmd.base < 0 || cmd.base >= elements) {
|
|
32416
32531
|
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
32417
32532
|
}
|
|
32418
32533
|
else if (cmd.quantity <= 0) {
|
|
@@ -33034,10 +33149,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
33034
33149
|
// begin with the end.
|
|
33035
33150
|
rows.sort((a, b) => b - a);
|
|
33036
33151
|
for (let group of groupConsecutive(rows)) {
|
|
33152
|
+
// indexes are sorted in the descending order
|
|
33153
|
+
const from = group[group.length - 1];
|
|
33154
|
+
const to = group[0];
|
|
33037
33155
|
// Move the cells.
|
|
33038
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
33039
|
-
// Effectively delete the
|
|
33040
|
-
|
|
33156
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
33157
|
+
// Effectively delete the rows
|
|
33158
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
33041
33159
|
}
|
|
33042
33160
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
33043
33161
|
if (count) {
|
|
@@ -33059,8 +33177,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
33059
33177
|
this.addEmptyRows(sheet, quantity);
|
|
33060
33178
|
// Move the cells.
|
|
33061
33179
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
33062
|
-
// Recompute the left-right/top-bottom.
|
|
33063
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
33064
33180
|
if (index < sheet.panes.ySplit) {
|
|
33065
33181
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
33066
33182
|
}
|
|
@@ -33161,35 +33277,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
33161
33277
|
}
|
|
33162
33278
|
}
|
|
33163
33279
|
}
|
|
33164
|
-
updateRowsStructureOnDeletion(
|
|
33280
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
33165
33281
|
const rows = [];
|
|
33166
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
33282
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
33167
33283
|
for (let i in sheet.rows) {
|
|
33168
|
-
|
|
33284
|
+
const row = Number(i);
|
|
33285
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
33169
33286
|
continue;
|
|
33170
33287
|
}
|
|
33171
33288
|
rows.push({
|
|
33172
|
-
cells: cellsQueue.
|
|
33289
|
+
cells: cellsQueue.pop(),
|
|
33173
33290
|
});
|
|
33174
33291
|
}
|
|
33175
33292
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
33176
33293
|
}
|
|
33177
|
-
/**
|
|
33178
|
-
* Update the rows of the sheet after an addition:
|
|
33179
|
-
* - Rename the rows
|
|
33180
|
-
*
|
|
33181
|
-
* @param sheet Sheet on which the deletion occurs
|
|
33182
|
-
* @param addedRow Index of the added row
|
|
33183
|
-
* @param rowsToAdd Number of the rows to add
|
|
33184
|
-
*/
|
|
33185
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
33186
|
-
const rows = [];
|
|
33187
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
33188
|
-
sheet.rows.forEach(() => rows.push({
|
|
33189
|
-
cells: cellsQueue.shift(),
|
|
33190
|
-
}));
|
|
33191
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
33192
|
-
}
|
|
33193
33294
|
/**
|
|
33194
33295
|
* Add empty rows at the end of the rows
|
|
33195
33296
|
*
|
|
@@ -33459,13 +33560,18 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
33459
33560
|
// Getters
|
|
33460
33561
|
// ---------------------------------------------------------------------------
|
|
33461
33562
|
evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
|
|
33462
|
-
|
|
33463
|
-
|
|
33464
|
-
|
|
33465
|
-
|
|
33466
|
-
|
|
33563
|
+
try {
|
|
33564
|
+
const compiledFormula = compile(formulaString);
|
|
33565
|
+
const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
|
|
33566
|
+
const ranges = [];
|
|
33567
|
+
for (let xc of compiledFormula.dependencies) {
|
|
33568
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
33569
|
+
}
|
|
33570
|
+
return compiledFormula.execute(ranges, ...params).value;
|
|
33571
|
+
}
|
|
33572
|
+
catch (error) {
|
|
33573
|
+
return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
|
|
33467
33574
|
}
|
|
33468
|
-
return compiledFormula.execute(ranges, ...params).value;
|
|
33469
33575
|
}
|
|
33470
33576
|
/**
|
|
33471
33577
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -33640,6 +33746,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
33640
33746
|
}
|
|
33641
33747
|
return evaluatedCell;
|
|
33642
33748
|
};
|
|
33749
|
+
const rangeCache = {};
|
|
33643
33750
|
/**
|
|
33644
33751
|
* Return the values of the cell(s) used in reference, but always in the format of a range even
|
|
33645
33752
|
* if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
|
|
@@ -33656,21 +33763,26 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
33656
33763
|
// Performance issue: Avoid fetching data on positions that are out of the spreadsheet
|
|
33657
33764
|
// e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
|
|
33658
33765
|
const sheetZone = getters.getSheetZone(sheetId);
|
|
33659
|
-
const result = [];
|
|
33660
33766
|
const zone = intersection(range.zone, sheetZone);
|
|
33661
33767
|
if (!zone) {
|
|
33662
|
-
|
|
33663
|
-
|
|
33768
|
+
return [[]];
|
|
33769
|
+
}
|
|
33770
|
+
const { top, left, bottom, right } = zone;
|
|
33771
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
33772
|
+
if (cacheKey in rangeCache) {
|
|
33773
|
+
return rangeCache[cacheKey];
|
|
33664
33774
|
}
|
|
33775
|
+
const result = new Array(right - left + 1);
|
|
33665
33776
|
// Performance issue: nested loop is faster than a map here
|
|
33666
|
-
for (let col =
|
|
33667
|
-
const rowValues =
|
|
33668
|
-
for (let row =
|
|
33777
|
+
for (let col = left; col <= right; col++) {
|
|
33778
|
+
const rowValues = new Array(bottom - top + 1);
|
|
33779
|
+
for (let row = top; row <= bottom; row++) {
|
|
33669
33780
|
const cell = evalContext.getters.getCell({ sheetId: range.sheetId, col, row });
|
|
33670
|
-
rowValues
|
|
33781
|
+
rowValues[row - top] = cell ? getEvaluatedCell(cell) : undefined;
|
|
33671
33782
|
}
|
|
33672
|
-
result
|
|
33783
|
+
result[col - left] = rowValues;
|
|
33673
33784
|
}
|
|
33785
|
+
rangeCache[cacheKey] = result;
|
|
33674
33786
|
return result;
|
|
33675
33787
|
}
|
|
33676
33788
|
/**
|
|
@@ -33884,39 +33996,34 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
33884
33996
|
this.computedIcons[sheetId] = {};
|
|
33885
33997
|
const computedStyle = this.computedStyles[sheetId];
|
|
33886
33998
|
for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
|
|
33887
|
-
|
|
33888
|
-
|
|
33889
|
-
|
|
33890
|
-
|
|
33891
|
-
|
|
33892
|
-
|
|
33893
|
-
|
|
33894
|
-
|
|
33895
|
-
|
|
33896
|
-
|
|
33897
|
-
|
|
33898
|
-
|
|
33899
|
-
|
|
33900
|
-
|
|
33901
|
-
|
|
33902
|
-
for (let
|
|
33903
|
-
|
|
33904
|
-
|
|
33905
|
-
|
|
33906
|
-
if (
|
|
33907
|
-
|
|
33908
|
-
|
|
33909
|
-
|
|
33910
|
-
computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
|
|
33911
|
-
}
|
|
33999
|
+
switch (cf.rule.type) {
|
|
34000
|
+
case "ColorScaleRule":
|
|
34001
|
+
for (let range of cf.ranges) {
|
|
34002
|
+
this.applyColorScale(range, cf.rule);
|
|
34003
|
+
}
|
|
34004
|
+
break;
|
|
34005
|
+
case "IconSetRule":
|
|
34006
|
+
for (let range of cf.ranges) {
|
|
34007
|
+
this.applyIcon(range, cf.rule);
|
|
34008
|
+
}
|
|
34009
|
+
break;
|
|
34010
|
+
default:
|
|
34011
|
+
for (let ref of cf.ranges) {
|
|
34012
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
|
|
34013
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
34014
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
34015
|
+
const pr = this.rulePredicate[cf.rule.type];
|
|
34016
|
+
let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
|
|
34017
|
+
if (pr && pr(cell, cf.rule)) {
|
|
34018
|
+
if (!computedStyle[col])
|
|
34019
|
+
computedStyle[col] = [];
|
|
34020
|
+
// we must combine all the properties of all the CF rules applied to the given cell
|
|
34021
|
+
computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
|
|
33912
34022
|
}
|
|
33913
34023
|
}
|
|
33914
34024
|
}
|
|
33915
|
-
|
|
33916
|
-
|
|
33917
|
-
}
|
|
33918
|
-
catch (_) {
|
|
33919
|
-
// we don't care about the errors within the evaluation of a rule
|
|
34025
|
+
}
|
|
34026
|
+
break;
|
|
33920
34027
|
}
|
|
33921
34028
|
}
|
|
33922
34029
|
}
|
|
@@ -33941,7 +34048,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
|
|
|
33941
34048
|
return percentile(rangeValues, Number(threshold.value) / 100, true);
|
|
33942
34049
|
case "formula":
|
|
33943
34050
|
const value = threshold.value && this.getters.evaluateFormula(threshold.value);
|
|
33944
|
-
return
|
|
34051
|
+
return typeof value === "number" ? value : null;
|
|
33945
34052
|
default:
|
|
33946
34053
|
return null;
|
|
33947
34054
|
}
|
|
@@ -35590,19 +35697,21 @@ class AutofillPlugin extends UIPlugin {
|
|
|
35590
35697
|
let col = zone.left;
|
|
35591
35698
|
let row = zone.bottom;
|
|
35592
35699
|
if (col > 0) {
|
|
35593
|
-
let
|
|
35594
|
-
while (
|
|
35700
|
+
let leftPosition = { sheetId, col: col - 1, row };
|
|
35701
|
+
while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
|
|
35702
|
+
this.getters.getCell(leftPosition)?.content) {
|
|
35595
35703
|
row += 1;
|
|
35596
|
-
|
|
35704
|
+
leftPosition = { sheetId, col: col - 1, row };
|
|
35597
35705
|
}
|
|
35598
35706
|
}
|
|
35599
35707
|
if (row === zone.bottom) {
|
|
35600
35708
|
col = zone.right;
|
|
35601
35709
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
35602
|
-
let
|
|
35603
|
-
while (
|
|
35710
|
+
let rightPosition = { sheetId, col: col + 1, row };
|
|
35711
|
+
while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
|
|
35712
|
+
this.getters.getCell(rightPosition)?.content) {
|
|
35604
35713
|
row += 1;
|
|
35605
|
-
|
|
35714
|
+
rightPosition = { sheetId, col: col + 1, row };
|
|
35606
35715
|
}
|
|
35607
35716
|
}
|
|
35608
35717
|
}
|
|
@@ -40550,6 +40659,10 @@ function setXcToReferenceType(xc, referenceType) {
|
|
|
40550
40659
|
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
40551
40660
|
case "colrow":
|
|
40552
40661
|
indexOfNumber = xc.search(/[0-9]/);
|
|
40662
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
40663
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
40664
|
+
return "$" + xc;
|
|
40665
|
+
}
|
|
40553
40666
|
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
40554
40667
|
return "$" + xc;
|
|
40555
40668
|
case "none":
|
|
@@ -41731,7 +41844,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
41731
41844
|
sheetId: cmd.sheetId,
|
|
41732
41845
|
base: cmd.base,
|
|
41733
41846
|
quantity: thickness,
|
|
41734
|
-
position:
|
|
41847
|
+
position: cmd.position,
|
|
41735
41848
|
});
|
|
41736
41849
|
const isCol = cmd.dimension === "COL";
|
|
41737
41850
|
const start = cmd.elements[0];
|
|
@@ -41748,12 +41861,13 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
41748
41861
|
},
|
|
41749
41862
|
];
|
|
41750
41863
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
41864
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
41751
41865
|
const pasteTarget = [
|
|
41752
41866
|
{
|
|
41753
|
-
left: isCol ?
|
|
41754
|
-
right: isCol ?
|
|
41755
|
-
top: !isCol ?
|
|
41756
|
-
bottom: !isCol ?
|
|
41867
|
+
left: isCol ? base : 0,
|
|
41868
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
41869
|
+
top: !isCol ? base : 0,
|
|
41870
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
41757
41871
|
},
|
|
41758
41872
|
];
|
|
41759
41873
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -41790,6 +41904,11 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
41790
41904
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
41791
41905
|
return 2 /* CommandResult.WillRemoveExistingMerge */;
|
|
41792
41906
|
}
|
|
41907
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
41908
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
41909
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
41910
|
+
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
41911
|
+
}
|
|
41793
41912
|
return 0 /* CommandResult.Success */;
|
|
41794
41913
|
}
|
|
41795
41914
|
//-------------------------------------------
|
|
@@ -44071,7 +44190,7 @@ class Spreadsheet extends owl.Component {
|
|
|
44071
44190
|
}
|
|
44072
44191
|
onKeydown(ev) {
|
|
44073
44192
|
let keyDownString = "";
|
|
44074
|
-
if (ev
|
|
44193
|
+
if (isCtrlKey(ev)) {
|
|
44075
44194
|
keyDownString += "CTRL+";
|
|
44076
44195
|
}
|
|
44077
44196
|
keyDownString += ev.key.toUpperCase();
|
|
@@ -44942,9 +45061,9 @@ function revertChanges(revisions) {
|
|
|
44942
45061
|
* Apply the changes of the given HistoryChange to the state
|
|
44943
45062
|
*/
|
|
44944
45063
|
function applyChange(change, target) {
|
|
44945
|
-
let val = change.
|
|
44946
|
-
|
|
44947
|
-
for (let pathIndex =
|
|
45064
|
+
let val = change.path[0];
|
|
45065
|
+
const key = change.path[change.path.length - 1];
|
|
45066
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
44948
45067
|
const p = change.path[pathIndex];
|
|
44949
45068
|
if (val[p] === undefined) {
|
|
44950
45069
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -45611,13 +45730,14 @@ class StateObserver {
|
|
|
45611
45730
|
}
|
|
45612
45731
|
addChange(...args) {
|
|
45613
45732
|
const val = args.pop();
|
|
45614
|
-
const
|
|
45733
|
+
const root = args[0];
|
|
45615
45734
|
let value = root;
|
|
45616
|
-
let key =
|
|
45617
|
-
|
|
45618
|
-
|
|
45735
|
+
let key = args[args.length - 1];
|
|
45736
|
+
const pathLength = args.length - 2;
|
|
45737
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
45738
|
+
const p = args[pathIndex];
|
|
45619
45739
|
if (value[p] === undefined) {
|
|
45620
|
-
const nextPath =
|
|
45740
|
+
const nextPath = args[pathIndex + 1];
|
|
45621
45741
|
value[p] = createEmptyStructure(nextPath);
|
|
45622
45742
|
}
|
|
45623
45743
|
value = value[p];
|
|
@@ -45626,8 +45746,7 @@ class StateObserver {
|
|
|
45626
45746
|
return;
|
|
45627
45747
|
}
|
|
45628
45748
|
this.changes.push({
|
|
45629
|
-
|
|
45630
|
-
path,
|
|
45749
|
+
path: args,
|
|
45631
45750
|
before: value[key],
|
|
45632
45751
|
after: val,
|
|
45633
45752
|
});
|
|
@@ -47477,19 +47596,22 @@ class Model extends EventBus {
|
|
|
47477
47596
|
* Check if the given command is allowed by all the plugins and the history.
|
|
47478
47597
|
*/
|
|
47479
47598
|
checkDispatchAllowed(command) {
|
|
47480
|
-
|
|
47481
|
-
|
|
47599
|
+
const results = isCoreCommand(command)
|
|
47600
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
47601
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
47602
|
+
if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
|
|
47603
|
+
return new DispatchResult(results.flat());
|
|
47482
47604
|
}
|
|
47483
|
-
return
|
|
47605
|
+
return DispatchResult.Success;
|
|
47484
47606
|
}
|
|
47485
47607
|
checkDispatchAllowedCoreCommand(command) {
|
|
47486
47608
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
47487
47609
|
results.push(this.range.allowDispatch(command));
|
|
47488
|
-
return
|
|
47610
|
+
return results;
|
|
47489
47611
|
}
|
|
47490
47612
|
checkDispatchAllowedLocalCommand(command) {
|
|
47491
47613
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
47492
|
-
return
|
|
47614
|
+
return results;
|
|
47493
47615
|
}
|
|
47494
47616
|
finalize() {
|
|
47495
47617
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -47805,6 +47927,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
47805
47927
|
exports.tokenize = tokenize;
|
|
47806
47928
|
|
|
47807
47929
|
|
|
47808
|
-
__info__.version = '16.3.
|
|
47809
|
-
__info__.date = '
|
|
47810
|
-
__info__.hash = '
|
|
47930
|
+
__info__.version = '16.3.22';
|
|
47931
|
+
__info__.date = '2024-01-17T10:24:07.652Z';
|
|
47932
|
+
__info__.hash = '2c1b136';
|