• 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 { BaseElement, element } from '../../../base-ui/BaseElement.js';
17import '../../../base-ui/select/LitAllocationSelect.js';
18
19import '../../../base-ui/switch/lit-switch.js';
20import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect.js';
21import { SpRecordTrace } from '../SpRecordTrace.js';
22import { Cmd } from '../../../command/Cmd.js';
23import { LitRadioBox } from '../../../base-ui/radiobox/LitRadioBox.js';
24import { SpCheckDesBox } from './SpCheckDesBox.js';
25import LitSwitch from '../../../base-ui/switch/lit-switch.js';
26
27@element('sp-ark-ts')
28export class SpArkTs extends BaseElement {
29  private processInput: LitAllocationSelect | undefined | null;
30  private spCheckDesBox: SpCheckDesBox | undefined | null;
31  private radioBox: LitRadioBox | undefined | null;
32  private interval: HTMLInputElement | undefined | null;
33  private memorySwitch: LitSwitch | undefined | null;
34  private cpuSwitch: LitSwitch | undefined | null;
35
36  set startSamp(jsHeapStart: boolean) {
37    if (jsHeapStart) {
38      this.setAttribute('startSamp', '');
39    } else {
40      this.removeAttribute('startSamp');
41    }
42  }
43
44  get startSamp(): boolean {
45    return this.hasAttribute('startSamp');
46  }
47
48  get process(): string {
49    if (this.processInput!.value.length > 0) {
50      return this.processInput!.value;
51    }
52    return '';
53  }
54
55  get radioBoxType(): number {
56    let memorySwitch = this.shadowRoot?.querySelector('#memory-switch');
57    let type: string;
58    if (memorySwitch!.getAttribute('checked') !== null) {
59      this.radioBox = this.shadowRoot?.querySelector(`lit-radio[checked]`);
60      type = this.radioBox?.getAttribute('type') || '';
61    } else {
62      type = '-1';
63    }
64    return Number(type);
65  }
66
67  get grabNumeric(): boolean {
68    if (this.radioBoxType === 0) {
69      this.spCheckDesBox = this.shadowRoot?.querySelector('#snapshot');
70      let isChecked = this.spCheckDesBox?.getAttribute('checked');
71      return isChecked === 'true';
72    } else {
73      return false;
74    }
75  }
76
77  get grabAllocations(): boolean {
78    if (this.radioBoxType === 1) {
79      this.spCheckDesBox = this.shadowRoot?.querySelector('#timeline');
80      let isChecked = this.spCheckDesBox?.getAttribute('checked');
81      return isChecked === 'true';
82    } else {
83      return false;
84    }
85  }
86
87  get intervalValue(): number {
88    if (this.radioBoxType === 0) {
89      return Number(this.interval!.value);
90    } else {
91      return 0;
92    }
93  }
94
95  get grabCpuProfiler(): boolean {
96    let isChecked = this.cpuSwitch?.getAttribute('checked');
97    return isChecked !== null;
98  }
99
100  get intervalCpuValue(): number {
101    let interval = this.shadowRoot?.querySelector<HTMLInputElement>('#cpuInterval');
102    if (interval) {
103      return Number(interval!.value);
104    } else {
105      return 0;
106    }
107  }
108
109  initElements(): void {
110    this.interval = this.shadowRoot?.querySelector('#interval');
111    this.processInput = this.shadowRoot?.querySelector<LitAllocationSelect>('lit-allocation-select');
112    let processInput = this.processInput?.shadowRoot?.querySelector('.multipleSelect') as HTMLDivElement;
113    this.cpuSwitch = this.shadowRoot?.querySelector('#cpu-switch') as LitSwitch;
114    processInput!.addEventListener('mousedown', (ev) => {
115      if (SpRecordTrace.serialNumber == '') {
116        this.processInput!.processData = [];
117        this.processInput!.initData();
118      }
119    });
120    processInput!.addEventListener('mouseup', () => {
121      if (SpRecordTrace.serialNumber == '') {
122        this.processInput!.processData = [];
123        this.processInput!.initData();
124      } else {
125        Cmd.getDebugProcess().then((processList) => {
126          this.processInput!.processData = processList;
127          this.processInput!.initData();
128        });
129      }
130    });
131    this.interval!.addEventListener('focusout', () => {
132      if (this.interval!.value === '') {
133        this.interval!.value = '10';
134      }
135    });
136
137    let litSwitch = this.shadowRoot?.querySelector('lit-switch') as LitSwitch;
138    litSwitch.addEventListener('change', (event: any) => {
139      let detail = event.detail;
140      if (detail.checked) {
141        this.unDisable();
142        this.unMemoryDisable();
143      } else {
144        this.disable();
145        this.memoryDisable();
146      }
147    });
148    this.memorySwitch = this.shadowRoot?.querySelector('#memory-switch') as LitSwitch;
149    this.memorySwitch.addEventListener('change', (event: any) => {
150      let detail = event.detail;
151      if (detail.checked) {
152        this.unMemoryDisable();
153      } else {
154        if (!this.cpuSwitch?.checked) {
155          litSwitch.checked = false;
156          this.disable();
157        }
158        this.memoryDisable();
159      }
160    });
161
162    this.cpuSwitch = this.shadowRoot?.querySelector('#cpu-switch') as LitSwitch;
163    this.cpuSwitch.addEventListener('change', (event: any) => {
164      let detail = event.detail;
165      let interval = this.shadowRoot?.querySelectorAll<HTMLInputElement>('#cpuInterval');
166      if (!detail.checked && !this.memorySwitch?.checked) {
167        litSwitch.checked = false;
168        this.disable();
169      } else if (detail.checked) {
170        interval!.forEach((item) => {
171          item.disabled = false;
172          item.style.background = 'var(--dark-background5,#FFFFFF)';
173        });
174      } else {
175        interval!.forEach((item) => {
176          item.disabled = true;
177          item.style.color = '#b7b7b7';
178          item.style.background = 'var(--dark-background1,#f5f5f5)';
179        });
180        litSwitch.checked = true;
181        this.startSamp = true;
182      }
183    });
184    this.disable();
185    this.memoryDisable();
186  }
187
188  private memoryDisable() {
189    let interval = this.shadowRoot?.querySelectorAll<HTMLInputElement>('#interval');
190    interval!.forEach((item) => {
191      item.disabled = true;
192      item.style.color = '#b7b7b7';
193      item.style.background = 'var(--dark-background1,#f5f5f5)';
194    });
195    let radioBoxes = this.shadowRoot?.querySelectorAll<LitRadioBox>('lit-radio');
196    radioBoxes!.forEach((item) => {
197      item.disabled = true;
198    });
199    let checkBoxes = this.shadowRoot?.querySelectorAll<SpCheckDesBox>('check-des-box');
200    checkBoxes!.forEach((item) => {
201      item.disabled = true;
202    });
203  }
204
205  private unMemoryDisable() {
206    let interval = this.shadowRoot?.querySelectorAll<HTMLInputElement>('#interval');
207    interval!.forEach((item) => {
208      item.disabled = false;
209      item.style.background = 'var(--dark-background5,#FFFFFF)';
210    });
211    let radioBoxes = this.shadowRoot?.querySelectorAll<LitRadioBox>('lit-radio');
212    radioBoxes!.forEach((item) => {
213      item.disabled = false;
214    });
215    let checkBoxes = this.shadowRoot?.querySelectorAll<SpCheckDesBox>('check-des-box');
216    checkBoxes!.forEach((item) => {
217      item.disabled = false;
218    });
219  }
220
221  private disable() {
222    this.startSamp = false;
223    this.processInput!.setAttribute('disabled', '');
224    let heapConfigs = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.select');
225    heapConfigs!.forEach((item) => {
226      item.disabled = true;
227    });
228    let switches = this.shadowRoot?.querySelectorAll<LitSwitch>('.switch');
229    switches!.forEach((item) => {
230      item.disabled = true;
231      item.checked = false;
232    });
233    let interval = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.inputstyle');
234    interval!.forEach((item) => {
235      item.disabled = true;
236      item.style.color = '#b7b7b7';
237      item.style.background = 'var(--dark-background1,#f5f5f5)';
238    });
239  }
240
241  private unDisable() {
242    this.startSamp = true;
243    this.processInput!.removeAttribute('disabled');
244    let heapConfigs = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.select');
245    heapConfigs!.forEach((item) => {
246      item.disabled = false;
247    });
248    let switches = this.shadowRoot?.querySelectorAll<LitSwitch>('.switch');
249    switches!.forEach((item) => {
250      item.disabled = false;
251      item.checked = true;
252    });
253    let interval = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.inputstyle');
254    interval!.forEach((item) => {
255      item.disabled = false;
256      item.style.background = 'var(--dark-background5,#FFFFFF)';
257    });
258  }
259
260  initHtml(): string {
261    return `
262        <style>
263        :host{
264            display: inline-block;
265            width: 100%;
266            height: 100%;
267            background: var(--dark-background3,#FFFFFF);
268            border-radius: 0px 16px 16px 0px;
269        }
270        .root {
271            padding-top: 30px;
272            padding-left: 54px;
273            margin-right: 30px;
274            font-size:16px;
275            margin-bottom: 30px;
276        }
277        .config-div {
278           width: 80%;
279           display: flex;
280           flex-direction: column;
281           margin-top: 5vh;
282           margin-bottom: 5vh;
283           gap: 25px;
284        }
285        .title {
286          opacity: 0.9;
287          font-family: Helvetica-Bold;
288          font-size: 18px;
289          text-align: center;
290          line-height: 40px;
291          font-weight: 700;
292          margin-right: 10px;
293        }
294        .config-title{
295            margin-left: 20px;
296            font-weight: 700;
297            line-height: 48px;
298        }
299        .memory {
300            margin-left: 40px;
301        }
302        .des {
303          color: #242424;
304            font-family: Helvetica;
305            font-size: 14px;
306            text-align: left;
307            line-height: 16px;
308            font-weight: 400;
309        }
310        .select {
311          border-radius: 15px;
312        }
313        input {
314           width: 35%;
315           height: 25px;
316           border:0;
317           outline:none;
318           border-radius: 16px;
319           text-indent:2%
320        }
321        input::-webkit-input-placeholder{
322            color:var(--bark-prompt,#999999);
323        }
324        .inputstyle{
325            background: var(--dark-background5,#FFFFFF);
326            border: 1px solid var(--dark-background5,#999999);
327            font-family: Helvetica;
328            font-size: 14px;
329            color: var(--dark-color1,#212121);
330            text-align: left;
331            line-height: 16px;
332            font-weight: 400;
333        }
334        .inputstyle::-webkit-input-placeholder {
335           background: var(--dark-background5,#FFFFFF);
336        }
337        .radio {
338            font-family: Helvetica-Bold;
339            font-size: 16px;
340            color: #000000;
341            line-height: 28px;
342            font-weight: 700;
343        }
344        .unit {
345            font-family: Helvetica;
346            font-size: 14px;
347            color: #000000;
348            line-height: 28px;
349            font-weight: 400;
350        }
351        lit-switch {
352          display:inline;
353          float: right;
354          height: 38px;
355          margin-top: 10px;
356        }
357        :host([startSamp]) .inputBoxes {
358            background: var(--dark-background5,#FFFFFF);
359        }
360        :host(:not([startSamp])) .inputBoxes {
361            color: #b7b7b7;
362            background: var(--dark-background1,#f5f5f5);
363        }
364        </style>
365        <div class="root">
366            <div class="config-div">
367                <div>
368                  <span class="title">Start Ark Ts Record</span>
369                  <lit-switch></lit-switch>
370                </div>
371            </div>
372            <div class="config-div">
373                <div>
374                    <span class="title">Process</span>
375                    <span class="des">Record process</span>
376                </div>
377                <lit-allocation-select style="width: 100%;" rounded="" default-value="" class="select inputBoxes" placement="bottom" ></lit-allocation-select>
378            </div>
379            <div class="config-div">
380                <div>
381                    <span class="title">Select profiling type</span>
382                </div>
383                <div>
384                    <span class="config-title">Start cpu profiler</span>
385                    <lit-switch class="switch" id='cpu-switch'></lit-switch>
386                </div>
387                <div style="margin-left: 40px;">
388                    <span class="des">Interval(Available on recent OpenHarmony 4.0)</span>
389                    <div style="margin-top: 12px;">
390                        <input class="inputstyle inputBoxes" id='cpuInterval' type="text" id="interval" placeholder="" onkeyup="this.value=this.value.replace(/\\D/g,'').replace(/^0{1,}/g,'')" value="1000">
391                        <span class="unit">μs</span>
392                    </div>
393                </div>
394                <div>
395                    <span class="config-title">Start memory profiler</span>
396                    <lit-switch class="switch" id='memory-switch'></lit-switch>
397                </div>
398                <div class='memory'>
399                    <lit-radio dis="round" class="radio" name="litRadio" checked type="0">Heap snapshot</lit-radio>
400                    <div style="margin-left: 10px;">
401                        <span class="des">Heap snapshot profiles show memory distribution among your page’s JavaScript objects and related DOM nodes.</span>
402                        <div style="display: flex;margin-bottom: 12px;margin-top: 12px;">
403                            <check-des-box checked="true" value ="lnclude numerical values in capture" id="snapshot">
404                            </check-des-box>
405                        </div>
406                        <span class="des">Interval(Available on recent OpenHarmony 4.0)</span>
407                        <div style="margin-top: 12px;">
408                            <input class="inputstyle inputBoxes" type="text" id="interval" placeholder="" onkeyup="this.value=this.value.replace(/\\D/g,'').replace(/^0{1,}/g,'')" value="10">
409                            <span class="unit">S</span>
410                        </div>
411                    </div>
412                    <lit-radio dis="round" name="litRadio" class="radio" type="1">Allocation insteumentation on timeline</lit-radio>
413                    <div style="margin-left: 10px;">
414                        <span class="des">Allocation timelines show insturmented Javascript memory allocations over time. Once profile is recorded you can select a time interval to see objects that werre allocated within it and still alive by the end of recording. Use this profile type to isolate memory leaks.</span>
415                        <div style="display: flex;margin-top: 12px;">
416                        <check-des-box value ="record stack traces of allocations(extra performance overhead)" id="timeline">
417                        </check-des-box>
418                        </div>
419                    </div>
420                </div>
421            </、div>
422        </div>
423        `;
424  }
425}
426