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