@odoo/o-spreadsheet 16.4.28 → 16.4.29

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.
@@ -617,7 +617,7 @@ function deepEquals(o1, o2) {
617
617
  if (typeof o1 !== typeof o2)
618
618
  return false;
619
619
  if (typeof o1 !== "object")
620
- return o1 === o2;
620
+ return false;
621
621
  // Objects can have different keys if the values are undefined
622
622
  const keys = new Set();
623
623
  Object.keys(o1).forEach((key) => keys.add(key));
@@ -15801,6 +15801,7 @@ class LinkEditor extends owl.Component {
15801
15801
  this.save();
15802
15802
  }
15803
15803
  ev.stopPropagation();
15804
+ ev.preventDefault();
15804
15805
  break;
15805
15806
  case "Escape":
15806
15807
  this.cancel();
@@ -24466,6 +24467,11 @@ class Composer extends owl.Component {
24466
24467
  }
24467
24468
  }
24468
24469
  }
24470
+ onContextMenu(ev) {
24471
+ if (this.env.model.getters.getEditionMode() === "inactive") {
24472
+ this.props.onInputContextMenu?.(ev);
24473
+ }
24474
+ }
24469
24475
  // ---------------------------------------------------------------------------
24470
24476
  // Private
24471
24477
  // ---------------------------------------------------------------------------
@@ -24690,6 +24696,7 @@ Composer.props = {
24690
24696
  onComposerCellFocused: { type: Function, optional: true },
24691
24697
  onComposerContentFocused: Function,
24692
24698
  isDefaultFocus: { type: Boolean, optional: true },
24699
+ onInputContextMenu: { type: Function, optional: true },
24693
24700
  };
24694
24701
 
24695
24702
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
@@ -24766,6 +24773,7 @@ class GridComposer extends owl.Component {
24766
24773
  isDefaultFocus: true,
24767
24774
  onComposerContentFocused: this.props.onComposerContentFocused,
24768
24775
  onComposerCellFocused: this.props.onComposerCellFocused,
24776
+ onInputContextMenu: this.props.onInputContextMenu,
24769
24777
  };
24770
24778
  }
