@odoo/o-spreadsheet 16.5.0-alpha.0 → 16.5.0-alpha.2

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.
@@ -112,8 +112,8 @@ const SELECTION_BORDER_COLOR = "#3266ca";
112
112
  const HEADER_BORDER_COLOR = "#C0C0C0";
113
113
  const CELL_BORDER_COLOR = "#E2E3E3";
114
114
  const BACKGROUND_CHART_COLOR = "#FFFFFF";
115
- const MENU_ITEM_DISABLED_COLOR = "#CACACA";
116
115
  const BG_HOVER_COLOR = "#EBEBEB";
116
+ const DISABLED_TEXT_COLOR = "#CACACA";
117
117
  const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
118
118
  const LINK_COLOR = "#01666b";
119
119
  const FILTERS_COLOR = "#188038";
@@ -1188,7 +1188,7 @@ const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
1188
1188
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
1189
1189
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
1190
1190
  const dateSeparatorsRegex = /\/|-|\s/;
1191
- const dateRegexp = /^(\d{1,4})[\/-\s](\d{1,2})([\/-\s](\d{1,4}))?$/;
1191
+ const dateRegexp = /^(\d{1,4})[\/-\s](\d{1,4})([\/-\s](\d{1,4}))?$/;
1192
1192
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
1193
1193
  function isDateTime(str, locale) {
1194
1194
  return parseDateTime(str, locale) !== null;
@@ -1249,6 +1249,10 @@ function getDateParts(dateString, locale) {
1249
1249
  }
1250
1250
  const localeDateType = getLocaleDateFormatType(locale);
1251
1251
  if (!part3) {
1252
+ if (part2.length > 2) {
1253
+ // e.g. 11/2023
1254
+ return { month: part1, year: part2, day: undefined, dateString, type: localeDateType };
1255
+ }
1252
1256
  if (localeDateType === "dmy") {
1253
1257
  return { day: part1, month: part2, year: part3, dateString, type: "dmy" };
1254
1258
  }
@@ -2995,11 +2999,18 @@ class RangeImpl {
2995
2999
  constructor(args, getSheetSize) {
2996
3000
  this.getSheetSize = getSheetSize;
2997
3001
  this._zone = args.zone;
2998
- this.parts = args.parts;
2999
3002
  this.prefixSheet = args.prefixSheet;
3000
3003
  this.invalidXc = args.invalidXc;
3001
3004
  this.sheetId = args.sheetId;
3002
3005
  this.invalidSheetName = args.invalidSheetName;
3006
+ let _fixedParts = [...args.parts];
3007
+ if (args.parts.length === 1 && getZoneArea(this.zone) > 1) {
3008
+ _fixedParts.push({ ...args.parts[0] });
3009
+ }
3010
+ else if (args.parts.length === 2 && getZoneArea(this.zone) === 1) {
3011
+ _fixedParts.pop();
3012
+ }
3013
+ this.parts = _fixedParts;
3003
3014
  }
3004
3015
  static fromRange(range, getters) {
3005
3016
  if (range instanceof RangeImpl) {
@@ -4049,13 +4060,10 @@ const readonlyAllowedCommands = new Set([
4049
4060
  "START",
4050
4061
  "ACTIVATE_SHEET",
4051
4062
  "COPY",
4052
- "PREPARE_SELECTION_INPUT_EXPANSION",
4053
- "STOP_SELECTION_INPUT",
4054
4063
  "RESIZE_SHEETVIEW",
4055
4064
  "SET_VIEWPORT_OFFSET",
4056
4065
  "SELECT_SEARCH_NEXT_MATCH",
4057
4066
  "SELECT_SEARCH_PREVIOUS_MATCH",
4058
- "REFRESH_SEARCH",
4059
4067
  "UPDATE_SEARCH",
4060
4068
  "CLEAR_SEARCH",
4061
4069
  "EVALUATE_CELLS",
@@ -5127,8 +5135,7 @@ autofillModifiersRegistry
5127
5135
  return { cellData: {} };
5128
5136
  }
5129
5137
  const sheetId = data.sheetId;
5130
- const ranges = getters.createAdaptedRanges(cell.dependencies, x, y, sheetId);
5131
- const content = getters.buildFormulaContent(sheetId, cell, ranges);
5138
+ const content = getters.getTranslatedCellFormula(sheetId, x, y, cell.compiledFormula, cell.dependencies);
5132
5139
  return {
5133
5140
  cellData: {
5134
5141
  border: data.border,
@@ -5994,7 +6001,7 @@ css /* scss */ `
5994
6001
  }
5995
6002
  }
5996
6003
  &.disabled {
5997
- color: ${MENU_ITEM_DISABLED_COLOR};
6004
+ color: ${DISABLED_TEXT_COLOR};
5998
6005
  cursor: not-allowed;
5999
6006
  }
6000
6007
  }
@@ -22420,6 +22427,18 @@ class ConditionalFormattingPanel extends owl.Component {
22420
22427
  style[tool] = !style[tool];
22421
22428
  this.closeMenus();
22422
22429
  }
22430
+ onKeydown(event) {
22431
+ if (event.key === "F4") {
22432
+ const target = event.target;
22433
+ const update = this.env.model.getters.getCycledReference({ start: target.selectionStart ?? 0, end: target.selectionEnd ?? 0 }, target.value);
22434
+ if (!update) {
22435
+ return;
22436
+ }
22437
+ target.value = update.content;
22438
+ target.setSelectionRange(update.selection.start, update.selection.end);
22439
+ target.dispatchEvent(new Event("input"));
22440
+ }
22441
+ }
22423
22442
  setColor(target, color) {
22424
22443
  this.state.rules.cellIs.style[target] = color;
22425
22444
  this.closeMenus();
@@ -22694,6 +22713,7 @@ class FindAndReplacePanel extends owl.Component {
22694
22713
  state = owl.useState(this.initialState());
22695
22714
  debounceTimeoutId;
22696
22715
  showFormulaState = false;
22716
+ debouncedUpdateSearch;
22697
22717
  findAndReplaceRef = owl.useRef("findAndReplace");
22698
22718
  get hasSearchResult() {
22699
22719
  return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
@@ -22703,11 +22723,16 @@ class FindAndReplacePanel extends owl.Component {
22703
22723
  }
22704
22724
  setup() {
22705
22725
  this.showFormulaState = this.env.model.getters.shouldShowFormulas();
22726
+ this.debouncedUpdateSearch = debounce(this.updateSearch.bind(this), 200);
22706
22727
  owl.onMounted(() => this.focusInput());
22707
22728
  owl.onWillUnmount(() => {
22708
22729
  this.env.model.dispatch("CLEAR_SEARCH");
22709
22730
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.showFormulaState });
22710
22731
  });
22732
+ owl.useEffect(() => {
22733
+ this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
22734
+ this.searchFormulas();
22735
+ }, () => [this.env.model.getters.shouldShowFormulas()]);
22711
22736
  }
22712
22737
  onInput(ev) {
22713
22738
  this.state.toSearch = ev.target.value;
@@ -22727,10 +22752,6 @@ class FindAndReplacePanel extends owl.Component {
22727
22752
  this.replace();
22728
22753
  }
22729
22754
  }
22730
- onFocusSidePanel() {
22731
- this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
22732
- this.env.model.dispatch("REFRESH_SEARCH");
22733
- }
22734
22755
  searchFormulas() {
22735
22756
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
22736
22757
  show: this.state.searchOptions.searchFormulas,
@@ -22749,13 +22770,6 @@ class FindAndReplacePanel extends owl.Component {
22749
22770
  searchOptions: this.state.searchOptions,
22750
22771
  });
22751
22772
  }
22752
- debouncedUpdateSearch() {
22753
- clearTimeout(this.debounceTimeoutId);
22754
- this.debounceTimeoutId = setTimeout(() => {
22755
- this.updateSearch();
22756
- this.debounceTimeoutId = undefined;
22757
- }, 400);
22758
- }
22759
22773
  replace() {
22760
22774
  this.env.model.dispatch("REPLACE_SEARCH", {
22761
22775
  replaceWith: this.state.replaceWith,
@@ -24695,6 +24709,15 @@ function dragFigureForResize(initialFigure, dirX, dirY, { x: mouseX, y: mouseY }
24695
24709
  y = initialFigure.y - deltaY;
24696
24710
  }
24697
24711
  }
24712
+ // Restrict resizing if x or y reaches header boundaries
24713
+ if (x < 0) {
24714
+ width += x;
24715
+ x = 0;
24716
+ }
24717
+ if (y < 0) {
24718
+ height += y;
24719
+ y = 0;
24720
+ }
24698
24721
  return { ...initialFigure, x, y, width, height };
24699
24722
  }
24700
24723
 
@@ -25287,10 +25310,29 @@ function useCellHovered(env, gridRef, callback) {
25287
25310
  setPosition(undefined, undefined);
25288
25311
  }
25289
25312
  }
25313
+ function onMouseLeave(e) {
25314
+ const x = e.offsetX;
25315
+ const y = e.offsetY;
25316
+ const gridRect = getBoundingRectAsPOJO(gridRef.el);
25317
+ if (y < 0 || y > gridRect.height || x < 0 || x > gridRect.width) {
25318
+ return updateMousePosition(e);
25319
+ }
25320
+ else {
25321
+ return pause();
25322
+ }
25323
+ }
25290
25324
  useRefListener(gridRef, "mousemove", updateMousePosition);
25291
- useRefListener(gridRef, "mouseleave", pause);
25325
+ useRefListener(gridRef, "mouseleave", onMouseLeave);
25292
25326
  useRefListener(gridRef, "mouseenter", resume);
25293
25327
  useRefListener(gridRef, "mousedown", recompute);
25328
+ owl.useExternalListener(window, "click", handleGlobalClick);
25329
+ function handleGlobalClick(e) {
25330
+ const target = e.target;
25331
+ const grid = gridRef.el;
25332
+ if (!grid.contains(target)) {
25333
+ setPosition(undefined, undefined);
25334
+ }
25335
+ }
25294
25336
  function setPosition(col, row) {
25295
25337
  if (col !== hoveredPosition.col || row !== hoveredPosition.row) {
25296
25338
  hoveredPosition.col = col;
@@ -25614,7 +25656,6 @@ class AbstractResizer extends owl.Component {
25614
25656
  const mouseUpSelect = () => {
25615
25657
  this.state.isSelecting = false;
25616
25658
  this.lastSelectedElementIndex = null;
25617
- this.env.model.dispatch(ev.ctrlKey ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
25618
25659
  this._computeGrabDisplay(ev);
25619
25660
  };
25620
25661
  dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
@@ -26179,9 +26220,7 @@ class Highlight extends owl.Component {
26179
26220
  let lastCol = isLeft ? z.left : z.right;
26180
26221
  let lastRow = isTop ? z.top : z.bottom;
26181
26222
  let currentZone = z;
26182
- this.env.model.dispatch("START_CHANGE_HIGHLIGHT", {
26183
- range: this.env.model.getters.getRangeDataFromZone(activeSheetId, currentZone),
26184
- });
26223
+ this.env.model.dispatch("START_CHANGE_HIGHLIGHT", { zone: currentZone });
26185
26224
  const mouseMove = (col, row) => {
26186
26225
  if (lastCol !== col || lastRow !== row) {
26187
26226
  lastCol = clip(col === -1 ? lastCol : col, 0, this.env.model.getters.getNumberCols(activeSheetId) - 1);
@@ -26192,21 +26231,17 @@ class Highlight extends owl.Component {
26192
26231
  right: Math.max(pivotCol, lastCol),
26193
26232
  bottom: Math.max(pivotRow, lastRow),
26194
26233
  };
26195
- newZone = this.env.model.getters.expandZone(activeSheetId, newZone);
26196
26234
  if (!isEqual(newZone, currentZone)) {
26197
- this.env.model.dispatch("CHANGE_HIGHLIGHT", {
26198
- range: this.env.model.getters.getRangeFromZone(activeSheetId, this.env.model.getters.getUnboundedZone(activeSheetId, newZone)).rangeData,
26199
- });
26235
+ this.env.model.selection.selectZone({
26236
+ cell: { col: newZone.left, row: newZone.top },
26237
+ zone: newZone,
26238
+ }, { unbounded: true });
26200
26239
  currentZone = newZone;
26201
26240
  }
26202
26241
  }
26203
26242
  };
26204
26243
  const mouseUp = () => {
26205
26244
  this.highlightState.shiftingMode = "none";
26206
- // To do:
26207
- // Command used here to restore focus to the current composer,
26208
- // to be changed when refactoring the 'edition' plugin
26209
- this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
26210
26245
  };
26211
26246
  dragAndDropBeyondTheViewport(this.env, mouseMove, mouseUp);
26212
26247
  }
@@ -26222,9 +26257,7 @@ class Highlight extends owl.Component {
26222
26257
  const deltaRowMin = -z.top;
26223
26258
  const deltaRowMax = this.env.model.getters.getNumberRows(activeSheetId) - z.bottom - 1;
26224
26259
  let currentZone = z;
26225
- this.env.model.dispatch("START_CHANGE_HIGHLIGHT", {
26226
- range: this.env.model.getters.getRangeDataFromZone(activeSheetId, currentZone),
26227
- });
26260
+ this.env.model.dispatch("START_CHANGE_HIGHLIGHT", { zone: currentZone });
26228
26261
  let lastCol = initCol;
26229
26262
  let lastRow = initRow;
26230
26263
  const mouseMove = (col, row) => {
@@ -26239,21 +26272,17 @@ class Highlight extends owl.Component {
26239
26272
  right: z.right + deltaCol,
26240
26273
  bottom: z.bottom + deltaRow,
26241
26274
  };
26242
- newZone = this.env.model.getters.expandZone(activeSheetId, newZone);
26243
26275
  if (!isEqual(newZone, currentZone)) {
26244
- this.env.model.dispatch("CHANGE_HIGHLIGHT", {
26245
- range: this.env.model.getters.getRangeFromZone(activeSheetId, this.env.model.getters.getUnboundedZone(activeSheetId, newZone)).rangeData,
26246
- });
26276
+ this.env.model.selection.selectZone({
26277
+ cell: { col: newZone.left, row: newZone.top },
26278
+ zone: newZone,
26279
+ }, { unbounded: true });
26247
26280
  currentZone = newZone;
26248
26281
  }
26249
26282
  }
26250
26283
  };
26251
26284
  const mouseUp = () => {
26252
26285
  this.highlightState.shiftingMode = "none";
26253
- // To do:
26254
- // Command used here to restore focus to the current composer,
26255
- // to be changed when refactoring the 'edition' plugin
26256
- this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
26257
26286
  };
26258
26287
  dragAndDropBeyondTheViewport(this.env, mouseMove, mouseUp);
26259
26288
  }
@@ -26746,9 +26775,6 @@ class Grid extends owl.Component {
26746
26775
  // Zone selection with mouse
26747
26776
  // ---------------------------------------------------------------------------
26748
26777
  onCellClicked(col, row, { ctrlKey, shiftKey }) {
26749
- if (ctrlKey) {
26750
- this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
26751
- }
26752
26778
  if (this.env.model.getters.hasOpenedPopover()) {
26753
26779
  this.closeOpenedPopover();
26754
26780
  }
@@ -26774,7 +26800,6 @@ class Grid extends owl.Component {
26774
26800
  }
26775
26801
  };
26776
26802
  const onMouseUp = () => {
26777
- this.env.model.dispatch("STOP_SELECTION_INPUT");
26778
26803
  if (this.env.model.getters.isPaintingFormat()) {
26779
26804
  this.env.model.dispatch("PASTE", {
26780
26805
  target: this.env.model.getters.getSelectedZones(),
@@ -31492,8 +31517,8 @@ class CellPlugin extends CorePlugin {
31492
31517
  "zoneToXC",
31493
31518
  "getCells",
31494
31519
  "getFormulaCellContent",
31520
+ "getTranslatedCellFormula",
31495
31521
  "getCellStyle",
31496
- "buildFormulaContent",
31497
31522
  "getCellById",
31498
31523
  ];
31499
31524
  nextId = 1;
@@ -31692,7 +31717,7 @@ class CellPlugin extends CorePlugin {
31692
31717
  /*
31693
31718
  * Reconstructs the original formula string based on a normalized form and its dependencies
31694
31719
  */
31695
- buildFormulaContent(sheetId, cell, dependencies) {
31720
+ getFormulaCellContent(sheetId, cell, dependencies) {
31696
31721
  const ranges = dependencies || [...cell.dependencies];
31697
31722
  return concat(cell.compiledFormula.tokens.map((token) => {
31698
31723
  if (token.type === "REFERENCE") {
@@ -31702,8 +31727,15 @@ class CellPlugin extends CorePlugin {
31702
31727
  return token.value;
31703
31728
  }));
31704
31729
  }
31705
- getFormulaCellContent(sheetId, cell) {
31706
- return this.buildFormulaContent(sheetId, cell);
31730
+ /*
31731
+ * Constructs a formula string based on an initial formula and a translation vector
31732
+ */
31733
+ getTranslatedCellFormula(sheetId, offsetX, offsetY, compiledFormula, dependencies) {
31734
+ const adaptedDependencies = this.getters.createAdaptedRanges(dependencies, offsetX, offsetY, sheetId);
31735
+ return this.getFormulaCellContent(sheetId, {
31736
+ compiledFormula,
31737
+ dependencies: adaptedDependencies,
31738
+ });
31707
31739
  }
31708
31740
  getCellStyle(position) {
31709
31741
  return this.getters.getCell(position)?.style || {};
@@ -31893,7 +31925,7 @@ class CellPlugin extends CorePlugin {
31893
31925
  */
31894
31926
  createFormulaCellWithDependencies(id, compiledFormula, format, style, sheetId) {
31895
31927
  const dependencies = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
31896
- return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.buildFormulaContent.bind(this));
31928
+ return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getFormulaCellContent.bind(this));
31897
31929
  }
31898
31930
  createErrorFormula(id, content, format, style, error) {
31899
31931
  return {
@@ -31927,19 +31959,19 @@ class FormulaCellWithDependencies {
31927
31959
  style;
31928
31960
  dependencies;
31929
31961
  sheetId;
31930
- buildFormulaContent;
31962
+ getFormulaCellContent;
31931
31963
  isFormula = true;
31932
- constructor(id, compiledFormula, format, style, dependencies, sheetId, buildFormulaContent) {
31964
+ constructor(id, compiledFormula, format, style, dependencies, sheetId, getFormulaCellContent) {
31933
31965
  this.id = id;
31934
31966
  this.compiledFormula = compiledFormula;
31935
31967
  this.format = format;
31936
31968
  this.style = style;
31937
31969
  this.dependencies = dependencies;
31938
31970
  this.sheetId = sheetId;
31939
- this.buildFormulaContent = buildFormulaContent;
31971
+ this.getFormulaCellContent = getFormulaCellContent;
31940
31972
  }
31941
31973
  get content() {
31942
- return this.buildFormulaContent(this.sheetId, {
31974
+ return this.getFormulaCellContent(this.sheetId, {
31943
31975
  dependencies: this.dependencies,
31944
31976
  compiledFormula: this.compiledFormula,
31945
31977
  });
@@ -36454,13 +36486,21 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
36454
36486
  }
36455
36487
  break;
36456
36488
  case "CellIsRule":
36489
+ const formulas = cf.rule.values.map((value) => value.startsWith("=") ? compile(value) : undefined);
36457
36490
  for (let ref of cf.ranges) {
36458
36491
  const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
36459
36492
  for (let row = zone.top; row <= zone.bottom; row++) {
36460
36493
  for (let col = zone.left; col <= zone.right; col++) {
36461
- const pr = this.rulePredicate[cf.rule.type];
36462
- let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
36463
- if (pr && pr(cell, cf.rule)) {
36494
+ const predicate = this.rulePredicate[cf.rule.type];
36495
+ const target = { sheetId, col, row };
36496
+ const values = cf.rule.values.map((value, i) => {
36497
+ const compiledFormula = formulas[i];
36498
+ if (compiledFormula) {
36499
+ return this.getters.getTranslatedCellFormula(sheetId, col - zone.left, row - zone.top, compiledFormula, compiledFormula.dependencies.map((d) => this.getters.getRangeFromSheetXC(sheetId, d)));
36500
+ }
36501
+ return value;
36502
+ });
36503
+ if (predicate && predicate(target, { ...cf.rule, values })) {
36464
36504
  if (!computedStyle[col])
36465
36505
  computedStyle[col] = [];
36466
36506
  // we must combine all the properties of all the CF rules applied to the given cell
@@ -36628,12 +36668,18 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
36628
36668
  * Execute the predicate to know if a conditional formatting rule should be applied to a cell
36629
36669
  */
36630
36670
  rulePredicate = {
36631
- CellIsRule: (cell, rule) => {
36671
+ CellIsRule: (target, rule) => {
36672
+ const cell = this.getters.getEvaluatedCell(target);
36632
36673
  if (cell.type === CellValueType.error) {
36633
36674
  return false;
36634
36675
  }
36635
36676
  const locale = this.getters.getLocale();
36636
- const values = rule.values.map((val) => parseLiteral(val, locale));
36677
+ const values = rule.values.map((value) => {
36678
+ if (value.startsWith("=")) {
36679
+ return this.getters.evaluateFormula(target.sheetId, value);
36680
+ }
36681
+ return parseLiteral(value, locale);
36682
+ });
36637
36683
  switch (rule.operator) {
36638
36684
  case "IsEmpty":
36639
36685
  return cell.value.toString().trim() === "";
@@ -38534,6 +38580,7 @@ class FindAndReplacePlugin extends UIPlugin {
38534
38580
  searchFormulas: false,
38535
38581
  };
38536
38582
  toSearch = "";
38583
+ isSearchDirty = false;
38537
38584
  // ---------------------------------------------------------------------------
38538
38585
  // Command Handling
38539
38586
  // ---------------------------------------------------------------------------
@@ -38557,18 +38604,33 @@ class FindAndReplacePlugin extends UIPlugin {
38557
38604
  case "REPLACE_ALL_SEARCH":
38558
38605
  this.replaceAll(cmd.replaceWith);
38559
38606
  break;
38607
+ case "EVALUATE_CELLS":
38608
+ case "UPDATE_CELL":
38609
+ case "REMOVE_FILTER_TABLE":
38610
+ case "UPDATE_FILTER":
38611
+ this.isSearchDirty = true;
38612
+ break;
38560
38613
  case "UNDO":
38561
38614
  case "REDO":
38562
38615
  case "REMOVE_COLUMNS_ROWS":
38616
+ case "HIDE_COLUMNS_ROWS":
38617
+ case "UNHIDE_COLUMNS_ROWS":
38563
38618
  case "ADD_COLUMNS_ROWS":
38564
- this.clearSearch();
38619
+ case "EVALUATE_CELLS":
38620
+ case "UPDATE_CELL":
38621
+ this.isSearchDirty = true;
38565
38622
  break;
38566
38623
  case "ACTIVATE_SHEET":
38567
- case "REFRESH_SEARCH":
38568
38624
  this.refreshSearch();
38569
38625
  break;
38570
38626
  }
38571
38627
  }
38628
+ finalize() {
38629
+ if (this.isSearchDirty) {
38630
+ this.refreshSearch();
38631
+ this.isSearchDirty = false;
38632
+ }
38633
+ }
38572
38634
  // ---------------------------------------------------------------------------
38573
38635
  // Getters
38574
38636
  // ---------------------------------------------------------------------------
@@ -38624,6 +38686,11 @@ class FindAndReplacePlugin extends UIPlugin {
38624
38686
  if (this.toSearch) {
38625
38687
  for (const cell of Object.values(cells)) {
38626
38688
  const { col, row } = this.getters.getCellPosition(cell.id);
38689
+ const isColHidden = this.getters.isColHidden(sheetId, col);
38690
+ const isRowHidden = this.getters.isRowHidden(sheetId, row);
38691
+ if (isColHidden || isRowHidden) {
38692
+ continue;
38693
+ }
38627
38694
  if (cell &&
38628
38695
  this.currentSearchRegex &&
38629
38696
  this.currentSearchRegex.test(this.getSearchableString({ sheetId, col, row }))) {
@@ -38683,37 +38750,32 @@ class FindAndReplacePlugin extends UIPlugin {
38683
38750
  // ---------------------------------------------------------------------------
38684
38751
  // Replace
38685
38752
  // ---------------------------------------------------------------------------
38686
- /**
38687
- * Replace the value of the currently selected match
38688
- */
38689
- replace(replaceWith) {
38690
- if (this.selectedMatchIndex === null || !this.currentSearchRegex) {
38753
+ replaceMatch(selectedMatch, replaceWith) {
38754
+ if (!this.currentSearchRegex) {
38691
38755
  return;
38692
38756
  }
38693
- const matches = this.searchMatches;
38694
- const selectedMatch = matches[this.selectedMatchIndex];
38695
38757
  const sheetId = this.getters.getActiveSheetId();
38696
38758
  const cell = this.getters.getCell({ sheetId, ...selectedMatch });
38759
+ const { col, row } = selectedMatch;
38697
38760
  if (cell?.isFormula && !this.searchOptions.searchFormulas) {
38698
- this.selectNextCell(Direction.next);
38761
+ return;
38699
38762
  }
38700
- else {
38701
- const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
38702
- const toReplace = this.getSearchableString({
38703
- sheetId,
38704
- col: selectedMatch.col,
38705
- row: selectedMatch.row,
38706
- });
38707
- const newContent = toReplace.replace(replaceRegex, replaceWith);
38708
- this.dispatch("UPDATE_CELL", {
38709
- sheetId: this.getters.getActiveSheetId(),
38710
- col: selectedMatch.col,
38711
- row: selectedMatch.row,
38712
- content: canonicalizeContent(newContent, this.getters.getLocale()),
38713
- });
38714
- this.searchMatches.splice(this.selectedMatchIndex, 1);
38715
- this.selectNextCell(Direction.current);
38763
+ const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
38764
+ const toReplace = this.getSearchableString({ sheetId, col, row });
38765
+ const content = toReplace.replace(replaceRegex, replaceWith);
38766
+ const canonicalContent = canonicalizeContent(content, this.getters.getLocale());
38767
+ this.dispatch("UPDATE_CELL", { sheetId, col, row, content: canonicalContent });
38768
+ }
38769
+ /**
38770
+ * Replace the value of the currently selected match
38771
+ */
38772
+ replace(replaceWith) {
38773
+ if (this.selectedMatchIndex === null) {
38774
+ return;
38716
38775
  }
38776
+ const selectedMatch = this.searchMatches[this.selectedMatchIndex];
38777
+ this.replaceMatch(selectedMatch, replaceWith);
38778
+ this.selectNextCell(Direction.next);
38717
38779
  }
38718
38780
  /**
38719
38781
  * Apply the replace function to all the matches one time.
@@ -38721,7 +38783,7 @@ class FindAndReplacePlugin extends UIPlugin {
38721
38783
  replaceAll(replaceWith) {
38722
38784
  const matchCount = this.searchMatches.length;
38723
38785
  for (let i = 0; i < matchCount; i++) {
38724
- this.replace(replaceWith);
38786
+ this.replaceMatch(this.searchMatches[i], replaceWith);
38725
38787
  }
38726
38788
  }
38727
38789
  getSearchableString(position) {
@@ -39643,8 +39705,7 @@ class SelectionInputPlugin extends UIPlugin {
39643
39705
  static getters = [];
39644
39706
  ranges = [];
39645
39707
  focusedRangeIndex = null;
39646
- activeSheet;
39647
- willAddNewRange = false;
39708
+ inputSheetId;
39648
39709
  constructor(config, initialRanges, inputHasSingleRange) {
39649
39710
  if (inputHasSingleRange && initialRanges.length > 1) {
39650
39711
  throw new Error("Input with a single range cannot be instantiated with several range references.");
@@ -39652,7 +39713,7 @@ class SelectionInputPlugin extends UIPlugin {
39652
39713
  super(config);
39653
39714
  this.inputHasSingleRange = inputHasSingleRange;
39654
39715
  this.insertNewRange(0, initialRanges);
39655
- this.activeSheet = this.getters.getActiveSheetId();
39716
+ this.inputSheetId = this.getters.getActiveSheetId();
39656
39717
  if (this.ranges.length === 0) {
39657
39718
  this.insertNewRange(this.ranges.length, [""]);
39658
39719
  this.focusLast();
@@ -39678,11 +39739,33 @@ class SelectionInputPlugin extends UIPlugin {
39678
39739
  return 0 /* CommandResult.Success */;
39679
39740
  }
39680
39741
  handleEvent(event) {
39681
- const inputSheetId = this.activeSheet;
39682
- const sheetId = this.getters.getActiveSheetId();
39683
- const zone = event.anchor.zone;
39684
- const range = this.getters.getRangeFromZone(sheetId, event.options.unbounded ? this.getters.getUnboundedZone(sheetId, zone) : zone);
39685
- this.add([this.getters.getSelectionRangeString(range, inputSheetId)]);
39742
+ if (this.focusedRangeIndex === null) {
39743
+ return;
39744
+ }
39745
+ const inputSheetId = this.inputSheetId;
39746
+ const activeSheetId = this.getters.getActiveSheetId();
39747
+ const zone = event.options.unbounded
39748
+ ? this.getters.getUnboundedZone(activeSheetId, event.anchor.zone)
39749
+ : event.anchor.zone;
39750
+ const range = this.getters.getRangeFromZone(activeSheetId, zone);
39751
+ const willAddNewRange = event.mode === "newAnchor" &&
39752
+ !this.inputHasSingleRange &&
39753
+ this.ranges[this.focusedRangeIndex].xc.trim() !== "";
39754
+ if (willAddNewRange) {
39755
+ const xc = this.getters.getSelectionRangeString(range, inputSheetId);
39756
+ this.insertNewRange(this.ranges.length, [xc]);
39757
+ this.focusLast();
39758
+ }
39759
+ else {
39760
+ let parts = range.parts;
39761
+ const previousXc = this.ranges[this.focusedRangeIndex].xc.trim();
39762
+ if (previousXc) {
39763
+ parts = this.getters.getRangeFromSheetXC(inputSheetId, previousXc).parts;
39764
+ }
39765
+ const newRange = range.clone({ parts });
39766
+ const xc = this.getters.getSelectionRangeString(newRange, inputSheetId);
39767
+ this.setRange(this.focusedRangeIndex, [xc]);
39768
+ }
39686
39769
  }
39687
39770
  handle(cmd) {
39688
39771
  switch (cmd.type) {
@@ -39718,16 +39801,6 @@ class SelectionInputPlugin extends UIPlugin {
39718
39801
  this.removeRange(index);
39719
39802
  }
39720
39803
  break;
39721
- case "STOP_SELECTION_INPUT":
39722
- this.willAddNewRange = false;
39723
- break;
39724
- case "PREPARE_SELECTION_INPUT_EXPANSION": {
39725
- const index = this.focusedRangeIndex;
39726
- if (index !== null && !this.inputHasSingleRange) {
39727
- this.willAddNewRange = this.ranges[index].xc.trim() !== "";
39728
- }
39729
- break;
39730
- }
39731
39804
  case "ACTIVATE_SHEET": {
39732
39805
  if (cmd.sheetIdFrom !== cmd.sheetIdTo) {
39733
39806
  const { col, row } = this.getters.getNextVisibleCellPosition({
@@ -39738,7 +39811,26 @@ class SelectionInputPlugin extends UIPlugin {
39738
39811
  const zone = this.getters.expandZone(cmd.sheetIdTo, positionToZone({ col, row }));
39739
39812
  this.selection.resetAnchor(this, { cell: { col, row }, zone });
39740
39813
  }
39814
+ break;
39741
39815
  }
39816
+ case "START_CHANGE_HIGHLIGHT":
39817
+ const activeSheetId = this.getters.getActiveSheetId();
39818
+ const newZone = this.getters.expandZone(activeSheetId, cmd.zone);
39819
+ const focusIndex = this.ranges.findIndex((range) => {
39820
+ const { xc, sheetName: sheet } = splitReference(range.xc);
39821
+ const sheetName = sheet || this.getters.getSheetName(this.inputSheetId);
39822
+ if (this.getters.getSheetName(activeSheetId) !== sheetName) {
39823
+ return false;
39824
+ }
39825
+ const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
39826
+ return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), newZone);
39827
+ });
39828
+ if (focusIndex !== -1) {
39829
+ this.focus(focusIndex);
39830
+ const { left, top } = newZone;
39831
+ this.selection.resetAnchor(this, { cell: { col: left, row: top }, zone: newZone });
39832
+ }
39833
+ break;
39742
39834
  }
39743
39835
  }
39744
39836
  // ---------------------------------------------------------------------------
@@ -39767,19 +39859,6 @@ class SelectionInputPlugin extends UIPlugin {
39767
39859
  unfocus() {
39768
39860
  this.focusedRangeIndex = null;
39769
39861
  }
39770
- add(newRanges) {
39771
- if (this.focusedRangeIndex === null || newRanges.length === 0) {
39772
- return;
39773
- }
39774
- if (this.willAddNewRange) {
39775
- this.insertNewRange(this.ranges.length, newRanges);
39776
- this.focusLast();
39777
- this.willAddNewRange = false;
39778
- }
39779
- else {
39780
- this.setRange(this.focusedRangeIndex, newRanges);
39781
- }
39782
- }
39783
39862
  setContent(index, xc) {
39784
39863
  this.ranges[index] = {
39785
39864
  ...this.ranges[index],
@@ -39825,12 +39904,12 @@ class SelectionInputPlugin extends UIPlugin {
39825
39904
  inputToHighlights({ xc, color }) {
39826
39905
  const XCs = this.cleanInputs([xc])
39827
39906
  .filter((range) => this.getters.isRangeValid(range))
39828
- .filter((reference) => this.shouldBeHighlighted(this.activeSheet, reference));
39907
+ .filter((reference) => this.shouldBeHighlighted(this.inputSheetId, reference));
39829
39908
  return XCs.map((xc) => {
39830
39909
  const { sheetName } = splitReference(xc);
39831
39910
  return {
39832
- zone: this.getters.getRangeFromSheetXC(this.activeSheet, xc).zone,
39833
- sheetId: (sheetName && this.getters.getSheetIdByName(sheetName)) || this.activeSheet,
39911
+ zone: this.getters.getRangeFromSheetXC(this.inputSheetId, xc).zone,
39912
+ sheetId: (sheetName && this.getters.getSheetIdByName(sheetName)) || this.inputSheetId,
39834
39913
  color,
39835
39914
  };
39836
39915
  });
@@ -40255,10 +40334,8 @@ class SortPlugin extends UIPlugin {
40255
40334
  let content = cell.content;
40256
40335
  if (cell.isFormula) {
40257
40336
  const position = this.getters.getCellPosition(cell.id);
40258
- const offsetY = newRow - position.row;
40259
40337
  // we only have a vertical offset
40260
- const ranges = this.getters.createAdaptedRanges(cell.dependencies, 0, offsetY, sheetId);
40261
- content = this.getters.buildFormulaContent(sheetId, cell, ranges);
40338
+ content = this.getters.getTranslatedCellFormula(sheetId, 0, newRow - position.row, cell.compiledFormula, cell.dependencies);
40262
40339
  }
40263
40340
  newCellValues.style = cell.style;
40264
40341
  newCellValues.content = content;
@@ -41365,9 +41442,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
41365
41442
  }
41366
41443
  let content = origin.cell.content;
41367
41444
  if (origin.cell.isFormula && operation === "COPY") {
41368
- const offsetX = col - origin.position.col;
41369
- const offsetY = row - origin.position.row;
41370
- content = this.getUpdatedContent(sheetId, origin.cell, offsetX, offsetY, operation);
41445
+ content = this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula, origin.cell.dependencies);
41371
41446
  }
41372
41447
  this.dispatch("UPDATE_CELL", {
41373
41448
  ...target,
@@ -41388,13 +41463,6 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
41388
41463
  }
41389
41464
  }
41390
41465
  }
41391
- /**
41392
- * Get the newly updated formula, after applying offsets
41393
- */
41394
- getUpdatedContent(sheetId, cell, offsetX, offsetY, operation) {
41395
- const ranges = this.getters.createAdaptedRanges(cell.dependencies, offsetX, offsetY, sheetId);
41396
- return this.getters.buildFormulaContent(sheetId, cell, ranges);
41397
- }
41398
41466
  /**
41399
41467
  * If the origin position given is the top left of a merge, merge the target
41400
41468
  * position.
@@ -42136,6 +42204,7 @@ class EditionPlugin extends UIPlugin {
42136
42204
  "getTokenAtCursor",
42137
42205
  "getComposerHighlights",
42138
42206
  "getCurrentEditedCell",
42207
+ "getCycledReference",
42139
42208
  ];
42140
42209
  col = 0;
42141
42210
  row = 0;
@@ -42145,10 +42214,7 @@ class EditionPlugin extends UIPlugin {
42145
42214
  currentTokens = [];
42146
42215
  selectionStart = 0;
42147
42216
  selectionEnd = 0;
42148
- selectionInitialStart = 0;
42149
42217
  initialContent = "";
42150
- previousRef = "";
42151
- previousRange = undefined;
42152
42218
  colorIndexByRange = {};
42153
42219
  // ---------------------------------------------------------------------------
42154
42220
  // Command Handling
@@ -42177,9 +42243,6 @@ class EditionPlugin extends UIPlugin {
42177
42243
  }
42178
42244
  }
42179
42245
  handleEvent(event) {
42180
- if (this.mode !== "selecting") {
42181
- return;
42182
- }
42183
42246
  const sheetId = this.getters.getActiveSheetId();
42184
42247
  let unboundedZone;
42185
42248
  if (event.options.unbounded) {
@@ -42190,10 +42253,17 @@ class EditionPlugin extends UIPlugin {
42190
42253
  }
42191
42254
  switch (event.mode) {
42192
42255
  case "newAnchor":
42193
- this.insertSelectedRange(unboundedZone);
42256
+ if (this.mode === "selecting") {
42257
+ this.insertSelectedRange(unboundedZone);
42258
+ }
42194
42259
  break;
42195
42260
  default:
42196
- this.replaceSelectedRanges(unboundedZone);
42261
+ if (this.mode === "selecting") {
42262
+ this.replaceSelectedRange(unboundedZone);
42263
+ }
42264
+ else {
42265
+ this.updateComposerRange(event.previousAnchor.zone, unboundedZone);
42266
+ }
42197
42267
  break;
42198
42268
  }
42199
42269
  }
@@ -42250,35 +42320,12 @@ class EditionPlugin extends UIPlugin {
42250
42320
  }
42251
42321
  break;
42252
42322
  case "START_CHANGE_HIGHLIGHT":
42253
- // FIXME: thiws whole ordeal could be handled with the Selection Processor which would extend the feature to selection inputs
42254
- this.dispatch("STOP_COMPOSER_RANGE_SELECTION");
42255
- // FIXME: we should check range SheetId compared to this.activeSheetId r maybe not have a sheetId in the payload ??
42256
- const range = this.getters.getRangeFromRangeData(cmd.range);
42257
- const previousRefToken = this.currentTokens
42258
- .filter((token) => token.type === "REFERENCE")
42259
- .find((token) => {
42260
- const { xc, sheetName: sheet } = splitReference(token.value);
42261
- const sheetName = sheet || this.getters.getSheetName(this.sheetId);
42262
- const activeSheetId = this.getters.getActiveSheetId();
42263
- if (this.getters.getSheetName(activeSheetId) !== sheetName) {
42264
- return false;
42265
- }
42266
- const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
42267
- return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), range.zone);
42268
- });
42269
- this.previousRef = previousRefToken.value;
42270
- this.previousRange = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), this.previousRef);
42271
- this.selectionInitialStart = previousRefToken.start;
42272
- break;
42273
- case "CHANGE_HIGHLIGHT":
42274
- const cmdRange = this.getters.getRangeFromRangeData(cmd.range);
42275
- const newRef = this.getRangeReference(cmdRange, this.previousRange.parts);
42276
- this.selectionStart = this.selectionInitialStart;
42277
- this.selectionEnd = this.selectionInitialStart + this.previousRef.length;
42278
- this.replaceSelection(newRef);
42279
- this.previousRef = newRef;
42280
- this.selectionStart = this.currentContent.length;
42281
- this.selectionEnd = this.currentContent.length;
42323
+ const { left, top } = cmd.zone;
42324
+ // changing the highlight can conflit with the 'selecting' mode
42325
+ if (this.isSelectingForComposer()) {
42326
+ this.mode = "editing";
42327
+ }
42328
+ this.selection.resetAnchor(this, { cell: { col: left, row: top }, zone: cmd.zone });
42282
42329
  break;
42283
42330
  case "ACTIVATE_SHEET":
42284
42331
  if (!this.currentContent.startsWith("=")) {
@@ -42362,33 +42409,45 @@ class EditionPlugin extends UIPlugin {
42362
42409
  return this.currentTokens.find((t) => t.start <= start && t.end >= end);
42363
42410
  }
42364
42411
  }
42365
- // ---------------------------------------------------------------------------
42366
- // Misc
42367
- // ---------------------------------------------------------------------------
42368
- cycleReferences() {
42369
- const tokens = this.getTokensInSelection();
42412
+ /**
42413
+ * Return the cycled reference if any (A1 -> $A$1 -> A$1 -> $A1 -> A1)
42414
+ */
42415
+ getCycledReference(selection, content) {
42416
+ const locale = this.getters.getLocale();
42417
+ const currentTokens = content.startsWith("=") ? composerTokenize(content, locale) : [];
42418
+ const tokens = currentTokens.filter((t) => (t.start <= selection.start && t.end >= selection.start) ||
42419
+ (t.start >= selection.start && t.start < selection.end));
42370
42420
  const refTokens = tokens.filter((token) => token.type === "REFERENCE");
42371
- if (refTokens.length === 0)
42421
+ if (refTokens.length === 0) {
42372
42422
  return;
42423
+ }
42373
42424
  const updatedReferences = tokens
42374
42425
  .map(loopThroughReferenceType)
42375
42426
  .map((token) => token.value)
42376
42427
  .join("");
42377
- const content = this.currentContent;
42378
42428
  const start = tokens[0].start;
42379
42429
  const end = tokens[tokens.length - 1].end;
42380
42430
  const newContent = content.slice(0, start) + updatedReferences + content.slice(end);
42381
42431
  const lengthDiff = newContent.length - content.length;
42382
42432
  const startOfTokens = refTokens[0].start;
42383
42433
  const endOfTokens = refTokens[refTokens.length - 1].end + lengthDiff;
42384
- const selection = { start: startOfTokens, end: endOfTokens };
42385
- // Put the selection at the end of the token if we cycled on a single token
42386
- if (refTokens.length === 1 && this.selectionStart === this.selectionEnd) {
42387
- selection.start = selection.end;
42434
+ const newSelection = { start: startOfTokens, end: endOfTokens };
42435
+ if (refTokens.length === 1 && selection.start === selection.end) {
42436
+ newSelection.start = newSelection.end;
42437
+ }
42438
+ return { content: newContent, selection: newSelection };
42439
+ }
42440
+ // ---------------------------------------------------------------------------
42441
+ // Misc
42442
+ // ---------------------------------------------------------------------------
42443
+ cycleReferences() {
42444
+ const updated = this.getCycledReference(this.getComposerSelection(), this.currentContent);
42445
+ if (updated === undefined) {
42446
+ return;
42388
42447
  }
42389
42448
  this.dispatch("SET_CURRENT_CONTENT", {
42390
- content: newContent,
42391
- selection,
42449
+ content: updated.content,
42450
+ selection: updated.selection,
42392
42451
  });
42393
42452
  }
42394
42453
  validateSelection(length, start, end) {
@@ -42436,7 +42495,6 @@ class EditionPlugin extends UIPlugin {
42436
42495
  this.selection.resetAnchor(this, { cell: { col: this.col, row: this.row }, zone });
42437
42496
  }
42438
42497
  this.mode = "selecting";
42439
- this.selectionInitialStart = this.selectionStart;
42440
42498
  }
42441
42499
  /**
42442
42500
  * start the edition of a cell
@@ -42596,19 +42654,49 @@ class EditionPlugin extends UIPlugin {
42596
42654
  const ref = this.getZoneReference(zone);
42597
42655
  if (this.canStartComposerRangeSelection()) {
42598
42656
  this.insertText(ref, start);
42599
- this.selectionInitialStart = start;
42600
42657
  }
42601
42658
  else {
42602
42659
  this.insertText("," + ref, start);
42603
- this.selectionInitialStart = start + 1;
42604
42660
  }
42605
42661
  }
42606
42662
  /**
42607
42663
  * Replace the current reference selected by the new one.
42608
42664
  * */
42609
- replaceSelectedRanges(zone) {
42665
+ replaceSelectedRange(zone) {
42610
42666
  const ref = this.getZoneReference(zone);
42611
- this.replaceText(ref, this.selectionInitialStart, this.selectionEnd);
42667
+ const currentToken = this.getTokenAtCursor();
42668
+ const start = currentToken?.type === "REFERENCE" ? currentToken.start : this.selectionStart;
42669
+ this.replaceText(ref, start, this.selectionEnd);
42670
+ }
42671
+ /**
42672
+ * Replace the reference of the old zone by the new one.
42673
+ */
42674
+ updateComposerRange(oldZone, newZone) {
42675
+ const activeSheetId = this.getters.getActiveSheetId();
42676
+ const tokentAtCursor = this.getTokenAtCursor();
42677
+ const tokens = tokentAtCursor ? [tokentAtCursor, ...this.currentTokens] : this.currentTokens;
42678
+ const previousRefToken = tokens
42679
+ .filter((token) => token.type === "REFERENCE")
42680
+ .find((token) => {
42681
+ const { xc, sheetName: sheet } = splitReference(token.value);
42682
+ const sheetName = sheet || this.getters.getSheetName(this.sheetId);
42683
+ if (this.getters.getSheetName(activeSheetId) !== sheetName) {
42684
+ return false;
42685
+ }
42686
+ const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
42687
+ return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), oldZone);
42688
+ });
42689
+ // this function assumes that the previous range is always found because
42690
+ // it's called when changing a highlight, which exists by definition
42691
+ if (!previousRefToken) {
42692
+ throw new Error("Previous range not found");
42693
+ }
42694
+ const previousRange = this.getters.getRangeFromSheetXC(activeSheetId, previousRefToken.value);
42695
+ this.selectionStart = previousRefToken.start;
42696
+ this.selectionEnd = this.selectionStart + previousRefToken.value.length;
42697
+ const newRange = this.getters.getRangeFromZone(activeSheetId, newZone);
42698
+ const newRef = this.getRangeReference(newRange, previousRange.parts);
42699
+ this.replaceSelection(newRef);
42612
42700
  }
42613
42701
  getZoneReference(zone) {
42614
42702
  const inputSheetId = this.getters.getCurrentEditedCell().sheetId;
@@ -42616,14 +42704,8 @@ class EditionPlugin extends UIPlugin {
42616
42704
  const range = this.getters.getRangeFromZone(sheetId, zone);
42617
42705
  return this.getters.getSelectionRangeString(range, inputSheetId);
42618
42706
  }
42619
- getRangeReference(range, fixedParts = [{ colFixed: false, rowFixed: false }]) {
42707
+ getRangeReference(range, fixedParts) {
42620
42708
  let _fixedParts = [...fixedParts];
42621
- if (fixedParts.length === 1 && getZoneArea(range.zone) > 1) {
42622
- _fixedParts.push({ ...fixedParts[0] });
42623
- }
42624
- else if (fixedParts.length === 2 && getZoneArea(range.zone) === 1) {
42625
- _fixedParts.pop();
42626
- }
42627
42709
  const newRange = range.clone({ parts: _fixedParts });
42628
42710
  return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell().sheetId);
42629
42711
  }
@@ -42750,15 +42832,6 @@ class EditionPlugin extends UIPlugin {
42750
42832
  }
42751
42833
  return false;
42752
42834
  }
42753
- /**
42754
- * Return all the tokens between selectionStart and selectionEnd.
42755
- * Includes token that begin right on selectionStart or end right on selectionEnd.
42756
- */
42757
- getTokensInSelection() {
42758
- const start = Math.min(this.selectionStart, this.selectionEnd);
42759
- const end = Math.max(this.selectionStart, this.selectionEnd);
42760
- return this.currentTokens.filter((t) => (t.start <= start && t.end >= start) || (t.start >= start && t.start < end));
42761
- }
42762
42835
  }
42763
42836
 
42764
42837
  class FilterEvaluationPlugin extends UIPlugin {
@@ -45724,6 +45797,11 @@ css /* scss */ `
45724
45797
  .o-sidePanelButton:enabled {
45725
45798
  cursor: pointer;
45726
45799
  }
45800
+
45801
+ .o-sidePanelButton:disabled {
45802
+ color: ${DISABLED_TEXT_COLOR};
45803
+ }
45804
+
45727
45805
  .o-sidePanelButton:last-child {
45728
45806
  margin-right: 0px;
45729
45807
  }
@@ -50287,10 +50365,17 @@ class Model extends EventBus {
50287
50365
  * It will call `beforeHandle` and `handle`
50288
50366
  */
50289
50367
  dispatchToHandlers(handlers, command) {
50368
+ const isCommandCore = isCoreCommand(command);
50290
50369
  for (const handler of handlers) {
50370
+ if (!isCommandCore && handler instanceof CorePlugin) {
50371
+ continue;
50372
+ }
50291
50373
  handler.beforeHandle(command);
50292
50374
  }
50293
50375
  for (const handler of handlers) {
50376
+ if (!isCommandCore && handler instanceof CorePlugin) {
50377
+ continue;
50378
+ }
50294
50379
  handler.handle(command);
50295
50380
  }
50296
50381
  }
@@ -50476,6 +50561,9 @@ const components = {
50476
50561
  };
50477
50562
  function addFunction(functionName, functionDescription) {
50478
50563
  functionRegistry.add(functionName, functionDescription);
50564
+ return {
50565
+ addFunction: (fName, fDescription) => addFunction(fName, fDescription),
50566
+ };
50479
50567
  }
50480
50568
  const constants = {
50481
50569
  DEFAULT_LOCALE,
@@ -50516,6 +50604,6 @@ exports.setTranslationMethod = setTranslationMethod;
50516
50604
  exports.tokenize = tokenize;
50517
50605
 
50518
50606
 
50519
- __info__.version = '16.5.0-alpha.0';
50520
- __info__.date = '2023-07-24T06:48:58.196Z';
50521
- __info__.hash = '3ba2c3c';
50607
+ __info__.version = '16.5.0-alpha.2';
50608
+ __info__.date = '2023-08-07T09:02:00.623Z';
50609
+ __info__.hash = 'e74f3ef';