@odoo/o-spreadsheet 16.0.21 → 16.0.23

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.
@@ -3951,13 +3951,16 @@ class Popover extends owl.Component {
3951
3951
  super(...arguments);
3952
3952
  this.spreadsheetPosition = useSpreadsheetPosition();
3953
3953
  }
3954
+ get maxHeight() {
3955
+ return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
3956
+ }
3954
3957
  get style() {
3955
3958
  // the props's position is expressed relative to the "body" element
3956
3959
  // but we teleport the element in ".o-spreadsheet" to keep everything
3957
3960
  // within our control and to avoid leaking into external DOM
3958
3961
  const horizontalPosition = `left:${this.horizontalPosition() - this.spreadsheetPosition.x}`;
3959
3962
  const verticalPosition = `top:${this.verticalPosition() - this.spreadsheetPosition.y}`;
3960
- const maxHeight = Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
3963
+ const maxHeight = this.maxHeight;
3961
3964
  const height = `max-height:${maxHeight}`;
3962
3965
  const shadow = maxHeight !== 0 ? "box-shadow: 1px 2px 5px 2px rgb(51 51 51 / 15%);" : "";
3963
3966
  return `
@@ -3981,7 +3984,7 @@ class Popover extends owl.Component {
3981
3984
  }
3982
3985
  get shouldRenderBottom() {
3983
3986
  const { y } = this.props.position;
3984
- return (y + this.props.childHeight <
3987
+ return (y + Math.min(this.props.childHeight, this.maxHeight) <
3985
3988
  this.viewportDimension.height + (this.env.isDashboard() ? 0 : TOPBAR_HEIGHT));
3986
3989
  }
3987
3990
  horizontalPosition() {
@@ -7688,7 +7691,7 @@ function createGaugeChartRuntime(chart, getters) {
7688
7691
  });
7689
7692
  return {
7690
7693
  chartJsConfig: config,
7691
- background: getters.getBackgroundOfSingleCellChart(chart.background, dataRange),
7694
+ background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
7692
7695
  };
7693
7696
  }
7694
7697
 
@@ -8362,7 +8365,7 @@ function createScorecardChartRuntime(chart, getters) {
8362
8365
  const baselineZone = chart.baseline.zone;
8363
8366
  baselineCell = getters.getCell(chart.baseline.sheetId, baselineZone.left, baselineZone.top);
8364
8367
  }
8365
- const background = getters.getBackgroundOfSingleCellChart(chart.background, chart.keyValue);
8368
+ const { background, fontColor } = getters.getStyleOfSingleCellChart(chart.background, chart.keyValue);
8366
8369
  return {
8367
8370
  title: _t(chart.title),
8368
8371
  keyValue: formattedKeyValue || keyValue,
@@ -8370,7 +8373,7 @@ function createScorecardChartRuntime(chart, getters) {
8370
8373
  baselineArrow: getBaselineArrowDirection(baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.evaluated, keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.evaluated, chart.baselineMode),
8371
8374
  baselineColor: getBaselineColor(baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.evaluated, chart.baselineMode, keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.evaluated, chart.baselineColorUp, chart.baselineColorDown),
8372
8375
  baselineDescr: chart.baselineDescr ? _t(chart.baselineDescr) : "",
8373
- fontColor: chartFontColor(background),
8376
+ fontColor,
8374
8377
  background,
8375
8378
  baselineStyle: chart.baselineMode !== "percentage" ? baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.style : undefined,
8376
8379
  keyValueStyle: keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.style,
@@ -25240,12 +25243,15 @@ function createXMLFile(doc, path, contentType) {
25240
25243
  };
25241
25244
  }
25242
25245
  function xmlEscape(str) {
25243
- return String(str)
25246
+ return (String(str)
25244
25247
  .replace(/\&/g, "&amp;")
25245
25248
  .replace(/\</g, "&lt;")
25246
25249
  .replace(/\>/g, "&gt;")
25247
25250
  .replace(/\"/g, "&quot;")
25248
- .replace(/\'/g, "&apos;");
25251
+ .replace(/\'/g, "&apos;")
25252
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
25253
+ // They are not valid at all in XML 1.0 (even escaped)
25254
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
25249
25255
  }
25250
25256
  function formatAttributes(attrs) {
25251
25257
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -28846,6 +28852,13 @@ class FiltersPlugin extends CorePlugin {
28846
28852
  }
28847
28853
  onDeleteColumnsRows(cmd) {
28848
28854
  for (const table of this.getFilterTables(cmd.sheetId)) {
28855
+ // Remove the filter tables whose data filter headers are in the removed rows.
28856
+ if (cmd.dimension === "ROW" && cmd.elements.includes(table.zone.top)) {
28857
+ const tables = { ...this.tables[cmd.sheetId] };
28858
+ delete tables[table.id];
28859
+ this.history.update("tables", cmd.sheetId, tables);
28860
+ continue;
28861
+ }
28849
28862
  const zone = reduceZoneOnDeletion(table.zone, cmd.dimension === "COL" ? "left" : "top", cmd.elements);
28850
28863
  if (!zone) {
28851
28864
  const tables = { ...this.tables[cmd.sheetId] };
@@ -32751,27 +32764,29 @@ class EvaluationChartPlugin extends UIPlugin {
32751
32764
  return this.charts[figureId];
32752
32765
  }
32753
32766
  /**
32754
- * Get the background color of a chart based on the color of the first cell of the main range
32755
- * of the chart. In order of priority, it will return :
32756
- *
32757
- * - the chart background color if one is defined
32758
- * - the fill color of the cell if one is defined
32759
- * - the fill color of the cell from conditional formats if one is defined
32760
- * - the default chart color if no other color is defined
32767
+ * Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
32761
32768
  */
32762
- getBackgroundOfSingleCellChart(chartBackground, mainRange) {
32769
+ getStyleOfSingleCellChart(chartBackground, mainRange) {
32763
32770
  if (chartBackground)
32764
- return chartBackground;
32771
+ return { background: chartBackground, fontColor: chartFontColor(chartBackground) };
32765
32772
  if (!mainRange) {
32766
- return BACKGROUND_CHART_COLOR;
32773
+ return {
32774
+ background: BACKGROUND_CHART_COLOR,
32775
+ fontColor: chartFontColor(BACKGROUND_CHART_COLOR),
32776
+ };
32767
32777
  }
32768
32778
  const col = mainRange.zone.left;
32769
32779
  const row = mainRange.zone.top;
32770
- const style = this.getters.getCellComputedStyle(mainRange.sheetId, col, row);
32771
- return style.fillColor || BACKGROUND_CHART_COLOR;
32780
+ const sheetId = mainRange.sheetId;
32781
+ const style = this.getters.getCellComputedStyle(sheetId, col, row);
32782
+ const background = style.fillColor || BACKGROUND_CHART_COLOR;
32783
+ return {
32784
+ background,
32785
+ fontColor: style.textColor || chartFontColor(background),
32786
+ };
32772
32787
  }
32773
32788
  }
32774
- EvaluationChartPlugin.getters = ["getChartRuntime", "getBackgroundOfSingleCellChart"];
32789
+ EvaluationChartPlugin.getters = ["getChartRuntime", "getStyleOfSingleCellChart"];
32775
32790
 
32776
32791
  // -----------------------------------------------------------------------------
32777
32792
  // Constants
@@ -33110,6 +33125,10 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
33110
33125
  }
33111
33126
  currentRanges = currentRanges.concat(toAdd);
33112
33127
  const newRangesXC = recomputeZones(currentRanges, toRemove);
33128
+ if (newRangesXC.length === 0) {
33129
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
33130
+ return;
33131
+ }
33113
33132
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
33114
33133
  cf: {
33115
33134
  id: cf.id,
@@ -33195,6 +33214,8 @@ class FilterEvaluationPlugin extends UIPlugin {
33195
33214
  break;
33196
33215
  case "HIDE_COLUMNS_ROWS":
33197
33216
  case "UNHIDE_COLUMNS_ROWS":
33217
+ case "ADD_COLUMNS_ROWS":
33218
+ case "REMOVE_COLUMNS_ROWS":
33198
33219
  this.updateHiddenRows();
33199
33220
  break;
33200
33221
  case "UPDATE_FILTER":
@@ -34765,11 +34786,18 @@ class GridSelectionPlugin extends UIPlugin {
34765
34786
  }
34766
34787
  }
34767
34788
  getStatisticFnResults() {
34789
+ const sheetId = this.getters.getActiveSheetId();
34768
34790
  // get deduplicated cells in zones
34769
34791
  const cells = new Set(this.gridSelection.zones
34770
- .map((zone) => this.getters.getCellsInZone(this.getters.getActiveSheetId(), zone))
34792
+ .map((zone) => this.getters.getCellsInZone(sheetId, zone))
34771
34793
  .flat()
34772
- .filter((cell) => cell !== undefined));
34794
+ .filter((cell) => {
34795
+ if (!cell) {
34796
+ return false;
34797
+ }
34798
+ const { col, row } = this.getters.getCellPosition(cell === null || cell === void 0 ? void 0 : cell.id);
34799
+ return !this.getters.isRowHidden(sheetId, row) && !this.getters.isColHidden(sheetId, col);
34800
+ }));
34773
34801
  let cellsTypes = new Set();
34774
34802
  let cellsValues = [];
34775
34803
  for (let cell of cells) {
@@ -42983,6 +43011,6 @@ exports.setTranslationMethod = setTranslationMethod;
42983
43011
  exports.tokenize = tokenize;
42984
43012
 
42985
43013
 
42986
- __info__.version = '16.0.21';
42987
- __info__.date = '2023-10-10T07:26:26.680Z';
42988
- __info__.hash = '5f66b12';
43014
+ __info__.version = '16.0.23';
43015
+ __info__.date = '2023-11-02T09:31:21.669Z';
43016
+ __info__.hash = '06ef793';
@@ -3893,22 +3893,20 @@ declare class EvaluationPlugin extends UIPlugin {
3893
3893
  private getCompilationParameters;
3894
3894
  }
3895
3895
 
3896
+ interface EvaluationChartStyle {
3897
+ background: Color;
3898
+ fontColor: Color;
3899
+ }
3896
3900
  declare class EvaluationChartPlugin extends UIPlugin {
3897
- static getters: readonly ["getChartRuntime", "getBackgroundOfSingleCellChart"];
3901
+ static getters: readonly ["getChartRuntime", "getStyleOfSingleCellChart"];
3898
3902
  readonly charts: Record<UID, ChartRuntime | undefined>;
3899
3903
  private createRuntimeChart;
3900
3904
  handle(cmd: Command): void;
3901
3905
  getChartRuntime(figureId: UID): ChartRuntime;
3902
3906
  /**
3903
- * Get the background color of a chart based on the color of the first cell of the main range
3904
- * of the chart. In order of priority, it will return :
3905
- *
3906
- * - the chart background color if one is defined
3907
- * - the fill color of the cell if one is defined
3908
- * - the fill color of the cell from conditional formats if one is defined
3909
- * - the default chart color if no other color is defined
3907
+ * Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
3910
3908
  */
3911
- getBackgroundOfSingleCellChart(chartBackground: Color | undefined, mainRange: Range | undefined): Color;
3909
+ getStyleOfSingleCellChart(chartBackground: Color | undefined, mainRange: Range | undefined): EvaluationChartStyle;
3912
3910
  }
3913
3911
 
3914
3912
  declare class EvaluationConditionalFormatPlugin extends UIPlugin {
@@ -5251,6 +5249,7 @@ declare class Popover extends Component<Props$p, SpreadsheetChildEnv> {
5251
5249
  zIndex: ComponentsImportance;
5252
5250
  };
5253
5251
  private spreadsheetPosition;
5252
+ get maxHeight(): number;
5254
5253
  get style(): string;
5255
5254
  private get viewportDimension();
5256
5255
  private get shouldRenderRight();
@@ -3947,13 +3947,16 @@ class Popover extends Component {
3947
3947
  super(...arguments);
3948
3948
  this.spreadsheetPosition = useSpreadsheetPosition();
3949
3949
  }
3950
+ get maxHeight() {
3951
+ return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
3952
+ }
3950
3953
  get style() {
3951
3954
  // the props's position is expressed relative to the "body" element
3952
3955
  // but we teleport the element in ".o-spreadsheet" to keep everything
3953
3956
  // within our control and to avoid leaking into external DOM
3954
3957
  const horizontalPosition = `left:${this.horizontalPosition() - this.spreadsheetPosition.x}`;
3955
3958
  const verticalPosition = `top:${this.verticalPosition() - this.spreadsheetPosition.y}`;
3956
- const maxHeight = Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
3959
+ const maxHeight = this.maxHeight;
3957
3960
  const height = `max-height:${maxHeight}`;
3958
3961
  const shadow = maxHeight !== 0 ? "box-shadow: 1px 2px 5px 2px rgb(51 51 51 / 15%);" : "";
3959
3962
  return `
@@ -3977,7 +3980,7 @@ class Popover extends Component {
3977
3980
  }
3978
3981
  get shouldRenderBottom() {
3979
3982
  const { y } = this.props.position;
3980
- return (y + this.props.childHeight <
3983
+ return (y + Math.min(this.props.childHeight, this.maxHeight) <
3981
3984
  this.viewportDimension.height + (this.env.isDashboard() ? 0 : TOPBAR_HEIGHT));
3982
3985
  }
3983
3986
  horizontalPosition() {
@@ -7684,7 +7687,7 @@ function createGaugeChartRuntime(chart, getters) {
7684
7687
  });
7685
7688
  return {
7686
7689
  chartJsConfig: config,
7687
- background: getters.getBackgroundOfSingleCellChart(chart.background, dataRange),
7690
+ background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
7688
7691
  };
7689
7692
  }
7690
7693
 
@@ -8358,7 +8361,7 @@ function createScorecardChartRuntime(chart, getters) {
8358
8361
  const baselineZone = chart.baseline.zone;
8359
8362
  baselineCell = getters.getCell(chart.baseline.sheetId, baselineZone.left, baselineZone.top);
8360
8363
  }
8361
- const background = getters.getBackgroundOfSingleCellChart(chart.background, chart.keyValue);
8364
+ const { background, fontColor } = getters.getStyleOfSingleCellChart(chart.background, chart.keyValue);
8362
8365
  return {
8363
8366
  title: _t(chart.title),
8364
8367
  keyValue: formattedKeyValue || keyValue,
@@ -8366,7 +8369,7 @@ function createScorecardChartRuntime(chart, getters) {
8366
8369
  baselineArrow: getBaselineArrowDirection(baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.evaluated, keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.evaluated, chart.baselineMode),
8367
8370
  baselineColor: getBaselineColor(baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.evaluated, chart.baselineMode, keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.evaluated, chart.baselineColorUp, chart.baselineColorDown),
8368
8371
  baselineDescr: chart.baselineDescr ? _t(chart.baselineDescr) : "",
8369
- fontColor: chartFontColor(background),
8372
+ fontColor,
8370
8373
  background,
8371
8374
  baselineStyle: chart.baselineMode !== "percentage" ? baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.style : undefined,
8372
8375
  keyValueStyle: keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.style,
@@ -25236,12 +25239,15 @@ function createXMLFile(doc, path, contentType) {
25236
25239
  };
25237
25240
  }
25238
25241
  function xmlEscape(str) {
25239
- return String(str)
25242
+ return (String(str)
25240
25243
  .replace(/\&/g, "&amp;")
25241
25244
  .replace(/\</g, "&lt;")
25242
25245
  .replace(/\>/g, "&gt;")
25243
25246
  .replace(/\"/g, "&quot;")
25244
- .replace(/\'/g, "&apos;");
25247
+ .replace(/\'/g, "&apos;")
25248
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
25249
+ // They are not valid at all in XML 1.0 (even escaped)
25250
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
25245
25251
  }
25246
25252
  function formatAttributes(attrs) {
25247
25253
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -28842,6 +28848,13 @@ class FiltersPlugin extends CorePlugin {
28842
28848
  }
28843
28849
  onDeleteColumnsRows(cmd) {
28844
28850
  for (const table of this.getFilterTables(cmd.sheetId)) {
28851
+ // Remove the filter tables whose data filter headers are in the removed rows.
28852
+ if (cmd.dimension === "ROW" && cmd.elements.includes(table.zone.top)) {
28853
+ const tables = { ...this.tables[cmd.sheetId] };
28854
+ delete tables[table.id];
28855
+ this.history.update("tables", cmd.sheetId, tables);
28856
+ continue;
28857
+ }
28845
28858
  const zone = reduceZoneOnDeletion(table.zone, cmd.dimension === "COL" ? "left" : "top", cmd.elements);
28846
28859
  if (!zone) {
28847
28860
  const tables = { ...this.tables[cmd.sheetId] };
@@ -32747,27 +32760,29 @@ class EvaluationChartPlugin extends UIPlugin {
32747
32760
  return this.charts[figureId];
32748
32761
  }
32749
32762
  /**
32750
- * Get the background color of a chart based on the color of the first cell of the main range
32751
- * of the chart. In order of priority, it will return :
32752
- *
32753
- * - the chart background color if one is defined
32754
- * - the fill color of the cell if one is defined
32755
- * - the fill color of the cell from conditional formats if one is defined
32756
- * - the default chart color if no other color is defined
32763
+ * Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
32757
32764
  */
32758
- getBackgroundOfSingleCellChart(chartBackground, mainRange) {
32765
+ getStyleOfSingleCellChart(chartBackground, mainRange) {
32759
32766
  if (chartBackground)
32760
- return chartBackground;
32767
+ return { background: chartBackground, fontColor: chartFontColor(chartBackground) };
32761
32768
  if (!mainRange) {
32762
- return BACKGROUND_CHART_COLOR;
32769
+ return {
32770
+ background: BACKGROUND_CHART_COLOR,
32771
+ fontColor: chartFontColor(BACKGROUND_CHART_COLOR),
32772
+ };
32763
32773
  }
32764
32774
  const col = mainRange.zone.left;
32765
32775
  const row = mainRange.zone.top;
32766
- const style = this.getters.getCellComputedStyle(mainRange.sheetId, col, row);
32767
- return style.fillColor || BACKGROUND_CHART_COLOR;
32776
+ const sheetId = mainRange.sheetId;
32777
+ const style = this.getters.getCellComputedStyle(sheetId, col, row);
32778
+ const background = style.fillColor || BACKGROUND_CHART_COLOR;
32779
+ return {
32780
+ background,
32781
+ fontColor: style.textColor || chartFontColor(background),
32782
+ };
32768
32783
  }
32769
32784
  }
32770
- EvaluationChartPlugin.getters = ["getChartRuntime", "getBackgroundOfSingleCellChart"];
32785
+ EvaluationChartPlugin.getters = ["getChartRuntime", "getStyleOfSingleCellChart"];
32771
32786
 
32772
32787
  // -----------------------------------------------------------------------------
32773
32788
  // Constants
@@ -33106,6 +33121,10 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
33106
33121
  }
33107
33122
  currentRanges = currentRanges.concat(toAdd);
33108
33123
  const newRangesXC = recomputeZones(currentRanges, toRemove);
33124
+ if (newRangesXC.length === 0) {
33125
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
33126
+ return;
33127
+ }
33109
33128
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
33110
33129
  cf: {
33111
33130
  id: cf.id,
@@ -33191,6 +33210,8 @@ class FilterEvaluationPlugin extends UIPlugin {
33191
33210
  break;
33192
33211
  case "HIDE_COLUMNS_ROWS":
33193
33212
  case "UNHIDE_COLUMNS_ROWS":
33213
+ case "ADD_COLUMNS_ROWS":
33214
+ case "REMOVE_COLUMNS_ROWS":
33194
33215
  this.updateHiddenRows();
33195
33216
  break;
33196
33217
  case "UPDATE_FILTER":
@@ -34761,11 +34782,18 @@ class GridSelectionPlugin extends UIPlugin {
34761
34782
  }
34762
34783
  }
34763
34784
  getStatisticFnResults() {
34785
+ const sheetId = this.getters.getActiveSheetId();
34764
34786
  // get deduplicated cells in zones
34765
34787
  const cells = new Set(this.gridSelection.zones
34766
- .map((zone) => this.getters.getCellsInZone(this.getters.getActiveSheetId(), zone))
34788
+ .map((zone) => this.getters.getCellsInZone(sheetId, zone))
34767
34789
  .flat()
34768
- .filter((cell) => cell !== undefined));
34790
+ .filter((cell) => {
34791
+ if (!cell) {
34792
+ return false;
34793
+ }
34794
+ const { col, row } = this.getters.getCellPosition(cell === null || cell === void 0 ? void 0 : cell.id);
34795
+ return !this.getters.isRowHidden(sheetId, row) && !this.getters.isColHidden(sheetId, col);
34796
+ }));
34769
34797
  let cellsTypes = new Set();
34770
34798
  let cellsValues = [];
34771
34799
  for (let cell of cells) {
@@ -42951,6 +42979,6 @@ function addFunction(functionName, functionDescription) {
42951
42979
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, cellTypes, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
42952
42980
 
42953
42981
 
42954
- __info__.version = '16.0.21';
42955
- __info__.date = '2023-10-10T07:26:26.680Z';
42956
- __info__.hash = '5f66b12';
42982
+ __info__.version = '16.0.23';
42983
+ __info__.date = '2023-11-02T09:31:21.669Z';
42984
+ __info__.hash = '06ef793';
@@ -3948,13 +3948,16 @@
3948
3948
  super(...arguments);
3949
3949
  this.spreadsheetPosition = useSpreadsheetPosition();
3950
3950
  }
3951
+ get maxHeight() {
3952
+ return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
3953
+ }
3951
3954
  get style() {
3952
3955
  // the props's position is expressed relative to the "body" element
3953
3956
  // but we teleport the element in ".o-spreadsheet" to keep everything
3954
3957
  // within our control and to avoid leaking into external DOM
3955
3958
  const horizontalPosition = `left:${this.horizontalPosition() - this.spreadsheetPosition.x}`;
3956
3959
  const verticalPosition = `top:${this.verticalPosition() - this.spreadsheetPosition.y}`;
3957
- const maxHeight = Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
3960
+ const maxHeight = this.maxHeight;
3958
3961
  const height = `max-height:${maxHeight}`;
3959
3962
  const shadow = maxHeight !== 0 ? "box-shadow: 1px 2px 5px 2px rgb(51 51 51 / 15%);" : "";
3960
3963
  return `
@@ -3978,7 +3981,7 @@
3978
3981
  }
3979
3982
  get shouldRenderBottom() {
3980
3983
  const { y } = this.props.position;
3981
- return (y + this.props.childHeight <
3984
+ return (y + Math.min(this.props.childHeight, this.maxHeight) <
3982
3985
  this.viewportDimension.height + (this.env.isDashboard() ? 0 : TOPBAR_HEIGHT));
3983
3986
  }
3984
3987
  horizontalPosition() {
@@ -7685,7 +7688,7 @@
7685
7688
  });
7686
7689
  return {
7687
7690
  chartJsConfig: config,
7688
- background: getters.getBackgroundOfSingleCellChart(chart.background, dataRange),
7691
+ background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
7689
7692
  };
7690
7693
  }
7691
7694
 
@@ -8359,7 +8362,7 @@
8359
8362
  const baselineZone = chart.baseline.zone;
8360
8363
  baselineCell = getters.getCell(chart.baseline.sheetId, baselineZone.left, baselineZone.top);
8361
8364
  }
8362
- const background = getters.getBackgroundOfSingleCellChart(chart.background, chart.keyValue);
8365
+ const { background, fontColor } = getters.getStyleOfSingleCellChart(chart.background, chart.keyValue);
8363
8366
  return {
8364
8367
  title: _t(chart.title),
8365
8368
  keyValue: formattedKeyValue || keyValue,
@@ -8367,7 +8370,7 @@
8367
8370
  baselineArrow: getBaselineArrowDirection(baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.evaluated, keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.evaluated, chart.baselineMode),
8368
8371
  baselineColor: getBaselineColor(baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.evaluated, chart.baselineMode, keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.evaluated, chart.baselineColorUp, chart.baselineColorDown),
8369
8372
  baselineDescr: chart.baselineDescr ? _t(chart.baselineDescr) : "",
8370
- fontColor: chartFontColor(background),
8373
+ fontColor,
8371
8374
  background,
8372
8375
  baselineStyle: chart.baselineMode !== "percentage" ? baselineCell === null || baselineCell === void 0 ? void 0 : baselineCell.style : undefined,
8373
8376
  keyValueStyle: keyValueCell === null || keyValueCell === void 0 ? void 0 : keyValueCell.style,
@@ -25237,12 +25240,15 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
25237
25240
  };
25238
25241
  }
25239
25242
  function xmlEscape(str) {
25240
- return String(str)
25243
+ return (String(str)
25241
25244
  .replace(/\&/g, "&amp;")
25242
25245
  .replace(/\</g, "&lt;")
25243
25246
  .replace(/\>/g, "&gt;")
25244
25247
  .replace(/\"/g, "&quot;")
25245
- .replace(/\'/g, "&apos;");
25248
+ .replace(/\'/g, "&apos;")
25249
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
25250
+ // They are not valid at all in XML 1.0 (even escaped)
25251
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
25246
25252
  }
25247
25253
  function formatAttributes(attrs) {
25248
25254
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -28843,6 +28849,13 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
28843
28849
  }
28844
28850
  onDeleteColumnsRows(cmd) {
28845
28851
  for (const table of this.getFilterTables(cmd.sheetId)) {
28852
+ // Remove the filter tables whose data filter headers are in the removed rows.
28853
+ if (cmd.dimension === "ROW" && cmd.elements.includes(table.zone.top)) {
28854
+ const tables = { ...this.tables[cmd.sheetId] };
28855
+ delete tables[table.id];
28856
+ this.history.update("tables", cmd.sheetId, tables);
28857
+ continue;
28858
+ }
28846
28859
  const zone = reduceZoneOnDeletion(table.zone, cmd.dimension === "COL" ? "left" : "top", cmd.elements);
28847
28860
  if (!zone) {
28848
28861
  const tables = { ...this.tables[cmd.sheetId] };
@@ -32748,27 +32761,29 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32748
32761
  return this.charts[figureId];
32749
32762
  }
32750
32763
  /**
32751
- * Get the background color of a chart based on the color of the first cell of the main range
32752
- * of the chart. In order of priority, it will return :
32753
- *
32754
- * - the chart background color if one is defined
32755
- * - the fill color of the cell if one is defined
32756
- * - the fill color of the cell from conditional formats if one is defined
32757
- * - the default chart color if no other color is defined
32764
+ * Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
32758
32765
  */
32759
- getBackgroundOfSingleCellChart(chartBackground, mainRange) {
32766
+ getStyleOfSingleCellChart(chartBackground, mainRange) {
32760
32767
  if (chartBackground)
32761
- return chartBackground;
32768
+ return { background: chartBackground, fontColor: chartFontColor(chartBackground) };
32762
32769
  if (!mainRange) {
32763
- return BACKGROUND_CHART_COLOR;
32770
+ return {
32771
+ background: BACKGROUND_CHART_COLOR,
32772
+ fontColor: chartFontColor(BACKGROUND_CHART_COLOR),
32773
+ };
32764
32774
  }
32765
32775
  const col = mainRange.zone.left;
32766
32776
  const row = mainRange.zone.top;
32767
- const style = this.getters.getCellComputedStyle(mainRange.sheetId, col, row);
32768
- return style.fillColor || BACKGROUND_CHART_COLOR;
32777
+ const sheetId = mainRange.sheetId;
32778
+ const style = this.getters.getCellComputedStyle(sheetId, col, row);
32779
+ const background = style.fillColor || BACKGROUND_CHART_COLOR;
32780
+ return {
32781
+ background,
32782
+ fontColor: style.textColor || chartFontColor(background),
32783
+ };
32769
32784
  }
32770
32785
  }
32771
- EvaluationChartPlugin.getters = ["getChartRuntime", "getBackgroundOfSingleCellChart"];
32786
+ EvaluationChartPlugin.getters = ["getChartRuntime", "getStyleOfSingleCellChart"];
32772
32787
 
32773
32788
  // -----------------------------------------------------------------------------
32774
32789
  // Constants
@@ -33107,6 +33122,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33107
33122
  }
33108
33123
  currentRanges = currentRanges.concat(toAdd);
33109
33124
  const newRangesXC = recomputeZones(currentRanges, toRemove);
33125
+ if (newRangesXC.length === 0) {
33126
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
33127
+ return;
33128
+ }
33110
33129
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
33111
33130
  cf: {
33112
33131
  id: cf.id,
@@ -33192,6 +33211,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33192
33211
  break;
33193
33212
  case "HIDE_COLUMNS_ROWS":
33194
33213
  case "UNHIDE_COLUMNS_ROWS":
33214
+ case "ADD_COLUMNS_ROWS":
33215
+ case "REMOVE_COLUMNS_ROWS":
33195
33216
  this.updateHiddenRows();
33196
33217
  break;
33197
33218
  case "UPDATE_FILTER":
@@ -34762,11 +34783,18 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
34762
34783
  }
34763
34784
  }
34764
34785
  getStatisticFnResults() {
34786
+ const sheetId = this.getters.getActiveSheetId();
34765
34787
  // get deduplicated cells in zones
34766
34788
  const cells = new Set(this.gridSelection.zones
34767
- .map((zone) => this.getters.getCellsInZone(this.getters.getActiveSheetId(), zone))
34789
+ .map((zone) => this.getters.getCellsInZone(sheetId, zone))
34768
34790
  .flat()
34769
- .filter((cell) => cell !== undefined));
34791
+ .filter((cell) => {
34792
+ if (!cell) {
34793
+ return false;
34794
+ }
34795
+ const { col, row } = this.getters.getCellPosition(cell === null || cell === void 0 ? void 0 : cell.id);
34796
+ return !this.getters.isRowHidden(sheetId, row) && !this.getters.isColHidden(sheetId, col);
34797
+ }));
34770
34798
  let cellsTypes = new Set();
34771
34799
  let cellsValues = [];
34772
34800
  for (let cell of cells) {
@@ -42982,9 +43010,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42982
43010
  Object.defineProperty(exports, '__esModule', { value: true });
42983
43011
 
42984
43012
 
42985
- __info__.version = '16.0.21';
42986
- __info__.date = '2023-10-10T07:26:26.680Z';
42987
- __info__.hash = '5f66b12';
43013
+ __info__.version = '16.0.23';
43014
+ __info__.date = '2023-11-02T09:31:21.669Z';
43015
+ __info__.hash = '06ef793';
42988
43016
 
42989
43017
 
42990
43018
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);