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'; 25 26@element('sp-js-heap') 27export class SpJsHeap extends BaseElement { 28 private processInput: LitAllocationSelect | undefined | null; 29 private spCheckDesBox: SpCheckDesBox | undefined | null; 30 private radioBox: LitRadioBox | undefined | null; 31 private interval: HTMLInputElement | undefined | null; 32 33 get process(): string { 34 if (this.processInput!.value.length > 0) { 35 return this.processInput!.value; 36 } 37 return ''; 38 } 39 40 get radioBoxType(): number { 41 this.radioBox = this.shadowRoot?.querySelector(`lit-radio[checked]`); 42 let type = this.radioBox?.getAttribute('type'); 43 return Number(type); 44 } 45 46 get grabNumeric(): boolean { 47 if (this.radioBoxType === 0) { 48 this.spCheckDesBox = this.shadowRoot?.querySelector('#snapshot'); 49 let isChecked = this.spCheckDesBox?.getAttribute('checked'); 50 return isChecked === 'true'; 51 } else { 52 return false; 53 } 54 } 55 56 get grabAllocations(): boolean { 57 if (this.radioBoxType === 1) { 58 this.spCheckDesBox = this.shadowRoot?.querySelector('#timeline'); 59 let isChecked = this.spCheckDesBox?.getAttribute('checked'); 60 return isChecked === 'true'; 61 } else { 62 return false; 63 } 64 } 65 66 get intervalValue(): number { 67 if (this.radioBoxType === 0) { 68 return Number(this.interval!.value); 69 } else { 70 return 0; 71 } 72 } 73 74 initElements(): void { 75 this.interval = this.shadowRoot?.querySelector('#interval'); 76 this.processInput = this.shadowRoot?.querySelector<LitAllocationSelect>('lit-allocation-select'); 77 let processInput = this.processInput?.shadowRoot?.querySelector('.multipleSelect') as HTMLDivElement; 78 processInput!.addEventListener('mousedown', (ev) => { 79 if (SpRecordTrace.serialNumber == '') { 80 this.processInput!.processData = []; 81 this.processInput!.initData(); 82 } 83 }); 84 processInput!.addEventListener('mouseup', () => { 85 if (SpRecordTrace.serialNumber == '') { 86 this.processInput!.processData = []; 87 this.processInput!.initData(); 88 } else { 89 Cmd.getDebugProcess().then((processList) => { 90 this.processInput!.processData = processList; 91 this.processInput!.initData(); 92 }); 93 } 94 }); 95 this.interval!.addEventListener('focusout', () => { 96 if (this.interval!.value === '') { 97 this.interval!.value = '10'; 98 } 99 }); 100 } 101 102 initHtml(): string { 103 return ` 104 <style> 105 :host{ 106 display: inline-block; 107 width: 100%; 108 height: 100%; 109 background: var(--dark-background3,#FFFFFF); 110 border-radius: 0px 16px 16px 0px; 111 } 112 .root { 113 padding-top: 30px; 114 padding-left: 54px; 115 margin-right: 30px; 116 font-size:16px; 117 margin-bottom: 30px; 118 } 119 .config-div { 120 width: 80%; 121 display: flex; 122 flex-direction: column; 123 margin-top: 5vh; 124 margin-bottom: 5vh; 125 gap: 25px; 126 } 127 .title { 128 opacity: 0.9; 129 font-family: Helvetica-Bold; 130 font-size: 18px; 131 text-align: center; 132 line-height: 40px; 133 font-weight: 700; 134 margin-right: 10px; 135 } 136 137 .des { 138 color: #242424; 139 font-family: Helvetica; 140 font-size: 14px; 141 text-align: left; 142 line-height: 16px; 143 font-weight: 400; 144 } 145 146 .select { 147 border-radius: 15px; 148 } 149 input { 150 width: 35%; 151 height: 25px; 152 border:0; 153 outline:none; 154 border-radius: 16px; 155 text-indent:2% 156 } 157 input::-webkit-input-placeholder{ 158 color:var(--bark-prompt,#999999); 159 } 160 161 .inputstyle{ 162 background: var(--dark-background5,#FFFFFF); 163 border: 1px solid var(--dark-background5,#999999); 164 font-family: Helvetica; 165 font-size: 14px; 166 color: var(--dark-color1,#212121); 167 text-align: left; 168 line-height: 16px; 169 font-weight: 400; 170 } 171 .inputstyle::-webkit-input-placeholder { 172 background: var(--dark-background5,#FFFFFF); 173 } 174 175 .radio { 176 font-family: Helvetica-Bold; 177 font-size: 16px; 178 color: #000000; 179 line-height: 28px; 180 font-weight: 700; 181 } 182 .unit { 183 font-family: Helvetica; 184 font-size: 14px; 185 color: #000000; 186 line-height: 28px; 187 font-weight: 400; 188 } 189 </style> 190 <div class="root"> 191 <div class="config-div"> 192 <div> 193 <span class="title">Process</span> 194 <span class="des">Record process</span> 195 </div> 196 <lit-allocation-select style="width: 100%;" rounded="" default-value="" class="select config" placement="bottom" ></lit-allocation-select> 197 </div> 198 <div class="config-div"> 199 <div> 200 <span class="title">Select profiling type</span> 201 </div> 202 <lit-radio dis="round" class="radio" name="litRadio" checked type="0">Heap snapshot</lit-radio> 203 <div style="margin-left: 10px;"> 204 <span class="des">Heap snapshot profiles show memory distribution among your page’s JavaScript objects and related DOM nodes.</span> 205 <div style="display: flex;margin-bottom: 12px;margin-top: 12px;"> 206 <check-des-box checked="true" value ="lnclude numerical values in capture" id="snapshot"> 207 </check-des-box> 208 </div> 209 <span class="des">Interval(Available on recent OpenHarmony 4.0)</span> 210 <div style="margin-top: 12px;"> 211 <input class="inputstyle" type="text" id="interval" placeholder="" onkeyup="this.value=this.value.replace(/\\D/g,'').replace(/^0{1,}/g,'')" value="10"> 212 <span class="unit">S</span> 213 </div> 214 </div> 215 216 <lit-radio dis="round" name="litRadio" class="radio" type="1">Allocation insteumentation on timeline</lit-radio> 217 <div style="margin-left: 10px;"> 218 <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> 219 <div style="display: flex;margin-top: 12px;"> 220 <check-des-box value ="record stack traces of allocations(extra performance overhead)" id="timeline"> 221 </check-des-box> 222 </div> 223 </div> 224 </div> 225 </div> 226 `; 227 } 228} 229