@cerios/playwright-table 2.0.0 → 2.0.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.
package/README.md CHANGED
@@ -140,6 +140,8 @@ console.log(headers);
140
140
  cellContentType?: CellContentType.InnerText | CellContentType.TextContent, // Default: InnerText
141
141
  emptyCellReplacement?: boolean, // Replace empty cells with "{{Empty}}" (default: false)
142
142
  duplicateSuffix?: boolean, // Add suffix to duplicate headers (default: false)
143
+ normalizeWhitespace?: boolean, // Collapse internal whitespace/newlines (default: false)
144
+ stripIconGlyphs?: boolean, // Remove icon-font private-use glyphs from headers (default: false)
143
145
  colspan?: {
144
146
  enabled?: boolean, // Enable colspan parsing (default: false)
145
147
  suffix?: boolean // Add suffix to colspan cells (default: false)
@@ -185,7 +187,7 @@ Retrieves all body rows with support for rowspan and colspan.
185
187
 
186
188
  **Parameters:**
187
189
 
188
- - `options?: { cellContentType?: CellContentType }` - Content extraction type
190
+ - `options?: TableOptions` - Full table options (`bodyRowOptions`, `headerRowOptions`) and legacy `cellContentType` shortcut
189
191
 
190
192
  **Returns:** `Promise<BodyRow[]>` - Array of body rows
191
193
 
@@ -194,9 +196,20 @@ Retrieves all body rows with support for rowspan and colspan.
194
196
  **Example:**
195
197
 
196
198
  ```ts
199
+ // Legacy shortcut
197
200
  const rows = await table.getBodyRows({
198
201
  cellContentType: CellContentType.TextContent, // Include hidden elements
199
202
  });
203
+
204
+ // Full table options (useful for custom grids with noisy headers)
205
+ const rowsWithOptions = await table.getBodyRows({
206
+ bodyRowOptions: { cellContentType: CellContentType.InnerText },
207
+ headerRowOptions: {
208
+ normalizeWhitespace: true,
209
+ stripIconGlyphs: true,
210
+ },
211
+ });
212
+
200
213
  console.log(rows);
201
214
  // Output: [["John", "30", "NYC"], ["Jane", "25", "LA"]]
202
215
  ```
@@ -206,6 +219,8 @@ console.log(rows);
206
219
  - `CellContentType.InnerText` - Rendered text (default, excludes hidden elements)
207
220
  - `CellContentType.TextContent` - Raw text content (includes hidden elements)
208
221
 
222
+ Header sanitization options (`normalizeWhitespace`, `stripIconGlyphs`) can be used in all methods that accept `HeaderRowOptions` or `TableOptions`, such as `getHeaderRows`, `getMainHeaderRow`, `getJson`, `findRowIndex`, and `getBodyCellLocatorByRowConditions`.
223
+
209
224
  ---
210
225
 
211
226
  ### 4. `getBodyCellLocator(rowNumber, headerPosition)`
@@ -669,6 +684,25 @@ const divTable = new PlaywrightTable(page.locator(".divTable"), {
669
684
  });
670
685
  ```
671
686
 
687
+ ### ARIA Treegrid Tables
688
+
689
+ For `role="treegrid"` structures, make sure header and body row selectors are scoped to different containers.
690
+ If both use the same selector (for example `div[role='row']`), header rows can be included in body rows.
691
+
692
+ ```ts
693
+ const table = new PlaywrightTable(page.locator("[role='treegrid']"), {
694
+ header: {
695
+ setMainHeaderRow: 0,
696
+ rowSelector: "[data-kind='header-group'] > div[role='row']",
697
+ columnSelector: "div[role='columnheader']",
698
+ },
699
+ row: {
700
+ rowSelector: "[data-kind='body-group'] > div[role='row']",
701
+ columnSelector: "div[role='gridcell']",
702
+ },
703
+ });
704
+ ```
705
+
672
706
  ### Header Row Options
673
707
 
674
708
  Control how headers are processed:
@@ -678,6 +712,8 @@ const headers = await table.getHeaderRows({
678
712
  cellContentType: CellContentType.TextContent, // Include hidden text
679
713
  emptyCellReplacement: true, // Replace "" with "{{Empty}}"
680
714
  duplicateSuffix: true, // "Name", "Name__D1", "Name__D2"
715
+ normalizeWhitespace: true, // "Account\nName" -> "Account Name"
716
+ stripIconGlyphs: true, // Removes private-use icon glyph chars from header text
681
717
  colspan: {
682
718
  enabled: true, // Process colspan attributes
683
719
  suffix: true, // "Col", "Col__C1", "Col__C2"
package/dist/index.d.mts CHANGED
@@ -61,6 +61,8 @@ type HeaderRowOptions = {
61
61
  enabled?: boolean;
62
62
  suffix?: boolean;
63
63
  };
64
+ normalizeWhitespace?: boolean;
65
+ stripIconGlyphs?: boolean;
64
66
  };
65
67
 
66
68
  /**
@@ -85,6 +87,8 @@ type TableOptions = {
85
87
  bodyRowOptions?: {
86
88
  cellContentType?: CellContentType;
87
89
  };
90
+ /** @deprecated Use `bodyRowOptions.cellContentType` instead. */
91
+ cellContentType?: CellContentType;
88
92
  };
89
93
  /**
90
94
  * Represents a table in Playwright, providing methods to interact with its headers, rows, and cells.
@@ -172,8 +176,10 @@ declare class PlaywrightTable {
172
176
  getMainHeaderRow(options?: HeaderRowOptions): Promise<HeaderRow>;
173
177
  /**
174
178
  * Retrieves all body rows of the table.
175
- * @param options - Optional configuration for body row parsing.
176
- * @param options.cellContentType - Content extraction type. See {@link CellContentType}. Defaults to InnerText.
179
+ * @param options - Optional table or body-row configuration.
180
+ * @param options.cellContentType - Legacy shortcut for body row content extraction. See {@link CellContentType}.
181
+ * @param options.bodyRowOptions - Body row parsing options.
182
+ * @param options.headerRowOptions - Header parsing options used when resolving row/colspan layouts.
177
183
  * @returns A promise that resolves to an array of body rows.
178
184
  * @throws Error if no body rows found after table loads.
179
185
  *
@@ -186,10 +192,15 @@ declare class PlaywrightTable {
186
192
  * @example
187
193
  * // Get body rows with default InnerText
188
194
  * const rows = await table.getBodyRows();
195
+ *
196
+ * @example
197
+ * // Use full table options (for example to sanitize noisy treegrid headers)
198
+ * const rows = await table.getBodyRows({
199
+ * bodyRowOptions: { cellContentType: CellContentType.InnerText },
200
+ * headerRowOptions: { normalizeWhitespace: true, stripIconGlyphs: true }
201
+ * });
189
202
  */
190
- getBodyRows(options?: {
191
- cellContentType?: CellContentType;
192
- }): Promise<BodyRow[]>;
203
+ getBodyRows(options?: TableOptions): Promise<BodyRow[]>;
193
204
  /**
194
205
  * Retrieves a specific cell locator in the body of the table by row and column index.
195
206
  * @param rowNumber - The row number (0-based index).
@@ -457,6 +468,10 @@ declare class PlaywrightTable {
457
468
  */
458
469
  findRowIndex(conditions: Record<string, string>, options?: TableOptions): Promise<number>;
459
470
  private getTable;
471
+ private normalizeGetBodyRowsOptions;
472
+ private resolveHeaderRowOptionsForJsonKeys;
473
+ private resolveTableOptionsForHeaderKeyMethods;
474
+ private resolveHeaderRowOptions;
460
475
  private mainHeaderRow;
461
476
  /**
462
477
  * Gets the index of a header in the main header row, throwing an error if not found.
package/dist/index.d.ts CHANGED
@@ -61,6 +61,8 @@ type HeaderRowOptions = {
61
61
  enabled?: boolean;
62
62
  suffix?: boolean;
63
63
  };
64
+ normalizeWhitespace?: boolean;
65
+ stripIconGlyphs?: boolean;
64
66
  };
65
67
 
66
68
  /**
@@ -85,6 +87,8 @@ type TableOptions = {
85
87
  bodyRowOptions?: {
86
88
  cellContentType?: CellContentType;
87
89
  };
90
+ /** @deprecated Use `bodyRowOptions.cellContentType` instead. */
91
+ cellContentType?: CellContentType;
88
92
  };
89
93
  /**
90
94
  * Represents a table in Playwright, providing methods to interact with its headers, rows, and cells.
@@ -172,8 +176,10 @@ declare class PlaywrightTable {
172
176
  getMainHeaderRow(options?: HeaderRowOptions): Promise<HeaderRow>;
173
177
  /**
174
178
  * Retrieves all body rows of the table.
175
- * @param options - Optional configuration for body row parsing.
176
- * @param options.cellContentType - Content extraction type. See {@link CellContentType}. Defaults to InnerText.
179
+ * @param options - Optional table or body-row configuration.
180
+ * @param options.cellContentType - Legacy shortcut for body row content extraction. See {@link CellContentType}.
181
+ * @param options.bodyRowOptions - Body row parsing options.
182
+ * @param options.headerRowOptions - Header parsing options used when resolving row/colspan layouts.
177
183
  * @returns A promise that resolves to an array of body rows.
178
184
  * @throws Error if no body rows found after table loads.
179
185
  *
@@ -186,10 +192,15 @@ declare class PlaywrightTable {
186
192
  * @example
187
193
  * // Get body rows with default InnerText
188
194
  * const rows = await table.getBodyRows();
195
+ *
196
+ * @example
197
+ * // Use full table options (for example to sanitize noisy treegrid headers)
198
+ * const rows = await table.getBodyRows({
199
+ * bodyRowOptions: { cellContentType: CellContentType.InnerText },
200
+ * headerRowOptions: { normalizeWhitespace: true, stripIconGlyphs: true }
201
+ * });
189
202
  */
190
- getBodyRows(options?: {
191
- cellContentType?: CellContentType;
192
- }): Promise<BodyRow[]>;
203
+ getBodyRows(options?: TableOptions): Promise<BodyRow[]>;
193
204
  /**
194
205
  * Retrieves a specific cell locator in the body of the table by row and column index.
195
206
  * @param rowNumber - The row number (0-based index).
@@ -457,6 +468,10 @@ declare class PlaywrightTable {
457
468
  */
458
469
  findRowIndex(conditions: Record<string, string>, options?: TableOptions): Promise<number>;
459
470
  private getTable;
471
+ private normalizeGetBodyRowsOptions;
472
+ private resolveHeaderRowOptionsForJsonKeys;
473
+ private resolveTableOptionsForHeaderKeyMethods;
474
+ private resolveHeaderRowOptions;
460
475
  private mainHeaderRow;
461
476
  /**
462
477
  * Gets the index of a header in the main header row, throwing an error if not found.
package/dist/index.js CHANGED
@@ -318,14 +318,16 @@ Error: ${error instanceof Error ? error.message : String(error)}`
318
318
  return headerRows;
319
319
  }
