@odoo/o-spreadsheet 18.2.0-alpha.3 → 18.2.0-alpha.5
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 +340 -266
- package/dist/o-spreadsheet.d.ts +15 -32
- package/dist/o-spreadsheet.esm.js +340 -266
- package/dist/o-spreadsheet.iife.js +340 -266
- package/dist/o-spreadsheet.iife.min.js +212 -216
- package/dist/o_spreadsheet.xml +5553 -5540
- package/package.json +8 -5
|
@@ -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.2.0-alpha.
|
|
6
|
-
* @date 2025-01-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.0-alpha.5
|
|
6
|
+
* @date 2025-01-31T07:59:30.667Z
|
|
7
|
+
* @hash efce841
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3361,11 +3361,11 @@ const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(l
|
|
|
3361
3361
|
* number from the point of view of the isNumber function.
|
|
3362
3362
|
*/
|
|
3363
3363
|
function parseNumber(str, locale) {
|
|
3364
|
+
// remove invaluable characters
|
|
3365
|
+
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3364
3366
|
if (locale.decimalSeparator !== ".") {
|
|
3365
3367
|
str = str.replace(locale.decimalSeparator, ".");
|
|
3366
3368
|
}
|
|
3367
|
-
// remove invaluable characters
|
|
3368
|
-
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3369
3369
|
let n = Number(str);
|
|
3370
3370
|
if (isNaN(n) && str.includes("%")) {
|
|
3371
3371
|
n = Number(str.split("%")[0]);
|
|
@@ -32538,36 +32538,58 @@ class ErrorToolTip extends owl.Component {
|
|
|
32538
32538
|
static maxSize = { maxHeight: ERROR_TOOLTIP_MAX_HEIGHT };
|
|
32539
32539
|
static template = "o-spreadsheet-ErrorToolTip";
|
|
32540
32540
|
static props = {
|
|
32541
|
-
|
|
32541
|
+
cellPosition: Object,
|
|
32542
32542
|
onClosed: { type: Function, optional: true },
|
|
32543
32543
|
};
|
|
32544
|
+
get dataValidationErrorMessage() {
|
|
32545
|
+
return this.env.model.getters.getInvalidDataValidationMessage(this.props.cellPosition);
|
|
32546
|
+
}
|
|
32547
|
+
get evaluationError() {
|
|
32548
|
+
const cell = this.env.model.getters.getEvaluatedCell(this.props.cellPosition);
|
|
32549
|
+
if (cell.message) {
|
|
32550
|
+
return cell;
|
|
32551
|
+
}
|
|
32552
|
+
return undefined;
|
|
32553
|
+
}
|
|
32554
|
+
get errorOriginPositionString() {
|
|
32555
|
+
const evaluationError = this.evaluationError;
|
|
32556
|
+
const position = evaluationError?.errorOriginPosition;
|
|
32557
|
+
if (!position || deepEquals(position, this.props.cellPosition)) {
|
|
32558
|
+
return "";
|
|
32559
|
+
}
|
|
32560
|
+
const sheetId = position.sheetId;
|
|
32561
|
+
return this.env.model.getters.getRangeString(this.env.model.getters.getRangeFromZone(sheetId, positionToZone(position)), this.env.model.getters.getActiveSheetId());
|
|
32562
|
+
}
|
|
32563
|
+
selectCell() {
|
|
32564
|
+
const position = this.evaluationError?.errorOriginPosition;
|
|
32565
|
+
if (!position) {
|
|
32566
|
+
return;
|
|
32567
|
+
}
|
|
32568
|
+
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
32569
|
+
if (position.sheetId !== activeSheetId) {
|
|
32570
|
+
this.env.model.dispatch("ACTIVATE_SHEET", {
|
|
32571
|
+
sheetIdFrom: activeSheetId,
|
|
32572
|
+
sheetIdTo: position.sheetId,
|
|
32573
|
+
});
|
|
32574
|
+
}
|
|
32575
|
+
this.env.model.selection.selectCell(position.col, position.row);
|
|
32576
|
+
}
|
|
32544
32577
|
}
|
|
32545
32578
|
const ErrorToolTipPopoverBuilder = {
|
|
32546
32579
|
onHover: (position, getters) => {
|
|
32547
32580
|
const cell = getters.getEvaluatedCell(position);
|
|
32548
|
-
|
|
32549
|
-
|
|
32550
|
-
|
|
32551
|
-
|
|
32552
|
-
|
|
32553
|
-
|
|
32554
|
-
|
|
32555
|
-
|
|
32556
|
-
|
|
32557
|
-
|
|
32558
|
-
title: _t("Invalid"),
|
|
32559
|
-
message: validationErrorMessage,
|
|
32560
|
-
});
|
|
32561
|
-
}
|
|
32562
|
-
if (!errors.length) {
|
|
32563
|
-
return { isOpen: false };
|
|
32581
|
+
if ((cell.type === CellValueType.error && !!cell.message) ||
|
|
32582
|
+
getters.getInvalidDataValidationMessage(position)) {
|
|
32583
|
+
return {
|
|
32584
|
+
isOpen: true,
|
|
32585
|
+
props: {
|
|
32586
|
+
cellPosition: position,
|
|
32587
|
+
},
|
|
32588
|
+
Component: ErrorToolTip,
|
|
32589
|
+
cellCorner: "TopRight",
|
|
32590
|
+
};
|
|
32564
32591
|
}
|
|
32565
|
-
return {
|
|
32566
|
-
isOpen: true,
|
|
32567
|
-
props: { errors: errors },
|
|
32568
|
-
Component: ErrorToolTip,
|
|
32569
|
-
cellCorner: "TopRight",
|
|
32570
|
-
};
|
|
32592
|
+
return { isOpen: false };
|
|
32571
32593
|
},
|
|
32572
32594
|
};
|
|
32573
32595
|
|
|
@@ -33131,6 +33153,100 @@ function* iterateChildren(el) {
|
|
|
33131
33153
|
function getOpenedMenus() {
|
|
33132
33154
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
33133
33155
|
}
|
|
33156
|
+
function getCurrentSelection(el) {
|
|
33157
|
+
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = getStartAndEndSelection(el);
|
|
33158
|
+
let startSizeBefore = findSelectionIndex(el, startElement, startSelectionOffset);
|
|
33159
|
+
let endSizeBefore = findSelectionIndex(el, endElement, endSelectionOffset);
|
|
33160
|
+
return {
|
|
33161
|
+
start: startSizeBefore,
|
|
33162
|
+
end: endSizeBefore,
|
|
33163
|
+
};
|
|
33164
|
+
}
|
|
33165
|
+
function getStartAndEndSelection(el) {
|
|
33166
|
+
const selection = document.getSelection();
|
|
33167
|
+
return {
|
|
33168
|
+
startElement: selection.anchorNode || el,
|
|
33169
|
+
startSelectionOffset: selection.anchorOffset,
|
|
33170
|
+
endElement: selection.focusNode || el,
|
|
33171
|
+
endSelectionOffset: selection.focusOffset,
|
|
33172
|
+
};
|
|
33173
|
+
}
|
|
33174
|
+
/**
|
|
33175
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
33176
|
+
* The selected node is either a Text node or an Element node.
|
|
33177
|
+
*
|
|
33178
|
+
* case 1 -Text node:
|
|
33179
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
33180
|
+
* content length of all previous nodes.
|
|
33181
|
+
*
|
|
33182
|
+
* case 2 - Element node:
|
|
33183
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
33184
|
+
* all the nodes prior to the selected node as well as the content of the child node before the offset.
|
|
33185
|
+
*
|
|
33186
|
+
* See the MDN documentation for more details.
|
|
33187
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
33188
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
33189
|
+
*
|
|
33190
|
+
*/
|
|
33191
|
+
function findSelectionIndex(el, nodeToFind, nodeOffset) {
|
|
33192
|
+
let usedCharacters = 0;
|
|
33193
|
+
let it = iterateChildren(el);
|
|
33194
|
+
let current = it.next();
|
|
33195
|
+
let isFirstParagraph = true;
|
|
33196
|
+
while (!current.done && current.value !== nodeToFind) {
|
|
33197
|
+
if (!current.value.hasChildNodes()) {
|
|
33198
|
+
if (current.value.textContent) {
|
|
33199
|
+
usedCharacters += current.value.textContent.length;
|
|
33200
|
+
}
|
|
33201
|
+
}
|
|
33202
|
+
// One new paragraph = one new line character, except for the first paragraph
|
|
33203
|
+
if (current.value.nodeName === "P" ||
|
|
33204
|
+
(current.value.nodeName === "DIV" && current.value !== el) // On paste, the HTML may contain <div> instead of <p>
|
|
33205
|
+
) {
|
|
33206
|
+
if (isFirstParagraph) {
|
|
33207
|
+
isFirstParagraph = false;
|
|
33208
|
+
}
|
|
33209
|
+
else {
|
|
33210
|
+
usedCharacters++;
|
|
33211
|
+
}
|
|
33212
|
+
}
|
|
33213
|
+
current = it.next();
|
|
33214
|
+
}
|
|
33215
|
+
if (current.value !== nodeToFind) {
|
|
33216
|
+
/** This situation can happen if the code is called while the selection is not currently on the element.
|
|
33217
|
+
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
33218
|
+
*
|
|
33219
|
+
* A known occurrence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
33220
|
+
*/
|
|
33221
|
+
return 0;
|
|
33222
|
+
}
|
|
33223
|
+
else {
|
|
33224
|
+
if (!current.value.hasChildNodes()) {
|
|
33225
|
+
usedCharacters += nodeOffset;
|
|
33226
|
+
}
|
|
33227
|
+
else {
|
|
33228
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
33229
|
+
usedCharacters += children.reduce((acc, child, index) => {
|
|
33230
|
+
if (child.textContent !== null) {
|
|
33231
|
+
// need to account for paragraph nodes that implicitly add a new line
|
|
33232
|
+
// except for the last paragraph
|
|
33233
|
+
let chars = child.textContent.length;
|
|
33234
|
+
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
33235
|
+
chars++;
|
|
33236
|
+
}
|
|
33237
|
+
return acc + chars;
|
|
33238
|
+
}
|
|
33239
|
+
else {
|
|
33240
|
+
return acc;
|
|
33241
|
+
}
|
|
33242
|
+
}, 0);
|
|
33243
|
+
}
|
|
33244
|
+
}
|
|
33245
|
+
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
33246
|
+
usedCharacters++;
|
|
33247
|
+
}
|
|
33248
|
+
return usedCharacters;
|
|
33249
|
+
}
|
|
33134
33250
|
const letterRegex = /^[a-zA-Z]$/;
|
|
33135
33251
|
/**
|
|
33136
33252
|
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
@@ -40096,14 +40212,21 @@ class ChartTypePicker extends owl.Component {
|
|
|
40096
40212
|
class MainChartPanelStore extends SpreadsheetStore {
|
|
40097
40213
|
mutators = ["activatePanel", "changeChartType"];
|
|
40098
40214
|
panel = "configuration";
|
|
40099
|
-
|
|
40215
|
+
creationContexts = {};
|
|
40100
40216
|
activatePanel(panel) {
|
|
40101
40217
|
this.panel = panel;
|
|
40102
40218
|
}
|
|
40103
40219
|
changeChartType(figureId, newDisplayType) {
|
|
40104
|
-
|
|
40105
|
-
|
|
40106
|
-
|
|
40220
|
+
const currentCreationContext = this.getters.getContextCreationChart(figureId);
|
|
40221
|
+
const savedCreationContext = this.creationContexts[figureId] || {};
|
|
40222
|
+
let newRanges = currentCreationContext?.range;
|
|
40223
|
+
if (newRanges?.every((range, i) => deepEquals(range, savedCreationContext.range?.[i]))) {
|
|
40224
|
+
newRanges = Object.assign([], savedCreationContext.range, currentCreationContext?.range);
|
|
40225
|
+
}
|
|
40226
|
+
this.creationContexts[figureId] = {
|
|
40227
|
+
...savedCreationContext,
|
|
40228
|
+
...currentCreationContext,
|
|
40229
|
+
range: newRanges,
|
|
40107
40230
|
};
|
|
40108
40231
|
const sheetId = this.getters.getFigureSheetId(figureId);
|
|
40109
40232
|
if (!sheetId) {
|
|
@@ -40119,12 +40242,8 @@ class MainChartPanelStore extends SpreadsheetStore {
|
|
|
40119
40242
|
getChartDefinitionFromContextCreation(figureId, newDisplayType) {
|
|
40120
40243
|
const newChartInfo = chartSubtypeRegistry.get(newDisplayType);
|
|
40121
40244
|
const ChartClass = chartRegistry.get(newChartInfo.chartType);
|
|
40122
|
-
const contextCreation = {
|
|
40123
|
-
...this.creationContext,
|
|
40124
|
-
...this.getters.getContextCreationChart(figureId),
|
|
40125
|
-
};
|
|
40126
40245
|
return {
|
|
40127
|
-
...ChartClass.getChartDefinitionFromContextCreation(
|
|
40246
|
+
...ChartClass.getChartDefinitionFromContextCreation(this.creationContexts[figureId]),
|
|
40128
40247
|
...newChartInfo.subtypeDefinition,
|
|
40129
40248
|
};
|
|
40130
40249
|
}
|
|
@@ -40335,6 +40454,10 @@ class ContentEditableHelper {
|
|
|
40335
40454
|
if (currentStart === start && currentEnd === end) {
|
|
40336
40455
|
return;
|
|
40337
40456
|
}
|
|
40457
|
+
if (selection.rangeCount === 0) {
|
|
40458
|
+
const range = document.createRange();
|
|
40459
|
+
selection.addRange(range);
|
|
40460
|
+
}
|
|
40338
40461
|
const currentRange = selection.getRangeAt(0);
|
|
40339
40462
|
let range;
|
|
40340
40463
|
if (this.el.contains(currentRange.startContainer)) {
|
|
@@ -40497,7 +40620,7 @@ class ContentEditableHelper {
|
|
|
40497
40620
|
if (!focusedNode || !this.el.contains(focusedNode))
|
|
40498
40621
|
return;
|
|
40499
40622
|
const element = focusedNode instanceof HTMLElement ? focusedNode : focusedNode.parentElement;
|
|
40500
|
-
element?.scrollIntoView({ block: "nearest" });
|
|
40623
|
+
element?.scrollIntoView?.({ block: "nearest" });
|
|
40501
40624
|
}
|
|
40502
40625
|
/**
|
|
40503
40626
|
* remove the current selection of the user
|
|
@@ -40517,100 +40640,7 @@ class ContentEditableHelper {
|
|
|
40517
40640
|
* finds the indexes of the current selection.
|
|
40518
40641
|
* */
|
|
40519
40642
|
getCurrentSelection() {
|
|
40520
|
-
|
|
40521
|
-
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
40522
|
-
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
40523
|
-
return {
|
|
40524
|
-
start: startSizeBefore,
|
|
40525
|
-
end: endSizeBefore,
|
|
40526
|
-
};
|
|
40527
|
-
}
|
|
40528
|
-
/**
|
|
40529
|
-
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
40530
|
-
* The selected node is either a Text node or an Element node.
|
|
40531
|
-
*
|
|
40532
|
-
* case 1 -Text node:
|
|
40533
|
-
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
40534
|
-
* content length of all previous nodes.
|
|
40535
|
-
*
|
|
40536
|
-
* case 2 - Element node:
|
|
40537
|
-
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
40538
|
-
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
40539
|
-
*
|
|
40540
|
-
* See the MDN documentation for more details.
|
|
40541
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
40542
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
40543
|
-
*
|
|
40544
|
-
*/
|
|
40545
|
-
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
40546
|
-
let usedCharacters = 0;
|
|
40547
|
-
let it = iterateChildren(this.el);
|
|
40548
|
-
let current = it.next();
|
|
40549
|
-
let isFirstParagraph = true;
|
|
40550
|
-
while (!current.done && current.value !== nodeToFind) {
|
|
40551
|
-
if (!current.value.hasChildNodes()) {
|
|
40552
|
-
if (current.value.textContent) {
|
|
40553
|
-
usedCharacters += current.value.textContent.length;
|
|
40554
|
-
}
|
|
40555
|
-
}
|
|
40556
|
-
// One new paragraph = one new line character, except for the first paragraph
|
|
40557
|
-
if (current.value.nodeName === "P" ||
|
|
40558
|
-
(current.value.nodeName === "DIV" && current.value !== this.el) // On paste, the HTML may contain <div> instead of <p>
|
|
40559
|
-
) {
|
|
40560
|
-
if (isFirstParagraph) {
|
|
40561
|
-
isFirstParagraph = false;
|
|
40562
|
-
}
|
|
40563
|
-
else {
|
|
40564
|
-
usedCharacters++;
|
|
40565
|
-
}
|
|
40566
|
-
}
|
|
40567
|
-
current = it.next();
|
|
40568
|
-
}
|
|
40569
|
-
if (current.value !== nodeToFind) {
|
|
40570
|
-
/** This situation can happen if the code is called while the selection is not currently on the ContentEditableHelper.
|
|
40571
|
-
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
40572
|
-
*
|
|
40573
|
-
* A known occurence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
40574
|
-
*
|
|
40575
|
-
* FIXME: find a way to test eventhough the selection API is not available in jsDOM.
|
|
40576
|
-
*/
|
|
40577
|
-
return 0;
|
|
40578
|
-
}
|
|
40579
|
-
else {
|
|
40580
|
-
if (!current.value.hasChildNodes()) {
|
|
40581
|
-
usedCharacters += nodeOffset;
|
|
40582
|
-
}
|
|
40583
|
-
else {
|
|
40584
|
-
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
40585
|
-
usedCharacters += children.reduce((acc, child, index) => {
|
|
40586
|
-
if (child.textContent !== null) {
|
|
40587
|
-
// need to account for paragraph nodes that implicitely add a new line
|
|
40588
|
-
// except for the last paragraph
|
|
40589
|
-
let chars = child.textContent.length;
|
|
40590
|
-
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
40591
|
-
chars++;
|
|
40592
|
-
}
|
|
40593
|
-
return acc + chars;
|
|
40594
|
-
}
|
|
40595
|
-
else {
|
|
40596
|
-
return acc;
|
|
40597
|
-
}
|
|
40598
|
-
}, 0);
|
|
40599
|
-
}
|
|
40600
|
-
}
|
|
40601
|
-
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
40602
|
-
usedCharacters++;
|
|
40603
|
-
}
|
|
40604
|
-
return usedCharacters;
|
|
40605
|
-
}
|
|
40606
|
-
getStartAndEndSelection() {
|
|
40607
|
-
const selection = document.getSelection();
|
|
40608
|
-
return {
|
|
40609
|
-
startElement: selection.anchorNode || this.el,
|
|
40610
|
-
startSelectionOffset: selection.anchorOffset,
|
|
40611
|
-
endElement: selection.focusNode || this.el,
|
|
40612
|
-
endSelectionOffset: selection.focusOffset,
|
|
40613
|
-
};
|
|
40643
|
+
return getCurrentSelection(this.el);
|
|
40614
40644
|
}
|
|
40615
40645
|
getText() {
|
|
40616
40646
|
let text = "";
|
|
@@ -40874,6 +40904,12 @@ class Composer extends owl.Component {
|
|
|
40874
40904
|
}
|
|
40875
40905
|
this.contentHelper.updateEl(el);
|
|
40876
40906
|
});
|
|
40907
|
+
this.env.model.selection.observe(this, {
|
|
40908
|
+
handleEvent: () => this.autoCompleteState.hide(),
|
|
40909
|
+
});
|
|
40910
|
+
owl.onWillUnmount(() => {
|
|
40911
|
+
this.env.model.selection.detachObserver(this);
|
|
40912
|
+
});
|
|
40877
40913
|
owl.useEffect(() => {
|
|
40878
40914
|
this.processContent();
|
|
40879
40915
|
if (document.activeElement === this.contentHelper.el &&
|
|
@@ -49213,7 +49249,7 @@ function isAxisVisible(getters, figure, axis) {
|
|
|
49213
49249
|
axisStartEndPositions.push({ x: axis.position, y: figure.y + figure.height });
|
|
49214
49250
|
break;
|
|
49215
49251
|
}
|
|
49216
|
-
return axisStartEndPositions.some(getters.
|
|
49252
|
+
return axisStartEndPositions.some(getters.isPixelPositionVisible);
|
|
49217
49253
|
}
|
|
49218
49254
|
/**
|
|
49219
49255
|
* Get a snap line for the given figure, if the figure can snap to any other figure
|
|
@@ -51240,8 +51276,8 @@ class GridRenderer {
|
|
|
51240
51276
|
previousColIndex = col;
|
|
51241
51277
|
}
|
|
51242
51278
|
else {
|
|
51243
|
-
nextColIndex = this.findNextEmptyCol(col, right, row);
|
|
51244
|
-
previousColIndex = this.findPreviousEmptyCol(col, left, row);
|
|
51279
|
+
nextColIndex = box.border?.right ? zone.right : this.findNextEmptyCol(col, right, row);
|
|
51280
|
+
previousColIndex = box.border?.left ? zone.left : this.findPreviousEmptyCol(col, left, row);
|
|
51245
51281
|
box.isOverflow = true;
|
|
51246
51282
|
}
|
|
51247
51283
|
switch (align) {
|
|
@@ -52714,7 +52750,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
52714
52750
|
// map and slice preserve empty values and do not set `undefined` instead
|
|
52715
52751
|
const bordersCopy = borders
|
|
52716
52752
|
.slice()
|
|
52717
|
-
.map((col) => col?.slice().map((border) => (
|
|
52753
|
+
.map((col) => col?.slice().map((border) => deepCopy(border)));
|
|
52718
52754
|
this.history.update("borders", cmd.sheetIdTo, bordersCopy);
|
|
52719
52755
|
}
|
|
52720
52756
|
break;
|
|
@@ -52744,32 +52780,12 @@ class BordersPlugin extends CorePlugin {
|
|
|
52744
52780
|
const elements = [...cmd.elements].sort((a, b) => b - a);
|
|
52745
52781
|
for (const group of groupConsecutive(elements)) {
|
|
52746
52782
|
if (cmd.dimension === "COL") {
|
|
52747
|
-
|
|
52748
|
-
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
52749
|
-
this.history.update("borders", cmd.sheetId, group[0] + 1, row, "vertical", undefined);
|
|
52750
|
-
}
|
|
52751
|
-
}
|
|
52752
|
-
if (group[group.length - 1] === 0) {
|
|
52753
|
-
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
52754
|
-
this.history.update("borders", cmd.sheetId, 0, row, "vertical", undefined);
|
|
52755
|
-
}
|
|
52756
|
-
}
|
|
52757
|
-
const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
52783
|
+
const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1], group[0]);
|
|
52758
52784
|
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
52759
52785
|
this.shiftBordersHorizontally(cmd.sheetId, group[0] + 1, -group.length);
|
|
52760
52786
|
}
|
|
52761
52787
|
else {
|
|
52762
|
-
|
|
52763
|
-
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
52764
|
-
this.history.update("borders", cmd.sheetId, col, group[0] + 1, "horizontal", undefined);
|
|
52765
|
-
}
|
|
52766
|
-
}
|
|
52767
|
-
if (group[group.length - 1] === 0) {
|
|
52768
|
-
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
52769
|
-
this.history.update("borders", cmd.sheetId, col, 0, "horizontal", undefined);
|
|
52770
|
-
}
|
|
52771
|
-
}
|
|
52772
|
-
const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
52788
|
+
const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1], group[0]);
|
|
52773
52789
|
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
52774
52790
|
this.shiftBordersVertically(cmd.sheetId, group[0] + 1, -group.length);
|
|
52775
52791
|
}
|
|
@@ -52794,16 +52810,12 @@ class BordersPlugin extends CorePlugin {
|
|
|
52794
52810
|
let colLeftOfInsertion;
|
|
52795
52811
|
let colRightOfInsertion;
|
|
52796
52812
|
if (cmd.position === "before") {
|
|
52797
|
-
this.shiftBordersHorizontally(cmd.sheetId, cmd.base, cmd.quantity
|
|
52798
|
-
moveFirstLeftBorder: true,
|
|
52799
|
-
});
|
|
52813
|
+
this.shiftBordersHorizontally(cmd.sheetId, cmd.base, cmd.quantity);
|
|
52800
52814
|
colLeftOfInsertion = cmd.base - 1;
|
|
52801
52815
|
colRightOfInsertion = cmd.base + cmd.quantity;
|
|
52802
52816
|
}
|
|
52803
52817
|
else {
|
|
52804
|
-
this.shiftBordersHorizontally(cmd.sheetId, cmd.base + 1, cmd.quantity
|
|
52805
|
-
moveFirstLeftBorder: false,
|
|
52806
|
-
});
|
|
52818
|
+
this.shiftBordersHorizontally(cmd.sheetId, cmd.base + 1, cmd.quantity);
|
|
52807
52819
|
colLeftOfInsertion = cmd.base;
|
|
52808
52820
|
colRightOfInsertion = cmd.base + cmd.quantity + 1;
|
|
52809
52821
|
}
|
|
@@ -52818,16 +52830,12 @@ class BordersPlugin extends CorePlugin {
|
|
|
52818
52830
|
let rowAboveInsertion;
|
|
52819
52831
|
let rowBelowInsertion;
|
|
52820
52832
|
if (cmd.position === "before") {
|
|
52821
|
-
this.shiftBordersVertically(cmd.sheetId, cmd.base, cmd.quantity
|
|
52822
|
-
moveFirstTopBorder: true,
|
|
52823
|
-
});
|
|
52833
|
+
this.shiftBordersVertically(cmd.sheetId, cmd.base, cmd.quantity);
|
|
52824
52834
|
rowAboveInsertion = cmd.base - 1;
|
|
52825
52835
|
rowBelowInsertion = cmd.base + cmd.quantity;
|
|
52826
52836
|
}
|
|
52827
52837
|
else {
|
|
52828
|
-
this.shiftBordersVertically(cmd.sheetId, cmd.base + 1, cmd.quantity
|
|
52829
|
-
moveFirstTopBorder: false,
|
|
52830
|
-
});
|
|
52838
|
+
this.shiftBordersVertically(cmd.sheetId, cmd.base + 1, cmd.quantity);
|
|
52831
52839
|
rowAboveInsertion = cmd.base;
|
|
52832
52840
|
rowBelowInsertion = cmd.base + cmd.quantity + 1;
|
|
52833
52841
|
}
|
|
@@ -52837,16 +52845,8 @@ class BordersPlugin extends CorePlugin {
|
|
|
52837
52845
|
// Getters
|
|
52838
52846
|
// ---------------------------------------------------------------------------
|
|
52839
52847
|
getCellBorder({ sheetId, col, row }) {
|
|
52840
|
-
const border =
|
|
52841
|
-
|
|
52842
|
-
bottom: this.borders[sheetId]?.[col]?.[row + 1]?.horizontal,
|
|
52843
|
-
left: this.borders[sheetId]?.[col]?.[row]?.vertical,
|
|
52844
|
-
right: this.borders[sheetId]?.[col + 1]?.[row]?.vertical,
|
|
52845
|
-
};
|
|
52846
|
-
if (!border.bottom && !border.left && !border.right && !border.top) {
|
|
52847
|
-
return null;
|
|
52848
|
-
}
|
|
52849
|
-
return border;
|
|
52848
|
+
const border = this.borders[sheetId]?.[col]?.[row];
|
|
52849
|
+
return border?.top || border?.bottom || border?.left || border?.right ? deepCopy(border) : null;
|
|
52850
52850
|
}
|
|
52851
52851
|
getBordersColors(sheetId) {
|
|
52852
52852
|
const colors = [];
|
|
@@ -52854,11 +52854,13 @@ class BordersPlugin extends CorePlugin {
|
|
|
52854
52854
|
if (sheetBorders) {
|
|
52855
52855
|
for (const borders of sheetBorders.filter(isDefined)) {
|
|
52856
52856
|
for (const cellBorder of borders) {
|
|
52857
|
-
if (cellBorder
|
|
52858
|
-
|
|
52859
|
-
|
|
52860
|
-
|
|
52861
|
-
|
|
52857
|
+
if (cellBorder) {
|
|
52858
|
+
for (const direction of ["top", "bottom", "left", "right"]) {
|
|
52859
|
+
const color = cellBorder[direction]?.color;
|
|
52860
|
+
if (color) {
|
|
52861
|
+
colors.push(color);
|
|
52862
|
+
}
|
|
52863
|
+
}
|
|
52862
52864
|
}
|
|
52863
52865
|
}
|
|
52864
52866
|
}
|
|
@@ -52911,7 +52913,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
52911
52913
|
getCommonSides(border1, border2) {
|
|
52912
52914
|
const commonBorder = {};
|
|
52913
52915
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
52914
|
-
if (border1[side] && border1[side]
|
|
52916
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
52915
52917
|
commonBorder[side] = border1[side];
|
|
52916
52918
|
}
|
|
52917
52919
|
}
|
|
@@ -52956,23 +52958,15 @@ class BordersPlugin extends CorePlugin {
|
|
|
52956
52958
|
* @param start starting column (included)
|
|
52957
52959
|
* @param delta how much borders will be moved (negative if moved to the left)
|
|
52958
52960
|
*/
|
|
52959
|
-
shiftBordersHorizontally(sheetId, start, delta
|
|
52961
|
+
shiftBordersHorizontally(sheetId, start, delta) {
|
|
52960
52962
|
const borders = this.borders[sheetId];
|
|
52961
52963
|
if (!borders)
|
|
52962
52964
|
return;
|
|
52963
|
-
if (delta < 0) {
|
|
52964
|
-
this.moveBordersOfColumn(sheetId, start, delta, "vertical", {
|
|
52965
|
-
destructive: false,
|
|
52966
|
-
});
|
|
52967
|
-
}
|
|
52968
52965
|
this.getColumnsWithBorders(sheetId)
|
|
52969
52966
|
.filter((col) => col >= start)
|
|
52970
52967
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
52971
52968
|
.forEach((col) => {
|
|
52972
|
-
|
|
52973
|
-
this.moveBordersOfColumn(sheetId, col, delta, "vertical");
|
|
52974
|
-
}
|
|
52975
|
-
this.moveBordersOfColumn(sheetId, col, delta, "horizontal");
|
|
52969
|
+
this.moveBordersOfColumn(sheetId, col, delta);
|
|
52976
52970
|
});
|
|
52977
52971
|
}
|
|
52978
52972
|
/**
|
|
@@ -52981,12 +52975,12 @@ class BordersPlugin extends CorePlugin {
|
|
|
52981
52975
|
* @param start starting row (included)
|
|
52982
52976
|
* @param delta how much borders will be moved (negative if moved to the above)
|
|
52983
52977
|
*/
|
|
52984
|
-
shiftBordersVertically(sheetId, start, delta
|
|
52978
|
+
shiftBordersVertically(sheetId, start, delta) {
|
|
52985
52979
|
const borders = this.borders[sheetId];
|
|
52986
52980
|
if (!borders)
|
|
52987
52981
|
return;
|
|
52988
52982
|
if (delta < 0) {
|
|
52989
|
-
this.moveBordersOfRow(sheetId, start, delta,
|
|
52983
|
+
this.moveBordersOfRow(sheetId, start, delta, {
|
|
52990
52984
|
destructive: false,
|
|
52991
52985
|
});
|
|
52992
52986
|
}
|
|
@@ -52994,10 +52988,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
52994
52988
|
.filter((row) => row >= start)
|
|
52995
52989
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
52996
52990
|
.forEach((row) => {
|
|
52997
|
-
|
|
52998
|
-
this.moveBordersOfRow(sheetId, row, delta, "horizontal");
|
|
52999
|
-
}
|
|
53000
|
-
this.moveBordersOfRow(sheetId, row, delta, "vertical");
|
|
52991
|
+
this.moveBordersOfRow(sheetId, row, delta);
|
|
53001
52992
|
});
|
|
53002
52993
|
}
|
|
53003
52994
|
/**
|
|
@@ -53011,15 +53002,15 @@ class BordersPlugin extends CorePlugin {
|
|
|
53011
53002
|
* argument `destructive` is given false, the target border is preserved if
|
|
53012
53003
|
* the moved border is empty
|
|
53013
53004
|
*/
|
|
53014
|
-
moveBordersOfRow(sheetId, row, delta,
|
|
53005
|
+
moveBordersOfRow(sheetId, row, delta, { destructive } = { destructive: true }) {
|
|
53015
53006
|
const borders = this.borders[sheetId];
|
|
53016
53007
|
if (!borders)
|
|
53017
53008
|
return;
|
|
53018
53009
|
this.getColumnsWithBorders(sheetId).forEach((col) => {
|
|
53019
|
-
const targetBorder = borders[col]?.[row + delta]
|
|
53020
|
-
const movedBorder = borders[col]?.[row]
|
|
53021
|
-
this.history.update("borders", sheetId, col, row + delta,
|
|
53022
|
-
this.history.update("borders", sheetId, col, row,
|
|
53010
|
+
const targetBorder = borders[col]?.[row + delta];
|
|
53011
|
+
const movedBorder = borders[col]?.[row];
|
|
53012
|
+
this.history.update("borders", sheetId, col, row + delta, destructive ? movedBorder : movedBorder || targetBorder);
|
|
53013
|
+
this.history.update("borders", sheetId, col, row, undefined);
|
|
53023
53014
|
});
|
|
53024
53015
|
}
|
|
53025
53016
|
/**
|
|
@@ -53033,15 +53024,17 @@ class BordersPlugin extends CorePlugin {
|
|
|
53033
53024
|
* argument `destructive` is given false, the target border is preserved if
|
|
53034
53025
|
* the moved border is empty
|
|
53035
53026
|
*/
|
|
53036
|
-
moveBordersOfColumn(sheetId, col, delta,
|
|
53027
|
+
moveBordersOfColumn(sheetId, col, delta, { destructive } = { destructive: true }) {
|
|
53037
53028
|
const borders = this.borders[sheetId];
|
|
53038
53029
|
if (!borders)
|
|
53039
53030
|
return;
|
|
53040
53031
|
this.getRowsRange(sheetId).forEach((row) => {
|
|
53041
|
-
const targetBorder = borders[col + delta]?.[row]
|
|
53042
|
-
const movedBorder = borders[col]?.[row]
|
|
53043
|
-
this.history.update("borders", sheetId, col + delta, row,
|
|
53044
|
-
|
|
53032
|
+
const targetBorder = borders[col + delta]?.[row];
|
|
53033
|
+
const movedBorder = borders[col]?.[row];
|
|
53034
|
+
this.history.update("borders", sheetId, col + delta, row, destructive ? movedBorder : movedBorder || targetBorder);
|
|
53035
|
+
if (destructive) {
|
|
53036
|
+
this.history.update("borders", sheetId, col, row, undefined);
|
|
53037
|
+
}
|
|
53045
53038
|
});
|
|
53046
53039
|
}
|
|
53047
53040
|
/**
|
|
@@ -53049,33 +53042,69 @@ class BordersPlugin extends CorePlugin {
|
|
|
53049
53042
|
* It overrides the current border if override === true.
|
|
53050
53043
|
*/
|
|
53051
53044
|
setBorder(sheetId, col, row, border, override = true) {
|
|
53052
|
-
|
|
53053
|
-
|
|
53045
|
+
const maxCol = this.getters.getNumberCols(sheetId) - 1;
|
|
53046
|
+
const maxRow = this.getters.getNumberRows(sheetId) - 1;
|
|
53047
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.left) {
|
|
53048
|
+
this.history.update("borders", sheetId, col, row, "left", border?.left);
|
|
53049
|
+
if (border?.left &&
|
|
53050
|
+
col > 0 &&
|
|
53051
|
+
!deepEquals(this.getCellBorder({ sheetId, col: col - 1, row })?.right, border?.left)) {
|
|
53052
|
+
this.history.update("borders", sheetId, col - 1, row, "right", undefined);
|
|
53053
|
+
}
|
|
53054
53054
|
}
|
|
53055
|
-
if (override || !this.borders
|
|
53056
|
-
this.history.update("borders", sheetId, col, row, "
|
|
53055
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.top) {
|
|
53056
|
+
this.history.update("borders", sheetId, col, row, "top", border?.top);
|
|
53057
|
+
if (border?.top &&
|
|
53058
|
+
row > 0 &&
|
|
53059
|
+
!deepEquals(this.getCellBorder({ sheetId, col, row: row - 1 })?.bottom, border?.top)) {
|
|
53060
|
+
this.history.update("borders", sheetId, col, row - 1, "bottom", undefined);
|
|
53061
|
+
}
|
|
53057
53062
|
}
|
|
53058
|
-
if (override || !this.borders
|
|
53059
|
-
this.history.update("borders", sheetId, col
|
|
53063
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.right) {
|
|
53064
|
+
this.history.update("borders", sheetId, col, row, "right", border?.right);
|
|
53065
|
+
if (border?.right &&
|
|
53066
|
+
col < maxCol &&
|
|
53067
|
+
!deepEquals(this.getCellBorder({ sheetId, col: col + 1, row })?.left, border?.right)) {
|
|
53068
|
+
this.history.update("borders", sheetId, col + 1, row, "left", undefined);
|
|
53069
|
+
}
|
|
53060
53070
|
}
|
|
53061
|
-
if (override || !this.borders
|
|
53062
|
-
this.history.update("borders", sheetId, col, row
|
|
53071
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.bottom) {
|
|
53072
|
+
this.history.update("borders", sheetId, col, row, "bottom", border?.bottom);
|
|
53073
|
+
if (border?.bottom &&
|
|
53074
|
+
row < maxRow &&
|
|
53075
|
+
!deepEquals(this.getCellBorder({ sheetId, col, row: row + 1 })?.top, border?.bottom)) {
|
|
53076
|
+
this.history.update("borders", sheetId, col, row + 1, "top", undefined);
|
|
53077
|
+
}
|
|
53063
53078
|
}
|
|
53064
53079
|
}
|
|
53065
53080
|
/**
|
|
53066
53081
|
* Remove the borders of a zone
|
|
53067
53082
|
*/
|
|
53068
|
-
clearBorders(sheetId, zones) {
|
|
53083
|
+
clearBorders(sheetId, zones, eraseBoundaries = false) {
|
|
53084
|
+
const maxCol = this.getters.getNumberCols(sheetId) - 1;
|
|
53085
|
+
const maxRow = this.getters.getNumberRows(sheetId) - 1;
|
|
53069
53086
|
for (let zone of recomputeZones(zones)) {
|
|
53070
53087
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53071
|
-
|
|
53088
|
+
if (eraseBoundaries) {
|
|
53089
|
+
if (zone.left > 0) {
|
|
53090
|
+
this.history.update("borders", sheetId, zone.left - 1, row, "right", undefined);
|
|
53091
|
+
}
|
|
53092
|
+
if (zone.right < maxCol) {
|
|
53093
|
+
this.history.update("borders", sheetId, zone.right + 1, row, "left", undefined);
|
|
53094
|
+
}
|
|
53095
|
+
}
|
|
53072
53096
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53073
53097
|
this.history.update("borders", sheetId, col, row, undefined);
|
|
53098
|
+
if (eraseBoundaries) {
|
|
53099
|
+
if (zone.top > 0) {
|
|
53100
|
+
this.history.update("borders", sheetId, col, zone.top - 1, "bottom", undefined);
|
|
53101
|
+
}
|
|
53102
|
+
if (zone.bottom < maxRow) {
|
|
53103
|
+
this.history.update("borders", sheetId, col, zone.bottom + 1, "top", undefined);
|
|
53104
|
+
}
|
|
53105
|
+
}
|
|
53074
53106
|
}
|
|
53075
53107
|
}
|
|
53076
|
-
for (let col = zone.left; col <= zone.right; col++) {
|
|
53077
|
-
this.history.update("borders", sheetId, col, zone.bottom + 1, "horizontal", undefined);
|
|
53078
|
-
}
|
|
53079
53108
|
}
|
|
53080
53109
|
}
|
|
53081
53110
|
/**
|
|
@@ -53105,41 +53134,63 @@ class BordersPlugin extends CorePlugin {
|
|
|
53105
53134
|
*/
|
|
53106
53135
|
setBorders(sheetId, zones, position, border) {
|
|
53107
53136
|
if (position === "clear") {
|
|
53108
|
-
return this.clearBorders(sheetId, zones);
|
|
53137
|
+
return this.clearBorders(sheetId, zones, true);
|
|
53109
53138
|
}
|
|
53110
53139
|
for (let zone of recomputeZones(zones)) {
|
|
53111
|
-
if (position === "
|
|
53112
|
-
for (let row = zone.top
|
|
53140
|
+
if (position === "all") {
|
|
53141
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53113
53142
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53114
|
-
this.addBorder(sheetId, col, row, {
|
|
53143
|
+
this.addBorder(sheetId, col, row, {
|
|
53144
|
+
top: border,
|
|
53145
|
+
right: border,
|
|
53146
|
+
bottom: border,
|
|
53147
|
+
left: border,
|
|
53148
|
+
});
|
|
53149
|
+
}
|
|
53150
|
+
}
|
|
53151
|
+
}
|
|
53152
|
+
if (position === "h" || position === "hv") {
|
|
53153
|
+
if (zone.top === zone.bottom) {
|
|
53154
|
+
continue;
|
|
53155
|
+
}
|
|
53156
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
53157
|
+
this.addBorder(sheetId, col, zone.top, { bottom: border });
|
|
53158
|
+
for (let row = zone.top + 1; row < zone.bottom; row++) {
|
|
53159
|
+
this.addBorder(sheetId, col, row, { top: border, bottom: border });
|
|
53115
53160
|
}
|
|
53161
|
+
this.addBorder(sheetId, col, zone.bottom, { top: border });
|
|
53116
53162
|
}
|
|
53117
53163
|
}
|
|
53118
|
-
if (position === "v" || position === "hv"
|
|
53164
|
+
if (position === "v" || position === "hv") {
|
|
53165
|
+
if (zone.left === zone.right) {
|
|
53166
|
+
continue;
|
|
53167
|
+
}
|
|
53119
53168
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53120
|
-
|
|
53121
|
-
|
|
53169
|
+
this.addBorder(sheetId, zone.left, row, { right: border });
|
|
53170
|
+
for (let col = zone.left + 1; col < zone.right; col++) {
|
|
53171
|
+
this.addBorder(sheetId, col, row, { left: border, right: border });
|
|
53122
53172
|
}
|
|
53173
|
+
this.addBorder(sheetId, zone.right, row, { left: border });
|
|
53123
53174
|
}
|
|
53124
53175
|
}
|
|
53125
|
-
if (position === "left" || position === "
|
|
53176
|
+
if (position === "left" || position === "external") {
|
|
53126
53177
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53127
53178
|
this.addBorder(sheetId, zone.left, row, { left: border });
|
|
53128
53179
|
}
|
|
53129
53180
|
}
|
|
53130
|
-
if (position === "right" || position === "
|
|
53181
|
+
if (position === "right" || position === "external") {
|
|
53131
53182
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53132
|
-
this.addBorder(sheetId, zone.right
|
|
53183
|
+
this.addBorder(sheetId, zone.right, row, { right: border });
|
|
53133
53184
|
}
|
|
53134
53185
|
}
|
|
53135
|
-
if (position === "top" || position === "
|
|
53186
|
+
if (position === "top" || position === "external") {
|
|
53136
53187
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53137
53188
|
this.addBorder(sheetId, col, zone.top, { top: border });
|
|
53138
53189
|
}
|
|
53139
53190
|
}
|
|
53140
|
-
if (position === "bottom" || position === "
|
|
53191
|
+
if (position === "bottom" || position === "external") {
|
|
53141
53192
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53142
|
-
this.addBorder(sheetId, col, zone.bottom
|
|
53193
|
+
this.addBorder(sheetId, col, zone.bottom, { bottom: border });
|
|
53143
53194
|
}
|
|
53144
53195
|
}
|
|
53145
53196
|
}
|
|
@@ -54685,10 +54736,20 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54685
54736
|
for (const sheet of data.sheets) {
|
|
54686
54737
|
sheet.dataValidationRules = [];
|
|
54687
54738
|
for (const rule of this.rules[sheet.id]) {
|
|
54688
|
-
|
|
54689
|
-
...rule,
|
|
54739
|
+
const excelRule = {
|
|
54740
|
+
...deepCopy(rule),
|
|
54690
54741
|
ranges: rule.ranges.map((range) => this.getters.getRangeString(range, sheet.id, { useBoundedReference: true })),
|
|
54691
|
-
}
|
|
54742
|
+
};
|
|
54743
|
+
if (rule.criterion.type === "isValueInRange") {
|
|
54744
|
+
excelRule.criterion.values = rule.criterion.values.map((value) => {
|
|
54745
|
+
const range = this.getters.getRangeFromSheetXC(sheet.id, value);
|
|
54746
|
+
return this.getters.getRangeString(range, sheet.id, {
|
|
54747
|
+
useBoundedReference: true,
|
|
54748
|
+
useFixedReference: true,
|
|
54749
|
+
});
|
|
54750
|
+
});
|
|
54751
|
+
}
|
|
54752
|
+
sheet.dataValidationRules.push(excelRule);
|
|
54692
54753
|
}
|
|
54693
54754
|
}
|
|
54694
54755
|
}
|
|
@@ -56109,9 +56170,10 @@ class RangeAdapter {
|
|
|
56109
56170
|
* @param range the range (received from getRangeFromXC or getRangeFromZone)
|
|
56110
56171
|
* @param forSheetId the id of the sheet where the range string is supposed to be used.
|
|
56111
56172
|
* @param options
|
|
56112
|
-
* @param options.useBoundedReference if true, the range will be returned with
|
|
56173
|
+
* @param options.useBoundedReference if true, the range will be returned with bounded row and column
|
|
56174
|
+
* @param options.useFixedReference if true, the range will be returned with fixed row and column
|
|
56113
56175
|
*/
|
|
56114
|
-
getRangeString(range, forSheetId, options = { useBoundedReference: false }) {
|
|
56176
|
+
getRangeString(range, forSheetId, options = { useBoundedReference: false, useFixedReference: false }) {
|
|
56115
56177
|
if (!range) {
|
|
56116
56178
|
return CellErrorType.InvalidReference;
|
|
56117
56179
|
}
|
|
@@ -56214,10 +56276,10 @@ class RangeAdapter {
|
|
|
56214
56276
|
/**
|
|
56215
56277
|
* Get a Xc string that represent a part of a range
|
|
56216
56278
|
*/
|
|
56217
|
-
getRangePartString(range, part, options = { useBoundedReference: false }) {
|
|
56218
|
-
const colFixed = range.parts
|
|
56279
|
+
getRangePartString(range, part, options = { useBoundedReference: false, useFixedReference: false }) {
|
|
56280
|
+
const colFixed = range.parts[part]?.colFixed || options.useFixedReference ? "$" : "";
|
|
56219
56281
|
const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
|
|
56220
|
-
const rowFixed = range.parts
|
|
56282
|
+
const rowFixed = range.parts[part]?.rowFixed || options.useFixedReference ? "$" : "";
|
|
56221
56283
|
const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
|
|
56222
56284
|
let str = "";
|
|
56223
56285
|
if (range.isFullCol && !options.useBoundedReference) {
|
|
@@ -59873,7 +59935,11 @@ class Evaluator {
|
|
|
59873
59935
|
computeFormulaCell(formulaPosition, cellData) {
|
|
59874
59936
|
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, formulaPosition.sheetId, this.buildSafeGetSymbolValue(), formulaPosition);
|
|
59875
59937
|
if (!isMatrix(formulaReturn)) {
|
|
59876
|
-
|
|
59938
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData);
|
|
59939
|
+
if (evaluatedCell.type === CellValueType.error) {
|
|
59940
|
+
evaluatedCell.errorOriginPosition = formulaReturn.errorOriginPosition ?? formulaPosition;
|
|
59941
|
+
}
|
|
59942
|
+
return evaluatedCell;
|
|
59877
59943
|
}
|
|
59878
59944
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
59879
59945
|
const nbColumns = formulaReturn.length;
|
|
@@ -59946,6 +60012,9 @@ class Evaluator {
|
|
|
59946
60012
|
const position = { sheetId, col: i + col, row: j + row };
|
|
59947
60013
|
const cell = this.getters.getCell(position);
|
|
59948
60014
|
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
60015
|
+
if (evaluatedCell.type === CellValueType.error) {
|
|
60016
|
+
evaluatedCell.errorOriginPosition = matrixResult[i][j].errorOriginPosition ?? position;
|
|
60017
|
+
}
|
|
59949
60018
|
this.evaluatedCells.set(position, evaluatedCell);
|
|
59950
60019
|
};
|
|
59951
60020
|
return spreadValues;
|
|
@@ -61504,7 +61573,7 @@ function withPivotPresentationLayer (PivotClass) {
|
|
|
61504
61573
|
const symbolIndex = rowDomain.findIndex((row) => row.field === symbolName);
|
|
61505
61574
|
return this.getPivotHeaderValueAndFormat(rowDomain.slice(0, symbolIndex + 1));
|
|
61506
61575
|
}
|
|
61507
|
-
return this.
|
|
61576
|
+
return this.getPivotCellValueAndFormat(symbolName, domain);
|
|
61508
61577
|
};
|
|
61509
61578
|
const result = this.getters.evaluateCompiledFormula(measure.computedBy.sheetId, formula, getSymbolValue);
|
|
61510
61579
|
if (isMatrix(result)) {
|
|
@@ -63403,6 +63472,7 @@ class Session extends EventBus {
|
|
|
63403
63472
|
waitingUndoRedoAck = false;
|
|
63404
63473
|
isReplayingInitialRevisions = false;
|
|
63405
63474
|
processedRevisions = new Set();
|
|
63475
|
+
lastRevisionMessage = undefined;
|
|
63406
63476
|
uuidGenerator = new UuidGenerator();
|
|
63407
63477
|
lastLocalOperation;
|
|
63408
63478
|
/**
|
|
@@ -63503,7 +63573,10 @@ class Session extends EventBus {
|
|
|
63503
63573
|
* Notify the server that the user client left the collaborative session
|
|
63504
63574
|
*/
|
|
63505
63575
|
async leave(data) {
|
|
63506
|
-
if (data &&
|
|
63576
|
+
if (data &&
|
|
63577
|
+
Object.keys(this.clients).length === 1 &&
|
|
63578
|
+
this.lastRevisionMessage &&
|
|
63579
|
+
this.lastRevisionMessage?.type !== "SNAPSHOT_CREATED") {
|
|
63507
63580
|
await this.snapshot(data());
|
|
63508
63581
|
}
|
|
63509
63582
|
delete this.clients[this.clientId];
|
|
@@ -63724,6 +63797,7 @@ class Session extends EventBus {
|
|
|
63724
63797
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
63725
63798
|
this.serverRevisionId = message.nextRevisionId;
|
|
63726
63799
|
this.processedRevisions.add(message.nextRevisionId);
|
|
63800
|
+
this.lastRevisionMessage = message;
|
|
63727
63801
|
this.sendPendingMessage();
|
|
63728
63802
|
break;
|
|
63729
63803
|
}
|
|
@@ -64685,14 +64759,12 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
64685
64759
|
}
|
|
64686
64760
|
break;
|
|
64687
64761
|
case "AUTORESIZE_ROWS":
|
|
64688
|
-
|
|
64689
|
-
|
|
64690
|
-
|
|
64691
|
-
|
|
64692
|
-
|
|
64693
|
-
|
|
64694
|
-
});
|
|
64695
|
-
}
|
|
64762
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
64763
|
+
elements: cmd.rows,
|
|
64764
|
+
dimension: "ROW",
|
|
64765
|
+
size: null,
|
|
64766
|
+
sheetId: cmd.sheetId,
|
|
64767
|
+
});
|
|
64696
64768
|
break;
|
|
64697
64769
|
}
|
|
64698
64770
|
}
|
|
@@ -67443,7 +67515,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67443
67515
|
"getSheetViewVisibleCols",
|
|
67444
67516
|
"getSheetViewVisibleRows",
|
|
67445
67517
|
"getFrozenSheetViewRatio",
|
|
67446
|
-
"
|
|
67518
|
+
"isPixelPositionVisible",
|
|
67447
67519
|
"getColDimensionsInViewport",
|
|
67448
67520
|
"getRowDimensionsInViewport",
|
|
67449
67521
|
"getAllActiveViewportsZones",
|
|
@@ -68067,7 +68139,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68067
68139
|
}
|
|
68068
68140
|
return result;
|
|
68069
68141
|
}
|
|
68070
|
-
|
|
68142
|
+
isPixelPositionVisible(position) {
|
|
68071
68143
|
const { scrollX, scrollY } = this.getters.getActiveSheetScrollInfo();
|
|
68072
68144
|
const { x: mainViewportX, y: mainViewportY } = this.getters.getMainViewportCoordinates();
|
|
68073
68145
|
const { width, height } = this.getters.getSheetViewDimension();
|
|
@@ -70462,12 +70534,8 @@ css /* scss */ `
|
|
|
70462
70534
|
.o-spreadsheet {
|
|
70463
70535
|
position: relative;
|
|
70464
70536
|
display: grid;
|
|
70465
|
-
color: ${TEXT_BODY};
|
|
70466
70537
|
font-size: 14px;
|
|
70467
70538
|
|
|
70468
|
-
input {
|
|
70469
|
-
background-color: white;
|
|
70470
|
-
}
|
|
70471
70539
|
.text-muted {
|
|
70472
70540
|
color: ${TEXT_BODY_MUTED} !important;
|
|
70473
70541
|
}
|
|
@@ -71714,6 +71782,9 @@ class EventStream {
|
|
|
71714
71782
|
observe(owner, callbacks) {
|
|
71715
71783
|
this.observers.set(owner, { owner, callbacks });
|
|
71716
71784
|
}
|
|
71785
|
+
detachObserver(owner) {
|
|
71786
|
+
this.observers.delete(owner);
|
|
71787
|
+
}
|
|
71717
71788
|
/**
|
|
71718
71789
|
* Capture the stream for yourself
|
|
71719
71790
|
*/
|
|
@@ -71806,6 +71877,9 @@ class SelectionStreamProcessorImpl {
|
|
|
71806
71877
|
observe(owner, callbacks) {
|
|
71807
71878
|
this.stream.observe(owner, callbacks);
|
|
71808
71879
|
}
|
|
71880
|
+
detachObserver(owner) {
|
|
71881
|
+
this.stream.detachObserver(owner);
|
|
71882
|
+
}
|
|
71809
71883
|
release(owner) {
|
|
71810
71884
|
if (this.stream.isListening(owner)) {
|
|
71811
71885
|
this.stream.release(owner);
|
|
@@ -75255,6 +75329,6 @@ exports.tokenColors = tokenColors;
|
|
|
75255
75329
|
exports.tokenize = tokenize;
|
|
75256
75330
|
|
|
75257
75331
|
|
|
75258
|
-
__info__.version = "18.2.0-alpha.
|
|
75259
|
-
__info__.date = "2025-01-
|
|
75260
|
-
__info__.hash = "
|
|
75332
|
+
__info__.version = "18.2.0-alpha.5";
|
|
75333
|
+
__info__.date = "2025-01-31T07:59:30.667Z";
|
|
75334
|
+
__info__.hash = "efce841";
|