24771
24779
  get containerStyle() {
@@ -24854,6 +24862,7 @@ GridComposer.props = {
24854
24862
  onComposerContentFocused: Function,
24855
24863
  gridDims: Object,
24856
24864
  onComposerCellFocused: Function,
24865
+ onInputContextMenu: Function,
24857
24866
  };
24858
24867
 
24859
24868
  const CSS$1 = css /* scss */ `
@@ -27203,8 +27212,8 @@ class Grid extends owl.Component {
27203
27212
  else if (this.env.model.getters.getActiveRows().has(row)) {
27204
27213
  type = "ROW";
27205
27214
  }
27206
- const { x, y, width, height } = this.env.model.getters.getVisibleRect(lastZone);
27207
- this.toggleContextMenu(type, x + width, y + height);
27215
+ const { x, y, width } = this.env.model.getters.getVisibleRect(lastZone);
27216
+ this.toggleContextMenu(type, this.canvasPosition.x + x + width, this.canvasPosition.y + y);
27208
27217
  }
27209
27218
  onCellRightClicked(col, row, { x, y }) {
27210
27219
  const zones = this.env.model.getters.getSelectedZones();
@@ -28494,29 +28503,12 @@ function convertWidthFromExcel(width) {
28494
28503
  return width;
28495
28504
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
28496
28505
  }
28497
- function convertBorderDescr(descr) {
28498
- if (!descr) {
28499
- return undefined;
28500
- }
28501
- return {
28502
- style: descr.style,
28503
- color: { rgb: descr.color },
28504
- };
28505
- }
28506
28506
  function extractStyle(cell, data) {
28507
28507
  let style = {};
28508
28508
  if (cell.style) {
28509
28509
  style = data.styles[cell.style];
28510
28510
  }
28511
28511
  const format = extractFormat(cell, data);
28512
- const exportedBorder = {};
28513
- if (cell.border) {
28514
- const border = data.borders[cell.border];
28515
- exportedBorder.left = convertBorderDescr(border.left);
28516
- exportedBorder.right = convertBorderDescr(border.right);
28517
- exportedBorder.bottom = convertBorderDescr(border.bottom);
28518
- exportedBorder.top = convertBorderDescr(border.top);
28519
- }
28520
28512
  const styles = {
28521
28513
  font: {
28522
28514
  size: style?.fontSize || DEFAULT_FONT_SIZE,
@@ -28530,7 +28522,7 @@ function extractStyle(cell, data) {
28530
28522
  }
28531
28523
  : { reservedAttribute: "none" },
28532
28524
  numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
28533
- border: exportedBorder || {},
28525
+ border: cell.border || 0,
28534
28526
  alignment: {
28535
28527
  horizontal: style.align,
28536
28528
  vertical: style.verticalAlign
@@ -28552,15 +28544,12 @@ function extractFormat(cell, data) {
28552
28544
  return undefined;
28553
28545
  }
28554
28546
  function normalizeStyle(construct, styles) {
28555
- const { id: fontId } = pushElement(styles["font"], construct.fonts);
28556
- const { id: fillId } = pushElement(styles["fill"], construct.fills);
28557
- const { id: borderId } = pushElement(styles["border"], construct.borders);
28558
28547
  // Normalize this
28559
28548
  const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
28560
28549
  const style = {
28561
- fontId,
28562
- fillId,
28563
- borderId,
28550
+ fontId: pushElement(styles.font, construct.fonts),
28551
+ fillId: pushElement(styles.fill, construct.fills),
28552
+ borderId: styles.border,
28564
28553
  numFmtId,
28565
28554
  alignment: {
28566
28555
  vertical: styles.alignment.vertical,
@@ -28568,8 +28557,7 @@ function normalizeStyle(construct, styles) {
28568
28557
  wrapText: styles.alignment.wrapText,
28569
28558
  },
28570
28559
  };
28571
- const { id } = pushElement(style, construct.styles);
28572
- return id;
28560
+ return pushElement(style, construct.styles);
28573
28561
  }
28574
28562
  function convertFormat(format, numFmtStructure) {
28575
28563
  if (!format) {
@@ -28577,8 +28565,7 @@ function convertFormat(format, numFmtStructure) {
28577
28565
  }
28578
28566
  let formatId = XLSX_FORMAT_MAP[format.format];
28579
28567
  if (!formatId) {
28580
- const { id } = pushElement(format, numFmtStructure);
28581
- formatId = id + FIRST_NUMFMT_ID;
28568
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
28582
28569
  }
28583
28570
  return formatId;
28584
28571
  }
@@ -28603,20 +28590,15 @@ function addRelsToFile(relsFiles, path, rel) {
28603
28590
  return id;
28604
28591
  }
28605
28592
  function pushElement(property, propertyList) {
28606
- for (let [key, value] of Object.entries(propertyList)) {
28607
- if (JSON.stringify(value) === JSON.stringify(property)) {
28608
- return { id: parseInt(key, 10), list: propertyList };
28593
+ let len = propertyList.length;
28594
+ const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
28595
+ for (let i = 0; i < len; i++) {
28596
+ if (operator(property, propertyList[i])) {
28597
+ return i;
28609
28598
  }
28610
28599
  }
28611
- let elemId = propertyList.findIndex((elem) => JSON.stringify(elem) === JSON.stringify(property));
28612
- if (elemId === -1) {
28613
- propertyList.push(property);
28614
- elemId = propertyList.length - 1;
28615
- }
28616
- return {
28617
- id: elemId,
28618
- list: propertyList,
28619
- };
28600
+ propertyList[propertyList.length] = property;
28601
+ return propertyList.length - 1;
28620
28602
  }
28621
28603
  const chartIds = [];
28622
28604
  /**
@@ -29337,7 +29319,25 @@ function parseXML(xmlString, mimeType = "text/xml") {
29337
29319
  }
29338
29320
  return document;
29339
29321
  }
29340
- function getDefaultXLSXStructure() {
29322
+ function convertBorderDescr(descr) {
29323
+ if (!descr) {
29324
+ return undefined;
29325
+ }
29326
+ return {
29327
+ style: descr.style,
29328
+ color: { rgb: descr.color },
29329
+ };
29330
+ }
29331
+ function getDefaultXLSXStructure(data) {
29332
+ const xlsxBorders = Object.values(data.borders).map((border) => {
29333
+ return {
29334
+ left: convertBorderDescr(border.left),
29335
+ right: convertBorderDescr(border.right),
29336
+ bottom: convertBorderDescr(border.bottom),
29337
+ top: convertBorderDescr(border.top),
29338
+ };
29339
+ });
29340
+ const borders = [{}, ...xlsxBorders];
29341
29341
  return {
29342
29342
  relsFiles: [],
29343
29343
  sharedStrings: [],
@@ -29360,7 +29360,7 @@ function getDefaultXLSXStructure() {
29360
29360
  },
29361
29361
  ],
29362
29362
  fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
29363
- borders: [{}],
29363
+ borders,
29364
29364
  numFmts: [],
29365
29365
  dxfs: [],
29366
29366
  };
@@ -33425,7 +33425,17 @@ class FiltersPlugin extends CorePlugin {
33425
33425
  }
33426
33426
  }
33427
33427
  exportForExcel(data) {
33428
- this.export(data);
33428
+ for (const sheet of data.sheets) {
33429
+ for (const filterTable of this.getFilterTables(sheet.id)) {
33430
+ if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
33431
+ continue;
33432
+ }
33433
+ sheet.filterTables.push({
33434
+ range: zoneToXc(filterTable.zone),
33435
+ filters: [],
33436
+ });
33437
+ }
33438
+ }
33429
33439
  }
33430
33440
  }
33431
33441
 
@@ -36719,7 +36729,9 @@ class Evaluator {
36719
36729
  this.blockedArrayFormulas = new Set();
36720
36730
  this.spreadingRelations = new SpreadingRelation();
36721
36731
  this.formulaDependencies = lazy(() => {
36722
- const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId).map((range) => ({
36732
+ const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
36733
+ .filter((range) => !range.invalidSheetName && !range.invalidXc)
36734
+ .map((range) => ({
36723
36735
  data: positionId,
36724
36736
  boundingBox: {
36725
36737
  zone: range.zone,
@@ -45254,13 +45266,14 @@ class SheetViewPlugin extends UIPlugin {
45254
45266
  }
45255
45267
  }
45256
45268
  handleEvent(event) {
45269
+ const sheetId = this.getters.getActiveSheetId();
45257
45270
  if (event.options.scrollIntoView) {
45258
45271
  let { col, row } = findCellInNewZone(event.previousAnchor.zone, event.anchor.zone);
45259
45272
  if (event.mode === "updateAnchor") {
45260
45273
  const oldZone = event.previousAnchor.zone;
45261
45274
  const newZone = event.anchor.zone;
45262
45275
  // altering a zone should not move the viewport in a dimension that wasn't changed
45263
- const { top, bottom, left, right } = this.getters.getActiveMainViewport();
45276
+ const { top, bottom, left, right } = this.getMainInternalViewport(sheetId);
45264
45277
  if (oldZone.left === newZone.left && oldZone.right === newZone.right) {
45265
45278
  col = left > col || col > right ? left : col;
45266
45279
  }
@@ -45268,7 +45281,6 @@ class SheetViewPlugin extends UIPlugin {
45268
45281
  row = top > row || row > bottom ? top : row;
45269
45282
  }
45270
45283
  }
45271
- const sheetId = this.getters.getActiveSheetId();
45272
45284
  col = Math.min(col, this.getters.getNumberCols(sheetId) - 1);
45273
45285
  row = Math.min(row, this.getters.getNumberRows(sheetId) - 1);
45274
45286
  this.refreshViewport(this.getters.getActiveSheetId(), { col, row });
@@ -45294,16 +45306,16 @@ class SheetViewPlugin extends UIPlugin {
45294
45306
  this.setSheetViewOffset(cmd.offsetX, cmd.offsetY);
45295
45307
  break;
45296
45308
  case "SHIFT_VIEWPORT_DOWN":
45297
- const { top } = this.getActiveMainViewport();
45298
45309
  const sheetId = this.getters.getActiveSheetId();
45299
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).start + this.sheetViewHeight);
45300
- this.shiftVertically(shiftedOffsetY);
45310
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
45311
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
45312
+ this.shiftVertically(topRowDims.start + viewportHeight - offsetCorrectionY);
45301
45313
  break;
45302
45314
  case "SHIFT_VIEWPORT_UP": {
45303
- const { top } = this.getActiveMainViewport();
45304
45315
  const sheetId = this.getters.getActiveSheetId();
45305
- const shiftedOffsetY = this.clipOffsetY(this.getters.getRowDimensions(sheetId, top).end - this.sheetViewHeight);
45306
- this.shiftVertically(shiftedOffsetY);
45316
+ const { top, viewportHeight, offsetCorrectionY } = this.getMainInternalViewport(sheetId);
45317
+ const topRowDims = this.getters.getRowDimensions(sheetId, top);
45318
+ this.shiftVertically(topRowDims.end - offsetCorrectionY - viewportHeight);
45307
45319
  break;
45308
45320
  }
45309
45321
  case "REMOVE_COLUMNS_ROWS":
@@ -45665,17 +45677,6 @@ class SheetViewPlugin extends UIPlugin {
45665
45677
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
45666
45678
  Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
45667
45679
  }
45668
- /**
45669
- * Clip the vertical offset within the allowed range.
45670
- * Not above the sheet, nor below the sheet.
45671
- */
45672
- clipOffsetY(offsetY) {
45673
- const { height } = this.getMainViewportRect();
45674
- const maxOffset = height - this.sheetViewHeight;
45675
- offsetY = Math.min(offsetY, maxOffset);
45676
- offsetY = Math.max(offsetY, 0);
45677
- return offsetY;
45678
- }
45679
45680
  getViewportOffset(sheetId) {
45680
45681
  return {
45681
45682
  x: this.viewports[sheetId]?.bottomRight.offsetScrollbarX || 0,
@@ -45731,12 +45732,15 @@ class SheetViewPlugin extends UIPlugin {
45731
45732
  * viewport top.
45732
45733
  */
45733
45734
  shiftVertically(offset) {
45734
- const { top } = this.getActiveMainViewport();
45735
+ const sheetId = this.getters.getActiveSheetId();
45736
+ const { top } = this.getMainInternalViewport(sheetId);
45735
45737
  const { scrollX } = this.getActiveSheetScrollInfo();
45736
45738
  this.setSheetViewOffset(scrollX, offset);
45737
45739
  const { anchor } = this.getters.getSelection();
45738
- const deltaRow = this.getActiveMainViewport().top - top;
45739
- this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
45740
+ if (anchor.cell.row >= this.getters.getPaneDivisions(sheetId).ySplit) {
45741
+ const deltaRow = this.getMainInternalViewport(sheetId).top - top;
45742
+ this.selection.selectCell(anchor.cell.col, anchor.cell.row + deltaRow);
45743
+ }
45740
45744
  }
45741
45745
  getVisibleFigures() {
45742
45746
  const sheetId = this.getters.getActiveSheetId();
@@ -49993,8 +49997,7 @@ function addContent(content, sharedStrings, forceString = false) {
49993
49997
  attrs.push(["t", "b"]);
49994
49998
  }
49995
49999
  else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
49996
- const { id } = pushElement(content, sharedStrings);
49997
- value = id.toString();
50000
+ value = pushElement(content, sharedStrings);
49998
50001
  attrs.push(["t", "s"]);
49999
50002
  }
50000
50003
  return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
@@ -50119,8 +50122,7 @@ function addCellIsRule(cf, rule, dxfs) {
50119
50122
  if (rule.style.fillColor) {
50120
50123
  dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
50121
50124
  }
50122
- const { id } = pushElement(dxf, dxfs);
50123
- ruleAttributes.push(["dxfId", id]);
50125
+ ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
50124
50126
  return escapeXml /*xml*/ `
50125
50127
  <conditionalFormatting sqref="${cf.ranges.join(" ")}">
50126
50128
  <cfRule ${formatAttributes(ruleAttributes)}>
@@ -50929,7 +50931,7 @@ function addSheetViews(sheet) {
50929
50931
  */
50930
50932
  function getXLSX(data) {
50931
50933
  const files = [];
50932
- const construct = getDefaultXLSXStructure();
50934
+ const construct = getDefaultXLSXStructure(data);
50933
50935
  files.push(createWorkbook(data, construct));
50934
50936
  files.push(...createWorksheets(data, construct));
50935
50937
  files.push(createStylesSheet(construct));
@@ -51784,6 +51786,6 @@ exports.setTranslationMethod = setTranslationMethod;
51784
51786
  exports.tokenize = tokenize;
51785
51787
 
51786
51788
 
51787
- __info__.version = '16.4.28';
51788
- __info__.date = '2024-04-05T13:59:39.997Z';
51789
- __info__.hash = '7127826';
51789
+ __info__.version = '16.4.29';
51790
+ __info__.date = '2024-04-10T12:19:13.935Z';
51791
+ __info__.hash = 'c022445';
@@ -4819,11 +4819,6 @@ declare class SheetViewPlugin extends UIPlugin {
4819
4819
  private resizeSheetView;
4820
4820
  private recomputeViewports;
4821
4821
  private setSheetViewOffset;
4822
- /**
4823
- * Clip the vertical offset within the allowed range.
4824
- * Not above the sheet, nor below the sheet.
4825
- */
4826
- private clipOffsetY;
4827
4822
  private getViewportOffset;
4828
4823
  private resetViewports;
4829
4824
  /**
@@ -6689,6 +6684,7 @@ interface ComposerProps {
6689
6684
  delimitation?: DOMDimension;
6690
6685
  onComposerContentFocused: () => void;
6691
6686
  onComposerCellFocused?: (content: String) => void;
6687
+ onInputContextMenu?: (event: MouseEvent) => void;
6692
6688
  isDefaultFocus?: boolean;
6693
6689
  }
6694
6690
  interface ComposerState$1 {
@@ -6759,6 +6755,7 @@ declare class Composer extends Component<ComposerProps, SpreadsheetChildEnv> {
6759
6755
  onMousedown(ev: MouseEvent): void;
6760
6756
  onClick(): void;
6761
6757
  onDblClick(): void;
6758
+ onContextMenu(ev: MouseEvent): void;
6762
6759
  private processContent;
6763
6760
  /**
6764
6761
  * Get the HTML content corresponding to the current composer token, divided by lines.
@@ -6937,6 +6934,7 @@ interface Props$5 {
6937
6934
  onComposerContentFocused: () => void;
6938
6935
  onComposerCellFocused: () => void;
6939
6936
  gridDims: DOMDimension;
6937
+ onInputContextMenu: (event: MouseEvent) => void;
6940
6938
  }
6941
6939
  /**
6942
6940
  * This component is a composer which positions itself on the grid at the anchor cell.