• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2024 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 */
15import {BaseElement} from '../base-ui/BaseElement.js';
16import '../base-ui/menu/LitMainMenu.js';
17import '../base-ui/icon/LitIcon.js';
18import '../base-ui/progress-bar/LitProgressBar.js';
19import './component/WelcomePage.js';
20import {error, info} from '../log/Log.js';
21import {appHtml,} from './MainMemoryFunc.js';
22import './component/MemoryDotting.js';
23import './component/MemoryTree.js';
24import { MemoryDotting } from './component/MemoryDotting.js';
25
26export class MainMemory extends BaseElement {
27  static get observedAttributes() {
28    return ['subsection'];
29  }
30
31  initHtml() {
32    return appHtml;
33  }
34
35  initElements() {
36    this.rootEL = this.shadowRoot.querySelector('.root');
37    this.welcomePage = this.shadowRoot.querySelector('#memory-welcome');
38    this.table = this.shadowRoot.querySelector('#tabpane-summary');
39    this.tree = this.shadowRoot.querySelector('#tab-pane-tree');
40    this.mainMenu = this.shadowRoot.querySelector('#main-menu');
41    this.menu = this.mainMenu.shadowRoot.querySelector('.menu-button');
42    this.initElementsAttr();
43    this.resetMenus();
44    this.initGlobalEvents();
45    this.downloadFile();
46  }
47
48  initElementsAttr() {
49    this.mainMenu.setAttribute('main_menu', '1');
50    this.childComponent = [
51      this.table,
52      this.welcomePage,
53      this.tree
54    ];
55  }
56
57
58
59  async downloadFile() {
60    let localUrl = `${window.location.origin}/get_filename`;
61    const response = await fetch(localUrl);
62    if (!response.ok) {
63        throw new Error('Failed to get filename: ' + response.statusText);
64    }
65    const filename = await response.text();
66    console.log(filename);
67    const downloadRes = await fetch(`${window.location.origin}/download?filename=${encodeURIComponent(filename)}`);
68    if (!downloadRes.ok) {
69        throw new Error('Failed to download file: ' + downloadRes.statusText);
70    }
71    const blob = await downloadRes.blob();
72    const file = new File([blob], filename, {type: blob.type});
73    this.openTraceFile(file);
74  }
75
76  openTraceFile(file) {
77    this.openFileInit();
78    let fileName = file.name;
79    let showFileName = fileName.lastIndexOf('.') === -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.'));
80    this.parseLogFile(file, showFileName, file.size, fileName);
81  }
82
83  initGlobalDropEvents() {
84    let body = document.querySelector('body');
85    body.addEventListener('drop', (event) => {
86      let fileItem;
87      let dirItem;
88      event.preventDefault();
89      event.stopPropagation();
90      if (this.rootEL.classList.contains('filedrag')) {
91        this.rootEL.classList.remove('filedrag');
92      }
93      if (event && event.dataTransfer && event.dataTransfer.items !== undefined && event.dataTransfer.items.length > 0) {
94        let item = event.dataTransfer.items[0];
95        if ((fileItem = item.webkitGetAsEntry()) === null || fileItem === void 0 ? void 0 : fileItem.isFile) {
96          this.openTraceFile(item.getAsFile());
97        } else if ((dirItem = item.webkitGetAsEntry()) === null || dirItem === void 0 ? void 0 : dirItem.isDirectory) {
98          this.freshMenuDisable(false);
99        }
100      }
101    }, false);
102  }
103
104  initGlobalEvents() {
105    let body = document.querySelector('body');
106    body.addEventListener('dragover', (event) => {
107      event.preventDefault();
108      event.stopPropagation();
109      if (event && event.dataTransfer && event.dataTransfer.items.length > 0 && event.dataTransfer.items[0].kind === 'file') {
110        event.dataTransfer.dropEffect = 'copy';
111        if (!this.rootEL.classList.contains('filedrag')) {
112          this.rootEL.classList.add('filedrag');
113        }
114      }
115    }, false);
116    body.addEventListener('dragleave', (event) => {
117      event.stopPropagation();
118      event.preventDefault();
119      if (this.rootEL.classList.contains('filedrag')) {
120        this.rootEL.classList.remove('filedrag');
121      }
122    }, false);
123    this.initGlobalDropEvents();
124  }
125
126  initDocumentListener() {
127    document.addEventListener('file-error', () => {
128    });
129  }
130
131  initNavigationMenu() {
132    return [
133      {
134        collapsed: false,
135        title: 'Navigation',
136        second: false,
137        icon: 'caret-down',
138        describe: 'Import file',
139        children: [
140          {
141            title: 'Import file',
142            icon: '',
143            fileChoose: true,
144            fileHandler: (ev) => {
145              this.openTraceFile(ev.detail);
146            },
147          },
148          {
149              title: 'Chart',
150              icon: '',
151              clickHandler: (item) => this.clickHandleChart(),
152          },
153          {
154              title: 'Tree',
155              icon: '',
156              clickHandler: (item) => this.clickHandleTree(),
157          }
158        ],
159      }
160    ];
161  }
162
163  clickHandleChart() {
164    this.showContent(this.table);
165  }
166  clickHandleTree() {
167    this.showContent(this.tree);
168  }
169
170  parseLogFile(file, showFileName, fileSize, fileName) {
171    let fileSizeStr = (fileSize / 1048576).toFixed(1);
172    document.title = `${showFileName} (${fileSizeStr}M)`;
173    console.log('fileName:' + fileName);
174    if (fileName.endsWith('.log') || fileName.endsWith('.txt')) {
175      let reader = new FileReader();
176      reader.readAsArrayBuffer(file);
177      reader.onloadend = () => {
178        let arrayBuffer = reader.result;
179        let decoder = new TextDecoder('utf-8');
180        let text = decoder.decode(arrayBuffer);
181        let modifiedText = `[${text.trim().replace(/,\s*$/, '')}]`;
182        let datas = JSON.parse(modifiedText);
183        this.freshMenuDisable(false);
184        let data = MemoryDotting.filterKeyPoints(datas, 10240);
185        this.table.data = data;
186        this.tree.data = data;
187      };
188    } else {
189      this.freshMenuDisable(false);
190    }
191  }
192
193  resetMenus() {
194    this.mainMenu.menus = [...this.initNavigationMenu()];
195  }
196
197  openFileInit() {
198    info('open memory File');
199    this.resetMenus();
200    this.freshMenuDisable(true);
201    this.showContent(this.table);
202  }
203
204  showContent(showNode) {
205    if (showNode === this.table) {
206      this.menu.style.pointerEvents = 'auto';
207    } else {
208      this.menu.style.pointerEvents = 'none';
209    }
210    this.childComponent.forEach((node) => {
211      if (node === showNode) {
212        showNode.style.visibility = 'visible';
213      } else {
214        node.style.visibility = 'hidden';
215      }
216    });
217  }
218
219  freshMenuDisable(disable) {
220    let menu;
221    this.mainMenu.menus[0].children[0].disabled = disable;
222    if (this.mainMenu.menus.length > 2) {
223      (menu = this.mainMenu.menus) === null || menu === void 0 ? void 0 : menu[1].children.map((it) => (it.disabled = disable));
224    }
225    this.mainMenu.menus = this.mainMenu.menus;
226  }
227}
228
229if (!customElements.get('main-memory')) {
230  customElements.define('main-memory', MainMemory);
231}
232