[FIX] spreadsheet: update o_spreadsheet to latest version
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/7346d0af9 [REL] 17.0.4 https://github.com/odoo/o-spreadsheet/commit/661e290f4 [FIX] sheet: remove zombie code https://github.com/odoo/o-spreadsheet/commit/7362fc105 [FIX] sheet: remove rows faster https://github.com/odoo/o-spreadsheet/commit/dcaa1ab0c [FIX] tokenizer: faster current char lookup https://github.com/odoo/o-spreadsheet/commit/0448b26f5 [FIX] tokenize: replace special chars faster https://github.com/odoo/o-spreadsheet/commit/88a57c6be [FIX] icons: use correct comment syntax in xml files https://github.com/odoo/o-spreadsheet/commit/cf8194df2 [FIX] clipboard: fix array formula copy https://github.com/odoo/o-spreadsheet/commit/ca24d7e8c [FIX] evaluation: faster range matrix https://github.com/odoo/o-spreadsheet/commit/a13ff80b3 [FIX] clipboard: traceback on paste from copy after deleting that sheet https://github.com/odoo/o-spreadsheet/commit/eaa0dca12 [FIX] evaluation: cache range references values Task: 3588401 https://github.com/odoo/o-spreadsheet/commit/cdeb716c3 [REF] evaluation: group compilation parameters https://github.com/odoo/o-spreadsheet/commit/943a7e7f8 [FIX] lookup: cache string normalization Task: 3588401 https://github.com/odoo/o-spreadsheet/commit/0330db03c [FIX] cells,borders: cancel useless commands Task: 3603259 https://github.com/odoo/o-spreadsheet/commit/38d77fe89 [FIX] cells: faster getter to get cell Task: 3588401 https://github.com/odoo/o-spreadsheet/commit/15bdafc80 [FIX] model: don't flatten command result closes odoo/odoo#143587 Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
||||
* @see https://github.com/odoo/o-spreadsheet
|
||||
* @version 17.0.3
|
||||
* @date 2023-11-16T13:27:10.083Z
|
||||
* @hash 8bd0fb2b4
|
||||
* @version 17.0.4
|
||||
* @date 2023-11-24T13:28:06.767Z
|
||||
* @hash 7346d0af9
|
||||
*/
|
||||
|
||||
(function (exports, owl) {
|
||||
@@ -692,8 +692,7 @@
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
||||
*/
|
||||
const whiteSpaceCharacters = [
|
||||
" ",
|
||||
const whiteSpaceSpecialCharacters = [
|
||||
"\t",
|
||||
"\f",
|
||||
"\v",
|
||||
@@ -708,8 +707,7 @@
|
||||
String.fromCharCode(parseInt("3000", 16)),
|
||||
String.fromCharCode(parseInt("feff", 16)),
|
||||
];
|
||||
const whiteSpaceRegexp = new RegExp(whiteSpaceCharacters.join("|"), "g");
|
||||
const newLineRegex = /\r\n|\r|\n/g;
|
||||
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
||||
/**
|
||||
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
||||
* different newlines types by \n.
|
||||
@@ -717,9 +715,9 @@
|
||||
function replaceSpecialSpaces(text) {
|
||||
if (!text)
|
||||
return "";
|
||||
text = text.replace(whiteSpaceRegexp, " ");
|
||||
text = text.replace(newLineRegex, NEWLINE);
|
||||
return text;
|
||||
if (!whiteSpaceRegexp.test(text))
|
||||
return text;
|
||||
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
||||
}
|
||||
/**
|
||||
* Determine if the numbers are consecutive.
|
||||
@@ -2061,6 +2059,7 @@
|
||||
CommandResult["InvalidNumberOfCriterionValues"] = "InvalidNumberOfCriterionValues";
|
||||
CommandResult["BlockingValidationRule"] = "BlockingValidationRule";
|
||||
CommandResult["InvalidCopyPasteSelection"] = "InvalidCopyPasteSelection";
|
||||
CommandResult["NoChanges"] = "NoChanges";
|
||||
})(exports.CommandResult || (exports.CommandResult = {}));
|
||||
|
||||
const DEFAULT_LOCALES = [
|
||||
@@ -2190,12 +2189,12 @@
|
||||
}
|
||||
}
|
||||
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
||||
function normalizeString(str) {
|
||||
const normalizeString = memoize(function normalizeString(str) {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "");
|
||||
}
|
||||
});
|
||||
const expectBooleanValueError = (value) => _t("The function [[FUNCTION_NAME]] expects a boolean value, but '%s' is a text, and cannot be coerced to a number.", value);
|
||||
function toBoolean(value) {
|
||||
switch (typeof value) {
|
||||
@@ -7330,7 +7329,7 @@
|
||||
return result;
|
||||
}
|
||||
function tokenizeDebugger(chars) {
|
||||
if (chars.current() === "?") {
|
||||
if (chars.current === "?") {
|
||||
chars.shift();
|
||||
return { type: "DEBUGGER", value: "?" };
|
||||
}
|
||||
@@ -7341,7 +7340,7 @@
|
||||
")": "RIGHT_PAREN",
|
||||
};
|
||||
function tokenizeMisc(chars) {
|
||||
if (chars.current() in misc$1) {
|
||||
if (chars.current in misc$1) {
|
||||
const value = chars.shift();
|
||||
const type = misc$1[value];
|
||||
return { type, value };
|
||||
@@ -7349,7 +7348,7 @@
|
||||
return null;
|
||||
}
|
||||
function tokenizeArgsSeparator(chars, locale) {
|
||||
if (chars.current() === locale.formulaArgSeparator) {
|
||||
if (chars.current === locale.formulaArgSeparator) {
|
||||
const value = chars.shift();
|
||||
const type = "ARG_SEPARATOR";
|
||||
return { type, value };
|
||||
@@ -7374,14 +7373,13 @@
|
||||
return null;
|
||||
}
|
||||
function tokenizeString(chars) {
|
||||
if (chars.current() === '"') {
|
||||
if (chars.current === '"') {
|
||||
const startChar = chars.shift();
|
||||
let letters = startChar;
|
||||
while (chars.current() &&
|
||||
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
||||
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
||||
letters += chars.shift();
|
||||
}
|
||||
if (chars.current() === '"') {
|
||||
if (chars.current === '"') {
|
||||
letters += chars.shift();
|
||||
}
|
||||
return {
|
||||
@@ -7408,14 +7406,14 @@
|
||||
let result = "";
|
||||
// there are two main cases to manage: either something which starts with
|
||||
// a ', like 'Sheet 2'A2, or a word-like element.
|
||||
if (chars.current() === "'") {
|
||||
if (chars.current === "'") {
|
||||
let lastChar = chars.shift();
|
||||
result += lastChar;
|
||||
while (chars.current()) {
|
||||
while (chars.current) {
|
||||
lastChar = chars.shift();
|
||||
result += lastChar;
|
||||
if (lastChar === "'") {
|
||||
if (chars.current() && chars.current() === "'") {
|
||||
if (chars.current && chars.current === "'") {
|
||||
lastChar = chars.shift();
|
||||
result += lastChar;
|
||||
}
|
||||
@@ -7431,7 +7429,7 @@
|
||||
};
|
||||
}
|
||||
}
|
||||
while (chars.current() && separatorRegexp.test(chars.current())) {
|
||||
while (chars.current && separatorRegexp.test(chars.current)) {
|
||||
result += chars.shift();
|
||||
}
|
||||
if (result.length) {
|
||||
@@ -7446,14 +7444,14 @@
|
||||
}
|
||||
function tokenizeSpace(chars) {
|
||||
let length = 0;
|
||||
while (chars.current() === NEWLINE) {
|
||||
while (chars.current === NEWLINE) {
|
||||
length++;
|
||||
chars.shift();
|
||||
}
|
||||
if (length) {
|
||||
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
||||
}
|
||||
while (chars.current() === " ") {
|
||||
while (chars.current === " ") {
|
||||
length++;
|
||||
chars.shift();
|
||||
}
|
||||
@@ -7472,17 +7470,20 @@
|
||||
class TokenizingChars {
|
||||
text;
|
||||
currentIndex = 0;
|
||||
current;
|
||||
constructor(text) {
|
||||
this.text = text;
|
||||
}
|
||||
current() {
|
||||
return this.text[this.currentIndex];
|
||||
this.current = text[0];
|
||||
}
|
||||
shift() {
|
||||
return this.text[this.currentIndex++];
|
||||
const current = this.current;
|
||||
const next = this.text[++this.currentIndex];
|
||||
this.current = next;
|
||||
return current;
|
||||
}
|
||||
advanceBy(length) {
|
||||
this.currentIndex += length;
|
||||
this.current = this.text[this.currentIndex];
|
||||
}
|
||||
isOver() {
|
||||
return this.currentIndex >= this.text.length;
|
||||
@@ -29758,6 +29759,7 @@
|
||||
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
||||
const target = this.env.model.getters.getSelectedZones();
|
||||
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
||||
const isCutOperation = this.env.model.getters.isCutOperation();
|
||||
if (clipboardString === content) {
|
||||
// the paste actually comes from o-spreadsheet itself
|
||||
interactivePaste(this.env, target);
|
||||
@@ -29765,7 +29767,7 @@
|
||||
else {
|
||||
interactivePasteFromOS(this.env, target, content);
|
||||
}
|
||||
if (this.env.model.getters.isCutOperation()) {
|
||||
if (isCutOperation) {
|
||||
await this.env.clipboard.write({ [ClipboardMIMEType.PlainText]: "" });
|
||||
}
|
||||
}
|
||||
@@ -34059,6 +34061,14 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Command Handling
|
||||
// ---------------------------------------------------------------------------
|
||||
allowDispatch(cmd) {
|
||||
switch (cmd.type) {
|
||||
case "SET_BORDER":
|
||||
return this.checkBordersUnchanged(cmd);
|
||||
default:
|
||||
return "Success" /* CommandResult.Success */;
|
||||
}
|
||||
}
|
||||
handle(cmd) {
|
||||
switch (cmd.type) {
|
||||
case "ADD_MERGE":
|
||||
@@ -34478,6 +34488,14 @@
|
||||
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
||||
}
|
||||
}
|
||||
checkBordersUnchanged(cmd) {
|
||||
const currentBorder = this.getCellBorder(cmd);
|
||||
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
||||
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
||||
return "NoChanges" /* CommandResult.NoChanges */;
|
||||
}
|
||||
return "Success" /* CommandResult.Success */;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Import/Export
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -35333,8 +35351,9 @@
|
||||
allowDispatch(cmd) {
|
||||
switch (cmd.type) {
|
||||
case "UPDATE_CELL":
|
||||
return this.checkCellOutOfSheet(cmd);
|
||||
case "CLEAR_CELL":
|
||||
return this.checkCellOutOfSheet(cmd.sheetId, cmd.col, cmd.row);
|
||||
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
||||
default:
|
||||
return "Success" /* CommandResult.Success */;
|
||||
}
|
||||
@@ -35503,14 +35522,9 @@
|
||||
*/
|
||||
getCellById(cellId) {
|
||||
// this must be as fast as possible
|
||||
for (const sheetId in this.cells) {
|
||||
const sheet = this.cells[sheetId];
|
||||
const cell = sheet[cellId];
|
||||
if (cell) {
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
const position = this.getters.getCellPosition(cellId);
|
||||
const sheet = this.cells[position.sheetId];
|
||||
return sheet[cellId];
|
||||
}
|
||||
/*
|
||||
* Reconstructs the original formula string based on a normalized form and its dependencies
|
||||
@@ -35741,13 +35755,23 @@
|
||||
},
|
||||
};
|
||||
}
|
||||
checkCellOutOfSheet(sheetId, col, row) {
|
||||
checkCellOutOfSheet(cmd) {
|
||||
const { sheetId, col, row } = cmd;
|
||||
const sheet = this.getters.tryGetSheet(sheetId);
|
||||
if (!sheet)
|
||||
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
||||
const sheetZone = this.getters.getSheetZone(sheetId);
|
||||
return isInside(col, row, sheetZone) ? "Success" /* CommandResult.Success */ : "TargetOutOfSheet" /* CommandResult.TargetOutOfSheet */;
|
||||
}
|
||||
checkUselessClearCell(cmd) {
|
||||
const cell = this.getters.getCell(cmd);
|
||||
if (!cell)
|
||||
return "NoChanges" /* CommandResult.NoChanges */;
|
||||
if (!cell.content && !cell.style && !cell.format) {
|
||||
return "NoChanges" /* CommandResult.NoChanges */;
|
||||
}
|
||||
return "Success" /* CommandResult.Success */;
|
||||
}
|
||||
}
|
||||
class FormulaCellWithDependencies {
|
||||
id;
|
||||
@@ -36437,6 +36461,9 @@
|
||||
return this.rules[sheetId].find((rule) => rule.id === id);
|
||||
}
|
||||
getValidationRuleForCell({ sheetId, col, row }) {
|
||||
if (!this.rules[sheetId]) {
|
||||
return undefined;
|
||||
}
|
||||
for (const rule of this.rules[sheetId]) {
|
||||
for (const range of rule.ranges) {
|
||||
if (isInside(col, row, range.zone)) {
|
||||
@@ -39034,10 +39061,13 @@
|
||||
// begin with the end.
|
||||
rows.sort((a, b) => b - a);
|
||||
for (let group of groupConsecutive(rows)) {
|
||||
// indexes are sorted in the descending order
|
||||
const from = group[group.length - 1];
|
||||
const to = group[0];
|
||||
// Move the cells.
|
||||
this.moveCellOnRowsDeletion(sheet, group[group.length - 1], group[0]);
|
||||
// Effectively delete the element and recompute the left-right/top-bottom.
|
||||
group.map((row) => this.updateRowsStructureOnDeletion(row, sheet));
|
||||
this.moveCellOnRowsDeletion(sheet, from, to);
|
||||
// Effectively delete the rows
|
||||
this.updateRowsStructureOnDeletion(sheet, from, to);
|
||||
}
|
||||
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
||||
if (count) {
|
||||
@@ -39059,8 +39089,6 @@
|
||||
this.addEmptyRows(sheet, quantity);
|
||||
// Move the cells.
|
||||
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
||||
// Recompute the left-right/top-bottom.
|
||||
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
||||
if (index < sheet.panes.ySplit) {
|
||||
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
||||
}
|
||||
@@ -39161,35 +39189,20 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
updateRowsStructureOnDeletion(index, sheet) {
|
||||
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
||||
const rows = [];
|
||||
const cellsQueue = sheet.rows.map((row) => row.cells);
|
||||
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
||||
for (let i in sheet.rows) {
|
||||
if (Number(i) === index) {
|
||||
const row = Number(i);
|
||||
if (row >= deleteFromRow && row <= deleteToRow) {
|
||||
continue;
|
||||
}
|
||||
rows.push({
|
||||
cells: cellsQueue.shift(),
|
||||
cells: cellsQueue.pop(),
|
||||
});
|
||||
}
|
||||
this.history.update("sheets", sheet.id, "rows", rows);
|
||||
}
|
||||
/**
|
||||
* Update the rows of the sheet after an addition:
|
||||
* - Rename the rows
|
||||
*
|
||||
* @param sheet Sheet on which the deletion occurs
|
||||
* @param addedRow Index of the added row
|
||||
* @param rowsToAdd Number of the rows to add
|
||||
*/
|
||||
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
||||
const rows = [];
|
||||
const cellsQueue = sheet.rows.map((row) => row.cells);
|
||||
sheet.rows.forEach(() => rows.push({
|
||||
cells: cellsQueue.shift(),
|
||||
}));
|
||||
this.history.update("sheets", sheet.id, "rows", rows);
|
||||
}
|
||||
/**
|
||||
* Add empty rows at the end of the rows
|
||||
*
|
||||
@@ -39716,6 +39729,7 @@
|
||||
getters;
|
||||
computeCell;
|
||||
evalContext;
|
||||
rangeCache = {};
|
||||
constructor(context, getters, computeCell) {
|
||||
this.getters = getters;
|
||||
this.computeCell = computeCell;
|
||||
@@ -39801,17 +39815,24 @@
|
||||
if (!_zone) {
|
||||
return [[]];
|
||||
}
|
||||
const { top, left, bottom, right } = zone;
|
||||
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
||||
if (cacheKey in this.rangeCache) {
|
||||
return this.rangeCache[cacheKey];
|
||||
}
|
||||
const height = _zone.bottom - _zone.top + 1;
|
||||
const width = _zone.right - _zone.left + 1;
|
||||
const matrix = Array.from({ length: width }, () => Array.from({ length: height }));
|
||||
const matrix = new Array(width);
|
||||
// Performance issue: nested loop is faster than a map here
|
||||
for (let col = _zone.left; col <= _zone.right; col++) {
|
||||
const colIndex = col - _zone.left;
|
||||
matrix[colIndex] = new Array(height);
|
||||
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
||||
const colIndex = col - _zone.left;
|
||||
const rowIndex = row - _zone.top;
|
||||
matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
|
||||
}
|
||||
}
|
||||
this.rangeCache[cacheKey] = matrix;
|
||||
return matrix;
|
||||
}
|
||||
}
|
||||
@@ -40017,6 +40038,7 @@
|
||||
this.formulaDependencies().addDependencies(positionId, dependencies);
|
||||
}
|
||||
updateCompilationParameters() {
|
||||
// rebuild the compilation parameters (with a clean cache)
|
||||
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
||||
}
|
||||
evaluateCells(positions) {
|
||||
@@ -40060,6 +40082,16 @@
|
||||
this.evaluatedCells = new Map();
|
||||
this.evaluate(this.getAllCells());
|
||||
}
|
||||
evaluateFormula(sheetId, formulaString) {
|
||||
const compiledFormula = compile(formulaString);
|
||||
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
||||
this.updateCompilationParameters();
|
||||
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
||||
if (isMatrix(array)) {
|
||||
return matrixMap(array, (cell) => cell.value);
|
||||
}
|
||||
return array.value;
|
||||
}
|
||||
getAllCells() {
|
||||
const positionIds = new JetSet();
|
||||
for (const sheetId of this.getters.getSheetIds()) {
|
||||
@@ -40086,6 +40118,7 @@
|
||||
this.nextPositionsToUpdate = cells;
|
||||
let currentIteration = 0;
|
||||
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
||||
this.updateCompilationParameters();
|
||||
const positionIds = Array.from(this.nextPositionsToUpdate);
|
||||
this.nextPositionsToUpdate.clear();
|
||||
for (let i = 0; i < positionIds.length; ++i) {
|
||||
@@ -40449,7 +40482,6 @@
|
||||
// of other cells depending on it, at the next iteration.
|
||||
//#endregion
|
||||
class EvaluationPlugin extends UIPlugin {
|
||||
config;
|
||||
static getters = [
|
||||
"evaluateFormula",
|
||||
"getCorrespondingFormulaCell",
|
||||
@@ -40460,15 +40492,13 @@
|
||||
"getEvaluatedCells",
|
||||
"getEvaluatedCellsInZone",
|
||||
"getSpreadPositionsOf",
|
||||
"getArrayFormulaSpreadingOn",
|
||||
];
|
||||
shouldRebuildDependenciesGraph = true;
|
||||
evaluator;
|
||||
compilationParams;
|
||||
positionsToUpdate = [];
|
||||
constructor(config) {
|
||||
super(config);
|
||||
this.config = config;
|
||||
this.compilationParams = this.getCompilationParameters();
|
||||
this.evaluator = new Evaluator(config.custom, this.getters);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -40493,10 +40523,6 @@
|
||||
case "EVALUATE_CELLS":
|
||||
this.evaluator.evaluateAllCells();
|
||||
break;
|
||||
case "UPDATE_LOCALE":
|
||||
this.compilationParams = this.getCompilationParameters();
|
||||
this.evaluator.updateCompilationParameters();
|
||||
break;
|
||||
}
|
||||
}
|
||||
finalize() {
|
||||
@@ -40514,16 +40540,7 @@
|
||||
// Getters
|
||||
// ---------------------------------------------------------------------------
|
||||
evaluateFormula(sheetId, formulaString) {
|
||||
const compiledFormula = compile(formulaString);
|
||||
const ranges = [];
|
||||
for (let xc of compiledFormula.dependencies) {
|
||||
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
||||
}
|
||||
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
||||
if (isMatrix(array)) {
|
||||
return array.map((col) => col.map((row) => row.value));
|
||||
}
|
||||
return array.value;
|
||||
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
||||
}
|
||||
/**
|
||||
* Return the value of each cell in the range as they are displayed in the grid.
|
||||
@@ -40572,6 +40589,9 @@
|
||||
getSpreadPositionsOf(position) {
|
||||
return this.evaluator.getSpreadPositionsOf(position);
|
||||
}
|
||||
getArrayFormulaSpreadingOn(position) {
|
||||
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Export
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -40615,7 +40635,7 @@
|
||||
else if (cell && cell.content) {
|
||||
return undefined;
|
||||
}
|
||||
const spreadingFormulaPosition = this.evaluator.getArrayFormulaSpreadingOn(position);
|
||||
const spreadingFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
||||
if (spreadingFormulaPosition === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -40625,9 +40645,6 @@
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
getCompilationParameters() {
|
||||
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
||||
}
|
||||
}
|
||||
function isBadExpression(tokens) {
|
||||
try {
|
||||
@@ -43326,11 +43343,26 @@
|
||||
let cellsInRow = [];
|
||||
for (let col of columnsIndex) {
|
||||
const position = { col, row, sheetId };
|
||||
const spreader = getters.getArrayFormulaSpreadingOn(position);
|
||||
let cell = getters.getCell(position);
|
||||
const evaluatedCell = getters.getEvaluatedCell(position);
|
||||
if (spreader) {
|
||||
const isSpreaderCopied = rowsIndex.includes(spreader.row) && columnsIndex.includes(spreader.col);
|
||||
const content = isSpreaderCopied
|
||||
? ""
|
||||
: formatValue(evaluatedCell.value, { locale: getters.getLocale() });
|
||||
cell = {
|
||||
id: cell?.id || "",
|
||||
style: cell?.style,
|
||||
format: evaluatedCell.format,
|
||||
content,
|
||||
isFormula: false,
|
||||
};
|
||||
}
|
||||
cellsInRow.push({
|
||||
cell: getters.getCell(position),
|
||||
style: getters.getCellComputedStyle(position),
|
||||
evaluatedCell: getters.getEvaluatedCell(position),
|
||||
cell,
|
||||
border: getters.getCellBorder(position) || undefined,
|
||||
evaluatedCell,
|
||||
position,
|
||||
});
|
||||
}
|
||||
@@ -43452,13 +43484,6 @@
|
||||
});
|
||||
}
|
||||
this.pasteCopiedTables(target);
|
||||
this.cells.forEach((row) => {
|
||||
row.forEach((c) => {
|
||||
if (c.cell) {
|
||||
c.cell = undefined;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* The clipped zone is copied as many times as it fits in the target.
|
||||
@@ -43530,7 +43555,7 @@
|
||||
clearClippedZones() {
|
||||
for (const row of this.cells) {
|
||||
for (const cell of row) {
|
||||
if (cell.cell) {
|
||||
if (cell?.cell) {
|
||||
this.dispatch("CLEAR_CELL", cell.position);
|
||||
}
|
||||
}
|
||||
@@ -43556,6 +43581,9 @@
|
||||
const rowCells = this.cells[r];
|
||||
for (let c = 0; c < width; c++) {
|
||||
const origin = rowCells[c];
|
||||
if (!origin) {
|
||||
continue;
|
||||
}
|
||||
const position = { col: col + c, row: row + r, sheetId: sheetId };
|
||||
// TODO: refactor this part. the "Paste merge" action is also executed with
|
||||
// MOVE_RANGES in pasteFromCut. Adding a condition on the operation type here
|
||||
@@ -43579,53 +43607,42 @@
|
||||
pasteCell(origin, target, operation, clipboardOption) {
|
||||
const { sheetId, col, row } = target;
|
||||
const targetCell = this.getters.getEvaluatedCell(target);
|
||||
if (clipboardOption?.pasteOption !== "onlyValue") {
|
||||
const targetBorders = this.getters.getCellBorder(target);
|
||||
const originBorders = origin.border;
|
||||
const border = {
|
||||
top: targetBorders?.top || originBorders?.top,
|
||||
bottom: targetBorders?.bottom || originBorders?.bottom,
|
||||
left: targetBorders?.left || originBorders?.left,
|
||||
right: targetBorders?.right || originBorders?.right,
|
||||
};
|
||||
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
||||
if (clipboardOption?.pasteOption === "onlyValue") {
|
||||
const locale = this.getters.getLocale();
|
||||
const content = formatValue(origin.evaluatedCell.value, { locale });
|
||||
this.dispatch("UPDATE_CELL", { ...target, content });
|
||||
return;
|
||||
}
|
||||
if (origin.cell) {
|
||||
if (clipboardOption?.pasteOption === "onlyFormat") {
|
||||
this.dispatch("UPDATE_CELL", {
|
||||
...target,
|
||||
style: origin.cell.style,
|
||||
format: origin.evaluatedCell.format,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (clipboardOption?.pasteOption === "onlyValue") {
|
||||
const locale = this.getters.getLocale();
|
||||
const content = formatValue(origin.evaluatedCell.value, { locale });
|
||||
this.dispatch("UPDATE_CELL", { ...target, content });
|
||||
return;
|
||||
}
|
||||
let content = origin.cell.content;
|
||||
if (origin.cell.isFormula && operation === "COPY") {
|
||||
content = this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula);
|
||||
}
|
||||
const targetBorders = this.getters.getCellBorder(target);
|
||||
const originBorders = origin.border;
|
||||
const border = {
|
||||
top: targetBorders?.top || originBorders?.top,
|
||||
bottom: targetBorders?.bottom || originBorders?.bottom,
|
||||
left: targetBorders?.left || originBorders?.left,
|
||||
right: targetBorders?.right || originBorders?.right,
|
||||
};
|
||||
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
||||
if (clipboardOption?.pasteOption === "onlyFormat") {
|
||||
this.dispatch("UPDATE_CELL", {
|
||||
...target,
|
||||
style: origin.cell?.style ?? null,
|
||||
format: origin.cell?.format ?? origin.evaluatedCell.format ?? targetCell.format,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const content = origin.cell && origin.cell.isFormula && operation === "COPY"
|
||||
? this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula)
|
||||
: origin.cell?.content;
|
||||
if (content !== "" || origin.cell?.format || origin.cell?.style) {
|
||||
this.dispatch("UPDATE_CELL", {
|
||||
...target,
|
||||
content,
|
||||
style: origin.cell.style || null,
|
||||
format: origin.cell.format,
|
||||
style: origin.cell?.style || null,
|
||||
format: origin.cell?.format,
|
||||
});
|
||||
}
|
||||
else if (targetCell) {
|
||||
if (clipboardOption?.pasteOption === "onlyValue") {
|
||||
this.dispatch("UPDATE_CELL", { ...target, content: "" });
|
||||
}
|
||||
else if (clipboardOption?.pasteOption === "onlyFormat") {
|
||||
this.dispatch("UPDATE_CELL", { ...target, style: null, format: "" });
|
||||
}
|
||||
else {
|
||||
this.dispatch("CLEAR_CELL", target);
|
||||
}
|
||||
this.dispatch("CLEAR_CELL", target);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -43687,22 +43704,28 @@
|
||||
return (this.cells
|
||||
.map((cells) => {
|
||||
return cells
|
||||
.map((c) => this.getters.shouldShowFormulas() && c.cell?.isFormula
|
||||
.map((c) => this.getters.shouldShowFormulas() && c?.cell?.isFormula
|
||||
? c.cell?.content || ""
|
||||
: c.evaluatedCell?.formattedValue || "")
|
||||
: c?.evaluatedCell?.formattedValue || "")
|
||||
.join("\t");
|
||||
})
|
||||
.join("\n") || "\t");
|
||||
}
|
||||
getHTMLContent() {
|
||||
if (this.cells.length === 1 && this.cells[0].length === 1) {
|
||||
if (!this.cells[0][0]) {
|
||||
return "";
|
||||
}
|
||||
return this.getters.getCellText(this.cells[0][0].position);
|
||||
}
|
||||
let htmlTable = '<table border="1" style="border-collapse:collapse">';
|
||||
for (const row of this.cells) {
|
||||
htmlTable += "<tr>";
|
||||
for (const cell of row) {
|
||||
const cssStyle = cssPropertiesToCss(cellStyleToCss(cell.style));
|
||||
if (!cell) {
|
||||
continue;
|
||||
}
|
||||
const cssStyle = cssPropertiesToCss(cellStyleToCss(this.getters.getCellComputedStyle(cell.position)));
|
||||
const cellText = this.getters.getCellText(cell.position);
|
||||
htmlTable += `<td style="${cssStyle}">` + xmlEscape(cellText) + "</td>";
|
||||
}
|
||||
@@ -46832,11 +46855,14 @@
|
||||
}
|
||||
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
||||
this.state.paste(cmd.target, { pasteOption, shouldPasteCF: true, selectTarget: true });
|
||||
if (this.state.operation === "CUT") {
|
||||
this.state = undefined;
|
||||
}
|
||||
this.lastPasteState = this.state;
|
||||
if (this.paintFormatStatus === "oneOff") {
|
||||
this.paintFormatStatus = "inactive";
|
||||
this.status = "invisible";
|
||||
}
|
||||
this.status = "invisible";
|
||||
break;
|
||||
case "COPY_PASTE_CELLS_ABOVE":
|
||||
{
|
||||
@@ -55560,19 +55586,22 @@
|
||||
* Check if the given command is allowed by all the plugins and the history.
|
||||
*/
|
||||
checkDispatchAllowed(command) {
|
||||
if (isCoreCommand(command)) {
|
||||
return this.checkDispatchAllowedCoreCommand(command);
|
||||
const results = isCoreCommand(command)
|
||||
? this.checkDispatchAllowedCoreCommand(command)
|
||||
: this.checkDispatchAllowedLocalCommand(command);
|
||||
if (results.some((r) => r !== "Success" /* CommandResult.Success */)) {
|
||||
return new DispatchResult(results.flat());
|
||||
}
|
||||
return this.checkDispatchAllowedLocalCommand(command);
|
||||
return DispatchResult.Success;
|
||||
}
|
||||
checkDispatchAllowedCoreCommand(command) {
|
||||
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
||||
results.push(this.range.allowDispatch(command));
|
||||
return new DispatchResult(results.flat());
|
||||
return results;
|
||||
}
|
||||
checkDispatchAllowedLocalCommand(command) {
|
||||
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
||||
return new DispatchResult(results.flat());
|
||||
return results;
|
||||
}
|
||||
finalize() {
|
||||
this.status = 3 /* Status.Finalizing */;
|
||||
@@ -55919,9 +55948,9 @@
|
||||
exports.tokenize = tokenize;
|
||||
|
||||
|
||||
__info__.version = "17.0.3";
|
||||
__info__.date = "2023-11-16T13:27:10.083Z";
|
||||
__info__.hash = "8bd0fb2b4";
|
||||
__info__.version = "17.0.4";
|
||||
__info__.date = "2023-11-24T13:28:06.767Z";
|
||||
__info__.hash = "7346d0af9";
|
||||
|
||||
|
||||
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<!--
|
||||
This file is generated by o-spreadsheet build tools. Do not edit it.
|
||||
@see https://github.com/odoo/o-spreadsheet
|
||||
@version 17.0.3
|
||||
@date 2023-11-16T13:27:13.577Z
|
||||
@hash 8bd0fb2b4
|
||||
@version 17.0.4
|
||||
@date 2023-11-24T13:28:11.116Z
|
||||
@hash 7346d0af9
|
||||
-->
|
||||
<odoo>
|
||||
<t t-name="o-spreadsheet-ActionButton">
|
||||
@@ -1963,10 +1963,9 @@
|
||||
/>
|
||||
</svg>
|
||||
</t>
|
||||
/** Font Awesome by Dave Gandy
|
||||
* http://fontawesome.io/
|
||||
* https://fontawesome.com/license
|
||||
*/
|
||||
<!-- Font Awesome by Dave Gandy
|
||||
http://fontawesome.io/
|
||||
https://fontawesome.com/license -->
|
||||
<t t-name="o-spreadsheet-Icon.CARET_UP">
|
||||
<svg class="caret-up" viewBox="0 0 320 512">
|
||||
<path
|
||||
|
||||
Reference in New Issue
Block a user