• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { LitTableColumn } from './lit-table-column';
17import { LitProgressBar } from './../progress-bar/LitProgressBar';
18import { element } from '../BaseElement';
19import '../utils/Template';
20import { TableRowObject } from './TableRowObject';
21import { ExcelFormater } from '../utils/ExcelFormater';
22import { LitIcon } from '../icon/LitIcon';
23import { NodeType } from '../../js-heap/model/DatabaseStruct';
24import { ConstructorType } from '../../js-heap/model/UiStruct';
25import { JsCpuProfilerStatisticsStruct } from '../../trace/bean/JsStruct';
26import {
27  iconPadding,
28  iconWidth,
29  createDownUpSvg,
30  litTableHtml,
31  exportData,
32  formatExportData,
33  recursionExportTableData,
34  addCopyEventListener,
35  addSelectAllBox,
36  fixed,
37  formatName,
38} from './LitTableHtml';
39
40@element('lit-table')
41export class LitTable extends HTMLElement {
42  meauseRowElement: HTMLDivElement | undefined;
43  currentRecycleList: HTMLDivElement[] = [];
44  currentTreeDivList: HTMLDivElement[] = [];
45  public rememberScrollTop = false;
46  public getItemTextColor?: (data: unknown) => string;
47  public itemTextHandleMap: Map<string, (value: unknown) => string> = new Map<string, (value: unknown) => string>();
48  public exportTextHandleMap: Map<string, (value: unknown) => string> = new Map<string, (value: unknown) => string>();
49  public ds: Array<unknown> = [];
50  public recycleDs: Array<unknown> = [];
51  public gridTemplateColumns: Array<string> = [];
52  public tableColumns: NodeListOf<LitTableColumn> | undefined;
53  public treeElement: HTMLDivElement | undefined | null;
54  public columns: Array<Element> | null | undefined;
55  public exportLoading: boolean = false;
56  public exportProgress: LitProgressBar | null | undefined;
57  public tableElement: HTMLDivElement | null | undefined;
58  private normalDs: Array<unknown> = [];
59  /*Grid css layout descriptions are obtained according to the clustern[] nested structure*/
60  private st: HTMLSlotElement | null | undefined;
61  private theadElement: HTMLDivElement | null | undefined;
62  private tbodyElement: HTMLDivElement | undefined | null;
63  private colCount: number = 0;
64  private isRecycleList: boolean = true;
65  private isScrollXOutSide: boolean = false;
66  private value: Array<unknown> = [];
67  private _mode = TableMode.Expand;
68  private columnResizeEnable: boolean = true;
69  private _isSearch: boolean = false;
70
71  constructor() {
72    super();
73    const shadowRoot = this.attachShadow({ mode: 'open' });
74    shadowRoot.innerHTML = litTableHtml;
75  }
76
77  static get observedAttributes(): string[] {
78    return [
79      'scroll-y',
80      'selectable',
81      'no-head',
82      'grid-line',
83      'defaultOrderColumn',
84      'hideDownload',
85      'noRecycle',
86      'loading',
87      'expand',
88    ];
89  }
90
91  set mode(mode: TableMode) {
92    this._mode = mode;
93  }
94
95  set loading(value: boolean) {
96    this.exportProgress!.loading = value;
97  }
98
99  get hideDownload(): boolean {
100    return this.hasAttribute('hideDownload');
101  }
102
103  set hideDownload(value) {
104    if (value) {
105      this.setAttribute('hideDownload', '');
106    } else {
107      this.removeAttribute('hideDownload');
108    }
109  }
110
111  get selectable(): boolean {
112    return this.hasAttribute('selectable');
113  }
114
115  set selectable(value) {
116    if (value) {
117      this.setAttribute('selectable', '');
118    } else {
119      this.removeAttribute('selectable');
120    }
121  }
122
123  get scrollY(): string {
124    return this.getAttribute('scroll-y') || 'auto';
125  }
126
127  set scrollY(value) {
128    this.setAttribute('scroll-y', value);
129  }
130
131  get dataSource(): unknown[] {
132    return this.ds || [];
133  }
134
135  set dataSource(value) {
136    if (this.hasAttribute('noRecycle')) {
137      this.ds = value;
138      this.isRecycleList = false;
139      this.renderTable();
140    } else {
141      this.columnResizeEnable = false;
142      this.recycleDataSource = value;
143    }
144  }
145
146  set noRecycle(value) {
147    if (value) {
148      this.setAttribute('noRecycle', '');
149    } else {
150      this.removeAttribute('noRecycle');
151    }
152  }
153
154  get noRecycle(): boolean {
155    return this.hasAttribute('noRecycle');
156  }
157
158  get recycleDataSource(): unknown[] {
159    return this.ds || [];
160  }
161
162  set isSearch(value: boolean) {
163    this._isSearch = value;
164  }
165
166  set recycleDataSource(value) {
167    if (this.tableElement) {
168      this.isScrollXOutSide = this.tableElement!.scrollWidth > this.tableElement!.clientWidth;
169      this.isRecycleList = true;
170      this.ds = value;
171      if (this.rememberScrollTop) {
172        this.tableElement!.scrollTop = 0;
173        this.tableElement!.scrollLeft = 0;
174      } else {
175        this.tableElement!.scrollTop = 0;
176      }
177      if (this.hasAttribute('tree') && this.querySelector('lit-table-column')?.hasAttribute('retract')) {
178        if ((value.length === 0 || this.value.length !== 0) && value !== this.value && !this._isSearch) {
179          if (this.shadowRoot!.querySelector<LitIcon>('.top')) {
180            this.shadowRoot!.querySelector<LitIcon>('.top')!.name = 'up';
181          }
182          if (this.shadowRoot!.querySelector<LitIcon>('.bottom')) {
183            this.shadowRoot!.querySelector<LitIcon>('.bottom')!.name = 'down';
184          }
185        }
186        this.value = value;
187        this._isSearch = false;
188        this.recycleDs = this.meauseTreeRowElement(value, RedrawTreeForm.Retract);
189      } else {
190        this.recycleDs = this.meauseAllRowHeight(value);
191      }
192    }
193  }
194
195  get snapshotDataSource(): unknown[] {
196    return this.ds || [];
197  }
198
199  set snapshotDataSource(value) {
200    this.ds = value;
201    if (this.hasAttribute('tree')) {
202      this.recycleDs = this.meauseTreeRowElement(value, RedrawTreeForm.Default);
203    } else {
204      this.recycleDs = this.meauseAllRowHeight(value);
205    }
206  }
207
208  move1px(): void {
209    this.tableElement!.scrollTop = this.tableElement!.scrollTop + 1;
210  }
211
212  dataExportInit(): void {
213    let exportDiv = this.shadowRoot!.querySelector<HTMLDivElement>('.export');
214    exportDiv &&
215      (exportDiv.onclick = (): void => {
216        this.exportData();
217      });
218  }
219
220  exportData(): void {
221    exportData(this);
222  }
223
224  exportExcelData(): void {
225    let now = Date.now();
226    ExcelFormater.testExport(
227      [
228        {
229          columns: this.columns as unknown[],
230          tables: this.ds,
231          sheetName: `${now}`,
232        },
233      ],
234      `${now}`
235    );
236  }
237
238  formatExportData(dataSource: unknown[]): unknown[] {
239    return formatExportData(dataSource, this);
240  }
241
242  formatExportCsvData(dataSource: unknown[]): string {
243    if (dataSource === undefined || dataSource.length === 0) {
244      return '';
245    }
246    if (this.columns === undefined) {
247      return '';
248    }
249    let str = '';
250    str += this.columns!.map((column) => {
251      let dataIndex = column.getAttribute('data-index');
252      let columnName = column.getAttribute('title');
253      if (columnName === '') {
254        columnName = dataIndex;
255      }
256      return columnName;
257    }).join(',');
258    str += recursionExportTableData(this.columns || [], dataSource);
259    return str;
260  }
261
262  injectColumns(): void {
263    this.columns = this.st!.assignedElements();
264    this.columns.forEach((column) => {
265      if (column.tagName === 'LIT-TABLE-COLUMN') {
266        this.gridTemplateColumns.push(column.getAttribute('width') || '1fr');
267      }
268    });
269  }
270  /**
271   * 设置表格每条数据的展开/收起状态
272   * @param list 表格数据
273   * @param status 展开/收起状态
274   * @param depth 展开深度,用来实现和图标的联动
275   * @param profundity 展开深度,用来实现逐级展开
276   */
277  public setStatus(list: unknown, status: boolean, depth: number = 0, profundity?: number): void {
278    this.tableElement!.scrollTop = 0;
279    // 添加depth参数,让切换图标的代码在递归中只走一遍
280    if (depth === 0) {
281      if (status) {
282        this.shadowRoot!.querySelector<LitIcon>('.top')!.name = 'down';
283        this.shadowRoot!.querySelector<LitIcon>('.bottom')!.name = 'up';
284      } else {
285        this.shadowRoot!.querySelector<LitIcon>('.top')!.name = 'up';
286        this.shadowRoot!.querySelector<LitIcon>('.bottom')!.name = 'down';
287      }
288    } // @ts-ignore
289    for (let item of list) {
290      if (profundity) {
291        if (depth < profundity) {
292          item.status = true;
293          status = true;
294        } else {
295          item.status = false;
296          status = false;
297        }
298      } else {
299        item.status = status;
300      }
301      if (item.children !== undefined && item.children.length > 0) {
302        this.setStatus(item.children, status, depth + 1, profundity);
303      }
304    }
305  }
306
307  //当 custom element首次被插入文档DOM时,被调用。
308  connectedCallback(): void {
309    this.st = this.shadowRoot?.querySelector('#slot');
310    this.tableElement = this.shadowRoot?.querySelector('.table');
311    this.exportProgress = this.shadowRoot?.querySelector('#export_progress_bar');
312    this.theadElement = this.shadowRoot?.querySelector('.thead');
313    this.treeElement = this.shadowRoot?.querySelector('.tree');
314    this.tbodyElement = this.shadowRoot?.querySelector('.body');
315    this.tableColumns = this.querySelectorAll<LitTableColumn>('lit-table-column');
316    this.colCount = this.tableColumns!.length;
317    this.dataExportInit();
318    addCopyEventListener(this);
319    this.st?.addEventListener('slotchange', () => {
320      this.theadElement!.innerHTML = '';
321      setTimeout(() => {
322        this.columns = this.st!.assignedElements();
323        let rowElement = document.createElement('div');
324        rowElement.classList.add('th');
325        addSelectAllBox(rowElement, this);
326        let area: Array<unknown> = [];
327        this.gridTemplateColumns = [];
328        this.resolvingArea(this.columns, 0, 0, area, rowElement);
329        area.forEach((rows, j, array) => {
330          for (let i = 0; i < this.colCount; i++) {
331            // @ts-ignore
332            if (!rows[i]) {
333              // @ts-ignore
334              rows[i] = array[j - 1][i];
335            }
336          }
337        });
338        if (this.selectable) {
339          // @ts-ignore
340          let s = area.map((a) => '"_checkbox_ ' + a.map((aa: unknown) => aa.t).join(' ') + '"').join(' ');
341          rowElement.style.gridTemplateColumns = '60px ' + this.gridTemplateColumns.join(' ');
342          rowElement.style.gridTemplateRows = `repeat(${area.length},1fr)`;
343          rowElement.style.gridTemplateAreas = s;
344        } else {
345          // @ts-ignore
346          let s = area.map((a) => '"' + a.map((aa: unknown) => aa.t).join(' ') + '"').join(' ');
347          rowElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' ');
348          rowElement.style.gridTemplateRows = `repeat(${area.length},1fr)`;
349          rowElement.style.gridTemplateAreas = s;
350        }
351        this.theadElement!.innerHTML = '';
352        this.theadElement!.append(rowElement);
353      });
354    });
355    this.shadowRoot!.addEventListener('load', function (event) {});
356    this.tableElement!.addEventListener('mouseout', (ev) => this.mouseOut());
357    this.treeElement && (this.treeElement!.style.transform = 'translateY(0px)');
358    this.tbodyElement && (this.tbodyElement!.style.transform = 'translateY(0px)');
359  }
360
361  resolvingArea(columns: unknown, x: unknown, y: unknown, area: Array<unknown>, rowElement: HTMLDivElement): void {
362    // @ts-ignore
363    columns.forEach((a: unknown, i: unknown) => {
364      // @ts-ignore
365      if (!area[y]) {
366        // @ts-ignore
367        area[y] = [];
368      } // @ts-ignore
369      let key = a.getAttribute('key') || a.getAttribute('title'); // @ts-ignore
370      if (a.tagName === 'LIT-TABLE-GROUP') {
371        // @ts-ignore
372        let len = a.querySelectorAll('lit-table-column').length; // @ts-ignore
373        let children = [...a.children].filter((a) => a.tagName !== 'TEMPLATE');
374        if (children.length > 0) {
375          // @ts-ignore
376          this.resolvingArea(children, x, y + 1, area, rowElement);
377        }
378        for (let j = 0; j < len; j++) {
379          // @ts-ignore
380          area[y][x] = { x, y, t: key }; // @ts-ignore
381          x++;
382        }
383        let h = document.createElement('div');
384        h.classList.add('td'); // @ts-ignore
385        h.style.justifyContent = a.getAttribute('align');
386        h.style.borderBottom = '1px solid #f0f0f0';
387        h.style.gridArea = key; // @ts-ignore
388        h.innerText = a.title; // @ts-ignore
389        if (a.hasAttribute('fixed')) {
390          // @ts-ignore
391          fixed(h, a.getAttribute('fixed'), '#42b983');
392        }
393        rowElement.append(h); // @ts-ignore
394      } else if (a.tagName === 'LIT-TABLE-COLUMN') {
395        // @ts-ignore
396        area[y][x] = { x, y, t: key }; // @ts-ignore
397        x++; // @ts-ignore
398        let head = this.resolvingAreaColumn(rowElement, a, i, key); // @ts-ignore
399        this.gridTemplateColumns.push(a.getAttribute('width') || '1fr'); // @ts-ignore
400        let labelArr = a.title.split('/');
401        for (let i = 0; i < labelArr.length; i++) {
402          let titleLabel = document.createElement('label');
403          titleLabel.style.cursor = 'pointer';
404          i === 0 ? (titleLabel.textContent = labelArr[i]) : (titleLabel.textContent = '/' + labelArr[i]);
405          head.appendChild(titleLabel);
406        } // @ts-ignore
407        if (a.hasAttribute('fixed')) {
408          // @ts-ignore
409          fixed(head, a.getAttribute('fixed'), '#42b983');
410        }
411        rowElement.append(head);
412      }
413    });
414  }
415
416  resolvingAreaColumn(rowElement: HTMLDivElement, column: unknown, index: number, key: string): HTMLDivElement {
417    let head: unknown = document.createElement('div'); // @ts-ignore
418    head.classList.add('td');
419    if ((this.hasAttribute('tree') && index > 1) || (!this.hasAttribute('tree') && index > 0)) {
420      let resizeDiv: HTMLDivElement = document.createElement('div');
421      resizeDiv.classList.add('resize'); // @ts-ignore
422      head.appendChild(resizeDiv);
423      this.resizeEventHandler(rowElement, resizeDiv, index);
424    } // @ts-ignore
425    this.resolvingAreaColumnRetract(column, head);
426    this.resolvingAreaColumnOrder(column, index, key, head); // @ts-ignore
427    this.resolvingAreaColumnButton(column, key, head); // @ts-ignore
428    head.style.justifyContent = column.getAttribute('align'); // @ts-ignore
429    head.style.gridArea = key; // @ts-ignore
430    return head;
431  }
432
433  resolvingAreaColumnRetract(column: unknown, columnHead: HTMLDivElement): void {
434    // @ts-ignore
435    if (column.hasAttribute('retract')) {
436      let expand = document.createElement('div');
437      expand.classList.add('expand');
438      expand.style.display = 'grid';
439      columnHead.append(expand);
440      let top = document.createElement('lit-icon') as LitIcon;
441      top.classList.add('top');
442      top.name = 'up';
443      expand.append(top);
444      let bottom = document.createElement('lit-icon') as LitIcon;
445      bottom.classList.add('bottom');
446      bottom.name = 'down';
447      expand.append(bottom);
448      expand.addEventListener('click', (e) => {
449        if (top.name === 'up' && bottom.name === 'down') {
450          top.name = 'down';
451          bottom.name = 'up';
452          // 一键展开
453          this.setStatus(this.value, true);
454          this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Expand);
455        } else {
456          top.name = 'up';
457          bottom.name = 'down';
458          // 一键收起
459          this.setStatus(this.value, false);
460          this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Retract);
461        }
462        e.stopPropagation();
463      });
464    }
465  }
466
467  resolvingAreaColumnButton(column: unknown, key: string, head: HTMLDivElement): void {
468    // @ts-ignore
469    if (column.hasAttribute('button')) {
470      let buttonIcon = document.createElement('button');
471      buttonIcon.innerHTML = 'GetBusyTime(ms)';
472      buttonIcon.classList.add('button-icon');
473      head.appendChild(buttonIcon);
474      buttonIcon.addEventListener('click', (event) => {
475        this.dispatchEvent(
476          new CustomEvent('button-click', {
477            detail: {
478              key: key,
479            },
480            composed: true,
481          })
482        );
483        event.stopPropagation();
484      });
485    }
486  }
487
488  resolvingAreaColumnOrder(column: unknown, index: number, key: string, columnHead: unknown): void {
489    // @ts-ignore
490    if (column.hasAttribute('order')) {
491      // @ts-ignore
492      (columnHead as unknown).sortType = 0; // @ts-ignore
493      columnHead.classList.add('td-order'); // @ts-ignore
494      columnHead.style.position = 'relative'; // @ts-ignore
495      let { upSvg, downSvg } = createDownUpSvg(index, columnHead); // @ts-ignore
496      columnHead.onclick = (): void => {
497        if (this.isResize || this.resizeColumnIndex !== -1) {
498          return;
499        }
500        this?.shadowRoot?.querySelectorAll('.td-order svg').forEach((it: unknown) => {
501          // @ts-ignore
502          it.setAttribute('fill', 'let(--dark-color1,#212121)'); // @ts-ignore
503          it.sortType = 0; // @ts-ignore
504          it.style.display = 'none';
505        }); // @ts-ignore
506        if (columnHead.sortType === undefined || columnHead.sortType === null) {
507          // @ts-ignore
508          columnHead.sortType = 0; // @ts-ignore
509        } else if (columnHead.sortType === 2) {
510          // @ts-ignore
511          columnHead.sortType = 0;
512        } else {
513          // @ts-ignore
514          columnHead.sortType += 1;
515        }
516        upSvg.setAttribute('fill', 'let(--dark-color1,#212121)');
517        downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); // @ts-ignore
518        upSvg.style.display = columnHead.sortType === 1 ? 'block' : 'none'; // @ts-ignore
519        downSvg.style.display = columnHead.sortType === 2 ? 'block' : 'none'; // @ts-ignore
520        switch (columnHead.sortType) {
521          case 1:
522            this.theadElement!.setAttribute('sort', '');
523            break;
524          case 2:
525            break;
526          default:
527            this.theadElement!.removeAttribute('sort');
528            break;
529        }
530        this.dispatchEvent(
531          new CustomEvent('column-click', {
532            detail: {
533              // @ts-ignore
534              sort: columnHead.sortType,
535              key: key,
536            },
537            composed: true,
538          })
539        );
540      };
541    }
542  }
543
544  private isResize: boolean = false;
545  private resizeColumnIndex: number = -1;
546  private resizeDownX: number = 0;
547  private columnMinWidth: number = 50;
548  private beforeResizeWidth: number = 0;
549
550  resizeEventHandler(header: HTMLDivElement, element: HTMLDivElement, index: number): void {
551    this.resizeMouseMoveEventHandler(header);
552    header.addEventListener('mouseup', (event) => {
553      if (!this.columnResizeEnable) {
554        return;
555      }
556      this.isResize = false;
557      this.resizeDownX = 0;
558      header.style.cursor = 'pointer';
559      setTimeout(() => {
560        this.resizeColumnIndex = -1;
561      }, 100);
562      event.stopPropagation();
563      event.preventDefault();
564    });
565    header.addEventListener('mouseleave', (event) => {
566      if (!this.columnResizeEnable) {
567        return;
568      }
569      event.stopPropagation();
570      event.preventDefault();
571      this.isResize = false;
572      this.resizeDownX = 0;
573      this.resizeColumnIndex = -1;
574      header.style.cursor = 'pointer';
575    });
576    element.addEventListener('mousedown', (event) => {
577      if (event.button === 0) {
578        if (!this.columnResizeEnable) {
579          return;
580        }
581        this.isResize = true;
582        this.resizeColumnIndex = index;
583        this.resizeDownX = event.clientX;
584        let pre = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement;
585        this.beforeResizeWidth = pre.clientWidth;
586        event.stopPropagation();
587      }
588    });
589    element.addEventListener('click', (event) => {
590      event.stopPropagation();
591    });
592  }
593
594  resizeMouseMoveEventHandler(header: HTMLDivElement): void {
595    header.addEventListener('mousemove', (event) => {
596      if (!this.columnResizeEnable) {
597        return;
598      }
599      if (this.isResize) {
600        let width = event.clientX - this.resizeDownX;
601        header.style.cursor = 'col-resize';
602        let preWidth = Math.max(this.beforeResizeWidth + width, this.columnMinWidth);
603        this.gridTemplateColumns[header.childNodes.length - 1] = '1fr';
604        for (let i = 0; i < header.childNodes.length; i++) {
605          let node = header.childNodes.item(i) as HTMLDivElement;
606          this.gridTemplateColumns[i] = `${node.clientWidth}px`;
607        }
608        this.gridTemplateColumns[this.resizeColumnIndex - 1] = `${preWidth}px`;
609        let lastNode = header.childNodes.item(header.childNodes.length - 1) as HTMLDivElement;
610        let totalWidth = 0;
611        this.gridTemplateColumns.forEach((it) => {
612          totalWidth += parseInt(it);
613        });
614        totalWidth = Math.max(totalWidth, this.shadowRoot!.querySelector<HTMLDivElement>('.table')!.scrollWidth);
615        this.gridTemplateColumns[this.gridTemplateColumns.length - 1] = `${totalWidth - lastNode.offsetLeft - 1}px`;
616        header.style.gridTemplateColumns = this.gridTemplateColumns.join(' ');
617        let preNode = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement;
618        preNode.style.width = `${preWidth}px`;
619        this.shadowRoot!.querySelectorAll<HTMLDivElement>('.tr').forEach((tr) => {
620          if (this.hasAttribute('tree')) {
621            tr.style.gridTemplateColumns = this.gridTemplateColumns.slice(1).join(' ');
622          } else {
623            tr.style.gridTemplateColumns = this.gridTemplateColumns.join(' ');
624          }
625        });
626        event.preventDefault();
627        event.stopPropagation();
628      } else {
629        header.style.cursor = 'pointer';
630      }
631    });
632  }
633
634  adoptedCallback(): void {}
635
636  getCheckRows(): unknown[] {
637    return (
638      [...this.shadowRoot!.querySelectorAll('div[class=tr][checked]')]
639        // @ts-ignore
640        .map((a) => (a as HTMLDivElement).data)
641        .map((a) => {
642          if ('children' in a) {
643            delete a.children;
644          }
645          return a;
646        })
647    );
648  }
649
650  deleteRowsCondition(fn: unknown): void {
651    this.shadowRoot!.querySelectorAll('div[class=tr]').forEach((tr) => {
652      // @ts-ignore
653      if (fn(tr.data)) {
654        tr.remove();
655      }
656    });
657  }
658
659  meauseElementHeight(rowData: unknown): number {
660    return 27;
661  }
662
663  meauseTreeElementHeight(rowData: unknown, depth: number): number {
664    return 27;
665  }
666
667  getVisibleObjects(list: unknown[]): { visibleObjects: TableRowObject[]; totalHeight: number } {
668    let headHeight = 0;
669    let totalHeight = headHeight;
670    let visibleObjects: TableRowObject[] = [];
671    let itemHandler = (rowData: unknown, index: number): void => {
672      let height = this.meauseElementHeight(rowData);
673      let tableRowObject = new TableRowObject();
674      tableRowObject.height = height;
675      tableRowObject.top = totalHeight;
676      tableRowObject.data = rowData;
677      tableRowObject.rowIndex = index;
678      if (
679        Math.max(totalHeight, this.tableElement!.scrollTop + headHeight) <=
680        Math.min(totalHeight + height, this.tableElement!.scrollTop + this.tableElement!.clientHeight + headHeight)
681      ) {
682        let newTableElement = this.addTableElement(tableRowObject, false, false, true, totalHeight);
683        let td = newTableElement?.querySelectorAll('.td'); //@ts-ignore
684        if (tableRowObject.data.rowName === 'cpu-profiler') {
685          td[0].innerHTML = '';
686          this.createTextColor(tableRowObject, td[0]);
687        }
688      }
689      totalHeight += height;
690      visibleObjects.push(tableRowObject);
691    };
692    let realIndex = 0;
693    list.forEach((item, index) => {
694      if (Array.isArray(item)) {
695        item.forEach((rowData, childIndex) => {
696          itemHandler(rowData, realIndex);
697          realIndex++;
698        });
699      } else {
700        itemHandler(item, index);
701      }
702    });
703    return { visibleObjects, totalHeight };
704  }
705
706  meauseAllRowHeight(list: unknown[]): TableRowObject[] {
707    this.tbodyElement!.innerHTML = '';
708    this.meauseRowElement = undefined;
709    let head = this.shadowRoot!.querySelector('.th');
710    this.tbodyElement && (this.tbodyElement.style.width = head?.clientWidth + 'px');
711    this.currentRecycleList = [];
712    let { visibleObjects, totalHeight } = this.getVisibleObjects(list);
713    this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide ? 0 : 0) + 'px');
714    this.tableElement &&
715      (this.tableElement.onscroll = (event): void => {
716        let tblScrollTop = this.tableElement!.scrollTop;
717        let skip = 0;
718        for (let i = 0; i < visibleObjects.length; i++) {
719          if (
720            visibleObjects[i].top <= tblScrollTop &&
721            visibleObjects[i].top + visibleObjects[i].height >= tblScrollTop
722          ) {
723            skip = i;
724            break;
725          }
726        }
727        let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0);
728        if (reduce === 0) {
729          return;
730        }
731        while (reduce <= this.tableElement!.clientHeight) {
732          let newTableElement = this.addTableElement(visibleObjects[skip], false, false, false);
733          reduce += newTableElement.clientHeight;
734        }
735        for (let i = 0; i < this.currentRecycleList.length; i++) {
736          this.freshLineHandler(i, skip, visibleObjects);
737        }
738      });
739    return visibleObjects;
740  }
741
742  freshLineHandler(index: number, skip: number, visibleObjects: TableRowObject[]): void {
743    this.freshCurrentLine(this.currentRecycleList[index], visibleObjects[index + skip]);
744    if (visibleObjects[index + skip]) {
745      //@ts-ignore
746      if (visibleObjects[index + skip].data.rowName === 'cpu-profiler') {
747        this.createTextColor(visibleObjects[index + skip], this.currentRecycleList[index].childNodes[0]);
748      }
749    }
750  }
751
752  newTableRowObject(item: unknown, totalHeight: number, depth: number, parentNode?: TableRowObject): TableRowObject {
753    let tableRowObject = new TableRowObject();
754    tableRowObject.depth = depth;
755    tableRowObject.data = item;
756    tableRowObject.top = totalHeight;
757    tableRowObject.height = this.meauseTreeElementHeight(tableRowObject, depth);
758    if (parentNode) {
759      parentNode!.children.push(tableRowObject);
760    }
761    return tableRowObject;
762  }
763
764  resetAllHeight(
765    list: unknown[],
766    depth: number,
767    totalHeight: number,
768    visibleObjects: TableRowObject[],
769    parentNode?: TableRowObject,
770    form?: RedrawTreeForm
771  ): number {
772    let th = totalHeight;
773    let headHeight = this.theadElement?.clientHeight || 0;
774    list.forEach((item) => {
775      let tableRowObject = this.newTableRowObject(item, th, depth, parentNode); // @ts-ignore
776      if (this._mode === TableMode.Expand && form === RedrawTreeForm.Retract && !item.status) {
777        tableRowObject.expanded = false;
778      } else if (this._mode === TableMode.Expand && form === RedrawTreeForm.Default) {
779        tableRowObject.expanded = true;
780      }
781      if (
782        // @ts-ignore
783        (this._mode === TableMode.Retract && !item.status) || // @ts-ignore
784        (this._mode === TableMode.Expand && !item.status && form !== RedrawTreeForm.Expand)
785      ) {
786        tableRowObject.expanded = false; // @ts-ignore
787        if (item.children !== undefined && item.children.length > 0) {
788          this.newTableRowObject(item, th, depth, tableRowObject);
789        }
790      }
791      if (
792        Math.max(th, this.tableElement!.scrollTop) <=
793        Math.min(
794          th + tableRowObject.height,
795          this.tableElement!.scrollTop + this.tableElement!.clientHeight - headHeight
796        )
797      ) {
798        this.addTableElement(tableRowObject, true, false, true, th);
799      }
800      th += tableRowObject.height;
801      visibleObjects.push(tableRowObject);
802      th = this.resetAllHeightChildrenHandler(item, depth, th, visibleObjects, tableRowObject, form);
803    });
804    return th;
805  }
806
807  resetAllHeightChildrenHandler(
808    item: unknown,
809    depth: number,
810    totalHeight: number,
811    visibleObjects: TableRowObject[],
812    tableRowObject?: TableRowObject,
813    form?: RedrawTreeForm
814  ): number {
815    let th = totalHeight; // @ts-ignore
816    if (item.hasNext) {
817      // js memory的表格
818      // @ts-ignore
819      if (item.parents !== undefined && item.parents.length > 0 && item.status) {
820        // @ts-ignore
821        th = this.resetAllHeight(item.parents, depth + 1, totalHeight, visibleObjects, tableRowObject); // @ts-ignore
822      } else if (item.children !== undefined && item.children.length > 0 && item.status) {
823        // @ts-ignore
824        th = this.resetAllHeight(item.children, depth + 1, totalHeight, visibleObjects, tableRowObject);
825      }
826    } else {
827      // 其他数据
828      if (
829        // @ts-ignore
830        item.children !== undefined && // @ts-ignore
831        item.children.length > 0 &&
832        form === RedrawTreeForm.Expand &&
833        this._mode === TableMode.Expand
834      ) {
835        // @ts-ignore
836        item.status = true; // @ts-ignore
837        th = this.resetAllHeight(item.children, depth + 1, totalHeight, visibleObjects, tableRowObject); // @ts-ignore
838      } else if (item.children !== undefined && item.children.length > 0 && item.status) {
839        // @ts-ignore
840        th = this.resetAllHeight(item.children, depth + 1, totalHeight, visibleObjects, tableRowObject);
841      }
842    }
843    return th;
844  }
845
846  measureReset(): void {
847    this.meauseRowElement = undefined;
848    this.tbodyElement!.innerHTML = '';
849    this.treeElement!.innerHTML = '';
850    this.currentRecycleList = [];
851    this.currentTreeDivList = [];
852  }
853
854  meauseTreeRowElement(list: unknown[], form?: RedrawTreeForm): TableRowObject[] {
855    this.measureReset();
856    let visibleObjects: TableRowObject[] = [];
857    let totalHeight = 0;
858    totalHeight = this.resetAllHeight(list, 0, totalHeight, visibleObjects);
859    this.tbodyElement && (this.tbodyElement.style.height = totalHeight + 'px');
860    this.treeElement!.style.height = this.tableElement!.clientHeight - this.theadElement!.clientHeight + 'px';
861    this.tableElement &&
862      (this.tableElement.onscroll = (event): void => {
863        let visibleObjects = this.recycleDs.filter((item) => {
864          // @ts-ignore
865          return !item.rowHidden;
866        });
867        let top = this.tableElement!.scrollTop;
868        this.treeElement && (this.treeElement!.style.transform = `translateY(${top}px)`);
869        let skip = 0;
870        for (let index = 0; index < visibleObjects.length; index++) {
871          // @ts-ignore
872          if (visibleObjects[index].top <= top && visibleObjects[index].top + visibleObjects[index].height >= top) {
873            skip = index;
874            break;
875          }
876        }
877        // 如果滚动高度大于数据全部收起的高度,并且this.currentRecycleList数组长度为0要给this.currentRecycleList赋值,不然tab页没有数据
878        if (
879          visibleObjects[0] && // @ts-ignore
880          this.tableElement!.scrollTop >= this.value.length * visibleObjects[0].height &&
881          this.currentRecycleList.length === 0
882        ) {
883          // @ts-ignore
884          this.addTableElement(visibleObjects[skip], true, false, false);
885        }
886        let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0);
887        if (reduce === 0) {
888          return;
889        }
890        while (reduce <= this.tableElement!.clientHeight) {
891          // @ts-ignore
892          let newTableElement = this.addTableElement(visibleObjects[skip], true, false, false);
893          reduce += newTableElement.clientHeight;
894        }
895        for (let i = 0; i < this.currentRecycleList.length; i++) {
896          this.freshCurrentLine(
897            this.currentRecycleList[i], // @ts-ignore
898            visibleObjects[i + skip],
899            this.treeElement?.children[i] as HTMLElement
900          );
901        }
902      });
903    return visibleObjects;
904  }
905
906  private addTableElement(
907    rowData: TableRowObject,
908    isTree: boolean,
909    last: boolean,
910    translate: boolean,
911    totalHeight?: number
912  ): HTMLDivElement {
913    let newTableElement;
914    if (isTree) {
915      newTableElement = this.createNewTreeTableElement(rowData);
916    } else {
917      newTableElement = this.createNewTableElement(rowData);
918    }
919    if (translate) {
920      newTableElement.style.transform = `translateY(${totalHeight}px)`;
921    }
922    this.tbodyElement?.append(newTableElement);
923    if (last) {
924      if (this.hasAttribute('tree')) {
925        if (this.treeElement?.lastChild) {
926          (this.treeElement?.lastChild as HTMLElement).style.height = rowData.height + 'px';
927        }
928      }
929    }
930    this.currentRecycleList.push(newTableElement);
931    return newTableElement;
932  }
933
934  createNewTreeTableElement(rowData: TableRowObject): HTMLDivElement {
935    let rowTreeElement = document.createElement('div');
936    rowTreeElement.classList.add('tr');
937    let treeTop = 0;
938    if (this.treeElement!.children?.length > 0) {
939      let transX = Number((this.treeElement?.lastChild as HTMLElement).style.transform.replace(/[^0-9]/gi, ''));
940      treeTop += transX + rowData.height;
941    }
942    this?.columns?.forEach((column: unknown, index) => {
943      // @ts-ignore
944      let dataIndex = column.getAttribute('data-index') || '1';
945      let td: unknown;
946      if (index === 0) {
947        td = this.firstElementTdHandler(rowTreeElement, dataIndex, rowData, column);
948      } else {
949        td = this.otherElementHandler(dataIndex, rowData, column); // @ts-ignore
950        rowTreeElement.append(td);
951      }
952    });
953    let lastChild = this.treeElement?.lastChild as HTMLElement;
954    if (lastChild) {
955      lastChild.style.transform = `translateY(${treeTop}px)`;
956    } // @ts-ignore
957    (rowTreeElement as unknown).data = rowData.data;
958    rowTreeElement.style.gridTemplateColumns = this.gridTemplateColumns.slice(1).join(' ');
959    rowTreeElement.style.position = 'absolute';
960    rowTreeElement.style.top = '0px';
961    rowTreeElement.style.left = '0px';
962    rowTreeElement.style.cursor = 'pointer'; //@ts-ignore
963    this.setHighLight(rowData.data.isSearch, rowTreeElement);
964    this.addRowElementEvent(rowTreeElement, rowData);
965    return rowTreeElement;
966  }
967
968  addRowElementEvent(rowTreeElement: HTMLDivElement, rowData: unknown): void {
969    rowTreeElement.onmouseenter = (): void => {
970      // @ts-ignore
971      if ((rowTreeElement as unknown).data.isSelected) {
972        return;
973      }
974      let indexOf = this.currentRecycleList.indexOf(rowTreeElement);
975      this.currentTreeDivList.forEach((row) => {
976        row.classList.remove('mouse-in');
977      });
978      if (indexOf >= 0 && indexOf < this.currentTreeDivList.length) {
979        this.setMouseIn(true, [this.currentTreeDivList[indexOf]]);
980      }
981    };
982    rowTreeElement.onmouseleave = (): void => {
983      // @ts-ignore
984      if ((rowTreeElement as unknown).data.isSelected) {
985        return;
986      }
987      let indexOf = this.currentRecycleList.indexOf(rowTreeElement);
988      if (indexOf >= 0 && indexOf < this.treeElement!.children.length) {
989        this.setMouseIn(false, [this.treeElement?.children[indexOf] as HTMLElement]);
990      }
991    };
992    rowTreeElement.onmouseup = (e: MouseEvent): void => {
993      let indexOf = this.currentRecycleList.indexOf(rowTreeElement);
994      this.dispatchRowClickEvent(rowData, [this.treeElement?.children[indexOf] as HTMLElement, rowTreeElement], e);
995      e.stopPropagation();
996    };
997  }
998
999  firstElementTdHandler(tr: HTMLDivElement, dataIndex: string, row: unknown, column: unknown): HTMLElement {
1000    let td: unknown; // @ts-ignore
1001    let text = formatName(dataIndex, row.data[dataIndex], this); // @ts-ignore
1002    if (column.template) {
1003      // @ts-ignore
1004      td = column.template.render(row.data).content.cloneNode(true); // @ts-ignore
1005      td.template = column.template; // @ts-ignore
1006      td.title = row.data[dataIndex];
1007    } else {
1008      td = document.createElement('div'); // @ts-ignore
1009      if (row.data.rowName === 'js-memory' || row.data.rowName === 'cpu-profiler') {
1010        // @ts-ignore
1011        td.innerHTML = '';
1012      } else {
1013        // @ts-ignore
1014        td.innerHTML = text;
1015      } // @ts-ignore
1016      td.dataIndex = dataIndex; //@ts-ignore
1017      if (text.indexOf('&lt;') === -1) {
1018        // @ts-ignore
1019        td.title = text;
1020      }
1021    } // @ts-ignore
1022    if (row.data.children && row.data.children.length > 0 && !row.data.hasNext) {
1023      let btn = this.createExpandBtn(row); // @ts-ignore
1024      td.insertBefore(btn, td.firstChild);
1025    } // @ts-ignore
1026    if (row.data.hasNext) {
1027      // @ts-ignore
1028      td.title = row.data.objectName;
1029      let btn = this.createBtn(row); // @ts-ignore
1030      td.insertBefore(btn, td.firstChild);
1031    } // @ts-ignore
1032    td.style.paddingLeft = row.depth * iconWidth + 'px'; // @ts-ignore
1033    if (!row.data.children || row.data.children.length === 0) {
1034      // @ts-ignore
1035      td.style.paddingLeft = iconWidth * row.depth + iconWidth + iconPadding * 2 + 'px';
1036    }
1037    this.jsMemoryHandler(row, td); // @ts-ignore
1038    if (row.data.rowName === 'cpu-profiler') {
1039      this.createTextColor(row, td);
1040    } // @ts-ignore
1041    (td as unknown).data = row.data; // @ts-ignore
1042    td.classList.add('tree-first-body'); // @ts-ignore
1043    td.style.position = 'absolute'; // @ts-ignore
1044    td.style.top = '0px'; // @ts-ignore
1045    td.style.left = '0px'; // @ts-ignore
1046    td.style.height = `${row.height}px`; // @ts-ignore
1047    this.addFirstElementEvent(td, tr, row); // @ts-ignore
1048    this.setHighLight(row.data.isSearch, td); // @ts-ignore
1049    this.treeElement!.style.width = column.getAttribute('width'); // @ts-ignore
1050    this.treeElement?.append(td); // @ts-ignore
1051    this.currentTreeDivList.push(td); // @ts-ignore
1052    return td;
1053  }
1054
1055  addFirstElementEvent(td: HTMLDivElement, tr: HTMLDivElement, rowData: unknown): void {
1056    td.onmouseenter = (): void => {
1057      let indexOf = this.currentTreeDivList.indexOf(td);
1058      this.currentRecycleList.forEach((row) => {
1059        row.classList.remove('mouse-in');
1060      });
1061      if (indexOf >= 0 && indexOf < this.currentRecycleList.length && td.innerHTML !== '') {
1062        this.setMouseIn(true, [tr]);
1063      }
1064    };
1065    td.onmouseleave = (): void => {
1066      let indexOf = this.currentTreeDivList.indexOf(td);
1067      if (indexOf >= 0 && indexOf < this.currentRecycleList.length) {
1068        this.setMouseIn(false, [tr]);
1069      }
1070    };
1071    td.onmouseup = (e: MouseEvent): void => {
1072      let indexOf = this.currentTreeDivList.indexOf(td);
1073      this.dispatchRowClickEvent(rowData, [td, tr], e);
1074      e.stopPropagation();
1075    };
1076  }
1077
1078  otherElementHandler(dataIndex: string, rowData: unknown, column: unknown): HTMLDivElement {
1079    // @ts-ignore
1080    let tdDiv: unknown = document.createElement('div'); // @ts-ignore
1081    tdDiv.classList.add('td'); // @ts-ignore
1082    tdDiv.style.overflow = 'hidden'; // @ts-ignore
1083    tdDiv.style.textOverflow = 'ellipsis'; // @ts-ignore
1084    tdDiv.style.whiteSpace = 'nowrap'; // @ts-ignore
1085    let text = formatName(dataIndex, rowData.data[dataIndex], this); //@ts-ignore
1086    if (text.indexOf('&lt;') === -1) {
1087      // @ts-ignore
1088      if (dataIndex === 'selfTimeStr' && rowData.data.chartFrameChildren) {
1089        // @ts-ignore
1090        tdDiv.title = rowData.data.selfTime + 'ns'; // @ts-ignore
1091      } else if (dataIndex === 'totalTimeStr' && rowData.data.chartFrameChildren) {
1092        // @ts-ignore
1093        tdDiv.title = rowData.data.totalTime + 'ns';
1094      } else {
1095        // @ts-ignore
1096        tdDiv.title = text;
1097      }
1098    } // @ts-ignore
1099    tdDiv.dataIndex = dataIndex; // @ts-ignore
1100    tdDiv.style.justifyContent = column.getAttribute('align') || 'flex-start'; // @ts-ignore
1101    if (column.template) {
1102      // @ts-ignore
1103      tdDiv.appendChild(column.template.render(rowData.data).content.cloneNode(true)); // @ts-ignore
1104      tdDiv.template = column.template;
1105    } else {
1106      // @ts-ignore
1107      tdDiv.innerHTML = text;
1108    } // @ts-ignore
1109    return tdDiv;
1110  }
1111
1112  createNewTableElement(rowData: unknown): HTMLDivElement {
1113    let newTableElement = document.createElement('div');
1114    newTableElement.classList.add('tr');
1115    this?.columns?.forEach((column: unknown) => {
1116      // @ts-ignore
1117      let dataIndex = column.getAttribute('data-index') || '1';
1118      let td = this.createColumnTd(dataIndex, column, rowData);
1119      newTableElement.append(td);
1120    });
1121    newTableElement.onmouseup = (e: MouseEvent): void => {
1122      this.dispatchRowClickEvent(rowData, [newTableElement], e);
1123      e.stopPropagation();
1124    };
1125    newTableElement.onmouseenter = (): void => {
1126      this.dispatchRowHoverEvent(rowData, [newTableElement]);
1127    }; // @ts-ignore
1128    if (rowData.data.isSelected !== undefined) {
1129      // @ts-ignore
1130      this.setSelectedRow(rowData.data.isSelected, [newTableElement]);
1131    } // @ts-ignore
1132    (newTableElement as unknown).data = rowData.data;
1133    newTableElement.style.cursor = 'pointer';
1134    newTableElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' ');
1135    newTableElement.style.position = 'absolute';
1136    newTableElement.style.top = '0px';
1137    newTableElement.style.left = '0px';
1138    if (this.getItemTextColor) {
1139      // @ts-ignore
1140      newTableElement.style.color = this.getItemTextColor(rowData.data);
1141    }
1142    return newTableElement;
1143  }
1144
1145  createColumnTd(dataIndex: string, column: unknown, rowData: unknown): HTMLDivElement {
1146    let td: unknown;
1147    td = document.createElement('div'); // @ts-ignore
1148    td.classList.add('td'); // @ts-ignore
1149    td.style.overflow = 'hidden'; // @ts-ignore
1150    td.style.textOverflow = 'ellipsis'; // @ts-ignore
1151    td.style.whiteSpace = 'nowrap'; // @ts-ignore
1152    td.dataIndex = dataIndex; // @ts-ignore
1153    td.style.justifyContent = column.getAttribute('align') || 'flex-start'; // @ts-ignore
1154    let text = formatName(dataIndex, rowData.data[dataIndex], this); //@ts-ignore
1155    if (text.indexOf('&lt;') === -1) {
1156      // @ts-ignore
1157      if (dataIndex === 'totalTimeStr' && rowData.data.chartFrameChildren) {
1158        // @ts-ignore
1159        td.title = rowData.data.totalTime + 'ns';
1160      } else {
1161        // @ts-ignore
1162        td.title = text;
1163      }
1164    }
1165    //   如果表格中有模板的情况,将模板中的数据放进td中,没有模板,直接将文本放进td
1166    //  但是对于Current Selection tab页来说,表格前两列是时间,第三列是input标签,第四列是button标签
1167    //  而第一行的数据只有第四列一个button,和模板中的数据并不一样,所以要特别处理一下
1168    // @ts-ignore
1169    if (column.template) {
1170      if (
1171        // @ts-ignore
1172        (dataIndex === 'color' && rowData.data.colorEl === undefined) || // @ts-ignore
1173        (dataIndex === 'text' && rowData.data.text === undefined)
1174      ) {
1175        // @ts-ignore
1176        td.innerHTML = ''; // @ts-ignore
1177        td.template = ''; // @ts-ignore
1178      } else if (dataIndex === 'operate' && rowData.data.operate && rowData.data.operate.innerHTML === 'RemoveAll') {
1179        let removeAll = document.createElement('button');
1180        removeAll.className = 'removeAll';
1181        removeAll.innerHTML = 'RemoveAll';
1182        removeAll.style.background = 'var(--dark-border1,#262f3c)';
1183        removeAll.style.color = 'white';
1184        removeAll.style.borderRadius = '10px';
1185        removeAll.style.fontSize = '10px';
1186        removeAll.style.height = '18px';
1187        removeAll.style.lineHeight = '18px';
1188        removeAll.style.minWidth = '7em';
1189        removeAll.style.border = 'none';
1190        removeAll.style.cursor = 'pointer';
1191        removeAll.style.outline = 'inherit'; // @ts-ignore
1192        td.appendChild(removeAll);
1193      } else {
1194        // @ts-ignore
1195        td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); // @ts-ignore
1196        td.template = column.template;
1197      }
1198    } else {
1199      // @ts-ignore
1200      td.innerHTML = text;
1201    } // @ts-ignore
1202    return td;
1203  }
1204
1205  createBtn(rowData: unknown): unknown {
1206    let btn: unknown = document.createElement('lit-icon'); // @ts-ignore
1207    btn.classList.add('tree-icon'); // @ts-ignore
1208    if (rowData.data.expanded) {
1209      // @ts-ignore
1210      btn.name = 'plus-square';
1211    } else {
1212      // @ts-ignore
1213      btn.name = 'minus-square';
1214    } // @ts-ignore
1215    btn.addEventListener('mouseup', (e: MouseEvent): void => {
1216      if (e.button === 0) {
1217        // @ts-ignore
1218        rowData.data.status = false;
1219        const resetNodeHidden = (hidden: boolean, rowData: unknown): void => {
1220          if (hidden) {
1221            // @ts-ignore
1222            rowData.children.forEach((child: unknown) => {
1223              // @ts-ignore
1224              child.rowHidden = false;
1225            });
1226          } else {
1227            // @ts-ignore
1228            rowData.children.forEach((child: unknown) => {
1229              // @ts-ignore
1230              child.rowHidden = true;
1231              resetNodeHidden(hidden, child);
1232            });
1233          }
1234        };
1235        // @ts-ignore
1236        if (rowData.data.expanded) {
1237          // @ts-ignore
1238          rowData.data.status = true;
1239          this.dispatchRowClickEventIcon(rowData, [btn]); // @ts-ignore
1240          rowData.data.expanded = false;
1241          resetNodeHidden(true, rowData);
1242        } else {
1243          // @ts-ignore
1244          rowData.data.expanded = true; // @ts-ignore
1245          rowData.data.status = false;
1246          resetNodeHidden(false, rowData);
1247        }
1248        this.reMeauseHeight();
1249      }
1250      e.stopPropagation();
1251    });
1252    return btn;
1253  }
1254
1255  resetExpandNodeHidden = (hidden: boolean, rowData: unknown): void => {
1256    // @ts-ignore
1257    if (rowData.children.length > 0) {
1258      if (hidden) {
1259        // @ts-ignore
1260        rowData.children.forEach((child: unknown) => {
1261          // @ts-ignore
1262          child.rowHidden = true;
1263          this.resetExpandNodeHidden(hidden, child);
1264        });
1265      } else {
1266        // @ts-ignore
1267        rowData.children.forEach((child: unknown) => {
1268          // @ts-ignore
1269          child.rowHidden = !rowData.expanded; // @ts-ignore
1270          if (rowData.expanded) {
1271            this.resetExpandNodeHidden(hidden, child);
1272          }
1273        });
1274      }
1275    }
1276  };
1277
1278  setChildrenStatus(rowData: unknown, data: unknown): void {
1279    // @ts-ignore
1280    for (let d of data) {
1281      // @ts-ignore
1282      if (rowData.data === d) {
1283        d.status = false;
1284      }
1285      if (d.children !== undefined && d.children.length > 0) {
1286        this.setChildrenStatus(rowData, d.children);
1287      }
1288    }
1289  }
1290  createExpandBtn(rowData: unknown): LitIcon {
1291    // @ts-ignore
1292    let btn: unknown = document.createElement('lit-icon'); // @ts-ignore
1293    btn.classList.add('tree-icon');
1294    // @ts-ignore
1295    if (rowData.expanded) {
1296      // @ts-ignore
1297      btn.name = 'minus-square';
1298    } else {
1299      // @ts-ignore
1300      btn.name = 'plus-square';
1301    } // @ts-ignore
1302    btn.onmouseup = (e: MouseEvent): void => {
1303      if (e.button === 0) {
1304        // @ts-ignore
1305        if (rowData.expanded && this._mode === TableMode.Retract) {
1306          // @ts-ignore
1307          rowData.data.status = false; // @ts-ignore
1308          rowData.expanded = false;
1309          this.resetExpandNodeHidden(true, rowData); // @ts-ignore
1310        } else if (!rowData.expanded && this._mode === TableMode.Retract) {
1311          // @ts-ignore
1312          rowData.expanded = true; // @ts-ignore
1313          rowData.data.status = true;
1314          this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Retract);
1315          this.resetExpandNodeHidden(false, rowData);
1316        } // @ts-ignore
1317        if (this._mode === TableMode.Expand && rowData.expanded) {
1318          // 点击收起的时候将点击的那条数据的status改为false
1319          this.setChildrenStatus(rowData, this.value); // @ts-ignore
1320          rowData.expanded = false;
1321          this.resetExpandNodeHidden(true, rowData); // @ts-ignore
1322        } else if (this._mode === TableMode.Expand && !rowData.expanded) {
1323          // @ts-ignore
1324          if (rowData.data.children) {
1325            // @ts-ignore
1326            rowData.data.status = true;
1327          }
1328          this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Default); // @ts-ignore
1329          rowData.expanded = true;
1330          this.resetExpandNodeHidden(false, rowData);
1331        }
1332        this.reMeauseHeight();
1333      }
1334      e.stopPropagation();
1335    }; // @ts-ignore
1336    return btn;
1337  }
1338
1339  reMeauseHeight(): void {
1340    if (this.currentRecycleList.length === 0 && this.ds.length !== 0) {
1341      this.recycleDataSource = this.ds;
1342      return;
1343    }
1344    let totalHeight = 0;
1345    this.recycleDs.forEach((it) => {
1346      // @ts-ignore
1347      if (!it.rowHidden) {
1348        // @ts-ignore
1349        it.top = totalHeight; // @ts-ignore
1350        totalHeight += it.height;
1351      }
1352    });
1353    this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide ? 0 : 0) + 'px');
1354    this.treeElement &&
1355      (this.treeElement.style.height = this.tableElement!.clientHeight - this.theadElement!.clientHeight + 'px');
1356    let visibleObjects = this.recycleDs.filter((item) => {
1357      // @ts-ignore
1358      return !item.rowHidden;
1359    });
1360    if (this.tableElement) {
1361      let top = this.tableElement!.scrollTop;
1362      let skip = 0;
1363      for (let i = 0; i < visibleObjects.length; i++) {
1364        // @ts-ignore
1365        if (visibleObjects[i].top <= top && visibleObjects[i].top + visibleObjects[i].height >= top) {
1366          skip = i;
1367          break;
1368        }
1369      }
1370      let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0);
1371      if (reduce === 0) {
1372        return;
1373      }
1374      while (reduce <= this.tableElement!.clientHeight + 1) {
1375        let isTree = this.hasAttribute('tree'); // @ts-ignore
1376        let newTableElement = this.addTableElement(visibleObjects[skip], isTree, isTree, false);
1377        reduce += newTableElement.clientHeight;
1378      }
1379      for (let i = 0; i < this.currentRecycleList.length; i++) {
1380        if (this.hasAttribute('tree')) {
1381          this.freshCurrentLine(
1382            this.currentRecycleList[i], // @ts-ignore
1383            visibleObjects[i + skip],
1384            this.treeElement?.children[i] as HTMLElement
1385          );
1386        } else {
1387          // @ts-ignore
1388          this.freshLineHandler(i, skip, visibleObjects);
1389        }
1390      }
1391    }
1392  }
1393
1394  getWheelStatus(element: unknown): void {
1395    // @ts-ignore
1396    element.addEventListener('wheel', (event: WheelEvent) => {
1397      // @ts-ignore
1398      if (element.scrollWidth !== element.offsetWidth) {
1399        event.preventDefault();
1400      } // @ts-ignore
1401      element.scrollLeft += event.deltaY;
1402    });
1403  }
1404
1405  renderTable(): void {
1406    if (!this.columns) {
1407      return;
1408    }
1409    if (!this.ds) {
1410      return;
1411    } // If no data source is set, it is returned directly
1412    this.normalDs = [];
1413    this.tbodyElement!.innerHTML = ''; // Clear the table contents
1414    this.ds.forEach((rowData: unknown) => {
1415      let tblRowElement = document.createElement('div');
1416      tblRowElement.classList.add('tr');
1417      // @ts-ignore
1418      tblRowElement.data = rowData;
1419      let gridTemplateColumns: Array<unknown> = [];
1420      // If the table is configured with selectable (select row mode) add a checkbox at the head of the line alone
1421      this.renderTableRowSelect(tblRowElement);
1422      this.tableColumns!.forEach((tblColumn) => {
1423        tblColumn.addEventListener('contextmenu', (e) => {
1424          e.preventDefault();
1425        });
1426        let dataIndex = tblColumn.getAttribute('data-index') || '1';
1427        gridTemplateColumns.push(tblColumn.getAttribute('width') || '1fr');
1428        this.renderTableRowColumnElement(tblColumn, tblRowElement, dataIndex, rowData);
1429      });
1430      if (this.selectable) {
1431        // If the table with selection is preceded by a 60px column
1432        tblRowElement.style.gridTemplateColumns = '60px ' + gridTemplateColumns.join(' ');
1433      } else {
1434        tblRowElement.style.gridTemplateColumns = gridTemplateColumns.join(' ');
1435      }
1436      this.renderTableRowElementEvent(tblRowElement, rowData);
1437      this.normalDs.push(tblRowElement);
1438      this.tbodyElement!.append(tblRowElement);
1439    });
1440  }
1441
1442  renderTableRowSelect(tblRowElement: HTMLDivElement): void {
1443    if (this.selectable) {
1444      let tblBox = document.createElement('div');
1445      tblBox.style.display = 'flex';
1446      tblBox.style.justifyContent = 'center';
1447      tblBox.style.alignItems = 'center';
1448      tblBox.classList.add('td');
1449      let checkbox = document.createElement('lit-checkbox');
1450      checkbox.classList.add('row-checkbox');
1451      checkbox.onchange = (e: unknown): void => {
1452        // Checkbox checking affects whether the div corresponding to the row has a checked attribute for marking
1453        // @ts-ignore
1454        if (e.detail.checked) {
1455          tblRowElement.setAttribute('checked', '');
1456        } else {
1457          tblRowElement.removeAttribute('checked');
1458        }
1459      };
1460      this.getWheelStatus(tblBox);
1461      tblBox.appendChild(checkbox);
1462      tblRowElement.appendChild(tblBox);
1463    }
1464  }
1465
1466  renderTableRowColumnElement(
1467    tblColumn: LitTableColumn,
1468    tblRowElement: HTMLDivElement,
1469    dataIndex: string,
1470    rowData: unknown
1471  ): void {
1472    if (tblColumn.template) {
1473      // If you customize the rendering, you get the nodes from the template
1474      // @ts-ignore
1475      let cloneNode = tblColumn.template.render(rowData).content.cloneNode(true);
1476      let tblCustomDiv = document.createElement('div');
1477      tblCustomDiv.classList.add('td');
1478      tblCustomDiv.style.wordBreak = 'break-all';
1479      tblCustomDiv.style.whiteSpace = 'pre-wrap';
1480      tblCustomDiv.style.justifyContent = tblColumn.getAttribute('align') || '';
1481      if (tblColumn.hasAttribute('fixed')) {
1482        fixed(tblCustomDiv, tblColumn.getAttribute('fixed') || '', '#ffffff');
1483      }
1484      this.getWheelStatus(tblCustomDiv);
1485      tblCustomDiv.append(cloneNode);
1486      tblRowElement.append(tblCustomDiv);
1487    } else {
1488      let tblDiv = document.createElement('div');
1489      tblDiv.classList.add('td');
1490      tblDiv.style.wordBreak = 'break-all';
1491      tblDiv.style.whiteSpace = 'pre-wrap'; // @ts-ignore
1492      tblDiv.title = rowData[dataIndex];
1493      tblDiv.style.justifyContent = tblColumn.getAttribute('align') || '';
1494      if (tblColumn.hasAttribute('fixed')) {
1495        fixed(tblDiv, tblColumn.getAttribute('fixed') || '', '#ffffff');
1496      }
1497      this.getWheelStatus(tblDiv); // @ts-ignore
1498      tblDiv.innerHTML = formatName(dataIndex, rowData[dataIndex], this);
1499      tblRowElement.append(tblDiv);
1500    }
1501  }
1502
1503  renderTableRowElementEvent(tblRowElement: HTMLDivElement, rowData: unknown): void {
1504    tblRowElement.onmouseup = (e: MouseEvent): void => {
1505      e.stopPropagation();
1506      this.dispatchEvent(
1507        new CustomEvent('row-click', {
1508          detail: {
1509            rowData,
1510            data: rowData,
1511            callBack: (isSelected: boolean): void => {
1512              //是否爲单选
1513              if (isSelected) {
1514                this.clearAllSelection(rowData);
1515              } // @ts-ignore
1516              this.setSelectedRow(rowData.isSelected, [tblRowElement]);
1517            },
1518          },
1519          composed: true,
1520        })
1521      );
1522      e.stopPropagation();
1523    };
1524  }
1525
1526  freshCurrentLine(element: HTMLElement, rowObject: TableRowObject, firstElement?: HTMLElement): void {
1527    if (!rowObject) {
1528      if (firstElement) {
1529        firstElement.style.display = 'none';
1530      }
1531      element.style.display = 'none';
1532      return;
1533    }
1534    let childIndex = -1; //@ts-ignore
1535    this.setHighLight(rowObject.data.isSearch, element);
1536    element.childNodes.forEach((child) => {
1537      if (child.nodeType !== 1) {
1538        return;
1539      }
1540      childIndex++;
1541      let idx = firstElement !== undefined ? childIndex + 1 : childIndex;
1542      this.freshLineFirstElementHandler(firstElement, rowObject, childIndex);
1543      if (idx < this.columns!.length) {
1544        //@ts-ignore
1545        let dataIndex = this.columns![idx].getAttribute('data-index') || '1'; //@ts-ignore
1546        let text = formatName(dataIndex, rowObject.data[dataIndex], this); // @ts-ignore
1547        if ((this.columns![idx] as unknown).template) {
1548          (child as HTMLElement).innerHTML = '';
1549          (child as HTMLElement).appendChild(
1550            // @ts-ignore
1551            (this.columns![idx] as unknown).template.render(rowObject.data).content.cloneNode(true)
1552          );
1553          // @ts-ignore
1554          (child as HTMLElement).title = text;
1555        } else {
1556          //@ts-ignore
1557          if (rowObject.data.rowName === 'cpu-profiler' && dataIndex === 'symbolName') {
1558            (child as HTMLElement).innerHTML = '';
1559          } else {
1560            //@ts-ignore
1561            (child as HTMLElement).innerHTML = text;
1562          } //@ts-ignore
1563          if (dataIndex === 'selfTimeStr' && rowObject.data.chartFrameChildren) {
1564            //@ts-ignore
1565            (child as HTMLElement).title = rowObject.data.selfTime + 'ns'; //@ts-ignore
1566          } else if (dataIndex === 'totalTimeStr' && rowObject.data.chartFrameChildren) {
1567            //@ts-ignore
1568            (child as HTMLElement).title = rowObject.data.totalTime + 'ns';
1569          } else if (dataIndex === 'timeStr' && rowObject.data instanceof JsCpuProfilerStatisticsStruct) {
1570            (child as HTMLElement).title = rowObject.data.time + 'ns';
1571          } else {
1572            //@ts-ignore
1573            (child as HTMLElement).title = text;
1574          }
1575        }
1576      }
1577    });
1578    this.freshLineStyleAndEvents(element, rowObject, firstElement);
1579  }
1580
1581  freshLineStyleAndEvents(element: HTMLElement, rowObject: TableRowObject, firstElement?: HTMLElement): void {
1582    if (element.style.display === 'none') {
1583      element.style.display = 'grid';
1584    }
1585    element.style.transform = `translateY(${rowObject.top}px)`;
1586    if (firstElement && firstElement.style.display === 'none') {
1587      firstElement.style.display = 'flex';
1588    }
1589    element.onmouseup = (e: MouseEvent): void => {
1590      if (firstElement !== undefined) {
1591        this.dispatchRowClickEvent(rowObject, [firstElement, element], e);
1592      } else {
1593        this.dispatchRowClickEvent(rowObject, [element], e);
1594      }
1595      e.stopPropagation();
1596    };
1597    element.onmouseenter = (): void => {
1598      this.dispatchRowHoverEvent(rowObject, [element]); // @ts-ignore
1599      if ((element as unknown).data.isSelected) {
1600        return;
1601      }
1602      let indexOf = this.currentRecycleList.indexOf(element as HTMLDivElement);
1603      this.currentTreeDivList.forEach((row) => {
1604        row.classList.remove('mouse-in');
1605      });
1606      if (indexOf >= 0 && indexOf < this.currentTreeDivList.length) {
1607        this.setMouseIn(true, [this.currentTreeDivList[indexOf]]);
1608      }
1609    };
1610    // @ts-ignore
1611    (element as unknown).data = rowObject.data; //@ts-ignore
1612    if (rowObject.data.isSelected !== undefined) {
1613      //@ts-ignore
1614      this.setSelectedRow(rowObject.data.isSelected, [element]);
1615    } else {
1616      this.setSelectedRow(false, [element]);
1617    } //@ts-ignore
1618    if (rowObject.data.isHover !== undefined) {
1619      //@ts-ignore
1620      this.setMouseIn(rowObject.data.isHover, [element]);
1621    } else {
1622      this.setMouseIn(false, [element]);
1623    }
1624    if (this.getItemTextColor) {
1625      // @ts-ignore
1626      element.style.color = this.getItemTextColor((element as unknown).data);
1627    }
1628  }
1629
1630  freshLineFirstElementHandler(firstElement: unknown, rowObject: TableRowObject, childIndex: number): void {
1631    if (firstElement !== undefined && childIndex === 0) {
1632      //@ts-ignore
1633      this.setHighLight(rowObject.data.isSearch, firstElement); // @ts-ignore
1634      (firstElement as unknown).data = rowObject.data; // @ts-ignore
1635      if ((this.columns![0] as unknown).template) {
1636        // @ts-ignore
1637        firstElement.innerHTML = (this.columns![0] as unknown).template
1638          .render(rowObject.data)
1639          .content.cloneNode(true).innerHTML;
1640      } else {
1641        let dataIndex = this.columns![0].getAttribute('data-index') || '1'; //@ts-ignore
1642        let text = formatName(dataIndex, rowObject.data[dataIndex], this); //@ts-ignore
1643        if (rowObject.data.rowName === 'js-memory' || rowObject.data.rowName === 'cpu-profiler') {
1644          // @ts-ignore
1645          firstElement.innerHTML = '';
1646        } else {
1647          // @ts-ignore
1648          firstElement.innerHTML = text;
1649        } // @ts-ignore
1650        firstElement.title = text;
1651      } //@ts-ignore
1652      if (rowObject.children && rowObject.children.length > 0 && !rowObject.data.hasNext) {
1653        let btn = this.createExpandBtn(rowObject); // @ts-ignore
1654        firstElement.insertBefore(btn, firstElement.firstChild);
1655      } // @ts-ignore
1656      firstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px';
1657      if (!rowObject.children || rowObject.children.length === 0) {
1658        // @ts-ignore
1659        firstElement.style.paddingLeft = iconWidth * rowObject.depth + iconWidth + iconPadding * 2 + 'px';
1660      } //@ts-ignore
1661      if (rowObject.data.hasNext) {
1662        let btn = this.createBtn(rowObject); // @ts-ignore
1663        firstElement.title = rowObject.data.objectName; // @ts-ignore
1664        firstElement.insertBefore(btn, firstElement.firstChild); // @ts-ignore
1665        firstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px';
1666      }
1667      this.jsMemoryHandler(rowObject, firstElement); //@ts-ignore
1668      if (rowObject.data.rowName === 'cpu-profiler') {
1669        this.createTextColor(rowObject, firstElement);
1670      } // @ts-ignore
1671      firstElement.onmouseup = (e: MouseEvent): void => {
1672        this.dispatchRowClickEvent(rowObject, [firstElement, element], e);
1673        e.stopPropagation();
1674      }; // @ts-ignore
1675      firstElement.style.transform = `translateY(${rowObject.top - this.tableElement!.scrollTop}px)`; //@ts-ignore
1676      if (rowObject.data.isSelected !== undefined) {
1677        //@ts-ignore
1678        this.setSelectedRow(rowObject.data.isSelected, [firstElement]);
1679      } else {
1680        this.setSelectedRow(false, [firstElement]);
1681      }
1682    }
1683  }
1684
1685  setSelectedRow(isSelected: boolean, rows: unknown[]): void {
1686    if (isSelected) {
1687      rows.forEach((row) => {
1688        // @ts-ignore
1689        if (row.classList) {
1690          // @ts-ignore
1691          if (row.classList.contains('mouse-in')) {
1692            // @ts-ignore
1693            row.classList.remove('mouse-in');
1694          } // @ts-ignore
1695          row.classList.add('mouse-select');
1696        }
1697      });
1698    } else {
1699      rows.forEach((row) => {
1700        // @ts-ignore
1701        row.classList && row.classList.remove('mouse-select');
1702      });
1703    }
1704  }
1705
1706  setMouseIn(isMouseIn: boolean, rows: unknown[]): void {
1707    if (isMouseIn) {
1708      rows.forEach((row) => {
1709        // @ts-ignore
1710        row.classList.add('mouse-in');
1711      });
1712    } else {
1713      rows.forEach((row) => {
1714        // @ts-ignore
1715        row.classList.remove('mouse-in');
1716      });
1717    }
1718  }
1719
1720  scrollToData(data: unknown): void {
1721    if (this.isRecycleList) {
1722      if (this.recycleDs.length > 0) {
1723        let filter = this.recycleDs.filter((item) => {
1724          // @ts-ignore
1725          return item.data === data;
1726        });
1727        if (filter.length > 0) {
1728          // @ts-ignore
1729          this.tableElement!.scrollTop = filter[0].top;
1730        }
1731        this.setCurrentSelection(data);
1732      }
1733    } else {
1734      if (this.normalDs.length > 0) {
1735        let filter = this.normalDs.filter((item) => {
1736          // @ts-ignore
1737          return item.data === data;
1738        });
1739        if (filter.length > 0) {
1740          // @ts-ignore
1741          this.tableElement!.scrollTop = filter[0].top;
1742        }
1743      }
1744    }
1745  }
1746
1747  expandList(datasource: unknown[]): void {
1748    let filter = this.recycleDs.filter((item) => {
1749      // @ts-ignore
1750      return datasource.indexOf(item.data) !== -1;
1751    });
1752    if (filter.length > 0) {
1753      filter.forEach((item) => {
1754        // @ts-ignore
1755        item.expanded = true; // @ts-ignore
1756        item.rowHidden = false;
1757      });
1758    }
1759    this.reMeauseHeight();
1760  }
1761
1762  clearAllSelection(rowObjectData: unknown): void {
1763    if (this.isRecycleList) {
1764      this.recycleDs.forEach((item) => {
1765        // @ts-ignore
1766        if (item.data !== rowObjectData && item.data.isSelected) {
1767          // @ts-ignore
1768          item.data.isSelected = false;
1769        }
1770      });
1771      this.setSelectedRow(false, this.currentTreeDivList);
1772      this.setSelectedRow(false, this.currentRecycleList);
1773    } else {
1774      this.dataSource.forEach((item) => {
1775        // @ts-ignore
1776        if (item !== rowObjectData && item.isSelected) {
1777          // @ts-ignore
1778          item.isSelected = false;
1779        }
1780      });
1781      this.setSelectedRow(false, this.normalDs);
1782    }
1783  }
1784
1785  clearAllHover(rowObjectData: unknown): void {
1786    if (this.isRecycleList) {
1787      this.recycleDs.forEach((item) => {
1788        // @ts-ignore
1789        if (item.data !== rowObjectData && item.data.isHover) {
1790          // @ts-ignore
1791          item.data.isHover = false;
1792        }
1793      });
1794      this.setMouseIn(false, this.currentTreeDivList);
1795      this.setMouseIn(false, this.currentRecycleList);
1796    } else {
1797      this.dataSource.forEach((item) => {
1798        // @ts-ignore
1799        if (item !== rowObjectData && item.isHover) {
1800          // @ts-ignore
1801          item.isHover = false;
1802        }
1803      });
1804      this.setMouseIn(false, this.normalDs);
1805    }
1806  }
1807
1808  mouseOut(): void {
1809    if (this.isRecycleList) {
1810      // @ts-ignore
1811      this.recycleDs.forEach((item) => (item.data.isHover = false));
1812      this.setMouseIn(false, this.currentTreeDivList);
1813      this.setMouseIn(false, this.currentRecycleList);
1814    } else {
1815      // @ts-ignore
1816      this.dataSource.forEach((item) => (item.isHover = false));
1817      this.setMouseIn(false, this.normalDs);
1818    }
1819    this.dispatchEvent(
1820      new CustomEvent('row-hover', {
1821        detail: {
1822          data: undefined,
1823        },
1824        composed: true,
1825      })
1826    );
1827  }
1828
1829  setCurrentSelection(selectionData: unknown): void {
1830    if (this.isRecycleList) {
1831      // @ts-ignore
1832      if (selectionData.isSelected !== undefined) {
1833        this.currentTreeDivList.forEach((itemEl) => {
1834          // @ts-ignore
1835          if ((itemEl as unknown).data === selectionData) {
1836            // @ts-ignore
1837            this.setSelectedRow(selectionData.isSelected, [itemEl]);
1838          }
1839        });
1840        this.currentRecycleList.forEach((recycleItem) => {
1841          // @ts-ignore
1842          if ((recycleItem as unknown).data === selectionData) {
1843            // @ts-ignore
1844            this.setSelectedRow(selectionData.isSelected, [recycleItem]);
1845          }
1846        });
1847      }
1848    } else {
1849      // @ts-ignore
1850      if (selectionData.isSelected !== undefined) {
1851        this.normalDs.forEach((item) => {
1852          // @ts-ignore
1853          if ((item as unknown).data === selectionData) {
1854            // @ts-ignore
1855            this.setSelectedRow(selectionData.isSelected, [item]);
1856          }
1857        });
1858      }
1859    }
1860  }
1861
1862  setCurrentHover(data: unknown): void {
1863    if (this.isRecycleList) {
1864      this.setMouseIn(false, this.currentTreeDivList);
1865      this.setMouseIn(false, this.currentRecycleList); // @ts-ignore
1866      if (data.isHover !== undefined) {
1867        this.currentTreeDivList.forEach((hoverItem) => {
1868          // @ts-ignore
1869          if ((hoverItem as unknown).data === data) {
1870            // @ts-ignore
1871            this.setMouseIn(data.isHover, [hoverItem]);
1872          }
1873        });
1874        this.currentRecycleList.forEach((hoverItem) => {
1875          // @ts-ignore
1876          if ((hoverItem as unknown).data === data) {
1877            // @ts-ignore
1878            this.setMouseIn(data.isHover, [hoverItem]);
1879          }
1880        });
1881      }
1882    } else {
1883      this.setMouseIn(false, this.normalDs); // @ts-ignore
1884      if (data.isHover !== undefined) {
1885        this.normalDs.forEach((item): void => {
1886          // @ts-ignore
1887          if ((item as unknown).data === data) {
1888            // @ts-ignore
1889            this.setMouseIn(data.isHover, [item]);
1890          }
1891        });
1892      }
1893    }
1894  }
1895
1896  dispatchRowClickEventIcon(rowData: unknown, elements: unknown[]): void {
1897    this.dispatchEvent(
1898      new CustomEvent('icon-click', {
1899        detail: {
1900          // @ts-ignore
1901          ...rowData.data, // @ts-ignore
1902          data: rowData.data,
1903          callBack: (isSelected: boolean): void => {
1904            //是否爲单选
1905            if (isSelected) {
1906              // @ts-ignore
1907              this.clearAllSelection(rowData.data);
1908            } // @ts-ignore
1909            this.setSelectedRow(rowData.data.isSelected, elements);
1910          },
1911        },
1912        composed: true,
1913      })
1914    );
1915  }
1916
1917  dispatchRowClickEvent(rowObject: unknown, elements: unknown[], event: MouseEvent): void {
1918    this.dispatchEvent(
1919      new CustomEvent('row-click', {
1920        detail: {
1921          button: event.button, // @ts-ignore
1922          ...rowObject.data, // @ts-ignore
1923          data: rowObject.data,
1924          callBack: (isSelected: boolean): void => {
1925            //是否爲单选
1926            if (isSelected) {
1927              // @ts-ignore
1928              this.clearAllSelection(rowObject.data);
1929            } // @ts-ignore
1930            this.setSelectedRow(rowObject.data.isSelected, elements);
1931          },
1932        },
1933        composed: true,
1934      })
1935    );
1936    event.stopPropagation();
1937  }
1938
1939  dispatchRowHoverEvent(rowObject: unknown, elements: unknown[]): void {
1940    this.dispatchEvent(
1941      new CustomEvent('row-hover', {
1942        detail: {
1943          // @ts-ignore
1944          data: rowObject.data,
1945          callBack: (): void => {
1946            // @ts-ignore
1947            this.clearAllHover(rowObject.data); // @ts-ignore
1948            this.setMouseIn(rowObject.data.isHover, elements);
1949          },
1950        },
1951        composed: true,
1952      })
1953    );
1954  }
1955
1956  setHighLight(isSearch: boolean, element: unknown): void {
1957    if (isSearch) {
1958      // @ts-ignore
1959      element.setAttribute('high-light', '');
1960    } else {
1961      // @ts-ignore
1962      element.removeAttribute('high-light');
1963    }
1964  }
1965
1966  createTextColor(rowData: unknown, divElement: unknown): void {
1967    let nodeText = document.createElement('text');
1968    nodeText.classList.add('functionName'); // @ts-ignore
1969    nodeText.textContent = rowData.data.name; // @ts-ignore
1970    divElement.append(nodeText); // @ts-ignore
1971    if (rowData.data.scriptName !== 'unknown') {
1972      let scriptText = document.createElement('text');
1973      scriptText.classList.add('scriptName'); // @ts-ignore
1974      scriptText.textContent = rowData.data.scriptName; // @ts-ignore
1975      divElement.append(scriptText);
1976      scriptText.style.color = '#a1a1a1';
1977    } // @ts-ignore
1978    divElement.title = rowData.data.symbolName;
1979  }
1980
1981  jsMemoryHandler(rowData: unknown, td: unknown): void {
1982    // @ts-ignore
1983    if (rowData.data.rowName === 'js-memory') {
1984      let nodeText = document.createElement('text');
1985      nodeText.classList.add('nodeName'); // @ts-ignore
1986      nodeText.textContent = rowData.data.nodeName; // @ts-ignore
1987      td.append(nodeText);
1988      let countText = document.createElement('text');
1989      countText.classList.add('countName'); // @ts-ignore
1990      countText.textContent = rowData.data.count; // @ts-ignore
1991      td.append(countText);
1992      let nodeIdText = document.createElement('text');
1993      nodeIdText.classList.add('nodeIdText'); // @ts-ignore
1994      nodeIdText.textContent = rowData.data.nodeId; // @ts-ignore
1995      td.append(nodeIdText); // @ts-ignore
1996      if (rowData.data.edgeName !== '') {
1997        let edgeNameText = document.createElement('text');
1998        edgeNameText.classList.add('edgeNameText'); // @ts-ignore
1999        edgeNameText.textContent = rowData.data.edgeName; // @ts-ignore
2000        td.insertBefore(edgeNameText, nodeText);
2001        let span = document.createElement('span');
2002        span.classList.add('span'); // @ts-ignore
2003        if (rowData.data.type === ConstructorType.RetainersType) {
2004          // @ts-ignore
2005          span.textContent = '\xa0' + 'in' + '\xa0'; // @ts-ignore
2006          nodeIdText.textContent = ` @${rowData.data.id}`;
2007        } else {
2008          span.textContent = '\xa0' + '::' + '\xa0';
2009        }
2010        edgeNameText.append(span);
2011      }
2012      if (
2013        // @ts-ignore
2014        (rowData.data.nodeType === NodeType.STRING || // @ts-ignore
2015          rowData.data.nodeType === NodeType.CONCATENATED_STRING || // @ts-ignore
2016          rowData.data.nodeType === NodeType.SLICED_STRING) && // @ts-ignore
2017        rowData.data.type !== ConstructorType.ClassType
2018      ) {
2019        nodeText.style.color = '#d53d3d'; // @ts-ignore
2020        nodeText.textContent = '"' + rowData.data.nodeName + '"';
2021      } // @ts-ignore
2022      td.title = rowData.data.objectName;
2023    }
2024  }
2025}
2026
2027// 表格默认是展开还是收起的
2028export enum TableMode {
2029  Expand, // 默认展开
2030  Retract, // 默认收起
2031}
2032
2033// 重绘的表格是要全部展开,全部收起,还是一层一层手动打开
2034export enum RedrawTreeForm {
2035  Expand, // 一键展开
2036  Retract, // 一键收起
2037  Default, //点击加号,逐层展开
2038}
2039