[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:
Lucas Lefèvre (lul)
2023-11-25 05:41:44 +00:00
parent 2a84495a47
commit d27d9a4757
2 changed files with 187 additions and 159 deletions
@@ -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