320
320
  static getDefaultOptions(options) {
321
- var _a, _b, _c, _d, _e, _f, _g;
321
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
322
322
  return {
323
323
  cellContentType: (_a = options == null ? void 0 : options.cellContentType) != null ? _a : "innerText" /* InnerText */,
324
324
  emptyCellReplacement: (_b = options == null ? void 0 : options.emptyCellReplacement) != null ? _b : false,
325
325
  duplicateSuffix: (_c = options == null ? void 0 : options.duplicateSuffix) != null ? _c : false,
326
+ normalizeWhitespace: (_d = options == null ? void 0 : options.normalizeWhitespace) != null ? _d : false,
327
+ stripIconGlyphs: (_e = options == null ? void 0 : options.stripIconGlyphs) != null ? _e : false,
326
328
  colspan: {
327
- enabled: (_e = (_d = options == null ? void 0 : options.colspan) == null ? void 0 : _d.enabled) != null ? _e : false,
328
- suffix: (_g = (_f = options == null ? void 0 : options.colspan) == null ? void 0 : _f.suffix) != null ? _g : false
329
+ enabled: (_g = (_f = options == null ? void 0 : options.colspan) == null ? void 0 : _f.enabled) != null ? _g : false,
330
+ suffix: (_i = (_h = options == null ? void 0 : options.colspan) == null ? void 0 : _h.suffix) != null ? _i : false
329
331
  }
330
332
  };
331
333
  }
