@odoo/o-spreadsheet 18.1.4 → 18.1.6
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 +206 -139
- package/dist/o-spreadsheet.d.ts +12 -14
- package/dist/o-spreadsheet.esm.js +206 -139
- package/dist/o-spreadsheet.iife.js +206 -139
- package/dist/o-spreadsheet.iife.min.js +7 -7
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.6
|
|
6
|
+
* @date 2025-02-05T07:18:57.089Z
|
|
7
|
+
* @hash f5b97e0
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3350,11 +3350,11 @@ const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(l
|
|
|
3350
3350
|
* number from the point of view of the isNumber function.
|
|
3351
3351
|
*/
|
|
3352
3352
|
function parseNumber(str, locale) {
|
|
3353
|
+
// remove invaluable characters
|
|
3354
|
+
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3353
3355
|
if (locale.decimalSeparator !== ".") {
|
|
3354
3356
|
str = str.replace(locale.decimalSeparator, ".");
|
|
3355
3357
|
}
|
|
3356
|
-
// remove invaluable characters
|
|
3357
|
-
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3358
3358
|
let n = Number(str);
|
|
3359
3359
|
if (isNaN(n) && str.includes("%")) {
|
|
3360
3360
|
n = Number(str.split("%")[0]);
|
|
@@ -18456,19 +18456,20 @@ const HLOOKUP = {
|
|
|
18456
18456
|
description: _t("Horizontal lookup"),
|
|
18457
18457
|
args: [
|
|
18458
18458
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18459
|
-
arg("range (range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18459
|
+
arg("range (any, range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18460
18460
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18461
18461
|
arg(`is_sorted (boolean, default=${DEFAULT_IS_SORTED})`, _t("Indicates whether the row to be searched (the first row of the specified range) is sorted, in which case the closest match for search_key will be returned.")),
|
|
18462
18462
|
],
|
|
18463
18463
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18464
18464
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18465
|
-
|
|
18465
|
+
const _range = toMatrix(range);
|
|
18466
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18466
18467
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18467
18468
|
const _isSorted = toBoolean(isSorted.value);
|
|
18468
18469
|
const colIndex = _isSorted
|
|
18469
|
-
? dichotomicSearch(
|
|
18470
|
-
: linearSearch(
|
|
18471
|
-
const col =
|
|
18470
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18471
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18472
|
+
const col = _range[colIndex];
|
|
18472
18473
|
if (col === undefined) {
|
|
18473
18474
|
return valueNotAvailable(searchKey);
|
|
18474
18475
|
}
|
|
@@ -18560,35 +18561,37 @@ const LOOKUP = {
|
|
|
18560
18561
|
description: _t("Look up a value."),
|
|
18561
18562
|
args: [
|
|
18562
18563
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18563
|
-
arg("search_array (range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18564
|
-
arg("result_range (range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18564
|
+
arg("search_array (any, range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18565
|
+
arg("result_range (any, range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18565
18566
|
],
|
|
18566
18567
|
compute: function (searchKey, searchArray, resultRange) {
|
|
18567
|
-
|
|
18568
|
-
|
|
18568
|
+
const _searchArray = toMatrix(searchArray);
|
|
18569
|
+
const _resultRange = toMatrix(resultRange);
|
|
18570
|
+
let nbCol = _searchArray.length;
|
|
18571
|
+
let nbRow = _searchArray[0].length;
|
|
18569
18572
|
const verticalSearch = nbRow >= nbCol;
|
|
18570
18573
|
const getElement = verticalSearch
|
|
18571
18574
|
? (range, index) => range[0][index].value
|
|
18572
18575
|
: (range, index) => range[index][0].value;
|
|
18573
18576
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18574
|
-
const index = dichotomicSearch(
|
|
18577
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
18575
18578
|
if (index === -1 ||
|
|
18576
|
-
(verticalSearch &&
|
|
18577
|
-
(!verticalSearch &&
|
|
18579
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
18580
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
18578
18581
|
return valueNotAvailable(searchKey);
|
|
18579
18582
|
}
|
|
18580
|
-
if (
|
|
18581
|
-
return verticalSearch ?
|
|
18583
|
+
if (_resultRange[0].length === 0) {
|
|
18584
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18582
18585
|
}
|
|
18583
|
-
nbCol =
|
|
18584
|
-
nbRow =
|
|
18586
|
+
nbCol = _resultRange.length;
|
|
18587
|
+
nbRow = _resultRange[0].length;
|
|
18585
18588
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18586
18589
|
if (nbCol > 1) {
|
|
18587
18590
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18588
|
-
return
|
|
18591
|
+
return _resultRange[index][0];
|
|
18589
18592
|
}
|
|
18590
18593
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18591
|
-
return
|
|
18594
|
+
return _resultRange[0][index];
|
|
18592
18595
|
},
|
|
18593
18596
|
isExported: true,
|
|
18594
18597
|
};
|
|
@@ -18605,28 +18608,29 @@ const MATCH = {
|
|
|
18605
18608
|
],
|
|
18606
18609
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
18607
18610
|
let _searchType = toNumber(searchType, this.locale);
|
|
18608
|
-
const
|
|
18609
|
-
const
|
|
18611
|
+
const _range = toMatrix(range);
|
|
18612
|
+
const nbCol = _range.length;
|
|
18613
|
+
const nbRow = _range[0].length;
|
|
18610
18614
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18611
18615
|
let index = -1;
|
|
18612
18616
|
const getElement = nbCol === 1
|
|
18613
|
-
? (
|
|
18614
|
-
: (
|
|
18615
|
-
const rangeLen = nbCol === 1 ?
|
|
18617
|
+
? (_range, index) => _range[0][index].value
|
|
18618
|
+
: (_range, index) => _range[index][0].value;
|
|
18619
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18616
18620
|
_searchType = Math.sign(_searchType);
|
|
18617
18621
|
switch (_searchType) {
|
|
18618
18622
|
case 1:
|
|
18619
|
-
index = dichotomicSearch(
|
|
18623
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18620
18624
|
break;
|
|
18621
18625
|
case 0:
|
|
18622
|
-
index = linearSearch(
|
|
18626
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18623
18627
|
break;
|
|
18624
18628
|
case -1:
|
|
18625
|
-
index = dichotomicSearch(
|
|
18629
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18626
18630
|
break;
|
|
18627
18631
|
}
|
|
18628
|
-
if ((nbCol === 1 &&
|
|
18629
|
-
(nbCol !== 1 &&
|
|
18632
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
18633
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
18630
18634
|
return valueNotAvailable(searchKey);
|
|
18631
18635
|
}
|
|
18632
18636
|
return index + 1;
|
|
@@ -18681,13 +18685,14 @@ const VLOOKUP = {
|
|
|
18681
18685
|
],
|
|
18682
18686
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18683
18687
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18684
|
-
|
|
18688
|
+
const _range = toMatrix(range);
|
|
18689
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18685
18690
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18686
18691
|
const _isSorted = toBoolean(isSorted.value);
|
|
18687
18692
|
const rowIndex = _isSorted
|
|
18688
|
-
? dichotomicSearch(
|
|
18689
|
-
: linearSearch(
|
|
18690
|
-
const value =
|
|
18693
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18694
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18695
|
+
const value = _range[_index - 1][rowIndex];
|
|
18691
18696
|
if (value === undefined) {
|
|
18692
18697
|
return valueNotAvailable(searchKey);
|
|
18693
18698
|
}
|
|
@@ -18724,27 +18729,29 @@ const XLOOKUP = {
|
|
|
18724
18729
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18725
18730
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18726
18731
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18727
|
-
|
|
18732
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18733
|
+
const _returnRange = toMatrix(returnRange);
|
|
18734
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18728
18735
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18729
18736
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18730
|
-
const lookupDirection =
|
|
18737
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18731
18738
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18732
18739
|
assert(() => lookupDirection === "col"
|
|
18733
|
-
?
|
|
18734
|
-
:
|
|
18740
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18741
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18735
18742
|
const getElement = lookupDirection === "col"
|
|
18736
18743
|
? (range, index) => range[0][index].value
|
|
18737
18744
|
: (range, index) => range[index][0].value;
|
|
18738
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18745
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18739
18746
|
const mode = MATCH_MODE[_matchMode];
|
|
18740
18747
|
const reverseSearch = _searchMode === -1;
|
|
18741
18748
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18742
|
-
? dichotomicSearch(
|
|
18743
|
-
: linearSearch(
|
|
18749
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18750
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18744
18751
|
if (index !== -1) {
|
|
18745
18752
|
return lookupDirection === "col"
|
|
18746
|
-
?
|
|
18747
|
-
: [
|
|
18753
|
+
? _returnRange.map((col) => [col[index]])
|
|
18754
|
+
: [_returnRange[index]];
|
|
18748
18755
|
}
|
|
18749
18756
|
if (defaultValue === undefined) {
|
|
18750
18757
|
return valueNotAvailable(searchKey);
|
|
@@ -28436,11 +28443,7 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28436
28443
|
if (values.length < 2 || labels.length < 2 || newLabels.length === 0) {
|
|
28437
28444
|
return [];
|
|
28438
28445
|
}
|
|
28439
|
-
const
|
|
28440
|
-
const labelMax = Math.max(...labels);
|
|
28441
|
-
const labelRange = labelMax - labelMin;
|
|
28442
|
-
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28443
|
-
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28446
|
+
const { normalizedLabels, normalizedNewLabels } = normalizeLabels(labels, newLabels, config);
|
|
28444
28447
|
try {
|
|
28445
28448
|
switch (config.type) {
|
|
28446
28449
|
case "polynomial": {
|
|
@@ -28485,6 +28488,30 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28485
28488
|
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28486
28489
|
}
|
|
28487
28490
|
}
|
|
28491
|
+
function normalizeLabels(labels, newLabels, config) {
|
|
28492
|
+
let normalizedLabels = [];
|
|
28493
|
+
let normalizedNewLabels = [];
|
|
28494
|
+
if (config.type === "logarithmic") {
|
|
28495
|
+
// Logarithmic trends in charts are used to visualize proportional growth or
|
|
28496
|
+
// relative changes. Therefore, we change the normalization technique for
|
|
28497
|
+
// logarithmic trend lines for a better fit. The method used here is Max Absolute
|
|
28498
|
+
// Scaling. This Technique is ideal for data spanning several orders of magnitude,
|
|
28499
|
+
// as it balances differences between small and large values by compressing larger
|
|
28500
|
+
// values while preserving proportionality and ensuring all values are scaled relative
|
|
28501
|
+
// to the largest magnitude.
|
|
28502
|
+
const labelMax = Math.max(...labels.map(Math.abs));
|
|
28503
|
+
normalizedLabels = labels.map((l) => l / labelMax);
|
|
28504
|
+
normalizedNewLabels = newLabels.map((l) => l / labelMax);
|
|
28505
|
+
}
|
|
28506
|
+
else {
|
|
28507
|
+
const labelMax = Math.max(...labels);
|
|
28508
|
+
const labelMin = Math.min(...labels);
|
|
28509
|
+
const labelRange = labelMax - labelMin;
|
|
28510
|
+
normalizedLabels = labels.map((l) => (l - labelMax) / labelRange);
|
|
28511
|
+
normalizedNewLabels = newLabels.map((l) => (l - labelMax) / labelRange);
|
|
28512
|
+
}
|
|
28513
|
+
return { normalizedLabels, normalizedNewLabels };
|
|
28514
|
+
}
|
|
28488
28515
|
function getChartAxisType(chart, labelRange, getters) {
|
|
28489
28516
|
if (isDateChart(chart, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
|
|
28490
28517
|
return "time";
|
|
@@ -40369,6 +40396,12 @@ class Composer extends owl.Component {
|
|
|
40369
40396
|
}
|
|
40370
40397
|
this.contentHelper.updateEl(el);
|
|
40371
40398
|
});
|
|
40399
|
+
this.env.model.selection.observe(this, {
|
|
40400
|
+
handleEvent: () => this.autoCompleteState.hide(),
|
|
40401
|
+
});
|
|
40402
|
+
owl.onWillUnmount(() => {
|
|
40403
|
+
this.env.model.selection.detachObserver(this);
|
|
40404
|
+
});
|
|
40372
40405
|
owl.useEffect(() => {
|
|
40373
40406
|
this.processContent();
|
|
40374
40407
|
if (document.activeElement === this.contentHelper.el &&
|
|
@@ -50482,11 +50515,10 @@ class GridRenderer {
|
|
|
50482
50515
|
switch (layer) {
|
|
50483
50516
|
case "Background":
|
|
50484
50517
|
this.drawGlobalBackground(renderingContext);
|
|
50485
|
-
for (const zone of this.getters.
|
|
50518
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
50486
50519
|
const { ctx } = renderingContext;
|
|
50487
50520
|
ctx.save();
|
|
50488
50521
|
ctx.beginPath();
|
|
50489
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
50490
50522
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
50491
50523
|
ctx.clip();
|
|
50492
50524
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -50762,10 +50794,8 @@ class GridRenderer {
|
|
|
50762
50794
|
const { ctx, thinLineWidth } = renderingContext;
|
|
50763
50795
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
50764
50796
|
const left = visibleCols[0];
|
|
50765
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
50766
50797
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
50767
50798
|
const top = visibleRows[0];
|
|
50768
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
50769
50799
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
50770
50800
|
const selection = this.getters.getSelectedZones();
|
|
50771
50801
|
const selectedCols = getZonesCols(selection);
|
|
@@ -50781,7 +50811,7 @@ class GridRenderer {
|
|
|
50781
50811
|
ctx.lineWidth = thinLineWidth;
|
|
50782
50812
|
ctx.strokeStyle = "#333";
|
|
50783
50813
|
// Columns headers background
|
|
50784
|
-
for (
|
|
50814
|
+
for (const col of visibleCols) {
|
|
50785
50815
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
50786
50816
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
50787
50817
|
const isColActive = activeCols.has(col);
|
|
@@ -50798,7 +50828,7 @@ class GridRenderer {
|
|
|
50798
50828
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
50799
50829
|
}
|
|
50800
50830
|
// Rows headers background
|
|
50801
|
-
for (
|
|
50831
|
+
for (const row of visibleRows) {
|
|
50802
50832
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
50803
50833
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
50804
50834
|
const isRowActive = activeRows.has(row);
|
|
@@ -50824,21 +50854,21 @@ class GridRenderer {
|
|
|
50824
50854
|
ctx.stroke();
|
|
50825
50855
|
ctx.beginPath();
|
|
50826
50856
|
// column text + separator
|
|
50827
|
-
for (const
|
|
50828
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
50829
|
-
const colName = numberToLetters(
|
|
50830
|
-
ctx.fillStyle = activeCols.has(
|
|
50831
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
50857
|
+
for (const col of visibleCols) {
|
|
50858
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
50859
|
+
const colName = numberToLetters(col);
|
|
50860
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
50861
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
50832
50862
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
50833
50863
|
ctx.moveTo(colStart + colSize, 0);
|
|
50834
50864
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
50835
50865
|
}
|
|
50836
50866
|
// row text + separator
|
|
50837
|
-
for (const
|
|
50838
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
50839
|
-
ctx.fillStyle = activeRows.has(
|
|
50840
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
50841
|
-
ctx.fillText(String(
|
|
50867
|
+
for (const row of visibleRows) {
|
|
50868
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
50869
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
50870
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
50871
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
50842
50872
|
ctx.moveTo(0, rowStart + rowSize);
|
|
50843
50873
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
50844
50874
|
}
|
|
@@ -51145,6 +51175,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51145
51175
|
canvas.width = width * dpr;
|
|
51146
51176
|
canvas.height = height * dpr;
|
|
51147
51177
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
51178
|
+
if (width === 0 || height === 0) {
|
|
51179
|
+
return;
|
|
51180
|
+
}
|
|
51148
51181
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
51149
51182
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
51150
51183
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -52691,7 +52724,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
52691
52724
|
getCommonSides(border1, border2) {
|
|
52692
52725
|
const commonBorder = {};
|
|
52693
52726
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
52694
|
-
if (border1[side] && border1[side]
|
|
52727
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
52695
52728
|
commonBorder[side] = border1[side];
|
|
52696
52729
|
}
|
|
52697
52730
|
}
|
|
@@ -61320,7 +61353,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
61320
61353
|
const symbolIndex = rowDomain.findIndex((row) => row.field === symbolName);
|
|
61321
61354
|
return this.getPivotHeaderValueAndFormat(rowDomain.slice(0, symbolIndex + 1));
|
|
61322
61355
|
}
|
|
61323
|
-
return this.
|
|
61356
|
+
return this.getPivotCellValueAndFormat(symbolName, domain);
|
|
61324
61357
|
};
|
|
61325
61358
|
const result = this.getters.evaluateCompiledFormula(measure.computedBy.sheetId, formula, getSymbolValue);
|
|
61326
61359
|
if (isMatrix(result)) {
|
|
@@ -64491,14 +64524,12 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
64491
64524
|
}
|
|
64492
64525
|
break;
|
|
64493
64526
|
case "AUTORESIZE_ROWS":
|
|
64494
|
-
|
|
64495
|
-
|
|
64496
|
-
|
|
64497
|
-
|
|
64498
|
-
|
|
64499
|
-
|
|
64500
|
-
});
|
|
64501
|
-
}
|
|
64527
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
64528
|
+
elements: cmd.rows,
|
|
64529
|
+
dimension: "ROW",
|
|
64530
|
+
size: null,
|
|
64531
|
+
sheetId: cmd.sheetId,
|
|
64532
|
+
});
|
|
64502
64533
|
break;
|
|
64503
64534
|
}
|
|
64504
64535
|
}
|
|
@@ -66909,8 +66940,17 @@ class InternalViewport {
|
|
|
66909
66940
|
this.getters = getters;
|
|
66910
66941
|
this.sheetId = sheetId;
|
|
66911
66942
|
this.boundaries = boundaries;
|
|
66912
|
-
|
|
66913
|
-
|
|
66943
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
66944
|
+
throw new Error("Viewport size cannot be negative");
|
|
66945
|
+
}
|
|
66946
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
66947
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
66948
|
+
this.top = boundaries.top;
|
|
66949
|
+
this.bottom = boundaries.bottom;
|
|
66950
|
+
this.left = boundaries.left;
|
|
66951
|
+
this.right = boundaries.right;
|
|
66952
|
+
this.offsetX = offsets.x;
|
|
66953
|
+
this.offsetY = offsets.y;
|
|
66914
66954
|
this.offsetScrollbarX = offsets.x;
|
|
66915
66955
|
this.offsetScrollbarY = offsets.y;
|
|
66916
66956
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -66953,9 +66993,9 @@ class InternalViewport {
|
|
|
66953
66993
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
66954
66994
|
);
|
|
66955
66995
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
66956
|
-
|
|
66957
|
-
|
|
66958
|
-
|
|
66996
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
66997
|
+
height += FOOTER_HEIGHT;
|
|
66998
|
+
}
|
|
66959
66999
|
}
|
|
66960
67000
|
return { width, height };
|
|
66961
67001
|
}
|
|
@@ -67096,6 +67136,9 @@ class InternalViewport {
|
|
|
67096
67136
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
67097
67137
|
}
|
|
67098
67138
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
67139
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
67140
|
+
return -1;
|
|
67141
|
+
}
|
|
67099
67142
|
const sheetId = this.sheetId;
|
|
67100
67143
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
67101
67144
|
// using a binary search:
|
|
@@ -67132,7 +67175,7 @@ class InternalViewport {
|
|
|
67132
67175
|
this.adjustViewportZoneY();
|
|
67133
67176
|
}
|
|
67134
67177
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
67135
|
-
* To make sure that at least
|
|
67178
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
67136
67179
|
*/
|
|
67137
67180
|
adjustViewportOffsetX() {
|
|
67138
67181
|
if (this.canScrollHorizontally) {
|
|
@@ -67144,7 +67187,7 @@ class InternalViewport {
|
|
|
67144
67187
|
this.adjustViewportZoneX();
|
|
67145
67188
|
}
|
|
67146
67189
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
67147
|
-
* To make sure that at least
|
|
67190
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
67148
67191
|
*/
|
|
67149
67192
|
adjustViewportOffsetY() {
|
|
67150
67193
|
if (this.canScrollVertically) {
|
|
@@ -67161,11 +67204,14 @@ class InternalViewport {
|
|
|
67161
67204
|
const sheetId = this.sheetId;
|
|
67162
67205
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
67163
67206
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
67207
|
+
if (!this.viewportWidth) {
|
|
67208
|
+
return;
|
|
67209
|
+
}
|
|
67164
67210
|
if (this.left === -1) {
|
|
67165
67211
|
this.left = this.boundaries.left;
|
|
67166
67212
|
}
|
|
67167
67213
|
if (this.right === -1) {
|
|
67168
|
-
this.right = this.
|
|
67214
|
+
this.right = this.boundaries.right;
|
|
67169
67215
|
}
|
|
67170
67216
|
this.offsetX =
|
|
67171
67217
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -67177,11 +67223,14 @@ class InternalViewport {
|
|
|
67177
67223
|
const sheetId = this.sheetId;
|
|
67178
67224
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
67179
67225
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
67226
|
+
if (!this.viewportHeight) {
|
|
67227
|
+
return;
|
|
67228
|
+
}
|
|
67180
67229
|
if (this.top === -1) {
|
|
67181
67230
|
this.top = this.boundaries.top;
|
|
67182
67231
|
}
|
|
67183
67232
|
if (this.bottom === -1) {
|
|
67184
|
-
this.bottom = this.
|
|
67233
|
+
this.bottom = this.boundaries.bottom;
|
|
67185
67234
|
}
|
|
67186
67235
|
this.offsetY =
|
|
67187
67236
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -67255,7 +67304,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67255
67304
|
"isPositionVisible",
|
|
67256
67305
|
"getColDimensionsInViewport",
|
|
67257
67306
|
"getRowDimensionsInViewport",
|
|
67258
|
-
"
|
|
67307
|
+
"getAllActiveViewportsZonesAndRect",
|
|
67259
67308
|
"getRect",
|
|
67260
67309
|
];
|
|
67261
67310
|
viewports = {};
|
|
@@ -67485,12 +67534,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67485
67534
|
const sheetId = this.getters.getActiveSheetId();
|
|
67486
67535
|
const viewports = this.getSubViewports(sheetId);
|
|
67487
67536
|
//TODO ake another commit to eimprove this
|
|
67488
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67537
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67489
67538
|
}
|
|
67490
67539
|
getSheetViewVisibleRows() {
|
|
67491
67540
|
const sheetId = this.getters.getActiveSheetId();
|
|
67492
67541
|
const viewports = this.getSubViewports(sheetId);
|
|
67493
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67542
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67494
67543
|
}
|
|
67495
67544
|
/**
|
|
67496
67545
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -67533,19 +67582,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67533
67582
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
67534
67583
|
};
|
|
67535
67584
|
}
|
|
67536
|
-
getColRowOffsetInViewport(dimension,
|
|
67537
|
-
|
|
67538
|
-
|
|
67539
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
67540
|
-
if (index < referenceIndex) {
|
|
67541
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
67585
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
67586
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
67587
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
67542
67588
|
}
|
|
67589
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
67590
|
+
const visibleHeaders = dimension === "COL"
|
|
67591
|
+
? this.getters.getSheetViewVisibleCols()
|
|
67592
|
+
: this.getters.getSheetViewVisibleRows();
|
|
67593
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
67594
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
67595
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
67543
67596
|
let offset = 0;
|
|
67544
|
-
const
|
|
67545
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
67546
|
-
if (!visibleIndexes.includes(i)) {
|
|
67547
|
-
continue;
|
|
67548
|
-
}
|
|
67597
|
+
for (const i of relevantIndexes) {
|
|
67549
67598
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
67550
67599
|
}
|
|
67551
67600
|
return offset;
|
|
@@ -67592,7 +67641,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67592
67641
|
}
|
|
67593
67642
|
return { canEdgeScroll, direction, delay };
|
|
67594
67643
|
}
|
|
67595
|
-
getEdgeScrollRow(y, previousY,
|
|
67644
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
67596
67645
|
let canEdgeScroll = false;
|
|
67597
67646
|
let direction = 0;
|
|
67598
67647
|
let delay = 0;
|
|
@@ -67613,7 +67662,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67613
67662
|
delay = scrollDelay(y - height);
|
|
67614
67663
|
direction = 1;
|
|
67615
67664
|
}
|
|
67616
|
-
else if (y < offsetCorrectionY &&
|
|
67665
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
67617
67666
|
// 2
|
|
67618
67667
|
canEdgeScroll = true;
|
|
67619
67668
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -67639,13 +67688,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67639
67688
|
*/
|
|
67640
67689
|
getVisibleRectWithoutHeaders(zone) {
|
|
67641
67690
|
const sheetId = this.getters.getActiveSheetId();
|
|
67642
|
-
|
|
67643
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
67644
|
-
.filter(isDefined);
|
|
67645
|
-
if (viewportRects.length === 0) {
|
|
67646
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67647
|
-
}
|
|
67648
|
-
return this.recomposeRect(viewportRects);
|
|
67691
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
67649
67692
|
}
|
|
67650
67693
|
/**
|
|
67651
67694
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -67653,13 +67696,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67653
67696
|
*/
|
|
67654
67697
|
getRect(zone) {
|
|
67655
67698
|
const sheetId = this.getters.getActiveSheetId();
|
|
67656
|
-
const
|
|
67657
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
67658
|
-
.filter(isDefined);
|
|
67659
|
-
if (viewportRects.length === 0) {
|
|
67660
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67661
|
-
}
|
|
67662
|
-
const rect = this.recomposeRect(viewportRects);
|
|
67699
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
67663
67700
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
67664
67701
|
}
|
|
67665
67702
|
/**
|
|
@@ -67704,9 +67741,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67704
67741
|
end: start + (isRowHidden ? 0 : size),
|
|
67705
67742
|
};
|
|
67706
67743
|
}
|
|
67707
|
-
|
|
67744
|
+
getAllActiveViewportsZonesAndRect() {
|
|
67708
67745
|
const sheetId = this.getters.getActiveSheetId();
|
|
67709
|
-
return this.getSubViewports(sheetId)
|
|
67746
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
67747
|
+
return {
|
|
67748
|
+
zone: viewport,
|
|
67749
|
+
rect: {
|
|
67750
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
67751
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
67752
|
+
...viewport.getMaxSize(),
|
|
67753
|
+
},
|
|
67754
|
+
};
|
|
67755
|
+
});
|
|
67710
67756
|
}
|
|
67711
67757
|
// ---------------------------------------------------------------------------
|
|
67712
67758
|
// Private
|
|
@@ -67765,12 +67811,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67765
67811
|
}
|
|
67766
67812
|
/** gets rid of deprecated sheetIds */
|
|
67767
67813
|
cleanViewports() {
|
|
67768
|
-
const
|
|
67769
|
-
for (
|
|
67770
|
-
|
|
67771
|
-
delete this.viewports[sheetId];
|
|
67772
|
-
}
|
|
67814
|
+
const newViewport = {};
|
|
67815
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
67816
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
67773
67817
|
}
|
|
67818
|
+
this.viewports = newViewport;
|
|
67774
67819
|
}
|
|
67775
67820
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
67776
67821
|
this.sheetViewHeight = height;
|
|
@@ -67780,7 +67825,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67780
67825
|
this.recomputeViewports();
|
|
67781
67826
|
}
|
|
67782
67827
|
recomputeViewports() {
|
|
67783
|
-
for (
|
|
67828
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
67784
67829
|
this.resetViewports(sheetId);
|
|
67785
67830
|
}
|
|
67786
67831
|
}
|
|
@@ -67802,8 +67847,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67802
67847
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
67803
67848
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
67804
67849
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
67805
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
67806
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
67850
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
67851
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
67852
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
67853
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
67807
67854
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
67808
67855
|
const canScrollHorizontally = xRatio < 1.0;
|
|
67809
67856
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -67814,14 +67861,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67814
67861
|
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: 0, bottom: ySplit - 1 }, { width: colOffset, height: rowOffset }, { canScrollHorizontally: false, canScrollVertically: false }, { x: 0, y: 0 })) ||
|
|
67815
67862
|
undefined,
|
|
67816
67863
|
topRight: (ySplit &&
|
|
67817
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
67864
|
+
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width: unfrozenWidth, height: rowOffset }, { canScrollHorizontally, canScrollVertically: false }, { x: canScrollHorizontally ? previousOffset.x : 0, y: 0 })) ||
|
|
67818
67865
|
undefined,
|
|
67819
67866
|
bottomLeft: (xSplit &&
|
|
67820
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
67867
|
+
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height: unfrozenHeight }, { canScrollHorizontally: false, canScrollVertically }, { x: 0, y: canScrollVertically ? previousOffset.y : 0 })) ||
|
|
67821
67868
|
undefined,
|
|
67822
67869
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
67823
|
-
width:
|
|
67824
|
-
height:
|
|
67870
|
+
width: unfrozenWidth,
|
|
67871
|
+
height: unfrozenHeight,
|
|
67825
67872
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
67826
67873
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
67827
67874
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -67898,12 +67945,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67898
67945
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
67899
67946
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
67900
67947
|
}
|
|
67901
|
-
|
|
67902
|
-
|
|
67903
|
-
|
|
67904
|
-
|
|
67905
|
-
|
|
67906
|
-
|
|
67948
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
67949
|
+
let x = Infinity;
|
|
67950
|
+
let y = Infinity;
|
|
67951
|
+
let width = 0;
|
|
67952
|
+
let height = 0;
|
|
67953
|
+
let hasViewports = false;
|
|
67954
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
67955
|
+
const rect = rectCallBack(viewport);
|
|
67956
|
+
if (rect) {
|
|
67957
|
+
hasViewports = true;
|
|
67958
|
+
x = Math.min(x, rect.x);
|
|
67959
|
+
y = Math.min(y, rect.y);
|
|
67960
|
+
width = Math.max(width, rect.x + rect.width);
|
|
67961
|
+
height = Math.max(height, rect.y + rect.height);
|
|
67962
|
+
}
|
|
67963
|
+
}
|
|
67964
|
+
if (!hasViewports) {
|
|
67965
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67966
|
+
}
|
|
67967
|
+
return { x, y, width: width - x, height: height - y };
|
|
67907
67968
|
}
|
|
67908
67969
|
}
|
|
67909
67970
|
|
|
@@ -71522,6 +71583,9 @@ class EventStream {
|
|
|
71522
71583
|
observe(owner, callbacks) {
|
|
71523
71584
|
this.observers.set(owner, { owner, callbacks });
|
|
71524
71585
|
}
|
|
71586
|
+
detachObserver(owner) {
|
|
71587
|
+
this.observers.delete(owner);
|
|
71588
|
+
}
|
|
71525
71589
|
/**
|
|
71526
71590
|
* Capture the stream for yourself
|
|
71527
71591
|
*/
|
|
@@ -71614,6 +71678,9 @@ class SelectionStreamProcessorImpl {
|
|
|
71614
71678
|
observe(owner, callbacks) {
|
|
71615
71679
|
this.stream.observe(owner, callbacks);
|
|
71616
71680
|
}
|
|
71681
|
+
detachObserver(owner) {
|
|
71682
|
+
this.stream.detachObserver(owner);
|
|
71683
|
+
}
|
|
71617
71684
|
release(owner) {
|
|
71618
71685
|
if (this.stream.isListening(owner)) {
|
|
71619
71686
|
this.stream.release(owner);
|
|
@@ -75033,6 +75100,6 @@ exports.tokenColors = tokenColors;
|
|
|
75033
75100
|
exports.tokenize = tokenize;
|
|
75034
75101
|
|
|
75035
75102
|
|
|
75036
|
-
__info__.version = "18.1.
|
|
75037
|
-
__info__.date = "2025-
|
|
75038
|
-
__info__.hash = "
|
|
75103
|
+
__info__.version = "18.1.6";
|
|
75104
|
+
__info__.date = "2025-02-05T07:18:57.089Z";
|
|
75105
|
+
__info__.hash = "f5b97e0";
|