@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.
@@ -108,8 +108,8 @@ const SELECTION_BORDER_COLOR = "#3266ca";
108
108
  const HEADER_BORDER_COLOR = "#C0C0C0";
109
109
  const CELL_BORDER_COLOR = "#E2E3E3";
110
110
  const BACKGROUND_CHART_COLOR = "#FFFFFF";
111
- const MENU_ITEM_DISABLED_COLOR = "#CACACA";
112
111
  const BG_HOVER_COLOR = "#EBEBEB";
112
+ const DISABLED_TEXT_COLOR = "#CACACA";
113
113
  const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
114
114
  const LINK_COLOR = "#01666b";
115
115
  const FILTERS_COLOR = "#188038";
@@ -1184,7 +1184,7 @@ const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
1184
1184
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
1185
1185
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
1186
1186
  const dateSeparatorsRegex = /\/|-|\s/;
1187
- const dateRegexp = /^(\d{1,4})[\/-\s](\d{1,2})([\/-\s](\d{1,4}))?$/;
1187
+ const dateRegexp = /^(\d{1,4})[\/-\s](\d{1,4})([\/-\s](\d{1,4}))?$/;
1188
1188
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
1189
1189
  function isDateTime(str, locale) {
1190
1190
  return parseDateTime(str, locale) !== null;
@@ -1245,6 +1245,10 @@ function getDateParts(dateString, locale) {
1245
1245
  }
1246
1246
  const localeDateType = getLocaleDateFormatType(locale);
1247
1247
  if (!part3) {
1248
+ if (part2.length > 2) {
1249
+ // e.g. 11/2023
1250
+ return { month: part1, year: part2, day: undefined, dateString, type: localeDateType };
1251
+ }
1248
1252
  if (localeDateType === "dmy") {
1249
1253
  return { day: part1, month: part2, year: part3, dateString, type: "dmy" };
1250
1254
  }
@@ -2991,11 +2995,18 @@ class RangeImpl {
2991
2995
  constructor(args, getSheetSize) {
2992
2996
  this.getSheetSize = getSheetSize;
2993
2997
  this._zone = args.zone;
2994
- this.parts = args.parts;
2995
2998
  this.prefixSheet = args.prefixSheet;
2996
2999
  this.invalidXc = args.invalidXc;
2997
3000
  this.sheetId = args.sheetId;
2998
3001
  this.invalidSheetName = args.invalidSheetName;
3002
+ let _fixedParts = [...args.parts];
3003
+ if (args.parts.length === 1 && getZoneArea(this.zone) > 1) {
3004
+ _fixedParts.push({ ...args.parts[0] });
3005
+ }
3006
+ else if (args.parts.length === 2 && getZoneArea(this.zone) === 1) {
3007
+ _fixedParts.pop();
3008
+ }
3009
+ this.parts = _fixedParts;
2999
3010
  }
3000
3011
  static fromRange(range, getters) {
3001
3012
  if (range instanceof RangeImpl) {
@@ -4045,13 +4056,10 @@ const readonlyAllowedCommands = new Set([
4045
4056
  "START",
4046
4057
  "ACTIVATE_SHEET",
4047
4058
  "COPY",
4048
- "PREPARE_SELECTION_INPUT_EXPANSION",
4049
- "STOP_SELECTION_INPUT",
4050
4059
  "RESIZE_SHEETVIEW",
4051
4060
  "SET_VIEWPORT_OFFSET",
4052
4061
  "SELECT_SEARCH_NEXT_MATCH",
4053
4062
  "SELECT_SEARCH_PREVIOUS_MATCH",
4054
- "REFRESH_SEARCH",
4055
4063
  "UPDATE_SEARCH",
4056
4064
  "CLEAR_SEARCH",
4057
4065
  "EVALUATE_CELLS",
@@ -5123,8 +5131,7 @@ autofillModifiersRegistry
5123
5131
  return { cellData: {} };
5124
5132
  }
5125
5133
  const sheetId = data.sheetId;
5126
- const ranges = getters.createAdaptedRanges(cell.dependencies, x, y, sheetId);
5127
- const content = getters.buildFormulaContent(sheetId, cell, ranges);
5134
+ const content = getters.getTranslatedCellFormula(sheetId, x, y, cell.compiledFormula, cell.dependencies);
5128
5135
  return {
5129
5136
  cellData: {
5130
5137
  border: data.border,
@@ -5990,7 +5997,7 @@ css /* scss */ `
5990
5997
  }
5991
5998
  }
5992
5999
  &.disabled {
5993
- color: ${MENU_ITEM_DISABLED_COLOR};
6000
+ color: ${DISABLED_TEXT_COLOR};
5994
6001
  cursor: not-allowed;
5995
6002
  }
5996
6003
  }
@@ -22416,6 +22423,18 @@ class ConditionalFormattingPanel extends Component {
22416
22423
  style[tool] = !style[tool];
22417
22424
  this.closeMenus();
22418
22425
  }
22426
+ onKeydown(event) {
22427
+ if (event.key === "F4") {
22428
+ const target = event.target;
22429
+ const update = this.env.model.getters.getCycledReference({ start: target.selectionStart ?? 0, end: target.selectionEnd ?? 0 }, target.value);
22430
+ if (!update) {
22431
+ return;
22432
+ }
22433
+ target.value = update.content;
22434
+ target.setSelectionRange(update.selection.start, update.selection.end);
22435
+ target.dispatchEvent(new Event("input"));
22436
+ }
22437
+ }
22419
22438
  setColor(target, color) {
22420
22439
  this.state.rules.cellIs.style[target] = color;
22421
22440
  this.closeMenus();
@@ -22690,6 +22709,7 @@ class FindAndReplacePanel extends Component {
22690
22709
  state = useState(this.initialState());
22691
22710
  debounceTimeoutId;
22692
22711
  showFormulaState = false;
22712
+ debouncedUpdateSearch;
22693
22713
  findAndReplaceRef = useRef("findAndReplace");
22694
22714
  get hasSearchResult() {
22695
22715
  return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
@@ -22699,11 +22719,16 @@ class FindAndReplacePanel extends Component {
22699
22719
  }
22700
22720
  setup() {
22701
22721
  this.showFormulaState = this.env.model.getters.shouldShowFormulas();
22722
+ this.debouncedUpdateSearch = debounce(this.updateSearch.bind(this), 200);
22702
22723
  onMounted(() => this.focusInput());
22703
22724
  onWillUnmount(() => {
22704
22725
  this.env.model.dispatch("CLEAR_SEARCH");
22705
22726
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.showFormulaState });
22706
22727
  });
22728
+ useEffect(() => {
22729
+ this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
22730
+ this.searchFormulas();
22731
+ }, () => [this.env.model.getters.shouldShowFormulas()]);
22707
22732
  }
22708
22733
  onInput(ev) {
22709
22734
  this.state.toSearch = ev.target.value;
@@ -22723,10 +22748,6 @@ class FindAndReplacePanel extends Component {
22723
22748
  this.replace();
22724
22749
  }
22725
22750
  }
22726
- onFocusSidePanel() {
22727
- this.state.searchOptions.searchFormulas = this.env.model.getters.shouldShowFormulas();
22728
- this.env.model.dispatch("REFRESH_SEARCH");
22729
- }
22730
22751
  searchFormulas() {
22731
22752
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
22732
22753
  show: this.state.searchOptions.searchFormulas,
@@ -22745,13 +22766,6 @@ class FindAndReplacePanel extends Component {
22745
22766
  searchOptions: this.state.searchOptions,
22746
22767
  });
22747
22768
  }
22748
- debouncedUpdateSearch() {
22749
- clearTimeout(this.debounceTimeoutId);
22750
- this.debounceTimeoutId = setTimeout(() => {
22751
- this.updateSearch();
22752
- this.debounceTimeoutId = undefined;
22753
- }, 400);
22754
- }
22755
22769
  replace() {
22756
22770
  this.env.model.dispatch("REPLACE_SEARCH", {
22757
22771
  replaceWith: this.state.replaceWith,
@@ -24691,6 +24705,15 @@ function dragFigureForResize(initialFigure, dirX, dirY, { x: mouseX, y: mouseY }
24691
24705
  y = initialFigure.y - deltaY;
24692
24706
  }
24693
24707
  }
24708
+ // Restrict resizing if x or y reaches header boundaries
24709
+ if (x < 0) {
24710
+ width += x;
24711
+ x = 0;
24712
+ }
24713
+ if (y < 0) {
24714
+ height += y;
24715
+ y = 0;
24716
+ }
24694
24717
  return { ...initialFigure, x, y, width, height };
24695
24718
  }
24696
24719
 
@@ -25283,10 +25306,29 @@ function useCellHovered(env, gridRef, callback) {
25283
25306
  setPosition(undefined, undefined);
25284
25307
  }
25285
25308
  }
25309
+ function onMouseLeave(e) {
25310
+ const x = e.offsetX;
25311
+ const y = e.offsetY;
25312
+ const gridRect = getBoundingRectAsPOJO(gridRef.el);
25313
+ if (y < 0 || y > gridRect.height || x < 0 || x > gridRect.width) {
25314
+ return updateMousePosition(e);
25315
+ }
25316
+ else {
25317
+ return pause();
25318
+ }
25319
+ }
25286
25320
  useRefListener(gridRef, "mousemove", updateMousePosition);
25287
- useRefListener(gridRef, "mouseleave", pause);
25321
+ useRefListener(gridRef, "mouseleave", onMouseLeave);
25288
25322
  useRefListener(gridRef, "mouseenter", resume);
25289
25323
  useRefListener(gridRef, "mousedown", recompute);
25324
+ useExternalListener(window, "click", handleGlobalClick);
25325
+ function handleGlobalClick(e) {
25326
+ const target = e.target;
25327
+ const grid = gridRef.el;
25328
+ if (!grid.contains(target)) {
25329
+ setPosition(undefined, undefined);
25330
+ }
25331
+ }
25290
25332
  function setPosition(col, row) {
25291
25333
  if (col !== hoveredPosition.col || row !== hoveredPosition.row) {
25292
25334
  hoveredPosition.col = col;
@@ -25610,7 +25652,6 @@ class AbstractResizer extends Component {
25610
25652
  const mouseUpSelect = () => {
25611
25653
  this.state.isSelecting = false;
25612
25654
  this.lastSelectedElementIndex = null;
25613
- this.env.model.dispatch(ev.ctrlKey ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
25614
25655
  this._computeGrabDisplay(ev);
25615
25656
  };
25616
25657
  dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
@@ -26175,9 +26216,7 @@ class Highlight extends Component {
26175
26216
  let lastCol = isLeft ? z.left : z.right;
26176
26217
  let lastRow = isTop ? z.top : z.bottom;
26177
26218
  let currentZone = z;
26178
- this.env.model.dispatch("START_CHANGE_HIGHLIGHT", {
26179
- range: this.env.model.getters.getRangeDataFromZone(activeSheetId, currentZone),
26180
- });
26219
+ this.env.model.dispatch("START_CHANGE_HIGHLIGHT", { zone: currentZone });
26181
26220
  const mouseMove = (col, row) => {
26182
26221
  if (lastCol !== col || lastRow !== row) {
26183
26222
  lastCol = clip(col === -1 ? lastCol : col, 0, this.env.model.getters.getNumberCols(activeSheetId) - 1);
@@ -26188,21 +26227,17 @@ class Highlight extends Component {
26188
26227
  right: Math.max(pivotCol, lastCol),
26189
26228
  bottom: Math.max(pivotRow, lastRow),
26190
26229
  };
26191
- newZone = this.env.model.getters.expandZone(activeSheetId, newZone);
26192
26230
  if (!isEqual(newZone, currentZone)) {
26193
- this.env.model.dispatch("CHANGE_HIGHLIGHT", {
26194
- range: this.env.model.getters.getRangeFromZone(activeSheetId, this.env.model.getters.getUnboundedZone(activeSheetId, newZone)).rangeData,
26195
- });
26231
+ this.env.model.selection.selectZone({
26232
+ cell: { col: newZone.left, row: newZone.top },
26233
+ zone: newZone,
26234
+ }, { unbounded: true });
26196
26235
  currentZone = newZone;
26197
26236
  }
26198
26237
  }
26199
26238
  };
26200
26239
  const mouseUp = () => {
26201
26240
  this.highlightState.shiftingMode = "none";
26202
- // To do:
26203
- // Command used here to restore focus to the current composer,
26204
- // to be changed when refactoring the 'edition' plugin
26205
- this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
26206
26241
  };
26207
26242
  dragAndDropBeyondTheViewport(this.env, mouseMove, mouseUp);
26208
26243
  }
@@ -26218,9 +26253,7 @@ class Highlight extends Component {
26218
26253
  const deltaRowMin = -z.top;
26219
26254
  const deltaRowMax = this.env.model.getters.getNumberRows(activeSheetId) - z.bottom - 1;
26220
26255
  let currentZone = z;
26221
- this.env.model.dispatch("START_CHANGE_HIGHLIGHT", {
26222
- range: this.env.model.getters.getRangeDataFromZone(activeSheetId, currentZone),
26223
- });
26256
+ this.env.model.dispatch("START_CHANGE_HIGHLIGHT", { zone: currentZone });
26224
26257
  let lastCol = initCol;
26225
26258
  let lastRow = initRow;
26226
26259
  const mouseMove = (col, row) => {
@@ -26235,21 +26268,17 @@ class Highlight extends Component {
26235
26268
  right: z.right + deltaCol,
26236
26269
  bottom: z.bottom + deltaRow,
26237
26270
  };
26238
- newZone = this.env.model.getters.expandZone(activeSheetId, newZone);
26239
26271
  if (!isEqual(newZone, currentZone)) {
26240
- this.env.model.dispatch("CHANGE_HIGHLIGHT", {
26241
- range: this.env.model.getters.getRangeFromZone(activeSheetId, this.env.model.getters.getUnboundedZone(activeSheetId, newZone)).rangeData,
26242
- });
26272
+ this.env.model.selection.selectZone({
26273
+ cell: { col: newZone.left, row: newZone.top },
26274
+ zone: newZone,
26275
+ }, { unbounded: true });
26243
26276
  currentZone = newZone;
26244
26277
  }
26245
26278
  }
26246
26279
  };
26247
26280
  const mouseUp = () => {
26248
26281
  this.highlightState.shiftingMode = "none";
26249
- // To do:
26250
- // Command used here to restore focus to the current composer,
26251
- // to be changed when refactoring the 'edition' plugin
26252
- this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
26253
26282
  };
26254
26283
  dragAndDropBeyondTheViewport(this.env, mouseMove, mouseUp);
26255
26284
  }
@@ -26742,9 +26771,6 @@ class Grid extends Component {
26742
26771
  // Zone selection with mouse
26743
26772
  // ---------------------------------------------------------------------------
26744
26773
  onCellClicked(col, row, { ctrlKey, shiftKey }) {
26745
- if (ctrlKey) {
26746
- this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
26747
- }
26748
26774
  if (this.env.model.getters.hasOpenedPopover()) {
26749
26775
  this.closeOpenedPopover();
26750
26776
  }
@@ -26770,7 +26796,6 @@ class Grid extends Component {
26770
26796
  }
26771
26797
  };
26772
26798
  const onMouseUp = () => {
26773
- this.env.model.dispatch("STOP_SELECTION_INPUT");
26774
26799
  if (this.env.model.getters.isPaintingFormat()) {
26775
26800
  this.env.model.dispatch("PASTE", {
26776
26801
  target: this.env.model.getters.getSelectedZones(),
@@ -31488,8 +31513,8 @@ class CellPlugin extends CorePlugin {
31488
31513
  "zoneToXC",
31489
31514
  "getCells",
31490
31515
  "getFormulaCellContent",
31516
+ "getTranslatedCellFormula",
31491
31517
  "getCellStyle",
31492
- "buildFormulaContent",
31493
31518
  "getCellById",
31494
31519
  ];
31495
31520
  nextId = 1;
@@ -31688,7 +31713,7 @@ class CellPlugin extends CorePlugin {
31688
31713
  /*
31689
31714
  * Reconstructs the original formula string based on a normalized form and its dependencies
31690
31715
  */
31691
- buildFormulaContent(sheetId, cell, dependencies) {
31716
+ getFormulaCellContent(sheetId, cell, dependencies) {
31692
31717
  const ranges = dependencies || [...cell.dependencies];
31693
31718
  return concat(cell.compiledFormula.tokens.map((token) => {
31694
31719
  if (token.type === "REFERENCE") {
@@ -31698,8 +31723,15 @@ class CellPlugin extends CorePlugin {
31698
31723
  return token.value;
31699
31724
  }));
31700
31725
  }
31701
- getFormulaCellContent(sheetId, cell) {
31702
- return this.buildFormulaContent(sheetId, cell);
31726
+ /*
31727
+ * Constructs a formula string based on an initial formula and a translation vector
31728
+ */
31729
+ getTranslatedCellFormula(sheetId, offsetX, offsetY, compiledFormula, dependencies) {
31730
+ const adaptedDependencies = this.getters.createAdaptedRanges(dependencies, offsetX, offsetY, sheetId);
31731
+ return this.getFormulaCellContent(sheetId, {
31732
+ compiledFormula,
31733
+ dependencies: adaptedDependencies,
31734
+ });
31703
31735
  }
31704
31736
  getCellStyle(position) {
31705
31737
  return this.getters.getCell(position)?.style || {};
@@ -31889,7 +31921,7 @@ class CellPlugin extends CorePlugin {
31889
31921
  */
31890
31922
  createFormulaCellWithDependencies(id, compiledFormula, format, style, sheetId) {
31891
31923
  const dependencies = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
31892
- return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.buildFormulaContent.bind(this));
31924
+ return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getFormulaCellContent.bind(this));
31893
31925
  }
31894
31926
  createErrorFormula(id, content, format, style, error) {
31895
31927
  return {
@@ -31923,19 +31955,19 @@ class FormulaCellWithDependencies {
31923
31955
  style;
31924
31956
  dependencies;
31925
31957
  sheetId;
31926
- buildFormulaContent;
31958
+ getFormulaCellContent;
31927
31959
  isFormula = true;
31928
- constructor(id, compiledFormula, format, style, dependencies, sheetId, buildFormulaContent) {
31960
+ constructor(id, compiledFormula, format, style, dependencies, sheetId, getFormulaCellContent) {
31929
31961
  this.id = id;
31930
31962
  this.compiledFormula = compiledFormula;
31931
31963
  this.format = format;
31932
31964
  this.style = style;
31933
31965
  this.dependencies = dependencies;
31934
31966
  this.sheetId = sheetId;
31935
- this.buildFormulaContent = buildFormulaContent;
31967
+ this.getFormulaCellContent = getFormulaCellContent;
31936
31968
  }
31937
31969
  get content() {
31938
- return this.buildFormulaContent(this.sheetId, {
31970
+ return this.getFormulaCellContent(this.sheetId, {
31939
31971
  dependencies: this.dependencies,
31940
31972
  compiledFormula: this.compiledFormula,
31941
31973
  });
@@ -36450,13 +36482,21 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
36450
36482
  }
36451
36483
  break;
36452
36484
  case "CellIsRule":
36485
+ const formulas = cf.rule.values.map((value) => value.startsWith("=") ? compile(value) : undefined);
36453
36486
  for (let ref of cf.ranges) {
36454
36487
  const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
36455
36488
  for (let row = zone.top; row <= zone.bottom; row++) {
36456
36489
  for (let col = zone.left; col <= zone.right; col++) {
36457
- const pr = this.rulePredicate[cf.rule.type];
36458
- let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
36459
- if (pr && pr(cell, cf.rule)) {
36490
+ const predicate = this.rulePredicate[cf.rule.type];
36491
+ const target = { sheetId, col, row };
36492
+ const values = cf.rule.values.map((value, i) => {
36493
+ const compiledFormula = formulas[i];
36494
+ if (compiledFormula) {
36495
+ return this.getters.getTranslatedCellFormula(sheetId, col - zone.left, row - zone.top, compiledFormula, compiledFormula.dependencies.map((d) => this.getters.getRangeFromSheetXC(sheetId, d)));
36496
+ }
36497
+ return value;
36498
+ });
36499
+ if (predicate && predicate(target, { ...cf.rule, values })) {
36460
36500
  if (!computedStyle[col])
36461
36501
  computedStyle[col] = [];
36462
36502
  // we must combine all the properties of all the CF rules applied to the given cell
@@ -36624,12 +36664,18 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
36624
36664
  * Execute the predicate to know if a conditional formatting rule should be applied to a cell
36625
36665
  */
36626
36666
  rulePredicate = {
36627
- CellIsRule: (cell, rule) => {
36667
+ CellIsRule: (target, rule) => {
36668
+ const cell = this.getters.getEvaluatedCell(target);
36628
36669
  if (cell.type === CellValueType.error) {
36629
36670
  return false;
36630
36671
  }
36631
36672
  const locale = this.getters.getLocale();
36632
- const values = rule.values.map((val) => parseLiteral(val, locale));
36673
+ const values = rule.values.map((value) => {
36674
+ if (value.startsWith("=")) {
36675
+ return this.getters.evaluateFormula(target.sheetId, value);
36676
+ }
36677
+ return parseLiteral(value, locale);
36678
+ });
36633
36679
  switch (rule.operator) {
36634
36680
  case "IsEmpty":
36635
36681
  return cell.value.toString().trim() === "";
@@ -38530,6 +38576,7 @@ class FindAndReplacePlugin extends UIPlugin {
38530
38576
  searchFormulas: false,
38531
38577
  };
38532
38578
  toSearch = "";
38579
+ isSearchDirty = false;
38533
38580
  // ---------------------------------------------------------------------------
38534
38581
  // Command Handling
38535
38582
  // ---------------------------------------------------------------------------
@@ -38553,18 +38600,33 @@ class FindAndReplacePlugin extends UIPlugin {
38553
38600
  case "REPLACE_ALL_SEARCH":
38554
38601
  this.replaceAll(cmd.replaceWith);
38555
38602
  break;
38603
+ case "EVALUATE_CELLS":
38604
+ case "UPDATE_CELL":
38605
+ case "REMOVE_FILTER_TABLE":
38606
+ case "UPDATE_FILTER":
38607
+ this.isSearchDirty = true;
38608
+ break;
38556
38609
  case "UNDO":
38557
38610
  case "REDO":
38558
38611
  case "REMOVE_COLUMNS_ROWS":
38612
+ case "HIDE_COLUMNS_ROWS":
38613
+ case "UNHIDE_COLUMNS_ROWS":
38559
38614
  case "ADD_COLUMNS_ROWS":
38560
- this.clearSearch();
38615
+ case "EVALUATE_CELLS":
38616
+ case "UPDATE_CELL":
38617
+ this.isSearchDirty = true;
38561
38618
  break;
38562
38619
  case "ACTIVATE_SHEET":
38563
- case "REFRESH_SEARCH":
38564
38620
  this.refreshSearch();
38565
38621
  break;
38566
38622
  }
38567
38623
  }
38624
+ finalize() {
38625
+ if (this.isSearchDirty) {
38626
+ this.refreshSearch();
38627
+ this.isSearchDirty = false;
38628
+ }
38629
+ }
38568
38630
  // ---------------------------------------------------------------------------
38569
38631
  // Getters
38570
38632
  // ---------------------------------------------------------------------------
@@ -38620,6 +38682,11 @@ class FindAndReplacePlugin extends UIPlugin {
38620
38682
  if (this.toSearch) {
38621
38683
  for (const cell of Object.values(cells)) {
38622
38684
  const { col, row } = this.getters.getCellPosition(cell.id);
38685
+ const isColHidden = this.getters.isColHidden(sheetId, col);
38686
+ const isRowHidden = this.getters.isRowHidden(sheetId, row);
38687
+ if (isColHidden || isRowHidden) {
38688
+ continue;
38689
+ }
38623
38690
  if (cell &&
38624
38691
  this.currentSearchRegex &&
38625
38692
  this.currentSearchRegex.test(this.getSearchableString({ sheetId, col, row }))) {
@@ -38679,37 +38746,32 @@ class FindAndReplacePlugin extends UIPlugin {
38679
38746
  // ---------------------------------------------------------------------------
38680
38747
  // Replace
38681
38748
  // ---------------------------------------------------------------------------
38682
- /**
38683
- * Replace the value of the currently selected match
38684
- */
38685
- replace(replaceWith) {
38686
- if (this.selectedMatchIndex === null || !this.currentSearchRegex) {
38749
+ replaceMatch(selectedMatch, replaceWith) {
38750
+ if (!this.currentSearchRegex) {
38687
38751
  return;
38688
38752
  }
38689
- const matches = this.searchMatches;
38690
- const selectedMatch = matches[this.selectedMatchIndex];
38691
38753
  const sheetId = this.getters.getActiveSheetId();
38692
38754
  const cell = this.getters.getCell({ sheetId, ...selectedMatch });
38755
+ const { col, row } = selectedMatch;
38693
38756
  if (cell?.isFormula && !this.searchOptions.searchFormulas) {
38694
- this.selectNextCell(Direction.next);
38757
+ return;
38695
38758
  }
38696
- else {
38697
- const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
38698
- const toReplace = this.getSearchableString({
38699
- sheetId,
38700
- col: selectedMatch.col,
38701
- row: selectedMatch.row,
38702
- });
38703
- const newContent = toReplace.replace(replaceRegex, replaceWith);
38704
- this.dispatch("UPDATE_CELL", {
38705
- sheetId: this.getters.getActiveSheetId(),
38706
- col: selectedMatch.col,
38707
- row: selectedMatch.row,
38708
- content: canonicalizeContent(newContent, this.getters.getLocale()),
38709
- });
38710
- this.searchMatches.splice(this.selectedMatchIndex, 1);
38711
- this.selectNextCell(Direction.current);
38759
+ const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
38760
+ const toReplace = this.getSearchableString({ sheetId, col, row });
38761
+ const content = toReplace.replace(replaceRegex, replaceWith);
38762
+ const canonicalContent = canonicalizeContent(content, this.getters.getLocale());
38763
+ this.dispatch("UPDATE_CELL", { sheetId, col, row, content: canonicalContent });
38764
+ }
38765
+ /**
38766
+ * Replace the value of the currently selected match
38767
+ */
38768
+ replace(replaceWith) {
38769
+ if (this.selectedMatchIndex === null) {
38770
+ return;
38712
38771
  }
38772
+ const selectedMatch = this.searchMatches[this.selectedMatchIndex];
38773
+ this.replaceMatch(selectedMatch, replaceWith);
38774
+ this.selectNextCell(Direction.next);
38713
38775
  }
38714
38776
  /**
38715
38777
  * Apply the replace function to all the matches one time.
@@ -38717,7 +38779,7 @@ class FindAndReplacePlugin extends UIPlugin {
38717
38779
  replaceAll(replaceWith) {
38718
38780
  const matchCount = this.searchMatches.length;
38719
38781
  for (let i = 0; i < matchCount; i++) {
38720
- this.replace(replaceWith);
38782
+ this.replaceMatch(this.searchMatches[i], replaceWith);
38721
38783
  }
38722
38784
  }
38723
38785
  getSearchableString(position) {
@@ -39639,8 +39701,7 @@ class SelectionInputPlugin extends UIPlugin {
39639
39701
  static getters = [];
39640
39702
  ranges = [];
39641
39703
  focusedRangeIndex = null;
39642
- activeSheet;
39643
- willAddNewRange = false;
39704
+ inputSheetId;
39644
39705
  constructor(config, initialRanges, inputHasSingleRange) {
39645
39706
  if (inputHasSingleRange && initialRanges.length > 1) {
39646
39707
  throw new Error("Input with a single range cannot be instantiated with several range references.");
@@ -39648,7 +39709,7 @@ class SelectionInputPlugin extends UIPlugin {
39648
39709
  super(config);
39649
39710
  this.inputHasSingleRange = inputHasSingleRange;
39650
39711
  this.insertNewRange(0, initialRanges);
39651
- this.activeSheet = this.getters.getActiveSheetId();
39712
+ this.inputSheetId = this.getters.getActiveSheetId();
39652
39713
  if (this.ranges.length === 0) {
39653
39714
  this.insertNewRange(this.ranges.length, [""]);
39654
39715
  this.focusLast();
@@ -39674,11 +39735,33 @@ class SelectionInputPlugin extends UIPlugin {
39674
39735
  return 0 /* CommandResult.Success */;
39675
39736
  }
39676
39737
  handleEvent(event) {
39677
- const inputSheetId = this.activeSheet;
39678
- const sheetId = this.getters.getActiveSheetId();
39679
- const zone = event.anchor.zone;
39680
- const range = this.getters.getRangeFromZone(sheetId, event.options.unbounded ? this.getters.getUnboundedZone(sheetId, zone) : zone);
39681
- this.add([this.getters.getSelectionRangeString(range, inputSheetId)]);
39738
+ if (this.focusedRangeIndex === null) {
39739
+ return;
39740
+ }
39741
+ const inputSheetId = this.inputSheetId;
39742
+ const activeSheetId = this.getters.getActiveSheetId();
39743
+ const zone = event.options.unbounded
39744
+ ? this.getters.getUnboundedZone(activeSheetId, event.anchor.zone)
39745
+ : event.anchor.zone;
39746
+ const range = this.getters.getRangeFromZone(activeSheetId, zone);
39747
+ const willAddNewRange = event.mode === "newAnchor" &&
39748
+ !this.inputHasSingleRange &&
39749
+ this.ranges[this.focusedRangeIndex].xc.trim() !== "";
39750
+ if (willAddNewRange) {
39751
+ const xc = this.getters.getSelectionRangeString(range, inputSheetId);
39752
+ this.insertNewRange(this.ranges.length, [xc]);
39753
+ this.focusLast();
39754
+ }
39755
+ else {
39756
+ let parts = range.parts;
39757
+ const previousXc = this.ranges[this.focusedRangeIndex].xc.trim();
39758
+ if (previousXc) {
39759
+ parts = this.getters.getRangeFromSheetXC(inputSheetId, previousXc).parts;
39760
+ }
39761
+ const newRange = range.clone({ parts });
39762
+ const xc = this.getters.getSelectionRangeString(newRange, inputSheetId);
39763
+ this.setRange(this.focusedRangeIndex, [xc]);
39764
+ }
39682
39765
  }
39683
39766
  handle(cmd) {
39684
39767
  switch (cmd.type) {
@@ -39714,16 +39797,6 @@ class SelectionInputPlugin extends UIPlugin {
39714
39797
  this.removeRange(index);
39715
39798
  }
39716
39799
  break;
39717
- case "STOP_SELECTION_INPUT":
39718
- this.willAddNewRange = false;
39719
- break;
39720
- case "PREPARE_SELECTION_INPUT_EXPANSION": {
39721
- const index = this.focusedRangeIndex;
39722
- if (index !== null && !this.inputHasSingleRange) {
39723
- this.willAddNewRange = this.ranges[index].xc.trim() !== "";
39724
- }
39725
- break;
39726
- }
39727
39800
  case "ACTIVATE_SHEET": {
39728
39801
  if (cmd.sheetIdFrom !== cmd.sheetIdTo) {
39729
39802
  const { col, row } = this.getters.getNextVisibleCellPosition({
@@ -39734,7 +39807,26 @@ class SelectionInputPlugin extends UIPlugin {
39734
39807
  const zone = this.getters.expandZone(cmd.sheetIdTo, positionToZone({ col, row }));
39735
39808
  this.selection.resetAnchor(this, { cell: { col, row }, zone });
39736
39809
  }
39810
+ break;
39737
39811
  }
39812
+ case "START_CHANGE_HIGHLIGHT":
39813
+ const activeSheetId = this.getters.getActiveSheetId();
39814
+ const newZone = this.getters.expandZone(activeSheetId, cmd.zone);
39815
+ const focusIndex = this.ranges.findIndex((range) => {
39816
+ const { xc, sheetName: sheet } = splitReference(range.xc);
39817
+ const sheetName = sheet || this.getters.getSheetName(this.inputSheetId);
39818
+ if (this.getters.getSheetName(activeSheetId) !== sheetName) {
39819
+ return false;
39820
+ }
39821
+ const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
39822
+ return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), newZone);
39823
+ });
39824
+ if (focusIndex !== -1) {
39825
+ this.focus(focusIndex);
39826
+ const { left, top } = newZone;
39827
+ this.selection.resetAnchor(this, { cell: { col: left, row: top }, zone: newZone });
39828
+ }
39829
+ break;
39738
39830
  }
39739
39831
  }
39740
39832
  // ---------------------------------------------------------------------------
@@ -39763,19 +39855,6 @@ class SelectionInputPlugin extends UIPlugin {
39763
39855
  unfocus() {
39764
39856
  this.focusedRangeIndex = null;
39765
39857
  }
39766
- add(newRanges) {
39767
- if (this.focusedRangeIndex === null || newRanges.length === 0) {
39768
- return;
39769
- }
39770
- if (this.willAddNewRange) {
39771
- this.insertNewRange(this.ranges.length, newRanges);
39772
- this.focusLast();
39773
- this.willAddNewRange = false;
39774
- }
39775
- else {
39776
- this.setRange(this.focusedRangeIndex, newRanges);
39777
- }
39778
- }
39779
39858
  setContent(index, xc) {
39780
39859
  this.ranges[index] = {
39781
39860
  ...this.ranges[index],
@@ -39821,12 +39900,12 @@ class SelectionInputPlugin extends UIPlugin {
39821
39900
  inputToHighlights({ xc, color }) {
39822
39901
  const XCs = this.cleanInputs([xc])
39823
39902
  .filter((range) => this.getters.isRangeValid(range))
39824
- .filter((reference) => this.shouldBeHighlighted(this.activeSheet, reference));
39903
+ .filter((reference) => this.shouldBeHighlighted(this.inputSheetId, reference));
39825
39904
  return XCs.map((xc) => {
39826
39905
  const { sheetName } = splitReference(xc);
39827
39906
  return {
39828
- zone: this.getters.getRangeFromSheetXC(this.activeSheet, xc).zone,
39829
- sheetId: (sheetName && this.getters.getSheetIdByName(sheetName)) || this.activeSheet,
39907
+ zone: this.getters.getRangeFromSheetXC(this.inputSheetId, xc).zone,
39908
+ sheetId: (sheetName && this.getters.getSheetIdByName(sheetName)) || this.inputSheetId,
39830
39909
  color,
39831
39910
  };
39832
39911
  });
@@ -40251,10 +40330,8 @@ class SortPlugin extends UIPlugin {
40251
40330
  let content = cell.content;
40252
40331
  if (cell.isFormula) {
40253
40332
  const position = this.getters.getCellPosition(cell.id);
40254
- const offsetY = newRow - position.row;
40255
40333
  // we only have a vertical offset
40256
- const ranges = this.getters.createAdaptedRanges(cell.dependencies, 0, offsetY, sheetId);
40257
- content = this.getters.buildFormulaContent(sheetId, cell, ranges);
40334
+ content = this.getters.getTranslatedCellFormula(sheetId, 0, newRow - position.row, cell.compiledFormula, cell.dependencies);
40258
40335
  }
40259
40336
  newCellValues.style = cell.style;
40260
40337
  newCellValues.content = content;
@@ -41361,9 +41438,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
41361
41438
  }
41362
41439
  let content = origin.cell.content;
41363
41440
  if (origin.cell.isFormula && operation === "COPY") {
41364
- const offsetX = col - origin.position.col;
41365
- const offsetY = row - origin.position.row;
41366
- content = this.getUpdatedContent(sheetId, origin.cell, offsetX, offsetY, operation);
41441
+ content = this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula, origin.cell.dependencies);
41367
41442
  }
41368
41443
  this.dispatch("UPDATE_CELL", {
41369
41444
  ...target,
@@ -41384,13 +41459,6 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
41384
41459
  }
41385
41460
  }
41386
41461
  }
41387
- /**
41388
- * Get the newly updated formula, after applying offsets
41389
- */
41390
- getUpdatedContent(sheetId, cell, offsetX, offsetY, operation) {
41391
- const ranges = this.getters.createAdaptedRanges(cell.dependencies, offsetX, offsetY, sheetId);
41392
- return this.getters.buildFormulaContent(sheetId, cell, ranges);
41393
- }
41394
41462
  /**
41395
41463
  * If the origin position given is the top left of a merge, merge the target
41396
41464
  * position.
@@ -42132,6 +42200,7 @@ class EditionPlugin extends UIPlugin {
42132
42200
  "getTokenAtCursor",
42133
42201
  "getComposerHighlights",
42134
42202
  "getCurrentEditedCell",
42203
+ "getCycledReference",
42135
42204
  ];
42136
42205
  col = 0;
42137
42206
  row = 0;
@@ -42141,10 +42210,7 @@ class EditionPlugin extends UIPlugin {
42141
42210
  currentTokens = [];
42142
42211
  selectionStart = 0;
42143
42212
  selectionEnd = 0;
42144
- selectionInitialStart = 0;
42145
42213
  initialContent = "";
42146
- previousRef = "";
42147
- previousRange = undefined;
42148
42214
  colorIndexByRange = {};
42149
42215
  // ---------------------------------------------------------------------------
42150
42216
  // Command Handling
@@ -42173,9 +42239,6 @@ class EditionPlugin extends UIPlugin {
42173
42239
  }
42174
42240
  }
42175
42241
  handleEvent(event) {
42176
- if (this.mode !== "selecting") {
42177
- return;
42178
- }
42179
42242
  const sheetId = this.getters.getActiveSheetId();
42180
42243
  let unboundedZone;
42181
42244
  if (event.options.unbounded) {
@@ -42186,10 +42249,17 @@ class EditionPlugin extends UIPlugin {
42186
42249
  }
42187
42250
  switch (event.mode) {
42188
42251
  case "newAnchor":
42189
- this.insertSelectedRange(unboundedZone);
42252
+ if (this.mode === "selecting") {
42253
+ this.insertSelectedRange(unboundedZone);
42254
+ }
42190
42255
  break;
42191
42256
  default:
42192
- this.replaceSelectedRanges(unboundedZone);
42257
+ if (this.mode === "selecting") {
42258
+ this.replaceSelectedRange(unboundedZone);
42259
+ }
42260
+ else {
42261
+ this.updateComposerRange(event.previousAnchor.zone, unboundedZone);
42262
+ }
42193
42263
  break;
42194
42264
  }
42195
42265
  }
@@ -42246,35 +42316,12 @@ class EditionPlugin extends UIPlugin {
42246
42316
  }
42247
42317
  break;
42248
42318
  case "START_CHANGE_HIGHLIGHT":
42249
- // FIXME: thiws whole ordeal could be handled with the Selection Processor which would extend the feature to selection inputs
42250
- this.dispatch("STOP_COMPOSER_RANGE_SELECTION");
42251
- // FIXME: we should check range SheetId compared to this.activeSheetId r maybe not have a sheetId in the payload ??
42252
- const range = this.getters.getRangeFromRangeData(cmd.range);
42253
- const previousRefToken = this.currentTokens
42254
- .filter((token) => token.type === "REFERENCE")
42255
- .find((token) => {
42256
- const { xc, sheetName: sheet } = splitReference(token.value);
42257
- const sheetName = sheet || this.getters.getSheetName(this.sheetId);
42258
- const activeSheetId = this.getters.getActiveSheetId();
42259
- if (this.getters.getSheetName(activeSheetId) !== sheetName) {
42260
- return false;
42261
- }
42262
- const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
42263
- return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), range.zone);
42264
- });
42265
- this.previousRef = previousRefToken.value;
42266
- this.previousRange = this.getters.getRangeFromSheetXC(this.getters.getActiveSheetId(), this.previousRef);
42267
- this.selectionInitialStart = previousRefToken.start;
42268
- break;
42269
- case "CHANGE_HIGHLIGHT":
42270
- const cmdRange = this.getters.getRangeFromRangeData(cmd.range);
42271
- const newRef = this.getRangeReference(cmdRange, this.previousRange.parts);
42272
- this.selectionStart = this.selectionInitialStart;
42273
- this.selectionEnd = this.selectionInitialStart + this.previousRef.length;
42274
- this.replaceSelection(newRef);
42275
- this.previousRef = newRef;
42276
- this.selectionStart = this.currentContent.length;
42277
- this.selectionEnd = this.currentContent.length;
42319
+ const { left, top } = cmd.zone;
42320
+ // changing the highlight can conflit with the 'selecting' mode
42321
+ if (this.isSelectingForComposer()) {
42322
+ this.mode = "editing";
42323
+ }
42324
+ this.selection.resetAnchor(this, { cell: { col: left, row: top }, zone: cmd.zone });
42278
42325
  break;
42279
42326
  case "ACTIVATE_SHEET":
42280
42327
  if (!this.currentContent.startsWith("=")) {
@@ -42358,33 +42405,45 @@ class EditionPlugin extends UIPlugin {
42358
42405
  return this.currentTokens.find((t) => t.start <= start && t.end >= end);
42359
42406
  }
42360
42407
  }
42361
- // ---------------------------------------------------------------------------
42362
- // Misc
42363
- // ---------------------------------------------------------------------------
42364
- cycleReferences() {
42365
- const tokens = this.getTokensInSelection();
42408
+ /**
42409
+ * Return the cycled reference if any (A1 -> $A$1 -> A$1 -> $A1 -> A1)
42410
+ */
42411
+ getCycledReference(selection, content) {
42412
+ const locale = this.getters.getLocale();
42413
+ const currentTokens = content.startsWith("=") ? composerTokenize(content, locale) : [];
42414
+ const tokens = currentTokens.filter((t) => (t.start <= selection.start && t.end >= selection.start) ||
42415
+ (t.start >= selection.start && t.start < selection.end));
42366
42416
  const refTokens = tokens.filter((token) => token.type === "REFERENCE");
42367
- if (refTokens.length === 0)
42417
+ if (refTokens.length === 0) {
42368
42418
  return;
42419
+ }
42369
42420
  const updatedReferences = tokens
42370
42421
  .map(loopThroughReferenceType)
42371
42422
  .map((token) => token.value)
42372
42423
  .join("");
42373
- const content = this.currentContent;
42374
42424
  const start = tokens[0].start;
42375
42425
  const end = tokens[tokens.length - 1].end;
42376
42426
  const newContent = content.slice(0, start) + updatedReferences + content.slice(end);
42377
42427
  const lengthDiff = newContent.length - content.length;
42378
42428
  const startOfTokens = refTokens[0].start;
42379
42429
  const endOfTokens = refTokens[refTokens.length - 1].end + lengthDiff;
42380
- const selection = { start: startOfTokens, end: endOfTokens };
42381
- // Put the selection at the end of the token if we cycled on a single token
42382
- if (refTokens.length === 1 && this.selectionStart === this.selectionEnd) {
42383
- selection.start = selection.end;
42430
+ const newSelection = { start: startOfTokens, end: endOfTokens };
42431
+ if (refTokens.length === 1 && selection.start === selection.end) {
42432
+ newSelection.start = newSelection.end;
42433
+ }
42434
+ return { content: newContent, selection: newSelection };
42435
+ }
42436
+ // ---------------------------------------------------------------------------
42437
+ // Misc
42438
+ // ---------------------------------------------------------------------------
42439
+ cycleReferences() {
42440
+ const updated = this.getCycledReference(this.getComposerSelection(), this.currentContent);
42441
+ if (updated === undefined) {
42442
+ return;
42384
42443
  }
42385
42444
  this.dispatch("SET_CURRENT_CONTENT", {
42386
- content: newContent,
42387
- selection,
42445
+ content: updated.content,
42446
+ selection: updated.selection,
42388
42447
  });
42389
42448
  }
42390
42449
  validateSelection(length, start, end) {
@@ -42432,7 +42491,6 @@ class EditionPlugin extends UIPlugin {
42432
42491
  this.selection.resetAnchor(this, { cell: { col: this.col, row: this.row }, zone });
42433
42492
  }
42434
42493
  this.mode = "selecting";
42435
- this.selectionInitialStart = this.selectionStart;
42436
42494
  }
42437
42495
  /**
42438
42496
  * start the edition of a cell
@@ -42592,19 +42650,49 @@ class EditionPlugin extends UIPlugin {
42592
42650
  const ref = this.getZoneReference(zone);
42593
42651
  if (this.canStartComposerRangeSelection()) {
42594
42652
  this.insertText(ref, start);
42595
- this.selectionInitialStart = start;
42596
42653
  }
42597
42654
  else {
42598
42655
  this.insertText("," + ref, start);
42599
- this.selectionInitialStart = start + 1;
42600
42656
  }
42601
42657
  }
42602
42658
  /**
42603
42659
  * Replace the current reference selected by the new one.
42604
42660
  * */
42605
- replaceSelectedRanges(zone) {
42661
+ replaceSelectedRange(zone) {
42606
42662
  const ref = this.getZoneReference(zone);
42607
- this.replaceText(ref, this.selectionInitialStart, this.selectionEnd);
42663
+ const currentToken = this.getTokenAtCursor();
42664
+ const start = currentToken?.type === "REFERENCE" ? currentToken.start : this.selectionStart;
42665
+ this.replaceText(ref, start, this.selectionEnd);
42666
+ }
42667
+ /**
42668
+ * Replace the reference of the old zone by the new one.
42669
+ */
42670
+ updateComposerRange(oldZone, newZone) {
42671
+ const activeSheetId = this.getters.getActiveSheetId();
42672
+ const tokentAtCursor = this.getTokenAtCursor();
42673
+ const tokens = tokentAtCursor ? [tokentAtCursor, ...this.currentTokens] : this.currentTokens;
42674
+ const previousRefToken = tokens
42675
+ .filter((token) => token.type === "REFERENCE")
42676
+ .find((token) => {
42677
+ const { xc, sheetName: sheet } = splitReference(token.value);
42678
+ const sheetName = sheet || this.getters.getSheetName(this.sheetId);
42679
+ if (this.getters.getSheetName(activeSheetId) !== sheetName) {
42680
+ return false;
42681
+ }
42682
+ const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
42683
+ return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), oldZone);
42684
+ });
42685
+ // this function assumes that the previous range is always found because
42686
+ // it's called when changing a highlight, which exists by definition
42687
+ if (!previousRefToken) {
42688
+ throw new Error("Previous range not found");
42689
+ }
42690
+ const previousRange = this.getters.getRangeFromSheetXC(activeSheetId, previousRefToken.value);
42691
+ this.selectionStart = previousRefToken.start;
42692
+ this.selectionEnd = this.selectionStart + previousRefToken.value.length;
42693
+ const newRange = this.getters.getRangeFromZone(activeSheetId, newZone);
42694
+ const newRef = this.getRangeReference(newRange, previousRange.parts);
42695
+ this.replaceSelection(newRef);
42608
42696
  }
42609
42697
  getZoneReference(zone) {
42610
42698
  const inputSheetId = this.getters.getCurrentEditedCell().sheetId;
@@ -42612,14 +42700,8 @@ class EditionPlugin extends UIPlugin {
42612
42700
  const range = this.getters.getRangeFromZone(sheetId, zone);
42613
42701
  return this.getters.getSelectionRangeString(range, inputSheetId);
42614
42702
  }
42615
- getRangeReference(range, fixedParts = [{ colFixed: false, rowFixed: false }]) {
42703
+ getRangeReference(range, fixedParts) {
42616
42704
  let _fixedParts = [...fixedParts];
42617
- if (fixedParts.length === 1 && getZoneArea(range.zone) > 1) {
42618
- _fixedParts.push({ ...fixedParts[0] });
42619
- }
42620
- else if (fixedParts.length === 2 && getZoneArea(range.zone) === 1) {
42621
- _fixedParts.pop();
42622
- }
42623
42705
  const newRange = range.clone({ parts: _fixedParts });
42624
42706
  return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell().sheetId);
42625
42707
  }
@@ -42746,15 +42828,6 @@ class EditionPlugin extends UIPlugin {
42746
42828
  }
42747
42829
  return false;
42748
42830
  }
42749
- /**
42750
- * Return all the tokens between selectionStart and selectionEnd.
42751
- * Includes token that begin right on selectionStart or end right on selectionEnd.
42752
- */
42753
- getTokensInSelection() {
42754
- const start = Math.min(this.selectionStart, this.selectionEnd);
42755
- const end = Math.max(this.selectionStart, this.selectionEnd);
42756
- return this.currentTokens.filter((t) => (t.start <= start && t.end >= start) || (t.start >= start && t.start < end));
42757
- }
42758
42831
  }
42759
42832
 
42760
42833
  class FilterEvaluationPlugin extends UIPlugin {
@@ -45720,6 +45793,11 @@ css /* scss */ `
45720
45793
  .o-sidePanelButton:enabled {
45721
45794
  cursor: pointer;
45722
45795
  }
45796
+
45797
+ .o-sidePanelButton:disabled {
45798
+ color: ${DISABLED_TEXT_COLOR};
45799
+ }
45800
+
45723
45801
  .o-sidePanelButton:last-child {
45724
45802
  margin-right: 0px;
45725
45803
  }
@@ -50283,10 +50361,17 @@ class Model extends EventBus {
50283
50361
  * It will call `beforeHandle` and `handle`
50284
50362
  */
50285
50363
  dispatchToHandlers(handlers, command) {
50364
+ const isCommandCore = isCoreCommand(command);
50286
50365
  for (const handler of handlers) {
50366
+ if (!isCommandCore && handler instanceof CorePlugin) {
50367
+ continue;
50368
+ }
50287
50369
  handler.beforeHandle(command);
50288
50370
  }
50289
50371
  for (const handler of handlers) {
50372
+ if (!isCommandCore && handler instanceof CorePlugin) {
50373
+ continue;
50374
+ }
50290
50375
  handler.handle(command);
50291
50376
  }
50292
50377
  }
@@ -50472,6 +50557,9 @@ const components = {
50472
50557
  };
50473
50558
  function addFunction(functionName, functionDescription) {
50474
50559
  functionRegistry.add(functionName, functionDescription);
50560
+ return {
50561
+ addFunction: (fName, fDescription) => addFunction(fName, fDescription),
50562
+ };
50475
50563
  }
50476
50564
  const constants = {
50477
50565
  DEFAULT_LOCALE,
@@ -50480,6 +50568,6 @@ const constants = {
50480
50568
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
50481
50569
 
50482
50570
 
50483
- __info__.version = '16.5.0-alpha.0';
50484
- __info__.date = '2023-07-24T06:48:58.196Z';
50485
- __info__.hash = '3ba2c3c';
50571
+ __info__.version = '16.5.0-alpha.2';
50572
+ __info__.date = '2023-08-07T09:02:00.623Z';
50573
+ __info__.hash = 'e74f3ef';