@@ -335,7 +337,11 @@ Error: ${error instanceof Error ? error.message : String(error)}`
335
337
  if (cells.length === 0) {
336
338
  return headerRow;
337
339
  }
338
- const cellDataArray = await Promise.all(cells.map((cell) => this.fetchHeaderCellData(cell, options.cellContentType)));
340
+ const cellDataArray = await Promise.all(
341
+ cells.map(
342
+ (cell) => this.fetchHeaderCellData(cell, options.cellContentType, options.normalizeWhitespace, options.stripIconGlyphs)
343
+ )
344
+ );
339
345
  let columnIndex = 0;
340
346
  for (let i = 0; i < cellDataArray.length; i++) {
341
347
  columnIndex = this.processHeaderCellData(
@@ -353,17 +359,27 @@ Error: ${error instanceof Error ? error.message : String(error)}`
353
359
  * Fetches header cell content and span attributes in parallel.
354
360
  * This method performs DOM operations that can be parallelized across multiple cells.
355
361
  */
356
- static async fetchHeaderCellData(cell, cellContentType) {
362
+ static async fetchHeaderCellData(cell, cellContentType, normalizeWhitespace, stripIconGlyphs) {
357
363
  const [text, spanAttributes] = await Promise.all([
358
364
  TableUtils.getCellContent(cell, cellContentType),
359
365
  TableUtils.parseSpanAttributes(cell)
360
366
  ]);
361
367
  return {
362
- text,
368
+ text: this.sanitizeHeaderText(text, normalizeWhitespace, stripIconGlyphs),
363
369
  rowspan: spanAttributes.rowspan,
364
370
  colspan: spanAttributes.colspan
365
371
  };
366
372
  }
373
+ static sanitizeHeaderText(text, normalizeWhitespace, stripIconGlyphs) {
374
+ let result = text;
375
+ if (stripIconGlyphs) {
376
+ result = result.replace(this.ICON_GLYPH_PATTERN, "");
377
+ }
378
+ if (normalizeWhitespace) {
379
+ result = result.replace(this.CONTROL_WHITESPACE_PATTERN, " ").replace(this.WHITESPACE_PATTERN, " ");
380
+ }
381
+ return result.trim();
382
+ }
367
383
  /**
368
384
  * Processes pre-fetched header cell data and applies it to the header row.
369
385
  * This method is purely computational and doesn't perform any DOM operations.
@@ -446,6 +462,9 @@ TableHeader.EMPTY_CELL_PLACEHOLDER = "{{Empty}}";
446
462
  TableHeader.COLSPAN_SUFFIX_PREFIX = "__C";
447
463
  TableHeader.DUPLICATE_SUFFIX_PREFIX = "__D";
448
464
  TableHeader.COLSPAN_PATTERN = /__C\d+/;
465
+ TableHeader.ICON_GLYPH_PATTERN = /[\uE000-\uF8FF\u{F0000}-\u{FFFFD}\u{100000}-\u{10FFFD}]/gu;
466
+ TableHeader.CONTROL_WHITESPACE_PATTERN = /[\p{Cc}\p{Zl}\p{Zp}]+/gu;
467
+ TableHeader.WHITESPACE_PATTERN = /\s+/g;
449
468
 
450
469
  // src/playwright-table.ts
451
470
  var PlaywrightTable = class {
@@ -480,11 +499,18 @@ var PlaywrightTable = class {
480
499
  constructor(_tableLocator, _options) {
481
500
  this._tableLocator = _tableLocator;
482
501
  this._options = _options;
483
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
484
- this._headerRowLocator = this._tableLocator.locator((_c = (_b = (_a = this._options) == null ? void 0 : _a.header) == null ? void 0 : _b.rowSelector) != null ? _c : "thead>tr");
485
- this._headerColumnSelector = (_f = (_e = (_d = this._options) == null ? void 0 : _d.header) == null ? void 0 : _e.columnSelector) != null ? _f : "th";
486
- this._bodyRowLocator = this._tableLocator.locator((_i = (_h = (_g = this._options) == null ? void 0 : _g.row) == null ? void 0 : _h.rowSelector) != null ? _i : "tbody>tr");
487
- this._bodyRowColumnSelector = (_l = (_k = (_j = this._options) == null ? void 0 : _j.row) == null ? void 0 : _k.columnSelector) != null ? _l : "td";
502
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
503
+ const headerRowSelector = (_b = (_a = this._options) == null ? void 0 : _a.header) == null ? void 0 : _b.rowSelector;
504
+ const bodyRowSelector = (_d = (_c = this._options) == null ? void 0 : _c.row) == null ? void 0 : _d.rowSelector;
505
+ if (headerRowSelector && bodyRowSelector && headerRowSelector === bodyRowSelector) {
506
+ console.warn(
507
+ `PlaywrightTable: header.rowSelector and row.rowSelector are identical ("${headerRowSelector}"). This can cause header rows to be included in body rows. Consider scoping selectors to separate row groups.`
508
+ );
509
+ }
510
+ this._headerRowLocator = this._tableLocator.locator((_g = (_f = (_e = this._options) == null ? void 0 : _e.header) == null ? void 0 : _f.rowSelector) != null ? _g : "thead>tr");
511
+ this._headerColumnSelector = (_j = (_i = (_h = this._options) == null ? void 0 : _h.header) == null ? void 0 : _i.columnSelector) != null ? _j : "th";
512
+ this._bodyRowLocator = this._tableLocator.locator((_m = (_l = (_k = this._options) == null ? void 0 : _k.row) == null ? void 0 : _l.rowSelector) != null ? _m : "tbody>tr");
513
+ this._bodyRowColumnSelector = (_p = (_o = (_n = this._options) == null ? void 0 : _n.row) == null ? void 0 : _o.columnSelector) != null ? _p : "td";
488
514
  }
489
515
  /**
490
516
  * Retrieves all header rows of the table.
@@ -533,8 +559,10 @@ var PlaywrightTable = class {
533
559
  }
534
560
  /**
535
561
  * Retrieves all body rows of the table.
536
- * @param options - Optional configuration for body row parsing.
537
- * @param options.cellContentType - Content extraction type. See {@link CellContentType}. Defaults to InnerText.
562
+ * @param options - Optional table or body-row configuration.
563
+ * @param options.cellContentType - Legacy shortcut for body row content extraction. See {@link CellContentType}.
564
+ * @param options.bodyRowOptions - Body row parsing options.
565
+ * @param options.headerRowOptions - Header parsing options used when resolving row/colspan layouts.
538
566
  * @returns A promise that resolves to an array of body rows.
539
567
  * @throws Error if no body rows found after table loads.
540
568
  *
@@ -547,13 +575,21 @@ var PlaywrightTable = class {
547
575
  * @example
548
576
  * // Get body rows with default InnerText
549
577
  * const rows = await table.getBodyRows();
578
+ *
579
+ * @example
580
+ * // Use full table options (for example to sanitize noisy treegrid headers)
581
+ * const rows = await table.getBodyRows({
582
+ * bodyRowOptions: { cellContentType: CellContentType.InnerText },
583
+ * headerRowOptions: { normalizeWhitespace: true, stripIconGlyphs: true }
584
+ * });
550
585
  */
551
586
  async getBodyRows(options) {
587
+ const tableOptions = this.normalizeGetBodyRowsOptions(options);
552
588
  const table = await this.getTable({
553
- bodyRowOptions: options,
554
- headerRowOptions: {
555
- colspan: { enabled: true }
556
- }
589
+ bodyRowOptions: tableOptions.bodyRowOptions,
590
+ headerRowOptions: this.resolveHeaderRowOptions(tableOptions.headerRowOptions, {
591
+ forceColspanEnabled: true
592
+ })
557
593
  });
558
594
  return table.bodyRows;
559
595
  }
@@ -618,7 +654,7 @@ var PlaywrightTable = class {
618
654
  */
619
655
  async getBodyCellLocatorByRowConditions(conditions, targetHeader, options) {
620
656
  var _a;
621
- const table = await this.getTable(options);
657
+ const table = await this.getTable(this.resolveTableOptionsForHeaderKeyMethods(options));
622
658
  const mainHeader = this.mainHeaderRow(table.headerRows);
623
659
  const targetHeaderIndex = this.getHeaderIndex(targetHeader, mainHeader);
624
660
  const conditionsObj = Array.isArray(conditions) ? { [conditions[0]]: conditions[1] } : conditions;
@@ -668,7 +704,7 @@ Body row locator: ${this._bodyRowLocator.toString()}`
668
704
  * @see {@link getBodyCellLocatorByRowConditions} for finding specific cells by content
669
705
  */
670
706
  async getAllBodyCellLocatorsByHeaderName(header, options) {
671
- const table = await this.getTable(options);
707
+ const table = await this.getTable(this.resolveTableOptionsForHeaderKeyMethods(options));
672
708
  const headers = this.mainHeaderRow(table.headerRows);
673
709
  const headerIndex = this.getHeaderIndex(header, headers);
674
710
  const locators = [];
@@ -740,17 +776,9 @@ Header row locator: ${this._headerRowLocator.toString()}`
740
776
  * });
741
777
  */
742
778
  async getJson(options) {
743
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
744
779
  const table = await this.getTable({
745
780
  bodyRowOptions: options == null ? void 0 : options.bodyRowOptions,
746
- headerRowOptions: {
747
- colspan: {
748
- enabled: (_c = (_b = (_a = options == null ? void 0 : options.headerRowOptions) == null ? void 0 : _a.colspan) == null ? void 0 : _b.enabled) != null ? _c : true,
749
- suffix: (_f = (_e = (_d = options == null ? void 0 : options.headerRowOptions) == null ? void 0 : _d.colspan) == null ? void 0 : _e.suffix) != null ? _f : true
750
- },
751
- duplicateSuffix: (_h = (_g = options == null ? void 0 : options.headerRowOptions) == null ? void 0 : _g.duplicateSuffix) != null ? _h : true,
752
- emptyCellReplacement: (_j = (_i = options == null ? void 0 : options.headerRowOptions) == null ? void 0 : _i.emptyCellReplacement) != null ? _j : true
753
- }
781
+ headerRowOptions: this.resolveHeaderRowOptionsForJsonKeys(options == null ? void 0 : options.headerRowOptions)
754
782
  });
755
783
  const headers = this.mainHeaderRow(table.headerRows);
756
784
  return table.bodyRows.map((row) => {
@@ -926,7 +954,7 @@ Body row locator: ${this._bodyRowLocator.toString()}`
926
954
  */
927
955
  async getDistinctColumnValues(headerName, options) {
928
956
  var _a;
929
- const table = await this.getTable(options);
957
+ const table = await this.getTable(this.resolveTableOptionsForHeaderKeyMethods(options));
930
958
  const mainHeader = this.mainHeaderRow(table.headerRows);
931
959
  const headerIndex = this.getHeaderIndex(headerName, mainHeader);
932
960
  const values = /* @__PURE__ */ new Set();
@@ -964,10 +992,7 @@ Body row locator: ${this._bodyRowLocator.toString()}`
964
992
  */
965
993
  async findRowIndex(conditions, options) {
966
994
  var _a;
967
- const table = await this.getTable({
968
- headerRowOptions: { colspan: { enabled: true }, ...options == null ? void 0 : options.headerRowOptions },
969
- bodyRowOptions: options == null ? void 0 : options.bodyRowOptions
970
- });
995
+ const table = await this.getTable(this.resolveTableOptionsForHeaderKeyMethods(options));
971
996
  const mainHeader = this.mainHeaderRow(table.headerRows);
972
997
  const headerIndices = /* @__PURE__ */ new Map();
973
998
  for (const header of Object.keys(conditions)) {
@@ -1011,6 +1036,54 @@ Table locator: ${this._tableLocator.toString()}`
1011
1036
  }
1012
1037
  return { headerRows, bodyRows };
1013
1038
  }
1039
+ normalizeGetBodyRowsOptions(options) {
1040
+ if (!options) {
1041
+ return {};
1042
+ }
1043
+ if (options.bodyRowOptions || options.headerRowOptions) {
1044
+ return options;
1045
+ }
1046
+ if (options.cellContentType !== void 0) {
1047
+ return {
1048
+ bodyRowOptions: {
1049
+ cellContentType: options.cellContentType
1050
+ }
1051
+ };
1052
+ }
1053
+ return options;
1054
+ }
1055
+ resolveHeaderRowOptionsForJsonKeys(headerOptions) {
1056
+ return this.resolveHeaderRowOptions(headerOptions, {
1057
+ defaultColspanEnabled: true,
1058
+ defaultColspanSuffix: true,
1059
+ defaultDuplicateSuffix: true,
1060
+ defaultEmptyCellReplacement: true,
1061
+ defaultNormalizeWhitespace: false,
1062
+ defaultStripIconGlyphs: false
1063
+ });
1064
+ }
1065
+ resolveTableOptionsForHeaderKeyMethods(options) {
1066
+ const tableOptions = this.normalizeGetBodyRowsOptions(options);
1067
+ return {
1068
+ bodyRowOptions: tableOptions.bodyRowOptions,
1069
+ headerRowOptions: this.resolveHeaderRowOptionsForJsonKeys(tableOptions.headerRowOptions)
1070
+ };
1071
+ }
1072
+ resolveHeaderRowOptions(headerOptions, defaults) {
1073
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1074
+ const resolvedColspanEnabled = (defaults == null ? void 0 : defaults.forceColspanEnabled) ? true : (_b = (_a = headerOptions == null ? void 0 : headerOptions.colspan) == null ? void 0 : _a.enabled) != null ? _b : defaults == null ? void 0 : defaults.defaultColspanEnabled;
1075
+ return {
1076
+ cellContentType: headerOptions == null ? void 0 : headerOptions.cellContentType,
1077
+ emptyCellReplacement: (_c = headerOptions == null ? void 0 : headerOptions.emptyCellReplacement) != null ? _c : defaults == null ? void 0 : defaults.defaultEmptyCellReplacement,
1078
+ duplicateSuffix: (_d = headerOptions == null ? void 0 : headerOptions.duplicateSuffix) != null ? _d : defaults == null ? void 0 : defaults.defaultDuplicateSuffix,
1079
+ normalizeWhitespace: (_e = headerOptions == null ? void 0 : headerOptions.normalizeWhitespace) != null ? _e : defaults == null ? void 0 : defaults.defaultNormalizeWhitespace,
1080
+ stripIconGlyphs: (_f = headerOptions == null ? void 0 : headerOptions.stripIconGlyphs) != null ? _f : defaults == null ? void 0 : defaults.defaultStripIconGlyphs,
1081
+ colspan: {
1082
+ enabled: resolvedColspanEnabled,
1083
+ suffix: (_h = (_g = headerOptions == null ? void 0 : headerOptions.colspan) == null ? void 0 : _g.suffix) != null ? _h : defaults == null ? void 0 : defaults.defaultColspanSuffix
1084
+ }
1085
+ };
1086
+ }
1014
1087
  mainHeaderRow(headers) {
1015
1088
  var _a, _b, _c;
1016
1089
  if (headers.length === 0) {