@odoo/o-spreadsheet 18.4.6 → 18.4.8

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.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.4.6
6
- * @date 2025-08-18T08:16:33.453Z
7
- * @hash 9c7c143
5
+ * @version 18.4.8
6
+ * @date 2025-08-26T10:14:08.954Z
7
+ * @hash 746217a
8
8
  */
9
9
 
10
10
  'use strict';
@@ -2781,6 +2781,7 @@ exports.CommandResult = void 0;
2781
2781
  CommandResult["Success"] = "Success";
2782
2782
  CommandResult["CancelledForUnknownReason"] = "CancelledForUnknownReason";
2783
2783
  CommandResult["WillRemoveExistingMerge"] = "WillRemoveExistingMerge";
2784
+ CommandResult["CannotMoveTableHeader"] = "CannotMoveTableHeader";
2784
2785
  CommandResult["MergeIsDestructive"] = "MergeIsDestructive";
2785
2786
  CommandResult["CellIsMerged"] = "CellIsMerged";
2786
2787
  CommandResult["InvalidTarget"] = "InvalidTarget";
@@ -7247,29 +7248,40 @@ function getPasteZones(target, content) {
7247
7248
  const width = content[0].length, height = content.length;
7248
7249
  return target.map((t) => splitZoneForPaste(t, width, height)).flat();
7249
7250
  }
