@odoo/o-spreadsheet 16.2.24 → 16.2.27
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 +172 -99
- package/dist/o-spreadsheet.d.ts +37 -10
- package/dist/o-spreadsheet.esm.js +172 -99
- package/dist/o-spreadsheet.iife.js +172 -99
- package/dist/o-spreadsheet.iife.min.js +243 -243
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -287,15 +287,76 @@
|
|
|
287
287
|
// -----------------------------------------------------------------------------
|
|
288
288
|
// Date Type
|
|
289
289
|
// -----------------------------------------------------------------------------
|
|
290
|
+
/**
|
|
291
|
+
* A DateTime object that can be used to manipulate spreadsheet dates.
|
|
292
|
+
* Conceptually, a spreadsheet date is simply a number with a date format,
|
|
293
|
+
* and it is timezone-agnostic.
|
|
294
|
+
* This DateTime object consistently uses UTC time to represent a naive date and time.
|
|
295
|
+
*/
|
|
296
|
+
class DateTime {
|
|
297
|
+
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
|
|
298
|
+
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
|
|
299
|
+
}
|
|
300
|
+
static fromTimestamp(timestamp) {
|
|
301
|
+
const date = new Date(timestamp);
|
|
302
|
+
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
|
|
303
|
+
}
|
|
304
|
+
static now() {
|
|
305
|
+
const now = new Date();
|
|
306
|
+
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
307
|
+
}
|
|
308
|
+
toString() {
|
|
309
|
+
return this.jsDate.toString();
|
|
310
|
+
}
|
|
311
|
+
getTime() {
|
|
312
|
+
return this.jsDate.getTime();
|
|
313
|
+
}
|
|
314
|
+
getFullYear() {
|
|
315
|
+
return this.jsDate.getUTCFullYear();
|
|
316
|
+
}
|
|
317
|
+
getMonth() {
|
|
318
|
+
return this.jsDate.getUTCMonth();
|
|
319
|
+
}
|
|
320
|
+
getDate() {
|
|
321
|
+
return this.jsDate.getUTCDate();
|
|
322
|
+
}
|
|
323
|
+
getDay() {
|
|
324
|
+
return this.jsDate.getUTCDay();
|
|
325
|
+
}
|
|
326
|
+
getHours() {
|
|
327
|
+
return this.jsDate.getUTCHours();
|
|
328
|
+
}
|
|
329
|
+
getMinutes() {
|
|
330
|
+
return this.jsDate.getUTCMinutes();
|
|
331
|
+
}
|
|
332
|
+
getSeconds() {
|
|
333
|
+
return this.jsDate.getUTCSeconds();
|
|
334
|
+
}
|
|
335
|
+
setFullYear(year) {
|
|
336
|
+
this.jsDate.setFullYear(year);
|
|
337
|
+
}
|
|
338
|
+
setDate(date) {
|
|
339
|
+
this.jsDate.setUTCDate(date);
|
|
340
|
+
}
|
|
341
|
+
setHours(hours) {
|
|
342
|
+
this.jsDate.setUTCHours(hours);
|
|
343
|
+
}
|
|
344
|
+
setMinutes(minutes) {
|
|
345
|
+
this.jsDate.setUTCMinutes(minutes);
|
|
346
|
+
}
|
|
347
|
+
setSeconds(seconds) {
|
|
348
|
+
this.jsDate.setUTCSeconds(seconds);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
290
351
|
// -----------------------------------------------------------------------------
|
|
291
352
|
// Parsing
|
|
292
353
|
// -----------------------------------------------------------------------------
|
|
293
|
-
const INITIAL_1900_DAY = new
|
|
354
|
+
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
|
|
294
355
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
295
356
|
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
|
|
296
|
-
const CURRENT_YEAR =
|
|
297
|
-
const INITIAL_JS_DAY =
|
|
298
|
-
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
|
|
357
|
+
const CURRENT_YEAR = DateTime.now().getFullYear();
|
|
358
|
+
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
359
|
+
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
299
360
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
300
361
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
301
362
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
@@ -344,7 +405,7 @@
|
|
|
344
405
|
return {
|
|
345
406
|
value: date.value + time.value,
|
|
346
407
|
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
|
|
347
|
-
jsDate: new
|
|
408
|
+
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()),
|
|
348
409
|
};
|
|
349
410
|
}
|
|
350
411
|
return date || time;
|
|
@@ -361,13 +422,13 @@
|
|
|
361
422
|
const day = Number(parts[dayIndex]);
|
|
362
423
|
const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
|
|
363
424
|
const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
|
|
364
|
-
const jsDate = new
|
|
425
|
+
const jsDate = new DateTime(year, month - 1, day);
|
|
365
426
|
const sep = str.match(/\/|-|\s/)[0];
|
|
366
427
|
if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
|
|
367
428
|
// invalid date
|
|
368
429
|
return null;
|
|
369
430
|
}
|
|
370
|
-
const delta = jsDate - INITIAL_1900_DAY;
|
|
431
|
+
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
371
432
|
let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
|
|
372
433
|
if (parts[yearIndex]) {
|
|
373
434
|
format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
|
|
@@ -427,7 +488,7 @@
|
|
|
427
488
|
if (hours >= 24) {
|
|
428
489
|
format = "hhhh:mm:ss";
|
|
429
490
|
}
|
|
430
|
-
const jsDate = new
|
|
491
|
+
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
|
|
431
492
|
return {
|
|
432
493
|
value: hours / 24 + minutes / 1440 + seconds / 86400,
|
|
433
494
|
format: format,
|
|
@@ -441,7 +502,7 @@
|
|
|
441
502
|
// -----------------------------------------------------------------------------
|
|
442
503
|
function numberToJsDate(value) {
|
|
443
504
|
const truncValue = Math.trunc(value);
|
|
444
|
-
let date =
|
|
505
|
+
let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
|
|
445
506
|
let time = value - truncValue;
|
|
446
507
|
time = time < 0 ? 1 + time : time;
|
|
447
508
|
const hours = Math.round(time * 24);
|
|
@@ -458,7 +519,7 @@
|
|
|
458
519
|
}
|
|
459
520
|
/** Return the number of days in the current month of the given date */
|
|
460
521
|
function getDaysInMonth(date) {
|
|
461
|
-
return new
|
|
522
|
+
return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
462
523
|
}
|
|
463
524
|
function isLastDayOfMonth(date) {
|
|
464
525
|
return getDaysInMonth(date) === date.getDate();
|
|
@@ -476,7 +537,7 @@
|
|
|
476
537
|
const yStart = date.getFullYear();
|
|
477
538
|
const mStart = date.getMonth();
|
|
478
539
|
const dStart = date.getDate();
|
|
479
|
-
const jsDate = new
|
|
540
|
+
const jsDate = new DateTime(yStart, mStart + months, 1);
|
|
480
541
|
if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
|
|
481
542
|
jsDate.setDate(getDaysInMonth(jsDate));
|
|
482
543
|
}
|
|
@@ -1897,7 +1958,7 @@
|
|
|
1897
1958
|
.map((p) => {
|
|
1898
1959
|
switch (p) {
|
|
1899
1960
|
case "hhhh":
|
|
1900
|
-
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
|
|
1961
|
+
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
|
|
1901
1962
|
return helapsedHours.toString();
|
|
1902
1963
|
case "hh":
|
|
1903
1964
|
return hours.toString().padStart(2, "0");
|
|
@@ -5045,6 +5106,7 @@
|
|
|
5045
5106
|
},
|
|
5046
5107
|
};
|
|
5047
5108
|
|
|
5109
|
+
const macRegex = /Mac/i;
|
|
5048
5110
|
/**
|
|
5049
5111
|
* Return true if the event was triggered from
|
|
5050
5112
|
* a child element.
|
|
@@ -5092,7 +5154,15 @@
|
|
|
5092
5154
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5093
5155
|
}
|
|
5094
5156
|
function isMacOS() {
|
|
5095
|
-
return navigator.userAgent
|
|
5157
|
+
return Boolean(macRegex.test(navigator.userAgent));
|
|
5158
|
+
}
|
|
5159
|
+
/**
|
|
5160
|
+
* @param {KeyboardEvent | MouseEvent} ev
|
|
5161
|
+
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
5162
|
+
* On Mac, this is the "meta" or "command" key.
|
|
5163
|
+
*/
|
|
5164
|
+
function isCtrlKey(ev) {
|
|
5165
|
+
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
5096
5166
|
}
|
|
5097
5167
|
|
|
5098
5168
|
/**
|
|
@@ -9484,6 +9554,9 @@
|
|
|
9484
9554
|
function makeArg(str) {
|
|
9485
9555
|
let parts = str.match(ARG_REGEXP);
|
|
9486
9556
|
let name = parts[1].trim();
|
|
9557
|
+
if (!name) {
|
|
9558
|
+
throw new Error(`Function argument definition is missing a name: '${str}'.`);
|
|
9559
|
+
}
|
|
9487
9560
|
let types = [];
|
|
9488
9561
|
let isOptional = false;
|
|
9489
9562
|
let isRepeating = false;
|
|
@@ -11947,7 +12020,7 @@
|
|
|
11947
12020
|
if (_year < 1900) {
|
|
11948
12021
|
_year += 1900;
|
|
11949
12022
|
}
|
|
11950
|
-
const jsDate = new
|
|
12023
|
+
const jsDate = new DateTime(_year, _month - 1, _day);
|
|
11951
12024
|
const result = jsDateToRoundNumber(jsDate);
|
|
11952
12025
|
assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
|
|
11953
12026
|
return result;
|
|
@@ -12055,7 +12128,7 @@
|
|
|
12055
12128
|
const _months = Math.trunc(toNumber(months));
|
|
12056
12129
|
const yStart = _startDate.getFullYear();
|
|
12057
12130
|
const mStart = _startDate.getMonth();
|
|
12058
|
-
const jsDate = new
|
|
12131
|
+
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
|
|
12059
12132
|
return jsDateToRoundNumber(jsDate);
|
|
12060
12133
|
},
|
|
12061
12134
|
isExported: true,
|
|
@@ -12092,17 +12165,17 @@
|
|
|
12092
12165
|
// The first week of the year is the week that contains the first
|
|
12093
12166
|
// Thursday of the year.
|
|
12094
12167
|
let firstThursday = 1;
|
|
12095
|
-
while (new
|
|
12168
|
+
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
|
|
12096
12169
|
firstThursday += 1;
|
|
12097
12170
|
}
|
|
12098
|
-
const firstDayOfFirstWeek = new
|
|
12171
|
+
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
|
|
12099
12172
|
// The last week of the year is the week that contains the last Thursday of
|
|
12100
12173
|
// the year.
|
|
12101
12174
|
let lastThursday = 31;
|
|
12102
|
-
while (new
|
|
12175
|
+
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
|
|
12103
12176
|
lastThursday -= 1;
|
|
12104
12177
|
}
|
|
12105
|
-
const lastDayOfLastWeek = new
|
|
12178
|
+
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
|
|
12106
12179
|
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
|
|
12107
12180
|
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
|
|
12108
12181
|
let offsetYear;
|
|
@@ -12128,17 +12201,17 @@
|
|
|
12128
12201
|
case 1:
|
|
12129
12202
|
// firstDay is the 1st day of the 1st week of the year after
|
|
12130
12203
|
// firstDay = lastDayOfLastWeek + 1 Day
|
|
12131
|
-
firstDay = new
|
|
12204
|
+
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
|
|
12132
12205
|
break;
|
|
12133
12206
|
case -1:
|
|
12134
12207
|
// firstDay is the 1st day of the 1st week of the previous year.
|
|
12135
12208
|
// The first week of the previous year is the week that contains the
|
|
12136
12209
|
// first Thursday of the previous year.
|
|
12137
12210
|
let firstThursdayPreviousYear = 1;
|
|
12138
|
-
while (new
|
|
12211
|
+
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
|
|
12139
12212
|
firstThursdayPreviousYear += 1;
|
|
12140
12213
|
}
|
|
12141
|
-
firstDay = new
|
|
12214
|
+
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
|
|
12142
12215
|
break;
|
|
12143
12216
|
}
|
|
12144
12217
|
const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
|
|
@@ -12273,8 +12346,8 @@
|
|
|
12273
12346
|
});
|
|
12274
12347
|
}
|
|
12275
12348
|
const invertDate = _startDate.getTime() > _endDate.getTime();
|
|
12276
|
-
const stopDate =
|
|
12277
|
-
let stepDate =
|
|
12349
|
+
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
|
|
12350
|
+
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
|
|
12278
12351
|
const timeStopDate = stopDate.getTime();
|
|
12279
12352
|
let timeStepDate = stepDate.getTime();
|
|
12280
12353
|
let netWorkingDay = 0;
|
|
@@ -12298,8 +12371,7 @@
|
|
|
12298
12371
|
returns: ["DATE"],
|
|
12299
12372
|
computeFormat: () => "m/d/yyyy hh:mm:ss",
|
|
12300
12373
|
compute: function () {
|
|
12301
|
-
let today =
|
|
12302
|
-
today.setMilliseconds(0);
|
|
12374
|
+
let today = DateTime.now();
|
|
12303
12375
|
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
|
|
12304
12376
|
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
|
|
12305
12377
|
return Math.floor(delta / MS_PER_DAY) + time;
|
|
@@ -12369,8 +12441,8 @@
|
|
|
12369
12441
|
returns: ["DATE"],
|
|
12370
12442
|
computeFormat: () => "m/d/yyyy",
|
|
12371
12443
|
compute: function () {
|
|
12372
|
-
const today =
|
|
12373
|
-
const jsDate = new
|
|
12444
|
+
const today = DateTime.now();
|
|
12445
|
+
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
|
|
12374
12446
|
return jsDateToRoundNumber(jsDate);
|
|
12375
12447
|
},
|
|
12376
12448
|
isExported: true,
|
|
@@ -12425,10 +12497,10 @@
|
|
|
12425
12497
|
}
|
|
12426
12498
|
const y = _date.getFullYear();
|
|
12427
12499
|
let dayStart = 1;
|
|
12428
|
-
let startDayOfFirstWeek = new
|
|
12500
|
+
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12429
12501
|
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
|
|
12430
12502
|
dayStart += 1;
|
|
12431
|
-
startDayOfFirstWeek = new
|
|
12503
|
+
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12432
12504
|
}
|
|
12433
12505
|
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
|
|
12434
12506
|
if (dif < 0) {
|
|
@@ -12482,7 +12554,7 @@
|
|
|
12482
12554
|
timesHoliday.add(holiday.getTime());
|
|
12483
12555
|
});
|
|
12484
12556
|
}
|
|
12485
|
-
let stepDate =
|
|
12557
|
+
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
|
|
12486
12558
|
let timeStepDate = stepDate.getTime();
|
|
12487
12559
|
const unitDay = Math.sign(_numDays);
|
|
12488
12560
|
let stepDay = Math.abs(_numDays);
|
|
@@ -12544,7 +12616,7 @@
|
|
|
12544
12616
|
const _startDate = toJsDate(date);
|
|
12545
12617
|
const yStart = _startDate.getFullYear();
|
|
12546
12618
|
const mStart = _startDate.getMonth();
|
|
12547
|
-
const jsDate = new
|
|
12619
|
+
const jsDate = new DateTime(yStart, mStart, 1);
|
|
12548
12620
|
return jsDateToRoundNumber(jsDate);
|
|
12549
12621
|
},
|
|
12550
12622
|
};
|
|
@@ -12582,7 +12654,7 @@
|
|
|
12582
12654
|
compute: function (date) {
|
|
12583
12655
|
const quarter = QUARTER.compute(date);
|
|
12584
12656
|
const year = YEAR.compute(date);
|
|
12585
|
-
const jsDate = new
|
|
12657
|
+
const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
|
|
12586
12658
|
return jsDateToRoundNumber(jsDate);
|
|
12587
12659
|
},
|
|
12588
12660
|
};
|
|
@@ -12597,7 +12669,7 @@
|
|
|
12597
12669
|
compute: function (date) {
|
|
12598
12670
|
const quarter = QUARTER.compute(date);
|
|
12599
12671
|
const year = YEAR.compute(date);
|
|
12600
|
-
const jsDate = new
|
|
12672
|
+
const jsDate = new DateTime(year, quarter * 3, 0);
|
|
12601
12673
|
return jsDateToRoundNumber(jsDate);
|
|
12602
12674
|
},
|
|
12603
12675
|
};
|
|
@@ -12611,7 +12683,7 @@
|
|
|
12611
12683
|
computeFormat: () => "m/d/yyyy",
|
|
12612
12684
|
compute: function (date) {
|
|
12613
12685
|
const year = YEAR.compute(date);
|
|
12614
|
-
const jsDate = new
|
|
12686
|
+
const jsDate = new DateTime(year, 0, 1);
|
|
12615
12687
|
return jsDateToRoundNumber(jsDate);
|
|
12616
12688
|
},
|
|
12617
12689
|
};
|
|
@@ -12625,7 +12697,7 @@
|
|
|
12625
12697
|
computeFormat: () => "m/d/yyyy",
|
|
12626
12698
|
compute: function (date) {
|
|
12627
12699
|
const year = YEAR.compute(date);
|
|
12628
|
-
const jsDate = new
|
|
12700
|
+
const jsDate = new DateTime(year + 1, 0, 0);
|
|
12629
12701
|
return jsDateToRoundNumber(jsDate);
|
|
12630
12702
|
},
|
|
12631
12703
|
};
|
|
@@ -12672,8 +12744,8 @@
|
|
|
12672
12744
|
const DELTA = {
|
|
12673
12745
|
description: _lt("Compare two numeric values, returning 1 if they're equal."),
|
|
12674
12746
|
args: [
|
|
12675
|
-
arg(" (number)", _lt("The first number to compare.")),
|
|
12676
|
-
arg(` (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12747
|
+
arg("number1 (number)", _lt("The first number to compare.")),
|
|
12748
|
+
arg(`number2 (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12677
12749
|
],
|
|
12678
12750
|
returns: ["NUMBER"],
|
|
12679
12751
|
compute: function (number1, number2 = DEFAULT_DELTA_ARG) {
|
|
@@ -12759,7 +12831,7 @@
|
|
|
12759
12831
|
function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
|
|
12760
12832
|
const startDate = toJsDate(settlement);
|
|
12761
12833
|
const endDate = toJsDate(maturity);
|
|
12762
|
-
const startDatePlusOneYear =
|
|
12834
|
+
const startDatePlusOneYear = toJsDate(settlement);
|
|
12763
12835
|
startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
|
|
12764
12836
|
assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
|
|
12765
12837
|
}
|
|
@@ -12894,7 +12966,7 @@
|
|
|
12894
12966
|
arg("salvage (number)", _lt("The value of the asset at the end of depreciation.")),
|
|
12895
12967
|
arg("period (number)", _lt("The single period within life for which to calculate depreciation.")),
|
|
12896
12968
|
arg("rate (number)", _lt("The deprecation rate.")),
|
|
12897
|
-
arg(" (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
12969
|
+
arg("day_count_convention (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
12898
12970
|
],
|
|
12899
12971
|
returns: ["NUMBER"],
|
|
12900
12972
|
compute: function (cost, purchaseDate, firstPeriodEnd, salvage, period, rate, dayCountConvention = DEFAULT_DAY_COUNT_CONVENTION) {
|
|
@@ -15838,8 +15910,8 @@
|
|
|
15838
15910
|
description: _lt("A segment of a string."),
|
|
15839
15911
|
args: [
|
|
15840
15912
|
arg("text (string)", _lt("The string to extract a segment from.")),
|
|
15841
|
-
arg(" (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
15842
|
-
arg(" (number)", _lt("The length of the segment to extract.")),
|
|
15913
|
+
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.")),
|
|
15914
|
+
arg("extract_length (number)", _lt("The length of the segment to extract.")),
|
|
15843
15915
|
],
|
|
15844
15916
|
returns: ["STRING"],
|
|
15845
15917
|
compute: function (text, starting_at, extract_length) {
|
|
@@ -16710,10 +16782,10 @@
|
|
|
16710
16782
|
function updateSelectionWithArrowKeys(ev, selection) {
|
|
16711
16783
|
const direction = arrowMap[ev.key];
|
|
16712
16784
|
if (ev.shiftKey) {
|
|
16713
|
-
selection.resizeAnchorZone(direction, ev
|
|
16785
|
+
selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
|
|
16714
16786
|
}
|
|
16715
16787
|
else {
|
|
16716
|
-
selection.moveAnchorCell(direction, ev
|
|
16788
|
+
selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
|
|
16717
16789
|
}
|
|
16718
16790
|
}
|
|
16719
16791
|
|
|
@@ -21048,7 +21120,10 @@
|
|
|
21048
21120
|
return;
|
|
21049
21121
|
}
|
|
21050
21122
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
21051
|
-
this.props.onCellClicked(col, row, {
|
|
21123
|
+
this.props.onCellClicked(col, row, {
|
|
21124
|
+
expandZone: ev.shiftKey,
|
|
21125
|
+
addZone: isCtrlKey(ev),
|
|
21126
|
+
});
|
|
21052
21127
|
}
|
|
21053
21128
|
onDoubleClick(ev) {
|
|
21054
21129
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
@@ -21292,7 +21367,7 @@
|
|
|
21292
21367
|
this._increaseSelection(index);
|
|
21293
21368
|
}
|
|
21294
21369
|
else {
|
|
21295
|
-
this._selectElement(index, ev
|
|
21370
|
+
this._selectElement(index, isCtrlKey(ev));
|
|
21296
21371
|
}
|
|
21297
21372
|
this.lastSelectedElementIndex = index;
|
|
21298
21373
|
const mouseMoveSelect = (col, row) => {
|
|
@@ -21305,7 +21380,7 @@
|
|
|
21305
21380
|
const mouseUpSelect = () => {
|
|
21306
21381
|
this.state.isSelecting = false;
|
|
21307
21382
|
this.lastSelectedElementIndex = null;
|
|
21308
|
-
this.env.model.dispatch(ev
|
|
21383
|
+
this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
|
|
21309
21384
|
this._computeGrabDisplay(ev);
|
|
21310
21385
|
};
|
|
21311
21386
|
dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
|
|
@@ -21455,8 +21530,8 @@
|
|
|
21455
21530
|
this.env.raiseError(MergeErrorMessage);
|
|
21456
21531
|
}
|
|
21457
21532
|
}
|
|
21458
|
-
_selectElement(index,
|
|
21459
|
-
this.env.model.selection.selectColumn(index,
|
|
21533
|
+
_selectElement(index, addDistinctHeader) {
|
|
21534
|
+
this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
21460
21535
|
}
|
|
21461
21536
|
_increaseSelection(index) {
|
|
21462
21537
|
this.env.model.selection.selectColumn(index, "updateAnchor");
|
|
@@ -21628,8 +21703,8 @@
|
|
|
21628
21703
|
this.env.raiseError(MergeErrorMessage);
|
|
21629
21704
|
}
|
|
21630
21705
|
}
|
|
21631
|
-
_selectElement(index,
|
|
21632
|
-
this.env.model.selection.selectRow(index,
|
|
21706
|
+
_selectElement(index, addDistinctHeader) {
|
|
21707
|
+
this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
21633
21708
|
}
|
|
21634
21709
|
_increaseSelection(index) {
|
|
21635
21710
|
this.env.model.selection.selectRow(index, "updateAnchor");
|
|
@@ -22376,8 +22451,8 @@
|
|
|
22376
22451
|
// ---------------------------------------------------------------------------
|
|
22377
22452
|
// Zone selection with mouse
|
|
22378
22453
|
// ---------------------------------------------------------------------------
|
|
22379
|
-
onCellClicked(col, row, {
|
|
22380
|
-
if (
|
|
22454
|
+
onCellClicked(col, row, { addZone, expandZone }) {
|
|
22455
|
+
if (addZone) {
|
|
22381
22456
|
this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
|
|
22382
22457
|
}
|
|
22383
22458
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
@@ -22386,10 +22461,10 @@
|
|
|
22386
22461
|
if (this.env.model.getters.getEditionMode() === "editing") {
|
|
22387
22462
|
this.env.model.dispatch("STOP_EDITION");
|
|
22388
22463
|
}
|
|
22389
|
-
if (
|
|
22464
|
+
if (expandZone) {
|
|
22390
22465
|
this.env.model.selection.setAnchorCorner(col, row);
|
|
22391
22466
|
}
|
|
22392
|
-
else if (
|
|
22467
|
+
else if (addZone) {
|
|
22393
22468
|
this.env.model.selection.addCellToSelection(col, row);
|
|
22394
22469
|
}
|
|
22395
22470
|
else {
|
|
@@ -22451,9 +22526,7 @@
|
|
|
22451
22526
|
return;
|
|
22452
22527
|
}
|
|
22453
22528
|
let keyDownString = "";
|
|
22454
|
-
if (ev
|
|
22455
|
-
keyDownString += "CTRL+";
|
|
22456
|
-
if (ev.metaKey)
|
|
22529
|
+
if (isCtrlKey(ev))
|
|
22457
22530
|
keyDownString += "CTRL+";
|
|
22458
22531
|
if (ev.altKey)
|
|
22459
22532
|
keyDownString += "ALT+";
|
|
@@ -31971,13 +32044,18 @@
|
|
|
31971
32044
|
// Getters
|
|
31972
32045
|
// ---------------------------------------------------------------------------
|
|
31973
32046
|
evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
|
|
31974
|
-
|
|
31975
|
-
|
|
31976
|
-
|
|
31977
|
-
|
|
31978
|
-
|
|
32047
|
+
try {
|
|
32048
|
+
const compiledFormula = compile(formulaString);
|
|
32049
|
+
const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
|
|
32050
|
+
const ranges = [];
|
|
32051
|
+
for (let xc of compiledFormula.dependencies) {
|
|
32052
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
32053
|
+
}
|
|
32054
|
+
return compiledFormula.execute(ranges, ...params).value;
|
|
32055
|
+
}
|
|
32056
|
+
catch (error) {
|
|
32057
|
+
return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
|
|
31979
32058
|
}
|
|
31980
|
-
return compiledFormula.execute(ranges, ...params).value;
|
|
31981
32059
|
}
|
|
31982
32060
|
/**
|
|
31983
32061
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -32479,39 +32557,34 @@
|
|
|
32479
32557
|
this.computedIcons[sheetId] = {};
|
|
32480
32558
|
const computedStyle = this.computedStyles[sheetId];
|
|
32481
32559
|
for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
|
|
32482
|
-
|
|
32483
|
-
|
|
32484
|
-
|
|
32485
|
-
|
|
32486
|
-
|
|
32487
|
-
|
|
32488
|
-
|
|
32489
|
-
|
|
32490
|
-
|
|
32491
|
-
|
|
32492
|
-
|
|
32493
|
-
|
|
32494
|
-
|
|
32495
|
-
|
|
32496
|
-
|
|
32497
|
-
for (let
|
|
32498
|
-
|
|
32499
|
-
|
|
32500
|
-
|
|
32501
|
-
if (
|
|
32502
|
-
|
|
32503
|
-
|
|
32504
|
-
|
|
32505
|
-
computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
|
|
32506
|
-
}
|
|
32560
|
+
switch (cf.rule.type) {
|
|
32561
|
+
case "ColorScaleRule":
|
|
32562
|
+
for (let range of cf.ranges) {
|
|
32563
|
+
this.applyColorScale(range, cf.rule);
|
|
32564
|
+
}
|
|
32565
|
+
break;
|
|
32566
|
+
case "IconSetRule":
|
|
32567
|
+
for (let range of cf.ranges) {
|
|
32568
|
+
this.applyIcon(range, cf.rule);
|
|
32569
|
+
}
|
|
32570
|
+
break;
|
|
32571
|
+
default:
|
|
32572
|
+
for (let ref of cf.ranges) {
|
|
32573
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
|
|
32574
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
32575
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
32576
|
+
const pr = this.rulePredicate[cf.rule.type];
|
|
32577
|
+
let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
|
|
32578
|
+
if (pr && pr(cell, cf.rule)) {
|
|
32579
|
+
if (!computedStyle[col])
|
|
32580
|
+
computedStyle[col] = [];
|
|
32581
|
+
// we must combine all the properties of all the CF rules applied to the given cell
|
|
32582
|
+
computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
|
|
32507
32583
|
}
|
|
32508
32584
|
}
|
|
32509
32585
|
}
|
|
32510
|
-
|
|
32511
|
-
|
|
32512
|
-
}
|
|
32513
|
-
catch (_) {
|
|
32514
|
-
// we don't care about the errors within the evaluation of a rule
|
|
32586
|
+
}
|
|
32587
|
+
break;
|
|
32515
32588
|
}
|
|
32516
32589
|
}
|
|
32517
32590
|
}
|
|
@@ -32536,7 +32609,7 @@
|
|
|
32536
32609
|
return percentile(rangeValues, Number(threshold.value) / 100, true);
|
|
32537
32610
|
case "formula":
|
|
32538
32611
|
const value = threshold.value && this.getters.evaluateFormula(threshold.value);
|
|
32539
|
-
return
|
|
32612
|
+
return typeof value === "number" ? value : null;
|
|
32540
32613
|
default:
|
|
32541
32614
|
return null;
|
|
32542
32615
|
}
|
|
@@ -41884,7 +41957,7 @@
|
|
|
41884
41957
|
}
|
|
41885
41958
|
onKeydown(ev) {
|
|
41886
41959
|
let keyDownString = "";
|
|
41887
|
-
if (ev
|
|
41960
|
+
if (isCtrlKey(ev)) {
|
|
41888
41961
|
keyDownString += "CTRL+";
|
|
41889
41962
|
}
|
|
41890
41963
|
keyDownString += ev.key.toUpperCase();
|
|
@@ -45590,9 +45663,9 @@
|
|
|
45590
45663
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
45591
45664
|
|
|
45592
45665
|
|
|
45593
|
-
__info__.version = '16.2.
|
|
45594
|
-
__info__.date = '
|
|
45595
|
-
__info__.hash = '
|
|
45666
|
+
__info__.version = '16.2.27';
|
|
45667
|
+
__info__.date = '2024-01-12T13:42:07.889Z';
|
|
45668
|
+
__info__.hash = 'd8b1d67';
|
|
45596
45669
|
|
|
45597
45670
|
|
|
45598
45671
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|