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'; 17import { log } from '../../../log/Log'; 18import { SpRecordTrace } from '../SpRecordTrace'; 19import { Cmd } from '../../../command/Cmd'; 20import LitSwitch from '../../../base-ui/switch/lit-switch'; 21import { LitSlider } from '../../../base-ui/slider/LitSlider'; 22import { LitSelectV } from '../../../base-ui/select/LitSelectV'; 23import { SpAllocationHtml } from './SpAllocation.html'; 24import { NUM_16384, NUM_1800, NUM_30, NUM_300, NUM_3600, NUM_450, NUM_60, NUM_600 } from '../../bean/NumBean'; 25import { LitSelect } from '../../../base-ui/select/LitSelect'; 26 27@element('sp-allocations') 28export class SpAllocations extends BaseElement { 29 // normal option 30 private processId: LitSelectV | null | undefined; 31 private packageName: LitSelect | null | undefined; 32 private unwindEL: HTMLInputElement | null | undefined; 33 private intervalResultInput: HTMLInputElement | null | undefined; 34 private fpUnWind: LitSwitch | null | undefined; 35 private statisticsSlider: LitSlider | null | undefined; 36 private useStatisticsEl: LitSwitch | null | undefined; 37 private recordStatisticsResult: HTMLDivElement | null | undefined; 38 private addOptionButton: HTMLButtonElement | undefined | null; 39 // advance option 40 private recordAccuratelyDivEl: HTMLDivElement | undefined | null; 41 private offlineSymbolizationDivEl: HTMLDivElement | undefined | null; 42 private maxUnwindLevelEl: HTMLDivElement | undefined | null; 43 private sharedMemorySizeEl: HTMLDivElement | undefined | null; 44 private filterMemorySizeEl: HTMLDivElement | undefined | null; 45 private sampleIntervalEl: HTMLDivElement | undefined | null; 46 private useStartupEl: HTMLDivElement | undefined | null; 47 private useResponseLibEl: HTMLDivElement | undefined | null; 48 private jsStackRecordDepthEl: HTMLDivElement | undefined | null; 49 private napiRecordEl: HTMLDivElement | undefined | null; 50 private advanceItems: Array<HTMLDivElement | undefined | null> = []; 51 private shareMemory: HTMLInputElement | null | undefined; 52 private shareMemoryUnit: HTMLSelectElement | null | undefined; 53 private filterMemory: HTMLInputElement | null | undefined; 54 private recordAccurately: LitSwitch | null | undefined; 55 private offlineSymbol: LitSwitch | null | undefined; 56 private startupMode: LitSwitch | null | undefined; 57 private jsStackModel: LitSwitch | null | undefined; 58 private responseLibMode: LitSwitch | null | undefined; 59 private napiName: HTMLInputElement | null | undefined; 60 private jsStackDepth: HTMLInputElement | null | undefined; 61 private statisticsIntervalInput: HTMLInputElement | null | undefined; 62 private statisticsIntervalName: HTMLSpanElement | null | undefined; 63 private statisticsIntervalRange: HTMLSpanElement | null | undefined; 64 65 set startSamp(allocationStart: boolean) { 66 if (allocationStart) { 67 this.setAttribute('startSamp', ''); 68 } else { 69 this.removeAttribute('startSamp'); 70 } 71 } 72 73 get startSamp(): boolean { 74 return this.hasAttribute('startSamp'); 75 } 76 77 get appProcess(): string { 78 return this.processId!.value || this.packageName!.value || ''; 79 } 80 81 get unwind(): number { 82 log(`unwind value is :${this.unwindEL!.value}`); 83 return Number(this.unwindEL!.value); 84 } 85 86 get shared(): number { 87 let value = this.shareMemory?.value || ''; 88 log(`shareMemory value is :${value}`); 89 if (value !== '') { 90 return Number(this.shareMemory?.value) || NUM_16384; 91 } 92 return NUM_16384; 93 } 94 95 get filter(): number { 96 let value = this.filterMemory?.value || ''; 97 log(`filter value is :${value}`); 98 if (value !== '') { 99 return Number(value); 100 } 101 return 0; 102 } 103 104 get fp_unwind(): boolean { 105 let value = this.fpUnWind?.checked; 106 if (value !== undefined) { 107 return value; 108 } 109 return true; 110 } 111 112 get record_accurately(): boolean { 113 let value = this.recordAccurately?.checked; 114 if (value !== undefined) { 115 return value; 116 } 117 return true; 118 } 119 120 get offline_symbolization(): boolean { 121 let value = this.offlineSymbol?.checked; 122 if (value !== undefined) { 123 return value; 124 } 125 return true; 126 } 127 128 get record_statistics(): boolean { 129 let value = this.useStatisticsEl!.checked; 130 if (value !== undefined) { 131 return value; 132 } 133 return true; 134 } 135 136 get statistics_interval(): number { 137 if (this.recordStatisticsResult?.hasAttribute('percentValue')) { 138 return Number(this.recordStatisticsResult?.getAttribute('percentValue')); 139 } 140 return 10; 141 } 142 143 get response_lib_mode(): boolean { 144 let value = this.responseLibMode?.checked; 145 if (value !== undefined) { 146 return value; 147 } 148 return false; 149 } 150 151 get startup_mode(): boolean { 152 let value = this.startupMode?.checked; 153 if (value !== undefined) { 154 return value; 155 } 156 return false; 157 } 158 159 set startup_mode(value: boolean) { 160 if (this.startupMode) { 161 this.startupMode.checked = value; 162 } 163 } 164 165 get recordJsStack(): boolean { 166 let value = this.jsStackModel?.checked; 167 if (value !== undefined) { 168 return value; 169 } 170 return false; 171 } 172 173 set recordJsStack(value: boolean) { 174 if (this.jsStackModel) { 175 this.jsStackModel.checked = value; 176 } 177 } 178 179 get expandPids(): number[] { 180 let allPidList: number[] = []; 181 if (this.processId!.value.length > 0) { 182 let result = this.processId?.value.match(/\((.+?)\)/g); 183 if (result) { 184 for (let index = 0; index < result.length; index++) { 185 let item = result[index]; 186 let currentPid = item!.replace('(', '').replace(')', ''); 187 allPidList.push(Number(currentPid)); 188 } 189 } 190 } 191 return allPidList; 192 } 193 194 get sample_interval(): number { 195 return Number(this.statisticsIntervalInput!.value); 196 } 197 198 get filter_napi_name(): string { 199 if (this.jsStackModel?.checked && !this.fp_unwind) { 200 return this.napiName!.value || ''; 201 } 202 return ''; 203 } 204 205 get max_js_stack_depth(): number { 206 if (this.jsStackModel?.checked) { 207 return Number(this.jsStackDepth!.value) || 10; 208 } 209 return 0; 210 } 211 212 initElements(): void { 213 // normal option 214 this.processId = this.shadowRoot?.getElementById('pid') as LitSelectV; 215 this.packageName = this.shadowRoot?.getElementById('packageName') as LitSelect; 216 this.unwindEL = this.shadowRoot?.getElementById('unwind') as HTMLInputElement; 217 this.fpUnWind = this.shadowRoot?.getElementById('use_fp_unwind') as LitSwitch; 218 this.statisticsSlider = this.shadowRoot?.querySelector<LitSlider>('#interval-slider') as LitSlider; 219 this.recordStatisticsResult = this.shadowRoot?.querySelector<HTMLDivElement>('.record-statistics-result'); 220 this.addOptionButton = this.shadowRoot?.querySelector<HTMLButtonElement>('#addOptions'); 221 this.intervalResultInput = this.shadowRoot?.querySelector('.interval-result') as HTMLInputElement; 222 // advance option 223 this.recordAccuratelyDivEl = this.shadowRoot?.getElementById('record_accurately_div') as HTMLDivElement; 224 this.offlineSymbolizationDivEl = this.shadowRoot?.getElementById('offline_symbolization_div') as HTMLDivElement; 225 this.jsStackRecordDepthEl = this.shadowRoot?.getElementById('js-stack-depth-div') as HTMLDivElement; 226 this.napiRecordEl = this.shadowRoot?.getElementById('napi-div') as HTMLDivElement; 227 this.maxUnwindLevelEl = this.shadowRoot?.getElementById('max-unwind-level-el') as HTMLDivElement; 228 this.sharedMemorySizeEl = this.shadowRoot?.getElementById('shared-memory-size-el') as HTMLDivElement; 229 this.filterMemorySizeEl = this.shadowRoot?.getElementById('filter-memory-size-el') as HTMLDivElement; 230 this.sampleIntervalEl = this.shadowRoot?.getElementById('sample-interval-el') as HTMLDivElement; 231 this.useStartupEl = this.shadowRoot?.getElementById('use-startup-el') as HTMLDivElement; 232 this.useResponseLibEl = this.shadowRoot?.getElementById('use-response-lib-el') as HTMLDivElement; 233 234 this.recordAccurately = this.shadowRoot?.getElementById('use_record_accurately') as LitSwitch; 235 this.shareMemory = this.shadowRoot?.getElementById('shareMemory') as HTMLInputElement; 236 this.shareMemoryUnit = this.shadowRoot?.getElementById('shareMemoryUnit') as HTMLSelectElement; 237 this.filterMemory = this.shadowRoot?.getElementById('filterSized') as HTMLInputElement; 238 this.offlineSymbol = this.shadowRoot?.getElementById('use_offline_symbolization') as LitSwitch; 239 this.startupMode = this.shadowRoot?.getElementById('use_startup_mode') as LitSwitch; 240 this.jsStackModel = this.shadowRoot?.getElementById('use_js-stack') as LitSwitch; 241 this.responseLibMode = this.shadowRoot?.getElementById('response_lib_mode') as LitSwitch; 242 this.useStatisticsEl = this.shadowRoot?.getElementById('use_statistics') as LitSwitch; 243 this.statisticsIntervalInput = this.shadowRoot?.getElementById('statistics-interval-input') as HTMLInputElement; 244 this.napiName = this.shadowRoot?.getElementById('napiName') as HTMLInputElement; 245 this.jsStackDepth = this.shadowRoot?.getElementById('jsStackDepth') as HTMLInputElement; 246 this.statisticsIntervalName = this.shadowRoot?.getElementById('statistics-interval-name') as HTMLSpanElement; 247 this.statisticsIntervalRange = this.shadowRoot?.getElementById('statistics-interval-range') as HTMLSpanElement; 248 this.initNativeSwitchOption(); 249 } 250 251 initHtml(): string { 252 return SpAllocationHtml; 253 } 254 255 connectedCallback(): void { 256 this.unwindEL?.addEventListener('keydown', this.handleInputChangeEvent); 257 this.shareMemory?.addEventListener('keydown', this.handleInputChangeEvent); 258 this.shareMemoryUnit?.addEventListener('keydown', this.handleInputChangeEvent); 259 this.filterMemory?.addEventListener('keydown', this.handleInputChangeEvent); 260 this.intervalResultInput?.addEventListener('keydown', this.handleInputChangeEvent); 261 this.statisticsSlider?.addEventListener('input', this.statisticsSliderInputEvent); 262 this.intervalResultInput?.addEventListener('input', this.statisticsValueInputEvent); 263 this.intervalResultInput?.addEventListener('focusout', this.statisticsFocusOutEvent); 264 this.statisticsSlider?.shadowRoot 265 ?.querySelector('#slider')! 266 .addEventListener('mouseup', this.statisticsSliderMouseupEvent); 267 this.startupMode?.addEventListener('change', this.startupModeChangeEvent); 268 this.jsStackModel?.addEventListener('change', this.jsStackModelChangeEvent); 269 this.addOptionButton?.addEventListener('click', this.advanceOptionClickEvent); 270 this.fpUnWind?.addEventListener('change', this.fpUnWindChangeEvent); 271 this.useStatisticsEl?.addEventListener('change', this.useStatisticsChangeEvent); 272 this.statisticsIntervalInput?.addEventListener('input', this.statisticsIntervalInputEvent); 273 this.statisticsIntervalInput?.addEventListener('keyup', this.statisticsIntervalKeyUpEvent); 274 } 275 276 disconnectedCallback(): void { 277 this.unwindEL?.removeEventListener('keydown', this.handleInputChangeEvent); 278 this.shareMemory?.removeEventListener('keydown', this.handleInputChangeEvent); 279 this.shareMemoryUnit?.removeEventListener('keydown', this.handleInputChangeEvent); 280 this.filterMemory?.removeEventListener('keydown', this.handleInputChangeEvent); 281 this.intervalResultInput?.removeEventListener('keydown', this.handleInputChangeEvent); 282 this.statisticsSlider?.removeEventListener('input', this.statisticsSliderInputEvent); 283 this.intervalResultInput?.removeEventListener('input', this.statisticsValueInputEvent); 284 this.intervalResultInput?.removeEventListener('focusout', this.statisticsFocusOutEvent); 285 this.statisticsSlider?.shadowRoot 286 ?.querySelector('#slider')! 287 .removeEventListener('mouseup', this.statisticsSliderMouseupEvent); 288 this.startupMode?.removeEventListener('change', this.startupModeChangeEvent); 289 this.jsStackModel?.removeEventListener('change', this.jsStackModelChangeEvent); 290 this.addOptionButton?.removeEventListener('click', this.advanceOptionClickEvent); 291 this.fpUnWind?.removeEventListener('change', this.fpUnWindChangeEvent); 292 this.useStatisticsEl?.removeEventListener('change', this.useStatisticsChangeEvent); 293 this.statisticsIntervalInput?.removeEventListener('input', this.statisticsIntervalInputEvent); 294 this.statisticsIntervalInput?.removeEventListener('keyup', this.statisticsIntervalKeyUpEvent); 295 } 296 297 handleInputChangeEvent = (ev: KeyboardEvent): void => { 298 // @ts-ignore 299 if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') { 300 ev.preventDefault(); 301 } 302 }; 303 304 statisticsSliderInputEvent = (): void => { 305 this.statisticsSlider!.sliderStyle = { 306 minRange: 0, 307 maxRange: 3600, 308 defaultValue: `${this.recordStatisticsResult!.getAttribute('percent')}`, 309 resultUnit: 'S', 310 stepSize: 450, 311 lineColor: 'var(--dark-color3,#46B1E3)', 312 buttonColor: '#999999', 313 }; 314 this.intervalResultInput!.style.color = 'var(--dark-color1,#000000)'; 315 if (this.recordStatisticsResult!.hasAttribute('percent')) { 316 let step = Math.round(Number(this.recordStatisticsResult!.getAttribute('percent')) / NUM_450); 317 this.recordStatisticsResult!.setAttribute('percentValue', `${stepValue[step]}`); 318 this.intervalResultInput!.value = `${stepValue[step]}`; 319 } 320 }; 321 322 statisticsValueInputEvent = (): void => { 323 if (this.intervalResultInput!.value === '0') { 324 this.useStatisticsEl!.checked = false; 325 this.useStatisticsChangeHandle(false); 326 } else { 327 this.statisticsIntervalHandle(); 328 } 329 }; 330 331 statisticsFocusOutEvent = (): void => { 332 let parentElement = this.statisticsSlider!.parentNode as Element; 333 if (this.intervalResultInput!.value.trim() === '') { 334 parentElement.setAttribute('percent', '3600'); 335 this.intervalResultInput!.value = '3600'; 336 this.intervalResultInput!.style.color = 'var(--dark-color,#6a6f77)'; 337 parentElement.setAttribute('percent', this.intervalResultInput!.value); 338 parentElement.setAttribute('percentValue', this.intervalResultInput!.value); 339 this.statisticsSlider!.percent = this.intervalResultInput!.value; 340 let htmlInputElement = this.statisticsSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 341 htmlInputElement.value = this.intervalResultInput!.value; 342 } 343 }; 344 345 useStatisticsChangeEvent = (): void => { 346 let useStatistics = this.useStatisticsEl!.checked; 347 this.useStatisticsChangeHandle(useStatistics); 348 }; 349 350 fpUnWindChangeEvent = (): void => { 351 this.napiName!.disabled = !(!this.fp_unwind && this.recordJsStack); 352 }; 353 354 advanceOptionClickEvent = (): void => { 355 if (!this.startSamp) { 356 return; 357 } 358 this.advanceOptionHandle(this.addOptionButton!.textContent!); 359 }; 360 361 startupModeChangeEvent = (): void => { 362 let process = this.processId?.shadowRoot?.querySelector('input') as HTMLInputElement; 363 let processDiv = this.processId?.shadowRoot?.querySelector('.root') as HTMLDivElement; 364 process.value = ''; 365 let packageInput = this.packageName?.shadowRoot?.querySelector('input') as HTMLInputElement; 366 let packageDiv = this.packageName?.shadowRoot?.querySelector('.root') as HTMLDivElement; 367 packageInput.value = ''; 368 if (this.startup_mode) { 369 this.packageName!.showItem = ''; 370 this.packageName!.style.display = 'block'; 371 this.processId!.style.display = 'none'; 372 packageDiv.style.width = 'auto'; 373 packageInput!.placeholder = 'please select package'; 374 this.processId!.dataSource([], ''); 375 } else { 376 this.processId!.showItems = []; 377 this.packageName!.style.display = 'none'; 378 this.processId!.style.display = 'block'; 379 processDiv.style.width = 'auto'; 380 process!.placeholder = 'please select process'; 381 this.packageName!.dataSource = []; 382 } 383 }; 384 385 jsStackModelChangeEvent = (): void => { 386 this.jsStackDepth!.disabled = !this.recordJsStack; 387 this.napiName!.disabled = !(!this.fp_unwind && this.recordJsStack); 388 }; 389 390 statisticsSliderMouseupEvent = (): void => { 391 setTimeout((): void => { 392 let percentValue = this.recordStatisticsResult!.getAttribute('percent'); 393 let index = Math.round(Number(percentValue) / NUM_450); 394 index = index < 1 ? 0 : index; 395 this.intervalResultInput!.value = `${stepValue[index]}`; 396 this.recordStatisticsResult!.setAttribute('percentValue', `${stepValue[index]}`); 397 if (this.intervalResultInput!.value === '0') { 398 this.useStatisticsEl!.checked = false; 399 this.useStatisticsChangeHandle(false); 400 } 401 }); 402 }; 403 404 statisticsIntervalInputEvent = (): void => { 405 let intervalValue = Number(this.statisticsIntervalInput!.value); 406 if (intervalValue > 65535) { 407 this.statisticsIntervalInput!.value = '65535'; 408 } 409 if (intervalValue === 0 || this.statisticsIntervalInput!.value.startsWith('0')) { 410 let resultValue = parseInt(this.statisticsIntervalInput!.value, 10); 411 this.statisticsIntervalInput!.value = `${resultValue}`; 412 } 413 }; 414 415 statisticsIntervalKeyUpEvent = (): void => { 416 this.statisticsIntervalInput!.value = this.statisticsIntervalInput!.value.replace(/\D/g, ''); 417 }; 418 419 private useStatisticsChangeHandle(useStatistics: boolean): void { 420 if (useStatistics) { 421 this.intervalResultInput!.value = '10'; 422 this.statisticsIntervalHandle(); 423 this.statisticsIntervalName!.textContent = 'Sample Interval'; 424 this.statisticsIntervalRange!.textContent = 'Rang is 0 - 65535, default 0 byte'; 425 this.statisticsIntervalInput!.value = '0'; 426 this.statisticsSlider!.disabled = false; 427 this.intervalResultInput!.disabled = false; 428 } else { 429 this.intervalResultInput!.value = '0'; 430 this.statisticsIntervalHandle(); 431 this.statisticsIntervalName!.textContent = 'Malloc Free Matching Interval'; 432 this.statisticsIntervalRange!.textContent = 'Rang is 0 - 65535, default 10 s'; 433 this.statisticsIntervalInput!.value = '10'; 434 this.statisticsSlider!.disabled = true; 435 this.intervalResultInput!.disabled = true; 436 } 437 } 438 439 private advanceOptionHandle(textValue: string): void { 440 this.resetAdvanceItems(); 441 let displayStyle = 'none'; 442 if (textValue === 'Advance Options') { 443 this.addOptionButton!.textContent = 'Normal Options'; 444 displayStyle = 'flex'; 445 } else { 446 this.addOptionButton!.textContent = 'Advance Options'; 447 } 448 this.advanceItems.forEach((itemEl) => { 449 if (itemEl) { 450 itemEl.style.display = displayStyle; 451 } 452 }); 453 this.jsStackDepth!.disabled = !this.recordJsStack; 454 this.napiName!.disabled = !(!this.fp_unwind && this.recordJsStack); 455 } 456 457 private resetAdvanceItems(): void { 458 this.advanceItems = [ 459 this.recordAccuratelyDivEl, 460 this.recordAccuratelyDivEl, 461 this.offlineSymbolizationDivEl, 462 this.jsStackRecordDepthEl, 463 this.napiRecordEl, 464 this.maxUnwindLevelEl, 465 this.sharedMemorySizeEl, 466 this.filterMemorySizeEl, 467 this.sampleIntervalEl, 468 this.useStartupEl, 469 this.useResponseLibEl, 470 ]; 471 } 472 473 private initNativeSwitchOption(): void { 474 this.packageName!.style.display = 'none'; 475 let processInputEl = this.processId!.shadowRoot?.querySelector('input') as HTMLInputElement; 476 processInputEl.addEventListener('mousedown', (): void => { 477 this.processMouseDownHandler(processInputEl); 478 }); 479 let packageInput = this.packageName!.shadowRoot?.querySelector('input') as HTMLInputElement; 480 packageInput.addEventListener('mousedown', (): void => { 481 this.packageMouseDownHandler(packageInput); 482 }); 483 this.statisticsSlider!.sliderStyle = { 484 minRange: 0, 485 maxRange: 3600, 486 defaultValue: '900', 487 resultUnit: 'S', 488 stepSize: 450, 489 lineColor: 'var(--dark-color3,#46B1E3)', 490 buttonColor: '#999999', 491 }; 492 let parentElement = this.statisticsSlider!.parentNode as Element; 493 this.intervalResultInput!.value = '10'; 494 parentElement.setAttribute('percent', '3600'); 495 this.intervalResultInput!.style.color = 'var(--dark-color1,#000000)'; 496 let litSwitch = this.shadowRoot?.querySelector('#switch-disabled') as LitSwitch; 497 litSwitch.addEventListener('change', (event: Event): void => { 498 // @ts-ignore 499 let detail = event.detail; 500 if (detail.checked) { 501 this.unDisable(); 502 } else { 503 this.disable(); 504 } 505 this.addOptionButton!.textContent = 'Advance Options'; 506 }); 507 this.packageName!.style.display = 'none'; 508 this.processId!.style.display = 'block'; 509 let processDivEl = this.processId?.shadowRoot?.querySelector('.root') as HTMLDivElement; 510 if (processDivEl) { 511 processDivEl.style.width = 'auto'; 512 } 513 this.disable(); 514 } 515 516 private processMouseDownHandler(process: HTMLInputElement): void { 517 if (this.startSamp && !this.startup_mode) { 518 Cmd.getProcess().then((processList: string[]): void => { 519 this.processId?.dataSource(processList, ''); 520 if (processList.length > 0) { 521 this.processId?.dataSource(processList, ''); 522 } else { 523 this.processId?.dataSource([], ''); 524 } 525 }); 526 process.readOnly = false; 527 } else { 528 process.readOnly = true; 529 return; 530 } 531 if (this.startSamp && (SpRecordTrace.serialNumber === '' || this.startup_mode)) { 532 this.processId?.dataSource([], ''); 533 } else { 534 } 535 } 536 537 private packageMouseDownHandler(packageInput: HTMLInputElement): void { 538 if (this.startSamp && this.startup_mode) { 539 Cmd.getPackage().then((packageList: string[]): void => { 540 let finalDataList = packageList.map(str => str.replace(/\t/g, '')); 541 if (finalDataList.length > 0) { 542 this.packageName!.dataSource = finalDataList; 543 } else { 544 this.packageName!.dataSource = []; 545 } 546 }); 547 packageInput.readOnly = false; 548 } else { 549 packageInput.readOnly = true; 550 return; 551 } 552 } 553 554 private statisticsIntervalHandle(): void { 555 let parentElement = this.statisticsSlider!.parentNode as Element; 556 if (this.recordStatisticsResult!.hasAttribute('percent')) { 557 this.recordStatisticsResult!.removeAttribute('percent'); 558 } 559 this.intervalResultInput!.style.color = 'var(--dark-color1,#000000)'; 560 this.intervalResultInput!.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 561 this.intervalResultInput!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; 562 if (this.intervalResultInput!.value.trim() === '') { 563 this.intervalResultInput!.style.color = 'red'; 564 parentElement.setAttribute('percent', '3600'); 565 return; 566 } 567 if ( 568 Number(this.intervalResultInput!.value) < this.statisticsSlider!.sliderStyle.minRange || 569 Number(this.intervalResultInput!.value) > this.statisticsSlider!.sliderStyle.maxRange 570 ) { 571 this.intervalResultInput!.style.color = 'red'; 572 parentElement.setAttribute('percent', '3600'); 573 } else { 574 let defaultSize = 0; 575 let stepSize = 450; 576 let inputValue = Number(this.intervalResultInput!.value); 577 for (let stepIndex = 0; stepIndex < stepValue.length; stepIndex++) { 578 let currentValue = stepValue[stepIndex]; 579 if (inputValue === currentValue) { 580 defaultSize = stepIndex * stepSize; 581 break; 582 } else if (inputValue < currentValue && stepIndex !== 0) { 583 defaultSize = 584 ((inputValue - stepValue[stepIndex - 1]) / (currentValue - stepValue[stepIndex - 1])) * stepSize + 585 stepSize * (stepIndex - 1); 586 break; 587 } 588 } 589 this.statisticsSlider!.percent = `${defaultSize}`; 590 let htmlInputElement = this.statisticsSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; 591 this.statisticsSlider!.sliderStyle = { 592 minRange: 0, 593 maxRange: 3600, 594 defaultValue: `${defaultSize}`, 595 resultUnit: 'S', 596 stepSize: 1, 597 lineColor: 'var(--dark-color3,#46B1E3)', 598 buttonColor: '#999999', 599 }; 600 htmlInputElement.value = `${defaultSize}`; 601 parentElement.setAttribute('percent', this.intervalResultInput!.value); 602 parentElement.setAttribute('percentValue', this.intervalResultInput!.value); 603 } 604 } 605 606 private unDisable(): void { 607 this.startSamp = true; 608 if (this.fpUnWind) { 609 this.fpUnWind.disabled = false; 610 } 611 if (this.recordAccurately) { 612 this.recordAccurately.disabled = false; 613 } 614 if (this.offlineSymbol) { 615 this.offlineSymbol.disabled = false; 616 } 617 if (this.startupMode) { 618 this.startupMode.disabled = false; 619 } 620 if (this.jsStackModel) { 621 this.jsStackModel.disabled = false; 622 } 623 if (this.responseLibMode) { 624 this.responseLibMode.disabled = false; 625 } 626 if (this.statisticsIntervalInput) { 627 this.statisticsIntervalInput.disabled = false; 628 } 629 if (this.useStatisticsEl) { 630 this.useStatisticsEl.disabled = false; 631 } 632 this.processId!.removeAttribute('disabled'); 633 let inputBoxes = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.inputBoxes'); 634 inputBoxes!.forEach((item: HTMLInputElement): void => { 635 item.disabled = false; 636 }); 637 if (this.startup_mode) { 638 this.packageName!.removeAttribute('disabled'); 639 } else { 640 this.processId!.removeAttribute('disabled'); 641 } 642 this.statisticsSlider!.disabled = false; 643 } 644 645 private disable(): void { 646 this.startSamp = false; 647 this.advanceOptionHandle('Normal Options'); 648 if (this.fpUnWind) { 649 this.fpUnWind.disabled = true; 650 } 651 if (this.recordAccurately) { 652 this.recordAccurately.disabled = true; 653 } 654 if (this.startupMode) { 655 this.startupMode.disabled = true; 656 } 657 if (this.jsStackModel) { 658 this.jsStackModel.disabled = true; 659 } 660 if (this.offlineSymbol) { 661 this.offlineSymbol.disabled = true; 662 } 663 if (this.responseLibMode) { 664 this.responseLibMode.disabled = true; 665 } 666 if (this.statisticsIntervalInput) { 667 this.statisticsIntervalInput.disabled = true; 668 } 669 if (this.useStatisticsEl) { 670 this.useStatisticsEl.disabled = true; 671 } 672 this.processId!.setAttribute('disabled', ''); 673 let inputBoxes = this.shadowRoot?.querySelectorAll<HTMLInputElement>('.inputBoxes'); 674 inputBoxes!.forEach((item: HTMLInputElement): void => { 675 item.disabled = true; 676 }); 677 if (this.startup_mode) { 678 this.packageName!.setAttribute('disabled', ''); 679 } else { 680 this.processId!.setAttribute('disabled', ''); 681 } 682 this.statisticsSlider!.disabled = true; 683 } 684} 685 686const stepValue: number[] = [0, 1, 10, NUM_30, NUM_60, NUM_300, NUM_600, NUM_1800, NUM_3600]; 687