@odoo/o-spreadsheet 16.3.18 → 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 +224 -136
- package/dist/o-spreadsheet.d.ts +40 -10
- package/dist/o-spreadsheet.esm.js +224 -136
- package/dist/o-spreadsheet.iife.js +224 -136
- package/dist/o-spreadsheet.iife.min.js +256 -256
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -299,15 +299,80 @@
|
|
|
299
299
|
// -----------------------------------------------------------------------------
|
|
300
300
|
// Date Type
|
|
301
301
|
// -----------------------------------------------------------------------------
|
|
302
|
+
/**
|
|
303
|
+
* A DateTime object that can be used to manipulate spreadsheet dates.
|
|
304
|
+
* Conceptually, a spreadsheet date is simply a number with a date format,
|
|
305
|
+
* and it is timezone-agnostic.
|
|
306
|
+
* This DateTime object consistently uses UTC time to represent a naive date and time.
|
|
307
|
+
*/
|
|
308
|
+
class DateTime {
|
|
309
|
+
jsDate;
|
|
310
|
+
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
|
|
311
|
+
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
|
|
312
|
+
}
|
|
313
|
+
static fromTimestamp(timestamp) {
|
|
314
|
+
const date = new Date(timestamp);
|
|
315
|
+
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
|
|
316
|
+
}
|
|
317
|
+
static now() {
|
|
318
|
+
const now = new Date();
|
|
319
|
+
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
320
|
+
}
|
|
321
|
+
toString() {
|
|
322
|
+
return this.jsDate.toString();
|
|
323
|
+
}
|
|
324
|
+
toLocaleDateString() {
|
|
325
|
+
return this.jsDate.toLocaleDateString();
|
|
326
|
+
}
|
|
327
|
+
getTime() {
|
|
328
|
+
return this.jsDate.getTime();
|
|
329
|
+
}
|
|
330
|
+
getFullYear() {
|
|
331
|
+
return this.jsDate.getUTCFullYear();
|
|
332
|
+
}
|
|
333
|
+
getMonth() {
|
|
334
|
+
return this.jsDate.getUTCMonth();
|
|
335
|
+
}
|
|
336
|
+
getDate() {
|
|
337
|
+
return this.jsDate.getUTCDate();
|
|
338
|
+
}
|
|
339
|
+
getDay() {
|
|
340
|
+
return this.jsDate.getUTCDay();
|
|
341
|
+
}
|
|
342
|
+
getHours() {
|
|
343
|
+
return this.jsDate.getUTCHours();
|
|
344
|
+
}
|
|
345
|
+
getMinutes() {
|
|
346
|
+
return this.jsDate.getUTCMinutes();
|
|
347
|
+
}
|
|
348
|
+
getSeconds() {
|
|
349
|
+
return this.jsDate.getUTCSeconds();
|
|
350
|
+
}
|
|
351
|
+
setFullYear(year) {
|
|
352
|
+
this.jsDate.setFullYear(year);
|
|
353
|
+
}
|
|
354
|
+
setDate(date) {
|
|
355
|
+
this.jsDate.setUTCDate(date);
|
|
356
|
+
}
|
|
357
|
+
setHours(hours) {
|
|
358
|
+
this.jsDate.setUTCHours(hours);
|
|
359
|
+
}
|
|
360
|
+
setMinutes(minutes) {
|
|
361
|
+
this.jsDate.setUTCMinutes(minutes);
|
|
362
|
+
}
|
|
363
|
+
setSeconds(seconds) {
|
|
364
|
+
this.jsDate.setUTCSeconds(seconds);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
302
367
|
// -----------------------------------------------------------------------------
|
|
303
368
|
// Parsing
|
|
304
369
|
// -----------------------------------------------------------------------------
|
|
305
|
-
const INITIAL_1900_DAY = new
|
|
370
|
+
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
|
|
306
371
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
307
372
|
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
|
|
308
|
-
const CURRENT_YEAR =
|
|
309
|
-
const INITIAL_JS_DAY =
|
|
310
|
-
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
|
|
373
|
+
const CURRENT_YEAR = DateTime.now().getFullYear();
|
|
374
|
+
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
375
|
+
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
311
376
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
312
377
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
313
378
|
const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
|
|
@@ -356,7 +421,7 @@
|
|
|
356
421
|
return {
|
|
357
422
|
value: date.value + time.value,
|
|
358
423
|
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
|
|
359
|
-
jsDate: new
|
|
424
|
+
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()),
|
|
360
425
|
};
|
|
361
426
|
}
|
|
362
427
|
return date || time;
|
|
@@ -373,13 +438,13 @@
|
|
|
373
438
|
const day = Number(parts[dayIndex]);
|
|
374
439
|
const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
|
|
375
440
|
const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
|
|
376
|
-
const jsDate = new
|
|
441
|
+
const jsDate = new DateTime(year, month - 1, day);
|
|
377
442
|
const sep = str.match(/\/|-|\s/)[0];
|
|
378
443
|
if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
|
|
379
444
|
// invalid date
|
|
380
445
|
return null;
|
|
381
446
|
}
|
|
382
|
-
const delta = jsDate - INITIAL_1900_DAY;
|
|
447
|
+
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
383
448
|
let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
|
|
384
449
|
if (parts[yearIndex]) {
|
|
385
450
|
format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
|
|
@@ -439,7 +504,7 @@
|
|
|
439
504
|
if (hours >= 24) {
|
|
440
505
|
format = "hhhh:mm:ss";
|
|
441
506
|
}
|
|
442
|
-
const jsDate = new
|
|
507
|
+
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
|
|
443
508
|
return {
|
|
444
509
|
value: hours / 24 + minutes / 1440 + seconds / 86400,
|
|
445
510
|
format: format,
|
|
@@ -453,7 +518,7 @@
|
|
|
453
518
|
// -----------------------------------------------------------------------------
|
|
454
519
|
function numberToJsDate(value) {
|
|
455
520
|
const truncValue = Math.trunc(value);
|
|
456
|
-
let date =
|
|
521
|
+
let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
|
|
457
522
|
let time = value - truncValue;
|
|
458
523
|
time = time < 0 ? 1 + time : time;
|
|
459
524
|
const hours = Math.round(time * 24);
|
|
@@ -470,7 +535,7 @@
|
|
|
470
535
|
}
|
|
471
536
|
/** Return the number of days in the current month of the given date */
|
|
472
537
|
function getDaysInMonth(date) {
|
|
473
|
-
return new
|
|
538
|
+
return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
474
539
|
}
|
|
475
540
|
function isLastDayOfMonth(date) {
|
|
476
541
|
return getDaysInMonth(date) === date.getDate();
|
|
@@ -488,7 +553,7 @@
|
|
|
488
553
|
const yStart = date.getFullYear();
|
|
489
554
|
const mStart = date.getMonth();
|
|
490
555
|
const dStart = date.getDate();
|
|
491
|
-
const jsDate = new
|
|
556
|
+
const jsDate = new DateTime(yStart, mStart + months, 1);
|
|
492
557
|
if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
|
|
493
558
|
jsDate.setDate(getDaysInMonth(jsDate));
|
|
494
559
|
}
|
|
@@ -648,13 +713,6 @@
|
|
|
648
713
|
}
|
|
649
714
|
|
|
650
715
|
//------------------------------------------------------------------------------
|
|
651
|
-
/**
|
|
652
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
653
|
-
* is ordered.
|
|
654
|
-
*/
|
|
655
|
-
function stringify(obj) {
|
|
656
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
657
|
-
}
|
|
658
716
|
/**
|
|
659
717
|
* Remove quotes from a quoted string
|
|
660
718
|
* ```js
|
|
@@ -884,7 +942,7 @@
|
|
|
884
942
|
function isDateTime(str) {
|
|
885
943
|
return parseDateTime(str) !== null;
|
|
886
944
|
}
|
|
887
|
-
const MARKDOWN_LINK_REGEX = /^\[(
|
|
945
|
+
const MARKDOWN_LINK_REGEX = /^\[(.+)\]\((.+)\)$/;
|
|
888
946
|
//link must start with http or https
|
|
889
947
|
//https://stackoverflow.com/a/3809435/4760614
|
|
890
948
|
const WEB_LINK_REGEX = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;
|
|
@@ -953,7 +1011,7 @@
|
|
|
953
1011
|
*/
|
|
954
1012
|
function getItemId(item, itemsDic) {
|
|
955
1013
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
956
|
-
if (
|
|
1014
|
+
if (deepEquals(value, item)) {
|
|
957
1015
|
return parseInt(key, 10);
|
|
958
1016
|
}
|
|
959
1017
|
}
|
|
@@ -1953,7 +2011,7 @@
|
|
|
1953
2011
|
.map((p) => {
|
|
1954
2012
|
switch (p) {
|
|
1955
2013
|
case "hhhh":
|
|
1956
|
-
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
|
|
2014
|
+
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
|
|
1957
2015
|
return helapsedHours.toString();
|
|
1958
2016
|
case "hh":
|
|
1959
2017
|
return hours.toString().padStart(2, "0");
|
|
@@ -2200,8 +2258,10 @@
|
|
|
2200
2258
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
2201
2259
|
// Same as above, but matches the exact string (nothing before or after)
|
|
2202
2260
|
const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
|
|
2203
|
-
/** Reference of a column header (eg. A, AB) */
|
|
2204
|
-
const colHeader = new RegExp(
|
|
2261
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
2262
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
2263
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
2264
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
2205
2265
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
2206
2266
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
2207
2267
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -2231,6 +2291,9 @@
|
|
|
2231
2291
|
function isColHeader(str) {
|
|
2232
2292
|
return colHeader.test(str);
|
|
2233
2293
|
}
|
|
2294
|
+
function isRowHeader(str) {
|
|
2295
|
+
return rowHeader.test(str);
|
|
2296
|
+
}
|
|
2234
2297
|
/**
|
|
2235
2298
|
* Return true if the given xc is the reference of a single cell,
|
|
2236
2299
|
* without any specified sheet (e.g. A1)
|
|
@@ -2297,18 +2360,10 @@
|
|
|
2297
2360
|
if (isFullCol) {
|
|
2298
2361
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2299
2362
|
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2300
|
-
if (zone.left === zone.right) {
|
|
2301
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2302
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2303
|
-
}
|
|
2304
2363
|
}
|
|
2305
2364
|
if (isFullRow) {
|
|
2306
2365
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2307
2366
|
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2308
|
-
if (zone.top === zone.bottom) {
|
|
2309
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2310
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2311
|
-
}
|
|
2312
2367
|
}
|
|
2313
2368
|
return parts;
|
|
2314
2369
|
}
|
|
@@ -5168,6 +5223,7 @@
|
|
|
5168
5223
|
},
|
|
5169
5224
|
};
|
|
5170
5225
|
|
|
5226
|
+
const macRegex = /Mac/i;
|
|
5171
5227
|
/**
|
|
5172
5228
|
* Return true if the event was triggered from
|
|
5173
5229
|
* a child element.
|
|
@@ -5213,6 +5269,17 @@
|
|
|
5213
5269
|
}
|
|
5214
5270
|
function getOpenedMenus() {
|
|
5215
5271
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5272
|
+
}
|
|
5273
|
+
function isMacOS() {
|
|
5274
|
+
return Boolean(macRegex.test(navigator.userAgent));
|
|
5275
|
+
}
|
|
5276
|
+
/**
|
|
5277
|
+
* @param {KeyboardEvent | MouseEvent} ev
|
|
5278
|
+
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
5279
|
+
* On Mac, this is the "meta" or "command" key.
|
|
5280
|
+
*/
|
|
5281
|
+
function isCtrlKey(ev) {
|
|
5282
|
+
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
5216
5283
|
}
|
|
5217
5284
|
|
|
5218
5285
|
/**
|
|
@@ -9599,6 +9666,9 @@
|
|
|
9599
9666
|
function makeArg(str, description) {
|
|
9600
9667
|
let parts = str.match(ARG_REGEXP);
|
|
9601
9668
|
let name = parts[1].trim();
|
|
9669
|
+
if (!name) {
|
|
9670
|
+
throw new Error(`Function argument definition is missing a name: '${str}'.`);
|
|
9671
|
+
}
|
|
9602
9672
|
let types = [];
|
|
9603
9673
|
let isOptional = false;
|
|
9604
9674
|
let isRepeating = false;
|
|
@@ -12052,7 +12122,7 @@
|
|
|
12052
12122
|
if (_year < 1900) {
|
|
12053
12123
|
_year += 1900;
|
|
12054
12124
|
}
|
|
12055
|
-
const jsDate = new
|
|
12125
|
+
const jsDate = new DateTime(_year, _month - 1, _day);
|
|
12056
12126
|
const result = jsDateToRoundNumber(jsDate);
|
|
12057
12127
|
assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
|
|
12058
12128
|
return result;
|
|
@@ -12095,7 +12165,7 @@
|
|
|
12095
12165
|
// See: https://support.microsoft.com/en-us/office/datedif-function-25dba1a4-2812-480b-84dd-8b32a451b35c
|
|
12096
12166
|
let days = jsEndDate.getDate() - jsStartDate.getDate();
|
|
12097
12167
|
if (days < 0) {
|
|
12098
|
-
const monthBeforeEndMonth = new
|
|
12168
|
+
const monthBeforeEndMonth = new DateTime(jsEndDate.getFullYear(), jsEndDate.getMonth() - 1, 1);
|
|
12099
12169
|
const daysInMonthBeforeEndMonth = getDaysInMonth(monthBeforeEndMonth);
|
|
12100
12170
|
days = daysInMonthBeforeEndMonth - Math.abs(days);
|
|
12101
12171
|
}
|
|
@@ -12104,7 +12174,7 @@
|
|
|
12104
12174
|
if (areTwoDatesWithinOneYear(_startDate, _endDate)) {
|
|
12105
12175
|
return getTimeDifferenceInWholeDays(jsStartDate, jsEndDate);
|
|
12106
12176
|
}
|
|
12107
|
-
const endDateWithinOneYear = new
|
|
12177
|
+
const endDateWithinOneYear = new DateTime(jsStartDate.getFullYear(), jsEndDate.getMonth(), jsEndDate.getDate());
|
|
12108
12178
|
let days = getTimeDifferenceInWholeDays(jsStartDate, endDateWithinOneYear);
|
|
12109
12179
|
if (days < 0) {
|
|
12110
12180
|
endDateWithinOneYear.setFullYear(jsStartDate.getFullYear() + 1);
|
|
@@ -12217,7 +12287,7 @@
|
|
|
12217
12287
|
const _months = Math.trunc(toNumber(months));
|
|
12218
12288
|
const yStart = _startDate.getFullYear();
|
|
12219
12289
|
const mStart = _startDate.getMonth();
|
|
12220
|
-
const jsDate = new
|
|
12290
|
+
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
|
|
12221
12291
|
return jsDateToRoundNumber(jsDate);
|
|
12222
12292
|
},
|
|
12223
12293
|
isExported: true,
|
|
@@ -12254,17 +12324,17 @@
|
|
|
12254
12324
|
// The first week of the year is the week that contains the first
|
|
12255
12325
|
// Thursday of the year.
|
|
12256
12326
|
let firstThursday = 1;
|
|
12257
|
-
while (new
|
|
12327
|
+
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
|
|
12258
12328
|
firstThursday += 1;
|
|
12259
12329
|
}
|
|
12260
|
-
const firstDayOfFirstWeek = new
|
|
12330
|
+
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
|
|
12261
12331
|
// The last week of the year is the week that contains the last Thursday of
|
|
12262
12332
|
// the year.
|
|
12263
12333
|
let lastThursday = 31;
|
|
12264
|
-
while (new
|
|
12334
|
+
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
|
|
12265
12335
|
lastThursday -= 1;
|
|
12266
12336
|
}
|
|
12267
|
-
const lastDayOfLastWeek = new
|
|
12337
|
+
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
|
|
12268
12338
|
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
|
|
12269
12339
|
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
|
|
12270
12340
|
let offsetYear;
|
|
@@ -12290,17 +12360,17 @@
|
|
|
12290
12360
|
case 1:
|
|
12291
12361
|
// firstDay is the 1st day of the 1st week of the year after
|
|
12292
12362
|
// firstDay = lastDayOfLastWeek + 1 Day
|
|
12293
|
-
firstDay = new
|
|
12363
|
+
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
|
|
12294
12364
|
break;
|
|
12295
12365
|
case -1:
|
|
12296
12366
|
// firstDay is the 1st day of the 1st week of the previous year.
|
|
12297
12367
|
// The first week of the previous year is the week that contains the
|
|
12298
12368
|
// first Thursday of the previous year.
|
|
12299
12369
|
let firstThursdayPreviousYear = 1;
|
|
12300
|
-
while (new
|
|
12370
|
+
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
|
|
12301
12371
|
firstThursdayPreviousYear += 1;
|
|
12302
12372
|
}
|
|
12303
|
-
firstDay = new
|
|
12373
|
+
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
|
|
12304
12374
|
break;
|
|
12305
12375
|
}
|
|
12306
12376
|
const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
|
|
@@ -12435,8 +12505,8 @@
|
|
|
12435
12505
|
});
|
|
12436
12506
|
}
|
|
12437
12507
|
const invertDate = _startDate.getTime() > _endDate.getTime();
|
|
12438
|
-
const stopDate =
|
|
12439
|
-
let stepDate =
|
|
12508
|
+
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
|
|
12509
|
+
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
|
|
12440
12510
|
const timeStopDate = stopDate.getTime();
|
|
12441
12511
|
let timeStepDate = stepDate.getTime();
|
|
12442
12512
|
let netWorkingDay = 0;
|
|
@@ -12460,8 +12530,7 @@
|
|
|
12460
12530
|
returns: ["DATE"],
|
|
12461
12531
|
computeFormat: () => "m/d/yyyy hh:mm:ss",
|
|
12462
12532
|
compute: function () {
|
|
12463
|
-
let today =
|
|
12464
|
-
today.setMilliseconds(0);
|
|
12533
|
+
let today = DateTime.now();
|
|
12465
12534
|
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
|
|
12466
12535
|
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
|
|
12467
12536
|
return Math.floor(delta / MS_PER_DAY) + time;
|
|
@@ -12531,8 +12600,8 @@
|
|
|
12531
12600
|
returns: ["DATE"],
|
|
12532
12601
|
computeFormat: () => "m/d/yyyy",
|
|
12533
12602
|
compute: function () {
|
|
12534
|
-
const today =
|
|
12535
|
-
const jsDate = new
|
|
12603
|
+
const today = DateTime.now();
|
|
12604
|
+
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
|
|
12536
12605
|
return jsDateToRoundNumber(jsDate);
|
|
12537
12606
|
},
|
|
12538
12607
|
isExported: true,
|
|
@@ -12587,10 +12656,10 @@
|
|
|
12587
12656
|
}
|
|
12588
12657
|
const y = _date.getFullYear();
|
|
12589
12658
|
let dayStart = 1;
|
|
12590
|
-
let startDayOfFirstWeek = new
|
|
12659
|
+
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12591
12660
|
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
|
|
12592
12661
|
dayStart += 1;
|
|
12593
|
-
startDayOfFirstWeek = new
|
|
12662
|
+
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
12594
12663
|
}
|
|
12595
12664
|
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
|
|
12596
12665
|
if (dif < 0) {
|
|
@@ -12644,7 +12713,7 @@
|
|
|
12644
12713
|
timesHoliday.add(holiday.getTime());
|
|
12645
12714
|
});
|
|
12646
12715
|
}
|
|
12647
|
-
let stepDate =
|
|
12716
|
+
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
|
|
12648
12717
|
let timeStepDate = stepDate.getTime();
|
|
12649
12718
|
const unitDay = Math.sign(_numDays);
|
|
12650
12719
|
let stepDay = Math.abs(_numDays);
|
|
@@ -12706,7 +12775,7 @@
|
|
|
12706
12775
|
const _startDate = toJsDate(date);
|
|
12707
12776
|
const yStart = _startDate.getFullYear();
|
|
12708
12777
|
const mStart = _startDate.getMonth();
|
|
12709
|
-
const jsDate = new
|
|
12778
|
+
const jsDate = new DateTime(yStart, mStart, 1);
|
|
12710
12779
|
return jsDateToRoundNumber(jsDate);
|
|
12711
12780
|
},
|
|
12712
12781
|
};
|
|
@@ -12744,7 +12813,7 @@
|
|
|
12744
12813
|
compute: function (date) {
|
|
12745
12814
|
const quarter = QUARTER.compute(date);
|
|
12746
12815
|
const year = YEAR.compute(date);
|
|
12747
|
-
const jsDate = new
|
|
12816
|
+
const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
|
|
12748
12817
|
return jsDateToRoundNumber(jsDate);
|
|
12749
12818
|
},
|
|
12750
12819
|
};
|
|
@@ -12759,7 +12828,7 @@
|
|
|
12759
12828
|
compute: function (date) {
|
|
12760
12829
|
const quarter = QUARTER.compute(date);
|
|
12761
12830
|
const year = YEAR.compute(date);
|
|
12762
|
-
const jsDate = new
|
|
12831
|
+
const jsDate = new DateTime(year, quarter * 3, 0);
|
|
12763
12832
|
return jsDateToRoundNumber(jsDate);
|
|
12764
12833
|
},
|
|
12765
12834
|
};
|
|
@@ -12773,7 +12842,7 @@
|
|
|
12773
12842
|
computeFormat: () => "m/d/yyyy",
|
|
12774
12843
|
compute: function (date) {
|
|
12775
12844
|
const year = YEAR.compute(date);
|
|
12776
|
-
const jsDate = new
|
|
12845
|
+
const jsDate = new DateTime(year, 0, 1);
|
|
12777
12846
|
return jsDateToRoundNumber(jsDate);
|
|
12778
12847
|
},
|
|
12779
12848
|
};
|
|
@@ -12787,7 +12856,7 @@
|
|
|
12787
12856
|
computeFormat: () => "m/d/yyyy",
|
|
12788
12857
|
compute: function (date) {
|
|
12789
12858
|
const year = YEAR.compute(date);
|
|
12790
|
-
const jsDate = new
|
|
12859
|
+
const jsDate = new DateTime(year + 1, 0, 0);
|
|
12791
12860
|
return jsDateToRoundNumber(jsDate);
|
|
12792
12861
|
},
|
|
12793
12862
|
};
|
|
@@ -12835,8 +12904,8 @@
|
|
|
12835
12904
|
const DELTA = {
|
|
12836
12905
|
description: _lt("Compare two numeric values, returning 1 if they're equal."),
|
|
12837
12906
|
args: [
|
|
12838
|
-
arg(" (number)", _lt("The first number to compare.")),
|
|
12839
|
-
arg(` (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12907
|
+
arg("number1 (number)", _lt("The first number to compare.")),
|
|
12908
|
+
arg(`number2 (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
|
|
12840
12909
|
],
|
|
12841
12910
|
returns: ["NUMBER"],
|
|
12842
12911
|
compute: function (number1, number2 = DEFAULT_DELTA_ARG) {
|
|
@@ -12922,7 +12991,7 @@
|
|
|
12922
12991
|
function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
|
|
12923
12992
|
const startDate = toJsDate(settlement);
|
|
12924
12993
|
const endDate = toJsDate(maturity);
|
|
12925
|
-
const startDatePlusOneYear =
|
|
12994
|
+
const startDatePlusOneYear = toJsDate(settlement);
|
|
12926
12995
|
startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
|
|
12927
12996
|
assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
|
|
12928
12997
|
}
|
|
@@ -13057,7 +13126,7 @@
|
|
|
13057
13126
|
arg("salvage (number)", _lt("The value of the asset at the end of depreciation.")),
|
|
13058
13127
|
arg("period (number)", _lt("The single period within life for which to calculate depreciation.")),
|
|
13059
13128
|
arg("rate (number)", _lt("The deprecation rate.")),
|
|
13060
|
-
arg(" (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
13129
|
+
arg("day_count_convention (number, optional)", _lt("An indicator of what day count method to use.")),
|
|
13061
13130
|
],
|
|
13062
13131
|
returns: ["NUMBER"],
|
|
13063
13132
|
compute: function (cost, purchaseDate, firstPeriodEnd, salvage, period, rate, dayCountConvention = DEFAULT_DAY_COUNT_CONVENTION) {
|
|
@@ -16040,8 +16109,8 @@
|
|
|
16040
16109
|
description: _lt("A segment of a string."),
|
|
16041
16110
|
args: [
|
|
16042
16111
|
arg("text (string)", _lt("The string to extract a segment from.")),
|
|
16043
|
-
arg(" (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
16044
|
-
arg(" (number)", _lt("The length of the segment to extract.")),
|
|
16112
|
+
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.")),
|
|
16113
|
+
arg("extract_length (number)", _lt("The length of the segment to extract.")),
|
|
16045
16114
|
],
|
|
16046
16115
|
returns: ["STRING"],
|
|
16047
16116
|
compute: function (text, starting_at, extract_length) {
|
|
@@ -17710,10 +17779,10 @@
|
|
|
17710
17779
|
function updateSelectionWithArrowKeys(ev, selection) {
|
|
17711
17780
|
const direction = arrowMap[ev.key];
|
|
17712
17781
|
if (ev.shiftKey) {
|
|
17713
|
-
selection.resizeAnchorZone(direction, ev
|
|
17782
|
+
selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
|
|
17714
17783
|
}
|
|
17715
17784
|
else {
|
|
17716
|
-
selection.moveAnchorCell(direction, ev
|
|
17785
|
+
selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
|
|
17717
17786
|
}
|
|
17718
17787
|
}
|
|
17719
17788
|
|
|
@@ -22410,7 +22479,10 @@
|
|
|
22410
22479
|
return;
|
|
22411
22480
|
}
|
|
22412
22481
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
22413
|
-
this.props.onCellClicked(col, row, {
|
|
22482
|
+
this.props.onCellClicked(col, row, {
|
|
22483
|
+
expandZone: ev.shiftKey,
|
|
22484
|
+
addZone: isCtrlKey(ev),
|
|
22485
|
+
});
|
|
22414
22486
|
}
|
|
22415
22487
|
onDoubleClick(ev) {
|
|
22416
22488
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
@@ -22483,6 +22555,7 @@
|
|
|
22483
22555
|
draggerShadowThickness: 0,
|
|
22484
22556
|
delta: 0,
|
|
22485
22557
|
base: 0,
|
|
22558
|
+
position: "before",
|
|
22486
22559
|
});
|
|
22487
22560
|
_computeHandleDisplay(ev) {
|
|
22488
22561
|
const position = this._getEvOffset(ev);
|
|
@@ -22607,11 +22680,13 @@
|
|
|
22607
22680
|
this.state.draggerLinePosition = dimensions.start;
|
|
22608
22681
|
this.state.draggerShadowPosition = dimensions.start;
|
|
22609
22682
|
this.state.base = elementIndex;
|
|
22683
|
+
this.state.position = "before";
|
|
22610
22684
|
}
|
|
22611
22685
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
22612
22686
|
this.state.draggerLinePosition = dimensions.end;
|
|
22613
22687
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
22614
|
-
this.state.base = elementIndex
|
|
22688
|
+
this.state.base = elementIndex;
|
|
22689
|
+
this.state.position = "after";
|
|
22615
22690
|
}
|
|
22616
22691
|
else {
|
|
22617
22692
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -22635,7 +22710,7 @@
|
|
|
22635
22710
|
this._increaseSelection(index);
|
|
22636
22711
|
}
|
|
22637
22712
|
else {
|
|
22638
|
-
this._selectElement(index, ev
|
|
22713
|
+
this._selectElement(index, isCtrlKey(ev));
|
|
22639
22714
|
}
|
|
22640
22715
|
this.lastSelectedElementIndex = index;
|
|
22641
22716
|
const mouseMoveSelect = (col, row) => {
|
|
@@ -22648,7 +22723,7 @@
|
|
|
22648
22723
|
const mouseUpSelect = () => {
|
|
22649
22724
|
this.state.isSelecting = false;
|
|
22650
22725
|
this.lastSelectedElementIndex = null;
|
|
22651
|
-
this.env.model.dispatch(ev
|
|
22726
|
+
this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
|
|
22652
22727
|
this._computeGrabDisplay(ev);
|
|
22653
22728
|
};
|
|
22654
22729
|
dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
|
|
@@ -22794,13 +22869,14 @@
|
|
|
22794
22869
|
dimension: "COL",
|
|
22795
22870
|
base: this.state.base,
|
|
22796
22871
|
elements,
|
|
22872
|
+
position: this.state.position,
|
|
22797
22873
|
});
|
|
22798
22874
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
22799
22875
|
this.env.raiseError(MergeErrorMessage);
|
|
22800
22876
|
}
|
|
22801
22877
|
}
|
|
22802
|
-
_selectElement(index,
|
|
22803
|
-
this.env.model.selection.selectColumn(index,
|
|
22878
|
+
_selectElement(index, addDistinctHeader) {
|
|
22879
|
+
this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
22804
22880
|
}
|
|
22805
22881
|
_increaseSelection(index) {
|
|
22806
22882
|
this.env.model.selection.selectColumn(index, "updateAnchor");
|
|
@@ -22967,13 +23043,14 @@
|
|
|
22967
23043
|
dimension: "ROW",
|
|
22968
23044
|
base: this.state.base,
|
|
22969
23045
|
elements,
|
|
23046
|
+
position: this.state.position,
|
|
22970
23047
|
});
|
|
22971
23048
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
22972
23049
|
this.env.raiseError(MergeErrorMessage);
|
|
22973
23050
|
}
|
|
22974
23051
|
}
|
|
22975
|
-
_selectElement(index,
|
|
22976
|
-
this.env.model.selection.selectRow(index,
|
|
23052
|
+
_selectElement(index, addDistinctHeader) {
|
|
23053
|
+
this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
22977
23054
|
}
|
|
22978
23055
|
_increaseSelection(index) {
|
|
22979
23056
|
this.env.model.selection.selectRow(index, "updateAnchor");
|
|
@@ -23074,8 +23151,8 @@
|
|
|
23074
23151
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
23075
23152
|
}
|
|
23076
23153
|
const onMouseWheel = (ev) => {
|
|
23077
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
23078
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
23154
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
23155
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
23079
23156
|
handler(deltaX, deltaY);
|
|
23080
23157
|
};
|
|
23081
23158
|
return onMouseWheel;
|
|
@@ -23777,8 +23854,8 @@
|
|
|
23777
23854
|
// ---------------------------------------------------------------------------
|
|
23778
23855
|
// Zone selection with mouse
|
|
23779
23856
|
// ---------------------------------------------------------------------------
|
|
23780
|
-
onCellClicked(col, row, {
|
|
23781
|
-
if (
|
|
23857
|
+
onCellClicked(col, row, { addZone, expandZone }) {
|
|
23858
|
+
if (addZone) {
|
|
23782
23859
|
this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
|
|
23783
23860
|
}
|
|
23784
23861
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
@@ -23787,10 +23864,10 @@
|
|
|
23787
23864
|
if (this.env.model.getters.getEditionMode() === "editing") {
|
|
23788
23865
|
this.env.model.dispatch("STOP_EDITION");
|
|
23789
23866
|
}
|
|
23790
|
-
if (
|
|
23867
|
+
if (expandZone) {
|
|
23791
23868
|
this.env.model.selection.setAnchorCorner(col, row);
|
|
23792
23869
|
}
|
|
23793
|
-
else if (
|
|
23870
|
+
else if (addZone) {
|
|
23794
23871
|
this.env.model.selection.addCellToSelection(col, row);
|
|
23795
23872
|
}
|
|
23796
23873
|
else {
|
|
@@ -23852,9 +23929,7 @@
|
|
|
23852
23929
|
return;
|
|
23853
23930
|
}
|
|
23854
23931
|
let keyDownString = "";
|
|
23855
|
-
if (ev
|
|
23856
|
-
keyDownString += "CTRL+";
|
|
23857
|
-
if (ev.metaKey)
|
|
23932
|
+
if (isCtrlKey(ev))
|
|
23858
23933
|
keyDownString += "CTRL+";
|
|
23859
23934
|
if (ev.altKey)
|
|
23860
23935
|
keyDownString += "ALT+";
|
|
@@ -25762,7 +25837,7 @@
|
|
|
25762
25837
|
SPACE: goTo(State.RightRef),
|
|
25763
25838
|
NUMBER: goTo(State.Found),
|
|
25764
25839
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
25765
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
25840
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
25766
25841
|
},
|
|
25767
25842
|
[State.RightColumnRef]: {
|
|
25768
25843
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -25773,6 +25848,7 @@
|
|
|
25773
25848
|
SPACE: goTo(State.RightRowRef),
|
|
25774
25849
|
NUMBER: goTo(State.Found),
|
|
25775
25850
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
25851
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
25776
25852
|
},
|
|
25777
25853
|
[State.Found]: {},
|
|
25778
25854
|
};
|
|
@@ -29480,7 +29556,7 @@
|
|
|
29480
29556
|
*/
|
|
29481
29557
|
function getBorderId(border) {
|
|
29482
29558
|
for (let [key, value] of Object.entries(borders)) {
|
|
29483
|
-
if (
|
|
29559
|
+
if (deepEquals(value, border)) {
|
|
29484
29560
|
return parseInt(key, 10);
|
|
29485
29561
|
}
|
|
29486
29562
|
}
|
|
@@ -32448,7 +32524,7 @@
|
|
|
32448
32524
|
const elements = cmd.dimension === "COL"
|
|
32449
32525
|
? this.getNumberCols(cmd.sheetId)
|
|
32450
32526
|
: this.getNumberRows(cmd.sheetId);
|
|
32451
|
-
if (cmd.base < 0 || cmd.base
|
|
32527
|
+
if (cmd.base < 0 || cmd.base >= elements) {
|
|
32452
32528
|
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
32453
32529
|
}
|
|
32454
32530
|
else if (cmd.quantity <= 0) {
|
|
@@ -33481,13 +33557,18 @@
|
|
|
33481
33557
|
// Getters
|
|
33482
33558
|
// ---------------------------------------------------------------------------
|
|
33483
33559
|
evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
|
|
33484
|
-
|
|
33485
|
-
|
|
33486
|
-
|
|
33487
|
-
|
|
33488
|
-
|
|
33560
|
+
try {
|
|
33561
|
+
const compiledFormula = compile(formulaString);
|
|
33562
|
+
const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
|
|
33563
|
+
const ranges = [];
|
|
33564
|
+
for (let xc of compiledFormula.dependencies) {
|
|
33565
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
33566
|
+
}
|
|
33567
|
+
return compiledFormula.execute(ranges, ...params).value;
|
|
33568
|
+
}
|
|
33569
|
+
catch (error) {
|
|
33570
|
+
return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
|
|
33489
33571
|
}
|
|
33490
|
-
return compiledFormula.execute(ranges, ...params).value;
|
|
33491
33572
|
}
|
|
33492
33573
|
/**
|
|
33493
33574
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -33912,39 +33993,34 @@
|
|
|
33912
33993
|
this.computedIcons[sheetId] = {};
|
|
33913
33994
|
const computedStyle = this.computedStyles[sheetId];
|
|
33914
33995
|
for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
|
|
33915
|
-
|
|
33916
|
-
|
|
33917
|
-
|
|
33918
|
-
|
|
33919
|
-
|
|
33920
|
-
|
|
33921
|
-
|
|
33922
|
-
|
|
33923
|
-
|
|
33924
|
-
|
|
33925
|
-
|
|
33926
|
-
|
|
33927
|
-
|
|
33928
|
-
|
|
33929
|
-
|
|
33930
|
-
for (let
|
|
33931
|
-
|
|
33932
|
-
|
|
33933
|
-
|
|
33934
|
-
if (
|
|
33935
|
-
|
|
33936
|
-
|
|
33937
|
-
|
|
33938
|
-
computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
|
|
33939
|
-
}
|
|
33996
|
+
switch (cf.rule.type) {
|
|
33997
|
+
case "ColorScaleRule":
|
|
33998
|
+
for (let range of cf.ranges) {
|
|
33999
|
+
this.applyColorScale(range, cf.rule);
|
|
34000
|
+
}
|
|
34001
|
+
break;
|
|
34002
|
+
case "IconSetRule":
|
|
34003
|
+
for (let range of cf.ranges) {
|
|
34004
|
+
this.applyIcon(range, cf.rule);
|
|
34005
|
+
}
|
|
34006
|
+
break;
|
|
34007
|
+
default:
|
|
34008
|
+
for (let ref of cf.ranges) {
|
|
34009
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
|
|
34010
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
34011
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
34012
|
+
const pr = this.rulePredicate[cf.rule.type];
|
|
34013
|
+
let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
|
|
34014
|
+
if (pr && pr(cell, cf.rule)) {
|
|
34015
|
+
if (!computedStyle[col])
|
|
34016
|
+
computedStyle[col] = [];
|
|
34017
|
+
// we must combine all the properties of all the CF rules applied to the given cell
|
|
34018
|
+
computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
|
|
33940
34019
|
}
|
|
33941
34020
|
}
|
|
33942
34021
|
}
|
|
33943
|
-
|
|
33944
|
-
|
|
33945
|
-
}
|
|
33946
|
-
catch (_) {
|
|
33947
|
-
// we don't care about the errors within the evaluation of a rule
|
|
34022
|
+
}
|
|
34023
|
+
break;
|
|
33948
34024
|
}
|
|
33949
34025
|
}
|
|
33950
34026
|
}
|
|
@@ -33969,7 +34045,7 @@
|
|
|
33969
34045
|
return percentile(rangeValues, Number(threshold.value) / 100, true);
|
|
33970
34046
|
case "formula":
|
|
33971
34047
|
const value = threshold.value && this.getters.evaluateFormula(threshold.value);
|
|
33972
|
-
return
|
|
34048
|
+
return typeof value === "number" ? value : null;
|
|
33973
34049
|
default:
|
|
33974
34050
|
return null;
|
|
33975
34051
|
}
|
|
@@ -35618,19 +35694,21 @@
|
|
|
35618
35694
|
let col = zone.left;
|
|
35619
35695
|
let row = zone.bottom;
|
|
35620
35696
|
if (col > 0) {
|
|
35621
|
-
let
|
|
35622
|
-
while (
|
|
35697
|
+
let leftPosition = { sheetId, col: col - 1, row };
|
|
35698
|
+
while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
|
|
35699
|
+
this.getters.getCell(leftPosition)?.content) {
|
|
35623
35700
|
row += 1;
|
|
35624
|
-
|
|
35701
|
+
leftPosition = { sheetId, col: col - 1, row };
|
|
35625
35702
|
}
|
|
35626
35703
|
}
|
|
35627
35704
|
if (row === zone.bottom) {
|
|
35628
35705
|
col = zone.right;
|
|
35629
35706
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
35630
|
-
let
|
|
35631
|
-
while (
|
|
35707
|
+
let rightPosition = { sheetId, col: col + 1, row };
|
|
35708
|
+
while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
|
|
35709
|
+
this.getters.getCell(rightPosition)?.content) {
|
|
35632
35710
|
row += 1;
|
|
35633
|
-
|
|
35711
|
+
rightPosition = { sheetId, col: col + 1, row };
|
|
35634
35712
|
}
|
|
35635
35713
|
}
|
|
35636
35714
|
}
|
|
@@ -40578,6 +40656,10 @@
|
|
|
40578
40656
|
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
40579
40657
|
case "colrow":
|
|
40580
40658
|
indexOfNumber = xc.search(/[0-9]/);
|
|
40659
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
40660
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
40661
|
+
return "$" + xc;
|
|
40662
|
+
}
|
|
40581
40663
|
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
40582
40664
|
return "$" + xc;
|
|
40583
40665
|
case "none":
|
|
@@ -41759,7 +41841,7 @@
|
|
|
41759
41841
|
sheetId: cmd.sheetId,
|
|
41760
41842
|
base: cmd.base,
|
|
41761
41843
|
quantity: thickness,
|
|
41762
|
-
position:
|
|
41844
|
+
position: cmd.position,
|
|
41763
41845
|
});
|
|
41764
41846
|
const isCol = cmd.dimension === "COL";
|
|
41765
41847
|
const start = cmd.elements[0];
|
|
@@ -41776,12 +41858,13 @@
|
|
|
41776
41858
|
},
|
|
41777
41859
|
];
|
|
41778
41860
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
41861
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
41779
41862
|
const pasteTarget = [
|
|
41780
41863
|
{
|
|
41781
|
-
left: isCol ?
|
|
41782
|
-
right: isCol ?
|
|
41783
|
-
top: !isCol ?
|
|
41784
|
-
bottom: !isCol ?
|
|
41864
|
+
left: isCol ? base : 0,
|
|
41865
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
41866
|
+
top: !isCol ? base : 0,
|
|
41867
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
41785
41868
|
},
|
|
41786
41869
|
];
|
|
41787
41870
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -41818,6 +41901,11 @@
|
|
|
41818
41901
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
41819
41902
|
return 2 /* CommandResult.WillRemoveExistingMerge */;
|
|
41820
41903
|
}
|
|
41904
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
41905
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
41906
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
41907
|
+
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
41908
|
+
}
|
|
41821
41909
|
return 0 /* CommandResult.Success */;
|
|
41822
41910
|
}
|
|
41823
41911
|
//-------------------------------------------
|
|
@@ -44099,7 +44187,7 @@
|
|
|
44099
44187
|
}
|
|
44100
44188
|
onKeydown(ev) {
|
|
44101
44189
|
let keyDownString = "";
|
|
44102
|
-
if (ev
|
|
44190
|
+
if (isCtrlKey(ev)) {
|
|
44103
44191
|
keyDownString += "CTRL+";
|
|
44104
44192
|
}
|
|
44105
44193
|
keyDownString += ev.key.toUpperCase();
|
|
@@ -47838,9 +47926,9 @@
|
|
|
47838
47926
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
47839
47927
|
|
|
47840
47928
|
|
|
47841
|
-
__info__.version = '16.3.
|
|
47842
|
-
__info__.date = '
|
|
47843
|
-
__info__.hash = '
|
|
47929
|
+
__info__.version = '16.3.22';
|
|
47930
|
+
__info__.date = '2024-01-17T10:24:07.652Z';
|
|
47931
|
+
__info__.hash = '2c1b136';
|
|
47844
47932
|
|
|
47845
47933
|
|
|
47846
47934
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|