7250
- function parseOSClipboardContent(content, clipboardId) {
7251
+ function parseOSClipboardContent(content) {
7251
7252
  let spreadsheetContent = undefined;
7252
7253
  if (content[ClipboardMIMEType.Html]) {
7253
7254
  const htmlDocument = new DOMParser().parseFromString(content[ClipboardMIMEType.Html], "text/html");
7254
- const oSheetClipboardData = htmlDocument
7255
- .querySelector("div")
7256
- ?.getAttribute("data-osheet-clipboard");
7257
- spreadsheetContent = oSheetClipboardData && JSON.parse(oSheetClipboardData);
7255
+ spreadsheetContent = getOSheetDataFromHTML(htmlDocument);
7258
7256
  }
7257
+ const textContent = content[ClipboardMIMEType.PlainText] || "";
7259
7258
  let imageBlob = undefined;
7260
- for (const type of AllowedImageMimeTypes) {
7261
- if (content[type]) {
7262
- imageBlob = content[type];
7263
- break;
7259
+ if (!textContent.trim()) {
7260
+ for (const type of AllowedImageMimeTypes) {
7261
+ if (content[type]) {
7262
+ imageBlob = content[type];
7263
+ break;
7264
+ }
7264
7265
  }
7265
7266
  }
7266
7267
  const osClipboardContent = {
7267
- text: content[ClipboardMIMEType.PlainText],
7268
+ text: textContent,
7268
7269
  data: spreadsheetContent,
7269
7270
  imageBlob,
7270
7271
  };
7271
7272
  return osClipboardContent;
7272
7273
  }
7274
+ function getOSheetDataFromHTML(htmlDocument) {
7275
+ const attributes = [...htmlDocument.documentElement.attributes];
7276
+ // Check if it's a Microsoft Office clipboard data (it will have some namespaces defined in the root element)
7277
+ if (attributes.some((attr) => attr.value.includes("microsoft"))) {
7278
+ return undefined;
7279
+ }
7280
+ const oSheetClipboardData = htmlDocument
7281
+ .querySelector("div")
7282
+ ?.getAttribute("data-osheet-clipboard");
7283
+ return oSheetClipboardData && JSON.parse(oSheetClipboardData);
7284
+ }
7273
7285
  /**
7274
7286
  * Applies each clipboard handler to paste its corresponding data into the target.
7275
7287
  */
@@ -24286,6 +24298,7 @@ const CustomCurrencyTerms = {
24286
24298
  Custom: _t("Custom"),
24287
24299
  };
24288
24300
  const MergeErrorMessage = _t("Merged cells are preventing this operation. Unmerge those cells and try again.");
24301
+ const TableHeaderMoveErrorMessage = _t("The header row of a table can't be moved.");
24289
24302
  const SplitToColumnsTerms = {
24290
24303
  Errors: {
24291
24304
  Unexpected: _t("Cannot split the selection for an unknown reason"),
@@ -27009,10 +27022,6 @@ class ComboChart extends AbstractChart {
27009
27022
  };
27010
27023
  }
27011
27024
  getDefinitionForExcel() {
27012
- // Excel does not support aggregating labels
27013
- if (this.aggregated) {
27014
- return undefined;
27015
- }
27016
27025
  const dataSets = this.dataSets
27017
27026
  .map((ds) => toExcelDataset(this.getters, ds))
27018
27027
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -28183,9 +28192,6 @@ class RadarChart extends AbstractChart {
28183
28192
  };
28184
28193
  }
28185
28194
  getDefinitionForExcel() {
28186
- if (this.aggregated) {
28187
- return undefined;
28188
- }
28189
28195
  const dataSets = this.dataSets
28190
28196
  .map((ds) => toExcelDataset(this.getters, ds))
28191
28197
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -28330,10 +28336,6 @@ class ScatterChart extends AbstractChart {
28330
28336
  return new ScatterChart(definition, this.sheetId, this.getters);
28331
28337
  }
28332
28338
  getDefinitionForExcel() {
28333
- // Excel does not support aggregating labels
28334
- if (this.aggregated) {
28335
- return undefined;
28336
- }
28337
28339
  const dataSets = this.dataSets
28338
28340
  .map((ds) => toExcelDataset(this.getters, ds))
28339
28341
  .filter((ds) => ds.range !== "");
@@ -47707,8 +47709,13 @@ class RowResizer extends AbstractResizer {
47707
47709
  elements,
47708
47710
  position: this.state.position,
47709
47711
  });
47710
- if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47711
- this.env.raiseError(MergeErrorMessage);
47712
+ if (!result.isSuccessful) {
47713
+ if (result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47714
+ this.env.raiseError(MergeErrorMessage);
47715
+ }
47716
+ else if (result.reasons.includes("CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */)) {
47717
+ this.env.raiseError(TableHeaderMoveErrorMessage);
47718
+ }
47712
47719
  }
47713
47720
  }
47714
47721
  _selectElement(index, addDistinctHeader) {
@@ -68387,7 +68394,7 @@ function withPivotPresentationLayer (PivotClass) {
68387
68394
  return PivotPresentationLayer;
68388
68395
  }
68389
68396
 
68390
- const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT"];
68397
+ const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT", "REMOVE_PIVOT"];
68391
68398
  function isPivotCommand(cmd) {
68392
68399
  return UNDO_REDO_PIVOT_COMMANDS.includes(cmd.type);
68393
68400
  }
@@ -74355,8 +74362,33 @@ class GridSelectionPlugin extends UIPlugin {
74355
74362
  if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
74356
74363
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
74357
74364
  }
74365
+ if (!isCol && !this.isTableRowMoveAllowed(id, cmd.elements)) {
74366
+ return "CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */;
74367
+ }
74358
74368
  return "Success" /* CommandResult.Success */;
74359
74369
  }
74370
+ isTableRowMoveAllowed(sheetId, selectedRows) {
74371
+ const tables = this.getters.getCoreTables(sheetId);
74372
+ if (tables.length === 0) {
74373
+ return true;
74374
+ }
74375
+ const selectedRowSet = new Set(selectedRows);
74376
+ return tables.every(({ range: { zone }, config }) => {
74377
+ const { top, bottom } = zone;
74378
+ if (config.numberOfHeaders === 0) {
74379
+ return true;
74380
+ }
74381
+ const headerRowEnd = top + config.numberOfHeaders - 1;
74382
+ // Moving the table is allowed if table header rows are not part of the selection
74383
+ // Or if the entire table (including header) is selected
74384
+ const isHeaderSelected = selectedRows.some((row) => row >= top && row <= headerRowEnd);
74385
+ if (!isHeaderSelected) {
74386
+ return true;
74387
+ }
74388
+ const isWholeTableSelected = range(top, bottom + 1).every((r) => selectedRowSet.has(r));
74389
+ return isWholeTableSelected;
74390
+ });
74391
+ }
74360
74392
  fallbackToVisibleSheet() {
74361
74393
  if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
74362
74394
  const currentSheetIds = this.getters.getVisibleSheetIds();
@@ -84719,6 +84751,6 @@ exports.tokenColors = tokenColors;
84719
84751
  exports.tokenize = tokenize;
84720
84752
 
84721
84753
 
84722
- __info__.version = "18.4.6";
84723
- __info__.date = "2025-08-18T08:16:33.453Z";
84724
- __info__.hash = "9c7c143";
84754
+ __info__.version = "18.4.8";
84755
+ __info__.date = "2025-08-26T10:14:08.954Z";
84756
+ __info__.hash = "746217a";
@@ -2312,6 +2312,7 @@ declare class GridSelectionPlugin extends UIPlugin {
2312
2312
  private getFiguresUpdates;
2313
2313
  private applyFigureUpdates;
2314
2314
  private isMoveElementAllowed;
2315
+ private isTableRowMoveAllowed;
2315
2316
  private fallbackToVisibleSheet;
2316
2317
  /**
2317
2318
  * Clip the selection if it spans outside the sheet
@@ -3327,6 +3328,7 @@ declare const enum CommandResult {
3327
3328
  Success = "Success",
3328
3329
  CancelledForUnknownReason = "CancelledForUnknownReason",
3329
3330
  WillRemoveExistingMerge = "WillRemoveExistingMerge",
3331
+ CannotMoveTableHeader = "CannotMoveTableHeader",
3330
3332
  MergeIsDestructive = "MergeIsDestructive",
3331
3333
  CellIsMerged = "CellIsMerged",
3332
3334
  InvalidTarget = "InvalidTarget",
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.4.6
6
- * @date 2025-08-18T08:16:33.453Z
7
- * @hash 9c7c143
5
+ * @version 18.4.8
6
+ * @date 2025-08-26T10:14:08.954Z
7
+ * @hash 746217a
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -2779,6 +2779,7 @@ var CommandResult;
2779
2779
  CommandResult["Success"] = "Success";
2780
2780
  CommandResult["CancelledForUnknownReason"] = "CancelledForUnknownReason";
2781
2781
  CommandResult["WillRemoveExistingMerge"] = "WillRemoveExistingMerge";
2782
+ CommandResult["CannotMoveTableHeader"] = "CannotMoveTableHeader";
2782
2783
  CommandResult["MergeIsDestructive"] = "MergeIsDestructive";
2783
2784
  CommandResult["CellIsMerged"] = "CellIsMerged";
2784
2785
  CommandResult["InvalidTarget"] = "InvalidTarget";
@@ -7245,29 +7246,40 @@ function getPasteZones(target, content) {
7245
7246
  const width = content[0].length, height = content.length;
7246
7247
  return target.map((t) => splitZoneForPaste(t, width, height)).flat();
7247
7248
  }
7248
- function parseOSClipboardContent(content, clipboardId) {
7249
+ function parseOSClipboardContent(content) {
7249
7250
  let spreadsheetContent = undefined;
7250
7251
  if (content[ClipboardMIMEType.Html]) {
7251
7252
  const htmlDocument = new DOMParser().parseFromString(content[ClipboardMIMEType.Html], "text/html");
7252
- const oSheetClipboardData = htmlDocument
7253
- .querySelector("div")
7254
- ?.getAttribute("data-osheet-clipboard");
7255
- spreadsheetContent = oSheetClipboardData && JSON.parse(oSheetClipboardData);
7253
+ spreadsheetContent = getOSheetDataFromHTML(htmlDocument);
7256
7254
  }
7255
+ const textContent = content[ClipboardMIMEType.PlainText] || "";
7257
7256
  let imageBlob = undefined;
7258
- for (const type of AllowedImageMimeTypes) {
7259
- if (content[type]) {
7260
- imageBlob = content[type];
7261
- break;
7257
+ if (!textContent.trim()) {
7258
+ for (const type of AllowedImageMimeTypes) {
7259
+ if (content[type]) {
7260
+ imageBlob = content[type];
7261
+ break;
7262
+ }
7262
7263
  }
7263
7264
  }
7264
7265
  const osClipboardContent = {
7265
- text: content[ClipboardMIMEType.PlainText],
7266
+ text: textContent,
7266
7267
  data: spreadsheetContent,
7267
7268
  imageBlob,
7268
7269
  };
7269
7270
  return osClipboardContent;
7270
7271
  }
7272
+ function getOSheetDataFromHTML(htmlDocument) {
7273
+ const attributes = [...htmlDocument.documentElement.attributes];
7274
+ // Check if it's a Microsoft Office clipboard data (it will have some namespaces defined in the root element)
7275
+ if (attributes.some((attr) => attr.value.includes("microsoft"))) {
7276
+ return undefined;
7277
+ }
7278
+ const oSheetClipboardData = htmlDocument
7279
+ .querySelector("div")
7280
+ ?.getAttribute("data-osheet-clipboard");
7281
+ return oSheetClipboardData && JSON.parse(oSheetClipboardData);
7282
+ }
7271
7283
  /**
7272
7284
  * Applies each clipboard handler to paste its corresponding data into the target.
7273
7285
  */
@@ -24284,6 +24296,7 @@ const CustomCurrencyTerms = {
24284
24296
  Custom: _t("Custom"),
24285
24297
  };
24286
24298
  const MergeErrorMessage = _t("Merged cells are preventing this operation. Unmerge those cells and try again.");
24299
+ const TableHeaderMoveErrorMessage = _t("The header row of a table can't be moved.");
24287
24300
  const SplitToColumnsTerms = {
24288
24301
  Errors: {
24289
24302
  Unexpected: _t("Cannot split the selection for an unknown reason"),
@@ -27007,10 +27020,6 @@ class ComboChart extends AbstractChart {
27007
27020
  };
27008
27021
  }
27009
27022
  getDefinitionForExcel() {
27010
- // Excel does not support aggregating labels
27011
- if (this.aggregated) {
27012
- return undefined;
27013
- }
27014
27023
  const dataSets = this.dataSets
27015
27024
  .map((ds) => toExcelDataset(this.getters, ds))
27016
27025
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -28181,9 +28190,6 @@ class RadarChart extends AbstractChart {
28181
28190
  };
28182
28191
  }
28183
28192
  getDefinitionForExcel() {
28184
- if (this.aggregated) {
28185
- return undefined;
28186
- }
28187
28193
  const dataSets = this.dataSets
28188
28194
  .map((ds) => toExcelDataset(this.getters, ds))
28189
28195
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -28328,10 +28334,6 @@ class ScatterChart extends AbstractChart {
28328
28334
  return new ScatterChart(definition, this.sheetId, this.getters);
28329
28335
  }
28330
28336
  getDefinitionForExcel() {
28331
- // Excel does not support aggregating labels
28332
- if (this.aggregated) {
28333
- return undefined;
28334
- }
28335
28337
  const dataSets = this.dataSets
28336
28338
  .map((ds) => toExcelDataset(this.getters, ds))
28337
28339
  .filter((ds) => ds.range !== "");
@@ -47705,8 +47707,13 @@ class RowResizer extends AbstractResizer {
47705
47707
  elements,
47706
47708
  position: this.state.position,
47707
47709
  });
47708
- if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47709
- this.env.raiseError(MergeErrorMessage);
47710
+ if (!result.isSuccessful) {
47711
+ if (result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47712
+ this.env.raiseError(MergeErrorMessage);
47713
+ }
47714
+ else if (result.reasons.includes("CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */)) {
47715
+ this.env.raiseError(TableHeaderMoveErrorMessage);
47716
+ }
47710
47717
  }
47711
47718
  }
47712
47719
  _selectElement(index, addDistinctHeader) {
@@ -68385,7 +68392,7 @@ function withPivotPresentationLayer (PivotClass) {
68385
68392
  return PivotPresentationLayer;
68386
68393
  }
68387
68394
 
68388
- const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT"];
68395
+ const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT", "REMOVE_PIVOT"];
68389
68396
  function isPivotCommand(cmd) {
68390
68397
  return UNDO_REDO_PIVOT_COMMANDS.includes(cmd.type);
68391
68398
  }
@@ -74353,8 +74360,33 @@ class GridSelectionPlugin extends UIPlugin {
74353
74360
  if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
74354
74361
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
74355
74362
  }
74363
+ if (!isCol && !this.isTableRowMoveAllowed(id, cmd.elements)) {
74364
+ return "CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */;
74365
+ }
74356
74366
  return "Success" /* CommandResult.Success */;
74357
74367
  }
74368
+ isTableRowMoveAllowed(sheetId, selectedRows) {
74369
+ const tables = this.getters.getCoreTables(sheetId);
74370
+ if (tables.length === 0) {
74371
+ return true;
74372
+ }
74373
+ const selectedRowSet = new Set(selectedRows);
74374
+ return tables.every(({ range: { zone }, config }) => {
74375
+ const { top, bottom } = zone;
74376
+ if (config.numberOfHeaders === 0) {
74377
+ return true;
74378
+ }
74379
+ const headerRowEnd = top + config.numberOfHeaders - 1;
74380
+ // Moving the table is allowed if table header rows are not part of the selection
74381
+ // Or if the entire table (including header) is selected
74382
+ const isHeaderSelected = selectedRows.some((row) => row >= top && row <= headerRowEnd);
74383
+ if (!isHeaderSelected) {
74384
+ return true;
74385
+ }
74386
+ const isWholeTableSelected = range(top, bottom + 1).every((r) => selectedRowSet.has(r));
74387
+ return isWholeTableSelected;
74388
+ });
74389
+ }
74358
74390
  fallbackToVisibleSheet() {
74359
74391
  if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
74360
74392
  const currentSheetIds = this.getters.getVisibleSheetIds();
@@ -84669,6 +84701,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84669
84701
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
84670
84702
 
84671
84703
 
84672
- __info__.version = "18.4.6";
84673
- __info__.date = "2025-08-18T08:16:33.453Z";
84674
- __info__.hash = "9c7c143";
84704
+ __info__.version = "18.4.8";
84705
+ __info__.date = "2025-08-26T10:14:08.954Z";
84706
+ __info__.hash = "746217a";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.4.6
6
- * @date 2025-08-18T08:16:33.453Z
7
- * @hash 9c7c143
5
+ * @version 18.4.8
6
+ * @date 2025-08-26T10:14:08.954Z
7
+ * @hash 746217a
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -2780,6 +2780,7 @@
2780
2780
  CommandResult["Success"] = "Success";
2781
2781
  CommandResult["CancelledForUnknownReason"] = "CancelledForUnknownReason";
2782
2782
  CommandResult["WillRemoveExistingMerge"] = "WillRemoveExistingMerge";
2783
+ CommandResult["CannotMoveTableHeader"] = "CannotMoveTableHeader";
2783
2784
  CommandResult["MergeIsDestructive"] = "MergeIsDestructive";
2784
2785
  CommandResult["CellIsMerged"] = "CellIsMerged";
2785
2786
  CommandResult["InvalidTarget"] = "InvalidTarget";
@@ -7246,29 +7247,40 @@
7246
7247
  const width = content[0].length, height = content.length;
7247
7248
  return target.map((t) => splitZoneForPaste(t, width, height)).flat();
7248
7249
  }
7249
- function parseOSClipboardContent(content, clipboardId) {
7250
+ function parseOSClipboardContent(content) {
7250
7251
  let spreadsheetContent = undefined;
7251
7252
  if (content[ClipboardMIMEType.Html]) {
7252
7253
  const htmlDocument = new DOMParser().parseFromString(content[ClipboardMIMEType.Html], "text/html");
7253
- const oSheetClipboardData = htmlDocument
7254
- .querySelector("div")
7255
- ?.getAttribute("data-osheet-clipboard");
7256
- spreadsheetContent = oSheetClipboardData && JSON.parse(oSheetClipboardData);
7254
+ spreadsheetContent = getOSheetDataFromHTML(htmlDocument);
7257
7255
  }
7256
+ const textContent = content[ClipboardMIMEType.PlainText] || "";
7258
7257
  let imageBlob = undefined;
7259
- for (const type of AllowedImageMimeTypes) {
7260
- if (content[type]) {
7261
- imageBlob = content[type];
7262
- break;
7258
+ if (!textContent.trim()) {
7259
+ for (const type of AllowedImageMimeTypes) {
7260
+ if (content[type]) {
7261
+ imageBlob = content[type];
7262
+ break;
7263
+ }
7263
7264
  }
7264
7265
  }
7265
7266
  const osClipboardContent = {
7266
- text: content[ClipboardMIMEType.PlainText],
7267
+ text: textContent,
7267
7268
  data: spreadsheetContent,
7268
7269
  imageBlob,
7269
7270
  };
7270
7271
  return osClipboardContent;
7271
7272
  }
7273
+ function getOSheetDataFromHTML(htmlDocument) {
7274
+ const attributes = [...htmlDocument.documentElement.attributes];
7275
+ // Check if it's a Microsoft Office clipboard data (it will have some namespaces defined in the root element)
7276
+ if (attributes.some((attr) => attr.value.includes("microsoft"))) {
7277
+ return undefined;
7278
+ }
7279
+ const oSheetClipboardData = htmlDocument
7280
+ .querySelector("div")
7281
+ ?.getAttribute("data-osheet-clipboard");
7282
+ return oSheetClipboardData && JSON.parse(oSheetClipboardData);
7283
+ }
7272
7284
  /**
7273
7285
  * Applies each clipboard handler to paste its corresponding data into the target.
7274
7286
  */
@@ -24285,6 +24297,7 @@ stores.inject(MyMetaStore, storeInstance);
24285
24297
  Custom: _t("Custom"),
24286
24298
  };
24287
24299
  const MergeErrorMessage = _t("Merged cells are preventing this operation. Unmerge those cells and try again.");
24300
+ const TableHeaderMoveErrorMessage = _t("The header row of a table can't be moved.");
24288
24301
  const SplitToColumnsTerms = {
24289
24302
  Errors: {
24290
24303
  Unexpected: _t("Cannot split the selection for an unknown reason"),
@@ -27008,10 +27021,6 @@ stores.inject(MyMetaStore, storeInstance);
27008
27021
  };
27009
27022
  }
27010
27023
  getDefinitionForExcel() {
27011
- // Excel does not support aggregating labels
27012
- if (this.aggregated) {
27013
- return undefined;
27014
- }
27015
27024
  const dataSets = this.dataSets
27016
27025
  .map((ds) => toExcelDataset(this.getters, ds))
27017
27026
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -28182,9 +28191,6 @@ stores.inject(MyMetaStore, storeInstance);
28182
28191
  };
28183
28192
  }
28184
28193
  getDefinitionForExcel() {
28185
- if (this.aggregated) {
28186
- return undefined;
28187
- }
28188
28194
  const dataSets = this.dataSets
28189
28195
  .map((ds) => toExcelDataset(this.getters, ds))
28190
28196
  .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
@@ -28329,10 +28335,6 @@ stores.inject(MyMetaStore, storeInstance);
28329
28335
  return new ScatterChart(definition, this.sheetId, this.getters);
28330
28336
  }
28331
28337
  getDefinitionForExcel() {
28332
- // Excel does not support aggregating labels
28333
- if (this.aggregated) {
28334
- return undefined;
28335
- }
28336
28338
  const dataSets = this.dataSets
28337
28339
  .map((ds) => toExcelDataset(this.getters, ds))
28338
28340
  .filter((ds) => ds.range !== "");
@@ -47706,8 +47708,13 @@ stores.inject(MyMetaStore, storeInstance);
47706
47708
  elements,
47707
47709
  position: this.state.position,
47708
47710
  });
47709
- if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47710
- this.env.raiseError(MergeErrorMessage);
47711
+ if (!result.isSuccessful) {
47712
+ if (result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
47713
+ this.env.raiseError(MergeErrorMessage);
47714
+ }
47715
+ else if (result.reasons.includes("CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */)) {
47716
+ this.env.raiseError(TableHeaderMoveErrorMessage);
47717
+ }
47711
47718
  }
47712
47719
  }
47713
47720
  _selectElement(index, addDistinctHeader) {
@@ -68386,7 +68393,7 @@ stores.inject(MyMetaStore, storeInstance);
68386
68393
  return PivotPresentationLayer;
68387
68394
  }
68388
68395
 
68389
- const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT"];
68396
+ const UNDO_REDO_PIVOT_COMMANDS = ["ADD_PIVOT", "UPDATE_PIVOT", "REMOVE_PIVOT"];
68390
68397
  function isPivotCommand(cmd) {
68391
68398
  return UNDO_REDO_PIVOT_COMMANDS.includes(cmd.type);
68392
68399
  }
@@ -74354,8 +74361,33 @@ stores.inject(MyMetaStore, storeInstance);
74354
74361
  if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
74355
74362
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
74356
74363
  }
74364
+ if (!isCol && !this.isTableRowMoveAllowed(id, cmd.elements)) {
74365
+ return "CannotMoveTableHeader" /* CommandResult.CannotMoveTableHeader */;
74366
+ }
74357
74367
  return "Success" /* CommandResult.Success */;
74358
74368
  }
74369
+ isTableRowMoveAllowed(sheetId, selectedRows) {
74370
+ const tables = this.getters.getCoreTables(sheetId);
74371
+ if (tables.length === 0) {
74372
+ return true;
74373
+ }
74374
+ const selectedRowSet = new Set(selectedRows);
74375
+ return tables.every(({ range: { zone }, config }) => {
74376
+ const { top, bottom } = zone;
74377
+ if (config.numberOfHeaders === 0) {
74378
+ return true;
74379
+ }
74380
+ const headerRowEnd = top + config.numberOfHeaders - 1;
74381
+ // Moving the table is allowed if table header rows are not part of the selection
74382
+ // Or if the entire table (including header) is selected
74383
+ const isHeaderSelected = selectedRows.some((row) => row >= top && row <= headerRowEnd);
74384
+ if (!isHeaderSelected) {
74385
+ return true;
74386
+ }
74387
+ const isWholeTableSelected = range(top, bottom + 1).every((r) => selectedRowSet.has(r));
74388
+ return isWholeTableSelected;
74389
+ });
74390
+ }
74359
74391
  fallbackToVisibleSheet() {
74360
74392
  if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
74361
74393
  const currentSheetIds = this.getters.getVisibleSheetIds();
@@ -84718,9 +84750,9 @@ stores.inject(MyMetaStore, storeInstance);
84718
84750
  exports.tokenize = tokenize;
84719
84751
 
84720
84752
 
84721
- __info__.version = "18.4.6";
84722
- __info__.date = "2025-08-18T08:16:33.453Z";
84723
- __info__.hash = "9c7c143";
84753
+ __info__.version = "18.4.8";
84754
+ __info__.date = "2025-08-26T10:14:08.954Z";
84755
+ __info__.hash = "746217a";
84724
84756
 
84725
84757
 
84726
84758
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);