@odoo/o-spreadsheet 17.4.14 → 17.4.16
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 +65 -37
- package/dist/o-spreadsheet.d.ts +4 -0
- package/dist/o-spreadsheet.esm.js +65 -37
- package/dist/o-spreadsheet.iife.js +65 -37
- package/dist/o-spreadsheet.iife.min.js +345 -346
- package/dist/o_spreadsheet.xml +8 -4
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.4.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.16
|
|
6
|
+
* @date 2024-12-19T07:50:04.021Z
|
|
7
|
+
* @hash 6b827fc
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -306,8 +306,8 @@ const LINE_FILL_TRANSPARENCY = 0.4;
|
|
|
306
306
|
const DEBOUNCE_TIME = 200;
|
|
307
307
|
const MESSAGE_VERSION = 1;
|
|
308
308
|
// Sheets
|
|
309
|
-
const
|
|
310
|
-
const
|
|
309
|
+
const FORBIDDEN_SHEETNAME_CHARS = ["'", "*", "?", "/", "\\", "[", "]"];
|
|
310
|
+
const FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX = /'|\*|\?|\/|\\|\[|\]/;
|
|
311
311
|
// Cells
|
|
312
312
|
const FORMULA_REF_IDENTIFIER = "|";
|
|
313
313
|
// Components
|
|
@@ -353,6 +353,7 @@ const PIVOT_TABLE_CONFIG = {
|
|
|
353
353
|
//------------------------------------------------------------------------------
|
|
354
354
|
// Miscellaneous
|
|
355
355
|
//------------------------------------------------------------------------------
|
|
356
|
+
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
356
357
|
/**
|
|
357
358
|
* Remove quotes from a quoted string
|
|
358
359
|
* ```js
|
|
@@ -448,6 +449,10 @@ function getCanonicalSheetName(sheetName) {
|
|
|
448
449
|
}
|
|
449
450
|
return sheetName;
|
|
450
451
|
}
|
|
452
|
+
/** Replace the excel-excluded characters of a sheetName */
|
|
453
|
+
function sanitizeSheetName(sheetName, replacementChar = " ") {
|
|
454
|
+
return sheetName.replace(sanitizeSheetNameRegex, replacementChar);
|
|
455
|
+
}
|
|
451
456
|
function clip(val, min, max) {
|
|
452
457
|
return val < min ? min : val > max ? max : val;
|
|
453
458
|
}
|
|
@@ -763,6 +768,7 @@ function removeFalsyAttributes(obj) {
|
|
|
763
768
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
764
769
|
*/
|
|
765
770
|
const whiteSpaceSpecialCharacters = [
|
|
771
|
+
" ",
|
|
766
772
|
"\t",
|
|
767
773
|
"\f",
|
|
768
774
|
"\v",
|
|
@@ -777,17 +783,15 @@ const whiteSpaceSpecialCharacters = [
|
|
|
777
783
|
String.fromCharCode(parseInt("3000", 16)),
|
|
778
784
|
String.fromCharCode(parseInt("feff", 16)),
|
|
779
785
|
];
|
|
780
|
-
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|")
|
|
786
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|"), "g");
|
|
787
|
+
const newLineRegexp = /(\r\n|\r)/g;
|
|
781
788
|
/**
|
|
782
|
-
* Replace all
|
|
783
|
-
* different newlines types by \n.
|
|
789
|
+
* Replace all different newlines characters by \n
|
|
784
790
|
*/
|
|
785
|
-
function
|
|
791
|
+
function replaceNewLines(text) {
|
|
786
792
|
if (!text)
|
|
787
793
|
return "";
|
|
788
|
-
|
|
789
|
-
return text;
|
|
790
|
-
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
794
|
+
return text.replace(newLineRegexp, NEWLINE);
|
|
791
795
|
}
|
|
792
796
|
/**
|
|
793
797
|
* Determine if the numbers are consecutive.
|
|
@@ -5679,7 +5683,7 @@ class BorderClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
5679
5683
|
const POSTFIX_UNARY_OPERATORS = ["%"];
|
|
5680
5684
|
const OPERATORS = "+,-,*,/,:,=,<>,>=,>,<=,<,^,&".split(",").concat(POSTFIX_UNARY_OPERATORS);
|
|
5681
5685
|
function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
5682
|
-
str =
|
|
5686
|
+
str = replaceNewLines(str);
|
|
5683
5687
|
const chars = new TokenizingChars(str);
|
|
5684
5688
|
const result = [];
|
|
5685
5689
|
while (!chars.isOver()) {
|
|
@@ -5826,12 +5830,12 @@ function tokenizeSpace(chars) {
|
|
|
5826
5830
|
if (length) {
|
|
5827
5831
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
5828
5832
|
}
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
chars.shift();
|
|
5833
|
+
let spaces = "";
|
|
5834
|
+
while (chars.current && chars.current.match(whiteSpaceRegexp)) {
|
|
5835
|
+
spaces += chars.shift();
|
|
5832
5836
|
}
|
|
5833
|
-
if (
|
|
5834
|
-
return { type: "SPACE", value:
|
|
5837
|
+
if (spaces) {
|
|
5838
|
+
return { type: "SPACE", value: spaces };
|
|
5835
5839
|
}
|
|
5836
5840
|
return null;
|
|
5837
5841
|
}
|
|
@@ -38561,6 +38565,7 @@ css /* scss */ `
|
|
|
38561
38565
|
}
|
|
38562
38566
|
}
|
|
38563
38567
|
`;
|
|
38568
|
+
const DEFAULT_TABLE_STYLE_COLOR = "#3C78D8";
|
|
38564
38569
|
class TableStyleEditorPanel extends owl.Component {
|
|
38565
38570
|
static template = "o-spreadsheet-TableStyleEditorPanel";
|
|
38566
38571
|
static components = { Section, RoundColorPicker, TableStylePreview };
|
|
@@ -38579,7 +38584,7 @@ class TableStyleEditorPanel extends owl.Component {
|
|
|
38579
38584
|
: null;
|
|
38580
38585
|
return {
|
|
38581
38586
|
pickerOpened: false,
|
|
38582
|
-
primaryColor: editedStyle?.primaryColor ||
|
|
38587
|
+
primaryColor: editedStyle?.primaryColor || DEFAULT_TABLE_STYLE_COLOR,
|
|
38583
38588
|
selectedTemplateName: editedStyle?.templateName || "lightColoredText",
|
|
38584
38589
|
styleName: editedStyle?.displayName || this.env.model.getters.getNewCustomTableStyleName(),
|
|
38585
38590
|
};
|
|
@@ -38588,7 +38593,7 @@ class TableStyleEditorPanel extends owl.Component {
|
|
|
38588
38593
|
this.state.pickerOpened = !this.state.pickerOpened;
|
|
38589
38594
|
}
|
|
38590
38595
|
onColorPicked(color) {
|
|
38591
|
-
this.state.primaryColor = color;
|
|
38596
|
+
this.state.primaryColor = isColorValid(color) ? color : DEFAULT_TABLE_STYLE_COLOR;
|
|
38592
38597
|
this.state.pickerOpened = false;
|
|
38593
38598
|
}
|
|
38594
38599
|
onTemplatePicked(templateName) {
|
|
@@ -39935,6 +39940,7 @@ class FiguresContainer extends owl.Component {
|
|
|
39935
39940
|
draggedFigure: undefined,
|
|
39936
39941
|
horizontalSnap: undefined,
|
|
39937
39942
|
verticalSnap: undefined,
|
|
39943
|
+
cancelDnd: undefined,
|
|
39938
39944
|
});
|
|
39939
39945
|
setup() {
|
|
39940
39946
|
owl.onMounted(() => {
|
|
@@ -39947,12 +39953,28 @@ class FiguresContainer extends owl.Component {
|
|
|
39947
39953
|
// new rendering
|
|
39948
39954
|
this.render();
|
|
39949
39955
|
});
|
|
39956
|
+
owl.onWillUpdateProps(() => {
|
|
39957
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
39958
|
+
const draggedFigureId = this.dnd.draggedFigure?.id;
|
|
39959
|
+
if (draggedFigureId && !this.env.model.getters.getFigure(sheetId, draggedFigureId)) {
|
|
39960
|
+
if (this.dnd.cancelDnd) {
|
|
39961
|
+
this.dnd.cancelDnd();
|
|
39962
|
+
}
|
|
39963
|
+
this.dnd.draggedFigure = undefined;
|
|
39964
|
+
this.dnd.horizontalSnap = undefined;
|
|
39965
|
+
this.dnd.verticalSnap = undefined;
|
|
39966
|
+
this.dnd.cancelDnd = undefined;
|
|
39967
|
+
}
|
|
39968
|
+
});
|
|
39950
39969
|
}
|
|
39951
39970
|
getVisibleFigures() {
|
|
39952
39971
|
const visibleFigures = this.env.model.getters.getVisibleFigures();
|
|
39953
39972
|
if (this.dnd.draggedFigure &&
|
|
39954
39973
|
!visibleFigures.some((figure) => figure.id === this.dnd.draggedFigure?.id)) {
|
|
39955
|
-
|
|
39974
|
+
const draggedFigure = this.env.model.getters.getFigure(this.env.model.getters.getActiveSheetId(), this.dnd.draggedFigure?.id);
|
|
39975
|
+
if (draggedFigure) {
|
|
39976
|
+
visibleFigures.push(draggedFigure);
|
|
39977
|
+
}
|
|
39956
39978
|
}
|
|
39957
39979
|
return visibleFigures;
|
|
39958
39980
|
}
|
|
@@ -40071,7 +40093,7 @@ class FiguresContainer extends owl.Component {
|
|
|
40071
40093
|
this.dnd.verticalSnap = undefined;
|
|
40072
40094
|
this.env.model.dispatch("UPDATE_FIGURE", { sheetId, id: figure.id, x, y });
|
|
40073
40095
|
};
|
|
40074
|
-
startDnd(onMouseMove, onMouseUp);
|
|
40096
|
+
this.dnd.cancelDnd = startDnd(onMouseMove, onMouseUp);
|
|
40075
40097
|
}
|
|
40076
40098
|
/**
|
|
40077
40099
|
* Initialize the resize of a figure with mouse movements
|
|
@@ -40119,7 +40141,7 @@ class FiguresContainer extends owl.Component {
|
|
|
40119
40141
|
this.dnd.horizontalSnap = undefined;
|
|
40120
40142
|
this.dnd.verticalSnap = undefined;
|
|
40121
40143
|
};
|
|
40122
|
-
startDnd(onMouseMove, onMouseUp);
|
|
40144
|
+
this.dnd.cancelDnd = startDnd(onMouseMove, onMouseUp);
|
|
40123
40145
|
}
|
|
40124
40146
|
getOtherFigures(figId) {
|
|
40125
40147
|
return this.getVisibleFigures().filter((f) => f.id !== figId);
|
|
@@ -46727,13 +46749,12 @@ const MIGRATIONS = [
|
|
|
46727
46749
|
to: 8,
|
|
46728
46750
|
applyMigration(data) {
|
|
46729
46751
|
const namesTaken = [];
|
|
46730
|
-
const globalForbiddenInExcel = new RegExp(FORBIDDEN_IN_EXCEL_REGEX, "g");
|
|
46731
46752
|
for (let sheet of data.sheets || []) {
|
|
46732
46753
|
if (!sheet.name) {
|
|
46733
46754
|
continue;
|
|
46734
46755
|
}
|
|
46735
46756
|
const oldName = sheet.name;
|
|
46736
|
-
const escapedName = oldName
|
|
46757
|
+
const escapedName = sanitizeSheetName(oldName, "_");
|
|
46737
46758
|
let i = 1;
|
|
46738
46759
|
let newName = escapedName;
|
|
46739
46760
|
while (namesTaken.includes(newName)) {
|
|
@@ -48232,7 +48253,7 @@ class CellPlugin extends CorePlugin {
|
|
|
48232
48253
|
const before = this.getters.getCell({ sheetId, col, row });
|
|
48233
48254
|
const hasContent = "content" in after || "formula" in after;
|
|
48234
48255
|
// Compute the new cell properties
|
|
48235
|
-
const afterContent = hasContent ?
|
|
48256
|
+
const afterContent = hasContent ? replaceNewLines(after?.content) : before?.content || "";
|
|
48236
48257
|
let style;
|
|
48237
48258
|
if (after.style !== undefined) {
|
|
48238
48259
|
style = after.style || undefined;
|
|
@@ -51093,6 +51114,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
51093
51114
|
};
|
|
51094
51115
|
}
|
|
51095
51116
|
getUnboundedZone(sheetId, zone) {
|
|
51117
|
+
if (zone.bottom === undefined || zone.right === undefined) {
|
|
51118
|
+
return zone;
|
|
51119
|
+
}
|
|
51096
51120
|
const isFullRow = zone.left === 0 && zone.right === this.getNumberCols(sheetId) - 1;
|
|
51097
51121
|
const isFullCol = zone.top === 0 && zone.bottom === this.getNumberRows(sheetId) - 1;
|
|
51098
51122
|
return {
|
|
@@ -51258,7 +51282,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
51258
51282
|
if (orderedSheetIds.find((id) => sheets[id]?.name.toLowerCase() === name && id !== cmd.sheetId)) {
|
|
51259
51283
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
51260
51284
|
}
|
|
51261
|
-
if (
|
|
51285
|
+
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
51262
51286
|
return "ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */;
|
|
51263
51287
|
}
|
|
51264
51288
|
return "Success" /* CommandResult.Success */;
|
|
@@ -56047,11 +56071,13 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
56047
56071
|
return EMPTY_PIVOT_CELL;
|
|
56048
56072
|
}
|
|
56049
56073
|
if (functionName === "PIVOT") {
|
|
56050
|
-
const includeTotal = args[2]
|
|
56051
|
-
const
|
|
56074
|
+
const includeTotal = toScalar(args[2]);
|
|
56075
|
+
const shouldIncludeTotal = includeTotal === undefined ? true : toBoolean(includeTotal);
|
|
56076
|
+
const includeColumnHeaders = toScalar(args[3]);
|
|
56077
|
+
const shouldIncludeColumnHeaders = includeColumnHeaders === undefined ? true : toBoolean(includeColumnHeaders);
|
|
56052
56078
|
const pivotCells = pivot
|
|
56053
56079
|
.getTableStructure()
|
|
56054
|
-
.getPivotCells(
|
|
56080
|
+
.getPivotCells(shouldIncludeTotal, shouldIncludeColumnHeaders);
|
|
56055
56081
|
const pivotCol = position.col - mainPosition.col;
|
|
56056
56082
|
const pivotRow = position.row - mainPosition.row;
|
|
56057
56083
|
return pivotCells[pivotCol][pivotRow];
|
|
@@ -58156,7 +58182,7 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
58156
58182
|
getPivotDuplicateSheetName(pivotName) {
|
|
58157
58183
|
let i = 1;
|
|
58158
58184
|
const names = this.getters.getSheetIds().map((id) => this.getters.getSheetName(id));
|
|
58159
|
-
const sanitizedName = pivotName
|
|
58185
|
+
const sanitizedName = sanitizeSheetName(pivotName);
|
|
58160
58186
|
let name = sanitizedName;
|
|
58161
58187
|
while (names.includes(name)) {
|
|
58162
58188
|
name = `${sanitizedName} (${i})`;
|
|
@@ -61300,6 +61326,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61300
61326
|
break;
|
|
61301
61327
|
case "DELETE_SHEET":
|
|
61302
61328
|
this.cleanViewports();
|
|
61329
|
+
this.sheetsWithDirtyViewports.delete(cmd.sheetId);
|
|
61303
61330
|
break;
|
|
61304
61331
|
case "ACTIVATE_SHEET":
|
|
61305
61332
|
this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
|
|
@@ -62197,7 +62224,7 @@ function interactiveRenameSheet(env, sheetId, name, errorCallback) {
|
|
|
62197
62224
|
env.raiseError(_t("A sheet with the name %s already exists. Please select another name.", name), errorCallback);
|
|
62198
62225
|
}
|
|
62199
62226
|
else if (result.reasons.includes("ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */)) {
|
|
62200
|
-
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).",
|
|
62227
|
+
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).", FORBIDDEN_SHEETNAME_CHARS.join(" ")), errorCallback);
|
|
62201
62228
|
}
|
|
62202
62229
|
}
|
|
62203
62230
|
|
|
@@ -63456,7 +63483,7 @@ class ActionButton extends owl.Component {
|
|
|
63456
63483
|
setup() {
|
|
63457
63484
|
owl.onWillUpdateProps((nextProps) => {
|
|
63458
63485
|
if (nextProps.action !== this.props.action) {
|
|
63459
|
-
this.actionButton = createAction(
|
|
63486
|
+
this.actionButton = createAction(nextProps.action);
|
|
63460
63487
|
}
|
|
63461
63488
|
});
|
|
63462
63489
|
}
|
|
@@ -63723,7 +63750,6 @@ css /* scss */ `
|
|
|
63723
63750
|
height: fit-content;
|
|
63724
63751
|
margin-top: -1px;
|
|
63725
63752
|
border: 1px solid;
|
|
63726
|
-
z-index: ${ComponentsImportance.TopBarComposer};
|
|
63727
63753
|
|
|
63728
63754
|
.o-composer:empty:not(:focus):not(.active)::before {
|
|
63729
63755
|
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
@@ -63765,6 +63791,7 @@ class TopBarComposer extends owl.Component {
|
|
|
63765
63791
|
}
|
|
63766
63792
|
return cssPropertiesToCss({
|
|
63767
63793
|
"border-color": SELECTION_BORDER_COLOR,
|
|
63794
|
+
"z-index": String(ComponentsImportance.TopBarComposer),
|
|
63768
63795
|
});
|
|
63769
63796
|
}
|
|
63770
63797
|
get delimitation() {
|
|
@@ -68589,6 +68616,7 @@ const helpers = {
|
|
|
68589
68616
|
createPivotFormula,
|
|
68590
68617
|
areDomainArgsFieldsValid,
|
|
68591
68618
|
formatTickValue,
|
|
68619
|
+
sanitizeSheetName,
|
|
68592
68620
|
};
|
|
68593
68621
|
const links = {
|
|
68594
68622
|
isMarkdownLink,
|
|
@@ -68719,6 +68747,6 @@ exports.tokenColors = tokenColors;
|
|
|
68719
68747
|
exports.tokenize = tokenize;
|
|
68720
68748
|
|
|
68721
68749
|
|
|
68722
|
-
__info__.version = "17.4.
|
|
68723
|
-
__info__.date = "2024-
|
|
68724
|
-
__info__.hash = "
|
|
68750
|
+
__info__.version = "17.4.16";
|
|
68751
|
+
__info__.date = "2024-12-19T07:50:04.021Z";
|
|
68752
|
+
__info__.hash = "6b827fc";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -5548,6 +5548,8 @@ declare function createCurrencyFormat(currency: Partial<Currency>): Format;
|
|
|
5548
5548
|
*/
|
|
5549
5549
|
declare function deepCopy<T>(obj: T): T;
|
|
5550
5550
|
declare function unquote(string: string, quoteChar?: "'" | '"'): string;
|
|
5551
|
+
/** Replace the excel-excluded characters of a sheetName */
|
|
5552
|
+
declare function sanitizeSheetName(sheetName: string, replacementChar?: string): string;
|
|
5551
5553
|
declare function isMarkdownLink(str: string): boolean;
|
|
5552
5554
|
/**
|
|
5553
5555
|
* Build a markdown link from a label and an url
|
|
@@ -8283,6 +8285,7 @@ interface DndState {
|
|
|
8283
8285
|
draggedFigure?: Figure;
|
|
8284
8286
|
horizontalSnap?: Snap<HFigureAxisType>;
|
|
8285
8287
|
verticalSnap?: Snap<VFigureAxisType>;
|
|
8288
|
+
cancelDnd: (() => void) | undefined;
|
|
8286
8289
|
}
|
|
8287
8290
|
/**
|
|
8288
8291
|
* Each figure ⭐ is positioned inside a container `div` placed and sized
|
|
@@ -11531,6 +11534,7 @@ declare const helpers: {
|
|
|
11531
11534
|
createPivotFormula: typeof createPivotFormula;
|
|
11532
11535
|
areDomainArgsFieldsValid: typeof areDomainArgsFieldsValid;
|
|
11533
11536
|
formatTickValue: typeof formatTickValue;
|
|
11537
|
+
sanitizeSheetName: typeof sanitizeSheetName;
|
|
11534
11538
|
};
|
|
11535
11539
|
declare const links: {
|
|
11536
11540
|
isMarkdownLink: typeof isMarkdownLink;
|
|
@@ -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 17.4.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.16
|
|
6
|
+
* @date 2024-12-19T07:50:04.021Z
|
|
7
|
+
* @hash 6b827fc
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -304,8 +304,8 @@ const LINE_FILL_TRANSPARENCY = 0.4;
|
|
|
304
304
|
const DEBOUNCE_TIME = 200;
|
|
305
305
|
const MESSAGE_VERSION = 1;
|
|
306
306
|
// Sheets
|
|
307
|
-
const
|
|
308
|
-
const
|
|
307
|
+
const FORBIDDEN_SHEETNAME_CHARS = ["'", "*", "?", "/", "\\", "[", "]"];
|
|
308
|
+
const FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX = /'|\*|\?|\/|\\|\[|\]/;
|
|
309
309
|
// Cells
|
|
310
310
|
const FORMULA_REF_IDENTIFIER = "|";
|
|
311
311
|
// Components
|
|
@@ -351,6 +351,7 @@ const PIVOT_TABLE_CONFIG = {
|
|
|
351
351
|
//------------------------------------------------------------------------------
|
|
352
352
|
// Miscellaneous
|
|
353
353
|
//------------------------------------------------------------------------------
|
|
354
|
+
const sanitizeSheetNameRegex = new RegExp(FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX, "g");
|
|
354
355
|
/**
|
|
355
356
|
* Remove quotes from a quoted string
|
|
356
357
|
* ```js
|
|
@@ -446,6 +447,10 @@ function getCanonicalSheetName(sheetName) {
|
|
|
446
447
|
}
|
|
447
448
|
return sheetName;
|
|
448
449
|
}
|
|
450
|
+
/** Replace the excel-excluded characters of a sheetName */
|
|
451
|
+
function sanitizeSheetName(sheetName, replacementChar = " ") {
|
|
452
|
+
return sheetName.replace(sanitizeSheetNameRegex, replacementChar);
|
|
453
|
+
}
|
|
449
454
|
function clip(val, min, max) {
|
|
450
455
|
return val < min ? min : val > max ? max : val;
|
|
451
456
|
}
|
|
@@ -761,6 +766,7 @@ function removeFalsyAttributes(obj) {
|
|
|
761
766
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
762
767
|
*/
|
|
763
768
|
const whiteSpaceSpecialCharacters = [
|
|
769
|
+
" ",
|
|
764
770
|
"\t",
|
|
765
771
|
"\f",
|
|
766
772
|
"\v",
|
|
@@ -775,17 +781,15 @@ const whiteSpaceSpecialCharacters = [
|
|
|
775
781
|
String.fromCharCode(parseInt("3000", 16)),
|
|
776
782
|
String.fromCharCode(parseInt("feff", 16)),
|
|
777
783
|
];
|
|
778
|
-
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|")
|
|
784
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|"), "g");
|
|
785
|
+
const newLineRegexp = /(\r\n|\r)/g;
|
|
779
786
|
/**
|
|
780
|
-
* Replace all
|
|
781
|
-
* different newlines types by \n.
|
|
787
|
+
* Replace all different newlines characters by \n
|
|
782
788
|
*/
|
|
783
|
-
function
|
|
789
|
+
function replaceNewLines(text) {
|
|
784
790
|
if (!text)
|
|
785
791
|
return "";
|
|
786
|
-
|
|
787
|
-
return text;
|
|
788
|
-
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
792
|
+
return text.replace(newLineRegexp, NEWLINE);
|
|
789
793
|
}
|
|
790
794
|
/**
|
|
791
795
|
* Determine if the numbers are consecutive.
|
|
@@ -5677,7 +5681,7 @@ class BorderClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
5677
5681
|
const POSTFIX_UNARY_OPERATORS = ["%"];
|
|
5678
5682
|
const OPERATORS = "+,-,*,/,:,=,<>,>=,>,<=,<,^,&".split(",").concat(POSTFIX_UNARY_OPERATORS);
|
|
5679
5683
|
function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
5680
|
-
str =
|
|
5684
|
+
str = replaceNewLines(str);
|
|
5681
5685
|
const chars = new TokenizingChars(str);
|
|
5682
5686
|
const result = [];
|
|
5683
5687
|
while (!chars.isOver()) {
|
|
@@ -5824,12 +5828,12 @@ function tokenizeSpace(chars) {
|
|
|
5824
5828
|
if (length) {
|
|
5825
5829
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
5826
5830
|
}
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
chars.shift();
|
|
5831
|
+
let spaces = "";
|
|
5832
|
+
while (chars.current && chars.current.match(whiteSpaceRegexp)) {
|
|
5833
|
+
spaces += chars.shift();
|
|
5830
5834
|
}
|
|
5831
|
-
if (
|
|
5832
|
-
return { type: "SPACE", value:
|
|
5835
|
+
if (spaces) {
|
|
5836
|
+
return { type: "SPACE", value: spaces };
|
|
5833
5837
|
}
|
|
5834
5838
|
return null;
|
|
5835
5839
|
}
|
|
@@ -38559,6 +38563,7 @@ css /* scss */ `
|
|
|
38559
38563
|
}
|
|
38560
38564
|
}
|
|
38561
38565
|
`;
|
|
38566
|
+
const DEFAULT_TABLE_STYLE_COLOR = "#3C78D8";
|
|
38562
38567
|
class TableStyleEditorPanel extends Component {
|
|
38563
38568
|
static template = "o-spreadsheet-TableStyleEditorPanel";
|
|
38564
38569
|
static components = { Section, RoundColorPicker, TableStylePreview };
|
|
@@ -38577,7 +38582,7 @@ class TableStyleEditorPanel extends Component {
|
|
|
38577
38582
|
: null;
|
|
38578
38583
|
return {
|
|
38579
38584
|
pickerOpened: false,
|
|
38580
|
-
primaryColor: editedStyle?.primaryColor ||
|
|
38585
|
+
primaryColor: editedStyle?.primaryColor || DEFAULT_TABLE_STYLE_COLOR,
|
|
38581
38586
|
selectedTemplateName: editedStyle?.templateName || "lightColoredText",
|
|
38582
38587
|
styleName: editedStyle?.displayName || this.env.model.getters.getNewCustomTableStyleName(),
|
|
38583
38588
|
};
|
|
@@ -38586,7 +38591,7 @@ class TableStyleEditorPanel extends Component {
|
|
|
38586
38591
|
this.state.pickerOpened = !this.state.pickerOpened;
|
|
38587
38592
|
}
|
|
38588
38593
|
onColorPicked(color) {
|
|
38589
|
-
this.state.primaryColor = color;
|
|
38594
|
+
this.state.primaryColor = isColorValid(color) ? color : DEFAULT_TABLE_STYLE_COLOR;
|
|
38590
38595
|
this.state.pickerOpened = false;
|
|
38591
38596
|
}
|
|
38592
38597
|
onTemplatePicked(templateName) {
|
|
@@ -39933,6 +39938,7 @@ class FiguresContainer extends Component {
|
|
|
39933
39938
|
draggedFigure: undefined,
|
|
39934
39939
|
horizontalSnap: undefined,
|
|
39935
39940
|
verticalSnap: undefined,
|
|
39941
|
+
cancelDnd: undefined,
|
|
39936
39942
|
});
|
|
39937
39943
|
setup() {
|
|
39938
39944
|
onMounted(() => {
|
|
@@ -39945,12 +39951,28 @@ class FiguresContainer extends Component {
|
|
|
39945
39951
|
// new rendering
|
|
39946
39952
|
this.render();
|
|
39947
39953
|
});
|
|
39954
|
+
onWillUpdateProps(() => {
|
|
39955
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
39956
|
+
const draggedFigureId = this.dnd.draggedFigure?.id;
|
|
39957
|
+
if (draggedFigureId && !this.env.model.getters.getFigure(sheetId, draggedFigureId)) {
|
|
39958
|
+
if (this.dnd.cancelDnd) {
|
|
39959
|
+
this.dnd.cancelDnd();
|
|
39960
|
+
}
|
|
39961
|
+
this.dnd.draggedFigure = undefined;
|
|
39962
|
+
this.dnd.horizontalSnap = undefined;
|
|
39963
|
+
this.dnd.verticalSnap = undefined;
|
|
39964
|
+
this.dnd.cancelDnd = undefined;
|
|
39965
|
+
}
|
|
39966
|
+
});
|
|
39948
39967
|
}
|
|
39949
39968
|
getVisibleFigures() {
|
|
39950
39969
|
const visibleFigures = this.env.model.getters.getVisibleFigures();
|
|
39951
39970
|
if (this.dnd.draggedFigure &&
|
|
39952
39971
|
!visibleFigures.some((figure) => figure.id === this.dnd.draggedFigure?.id)) {
|
|
39953
|
-
|
|
39972
|
+
const draggedFigure = this.env.model.getters.getFigure(this.env.model.getters.getActiveSheetId(), this.dnd.draggedFigure?.id);
|
|
39973
|
+
if (draggedFigure) {
|
|
39974
|
+
visibleFigures.push(draggedFigure);
|
|
39975
|
+
}
|
|
39954
39976
|
}
|
|
39955
39977
|
return visibleFigures;
|
|
39956
39978
|
}
|
|
@@ -40069,7 +40091,7 @@ class FiguresContainer extends Component {
|
|
|
40069
40091
|
this.dnd.verticalSnap = undefined;
|
|
40070
40092
|
this.env.model.dispatch("UPDATE_FIGURE", { sheetId, id: figure.id, x, y });
|
|
40071
40093
|
};
|
|
40072
|
-
startDnd(onMouseMove, onMouseUp);
|
|
40094
|
+
this.dnd.cancelDnd = startDnd(onMouseMove, onMouseUp);
|
|
40073
40095
|
}
|
|
40074
40096
|
/**
|
|
40075
40097
|
* Initialize the resize of a figure with mouse movements
|
|
@@ -40117,7 +40139,7 @@ class FiguresContainer extends Component {
|
|
|
40117
40139
|
this.dnd.horizontalSnap = undefined;
|
|
40118
40140
|
this.dnd.verticalSnap = undefined;
|
|
40119
40141
|
};
|
|
40120
|
-
startDnd(onMouseMove, onMouseUp);
|
|
40142
|
+
this.dnd.cancelDnd = startDnd(onMouseMove, onMouseUp);
|
|
40121
40143
|
}
|
|
40122
40144
|
getOtherFigures(figId) {
|
|
40123
40145
|
return this.getVisibleFigures().filter((f) => f.id !== figId);
|
|
@@ -46725,13 +46747,12 @@ const MIGRATIONS = [
|
|
|
46725
46747
|
to: 8,
|
|
46726
46748
|
applyMigration(data) {
|
|
46727
46749
|
const namesTaken = [];
|
|
46728
|
-
const globalForbiddenInExcel = new RegExp(FORBIDDEN_IN_EXCEL_REGEX, "g");
|
|
46729
46750
|
for (let sheet of data.sheets || []) {
|
|
46730
46751
|
if (!sheet.name) {
|
|
46731
46752
|
continue;
|
|
46732
46753
|
}
|
|
46733
46754
|
const oldName = sheet.name;
|
|
46734
|
-
const escapedName = oldName
|
|
46755
|
+
const escapedName = sanitizeSheetName(oldName, "_");
|
|
46735
46756
|
let i = 1;
|
|
46736
46757
|
let newName = escapedName;
|
|
46737
46758
|
while (namesTaken.includes(newName)) {
|
|
@@ -48230,7 +48251,7 @@ class CellPlugin extends CorePlugin {
|
|
|
48230
48251
|
const before = this.getters.getCell({ sheetId, col, row });
|
|
48231
48252
|
const hasContent = "content" in after || "formula" in after;
|
|
48232
48253
|
// Compute the new cell properties
|
|
48233
|
-
const afterContent = hasContent ?
|
|
48254
|
+
const afterContent = hasContent ? replaceNewLines(after?.content) : before?.content || "";
|
|
48234
48255
|
let style;
|
|
48235
48256
|
if (after.style !== undefined) {
|
|
48236
48257
|
style = after.style || undefined;
|
|
@@ -51091,6 +51112,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
51091
51112
|
};
|
|
51092
51113
|
}
|
|
51093
51114
|
getUnboundedZone(sheetId, zone) {
|
|
51115
|
+
if (zone.bottom === undefined || zone.right === undefined) {
|
|
51116
|
+
return zone;
|
|
51117
|
+
}
|
|
51094
51118
|
const isFullRow = zone.left === 0 && zone.right === this.getNumberCols(sheetId) - 1;
|
|
51095
51119
|
const isFullCol = zone.top === 0 && zone.bottom === this.getNumberRows(sheetId) - 1;
|
|
51096
51120
|
return {
|
|
@@ -51256,7 +51280,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
51256
51280
|
if (orderedSheetIds.find((id) => sheets[id]?.name.toLowerCase() === name && id !== cmd.sheetId)) {
|
|
51257
51281
|
return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
|
|
51258
51282
|
}
|
|
51259
|
-
if (
|
|
51283
|
+
if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
|
|
51260
51284
|
return "ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */;
|
|
51261
51285
|
}
|
|
51262
51286
|
return "Success" /* CommandResult.Success */;
|
|
@@ -56045,11 +56069,13 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
56045
56069
|
return EMPTY_PIVOT_CELL;
|
|
56046
56070
|
}
|
|
56047
56071
|
if (functionName === "PIVOT") {
|
|
56048
|
-
const includeTotal = args[2]
|
|
56049
|
-
const
|
|
56072
|
+
const includeTotal = toScalar(args[2]);
|
|
56073
|
+
const shouldIncludeTotal = includeTotal === undefined ? true : toBoolean(includeTotal);
|
|
56074
|
+
const includeColumnHeaders = toScalar(args[3]);
|
|
56075
|
+
const shouldIncludeColumnHeaders = includeColumnHeaders === undefined ? true : toBoolean(includeColumnHeaders);
|
|
56050
56076
|
const pivotCells = pivot
|
|
56051
56077
|
.getTableStructure()
|
|
56052
|
-
.getPivotCells(
|
|
56078
|
+
.getPivotCells(shouldIncludeTotal, shouldIncludeColumnHeaders);
|
|
56053
56079
|
const pivotCol = position.col - mainPosition.col;
|
|
56054
56080
|
const pivotRow = position.row - mainPosition.row;
|
|
56055
56081
|
return pivotCells[pivotCol][pivotRow];
|
|
@@ -58154,7 +58180,7 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
58154
58180
|
getPivotDuplicateSheetName(pivotName) {
|
|
58155
58181
|
let i = 1;
|
|
58156
58182
|
const names = this.getters.getSheetIds().map((id) => this.getters.getSheetName(id));
|
|
58157
|
-
const sanitizedName = pivotName
|
|
58183
|
+
const sanitizedName = sanitizeSheetName(pivotName);
|
|
58158
58184
|
let name = sanitizedName;
|
|
58159
58185
|
while (names.includes(name)) {
|
|
58160
58186
|
name = `${sanitizedName} (${i})`;
|
|
@@ -61298,6 +61324,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61298
61324
|
break;
|
|
61299
61325
|
case "DELETE_SHEET":
|
|
61300
61326
|
this.cleanViewports();
|
|
61327
|
+
this.sheetsWithDirtyViewports.delete(cmd.sheetId);
|
|
61301
61328
|
break;
|
|
61302
61329
|
case "ACTIVATE_SHEET":
|
|
61303
61330
|
this.sheetsWithDirtyViewports.add(cmd.sheetIdTo);
|
|
@@ -62195,7 +62222,7 @@ function interactiveRenameSheet(env, sheetId, name, errorCallback) {
|
|
|
62195
62222
|
env.raiseError(_t("A sheet with the name %s already exists. Please select another name.", name), errorCallback);
|
|
62196
62223
|
}
|
|
62197
62224
|
else if (result.reasons.includes("ForbiddenCharactersInSheetName" /* CommandResult.ForbiddenCharactersInSheetName */)) {
|
|
62198
|
-
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).",
|
|
62225
|
+
env.raiseError(_t("Some used characters are not allowed in a sheet name (Forbidden characters are %s).", FORBIDDEN_SHEETNAME_CHARS.join(" ")), errorCallback);
|
|
62199
62226
|
}
|
|
62200
62227
|
}
|
|
62201
62228
|
|
|
@@ -63454,7 +63481,7 @@ class ActionButton extends Component {
|
|
|
63454
63481
|
setup() {
|
|
63455
63482
|
onWillUpdateProps((nextProps) => {
|
|
63456
63483
|
if (nextProps.action !== this.props.action) {
|
|
63457
|
-
this.actionButton = createAction(
|
|
63484
|
+
this.actionButton = createAction(nextProps.action);
|
|
63458
63485
|
}
|
|
63459
63486
|
});
|
|
63460
63487
|
}
|
|
@@ -63721,7 +63748,6 @@ css /* scss */ `
|
|
|
63721
63748
|
height: fit-content;
|
|
63722
63749
|
margin-top: -1px;
|
|
63723
63750
|
border: 1px solid;
|
|
63724
|
-
z-index: ${ComponentsImportance.TopBarComposer};
|
|
63725
63751
|
|
|
63726
63752
|
.o-composer:empty:not(:focus):not(.active)::before {
|
|
63727
63753
|
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
@@ -63763,6 +63789,7 @@ class TopBarComposer extends Component {
|
|
|
63763
63789
|
}
|
|
63764
63790
|
return cssPropertiesToCss({
|
|
63765
63791
|
"border-color": SELECTION_BORDER_COLOR,
|
|
63792
|
+
"z-index": String(ComponentsImportance.TopBarComposer),
|
|
63766
63793
|
});
|
|
63767
63794
|
}
|
|
63768
63795
|
get delimitation() {
|
|
@@ -68587,6 +68614,7 @@ const helpers = {
|
|
|
68587
68614
|
createPivotFormula,
|
|
68588
68615
|
areDomainArgsFieldsValid,
|
|
68589
68616
|
formatTickValue,
|
|
68617
|
+
sanitizeSheetName,
|
|
68590
68618
|
};
|
|
68591
68619
|
const links = {
|
|
68592
68620
|
isMarkdownLink,
|
|
@@ -68674,6 +68702,6 @@ const constants = {
|
|
|
68674
68702
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, 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 };
|
|
68675
68703
|
|
|
68676
68704
|
|
|
68677
|
-
__info__.version = "17.4.
|
|
68678
|
-
__info__.date = "2024-
|
|
68679
|
-
__info__.hash = "
|
|
68705
|
+
__info__.version = "17.4.16";
|
|
68706
|
+
__info__.date = "2024-12-19T07:50:04.021Z";
|
|
68707
|
+
__info__.hash = "6b827fc";
|