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 { SpSystemTrace } from './SpSystemTrace'; 17import { ThreadStruct, ThreadStructOnClick } from '../database/ui-worker/ProcedureWorkerThread'; 18import { TraceRow } from './trace/base/TraceRow'; 19import { JankStruct, JankStructOnClick } from '../database/ui-worker/ProcedureWorkerJank'; 20import { HeapSnapshotStruct, HeapSnapshotStructOnClick } from '../database/ui-worker/ProcedureWorkerHeapSnapshot'; 21import { FuncStruct, funcStructOnClick } from '../database/ui-worker/ProcedureWorkerFunc'; 22import { CpuFreqStruct, CpuFreqStructOnClick } from '../database/ui-worker/ProcedureWorkerFreq'; 23import { ClockStruct, ClockStructOnClick } from '../database/ui-worker/ProcedureWorkerClock'; 24import { DmaFenceStruct, DmaFenceStructOnClick } from '../database/ui-worker/ProcedureWorkerDmaFence'; 25import { SnapshotStruct, SnapshotStructOnClick } from '../database/ui-worker/ProcedureWorkerSnapshot'; 26import { IrqStruct, IrqStructOnClick } from '../database/ui-worker/ProcedureWorkerIrq'; 27import { HeapStruct, HeapStructOnClick } from '../database/ui-worker/ProcedureWorkerHeap'; 28import { JsCpuProfilerStruct, JsCpuProfilerStructOnClick } from '../database/ui-worker/ProcedureWorkerCpuProfiler'; 29import { AppStartupStruct, AppStartupStructOnClick } from '../database/ui-worker/ProcedureWorkerAppStartup'; 30import { AllAppStartupStruct, allAppStartupStructOnClick } from '../database/ui-worker/ProcedureWorkerAllAppStartup'; 31import { SoStruct, SoStructOnClick } from '../database/ui-worker/ProcedureWorkerSoInit'; 32import { FrameAnimationStruct, FrameAnimationStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameAnimation'; 33import { FrameDynamicStruct, FrameDynamicStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameDynamic'; 34import { FrameSpacingStruct, FrameSpacingStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameSpacing'; 35import { SampleStruct, sampleStructOnClick } from '../database/ui-worker/ProcedureWorkerBpftrace'; 36import { SportRuler } from './trace/timer-shaft/SportRuler'; 37import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; 38import { LitSearch } from './trace/search/Search'; 39import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent'; 40import type { SpKeyboard } from './SpKeyboard'; 41import { enableVSync } from './chart/VSync'; 42import { CpuStruct, CpuStructOnClick } from '../database/ui-worker/cpu/ProcedureWorkerCPU'; 43import { ProcessMemStruct } from '../database/ui-worker/ProcedureWorkerMem'; 44import { CpuStateStruct, CpuStateStructOnClick } from '../database/ui-worker/cpu/ProcedureWorkerCpuState'; 45import { 46 CpuFreqLimitsStruct, 47 CpuFreqLimitsStructOnClick 48} from '../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits'; 49import { FlagsConfig } from './SpFlags'; 50import { LitMainMenu } from '../../base-ui/menu/LitMainMenu'; 51import { PerfToolsStructOnClick, PerfToolStruct } from '../database/ui-worker/ProcedureWorkerPerfTool'; 52import { Utils } from './trace/base/Utils'; 53import { BaseStruct } from '../bean/BaseStruct'; 54import { GpuCounterStruct, gpuCounterStructOnClick } from '../database/ui-worker/ProcedureWorkerGpuCounter'; 55import { HangStructOnClick } from '../database/ui-worker/ProcedureWorkerHang'; 56import { XpowerStruct, XpowerStructOnClick } from '../database/ui-worker/ProcedureWorkerXpower'; 57import { XpowerStatisticStruct, XpowerStatisticStructOnClick } from '../database/ui-worker/ProcedureWorkerXpowerStatistic'; 58import { SpAiAnalysisPage } from './SpAiAnalysisPage'; 59import { XpowerAppDetailStruct, XpowerAppDetailStructOnClick } from '../database/ui-worker/ProcedureWorkerXpowerAppDetail'; 60import { XpowerWifiBytesStructOnClick, XpowerWifiPacketsStructOnClick, XpowerWifiStruct } from '../database/ui-worker/ProcedureWorkerXpowerWifi'; 61import { XpowerThreadInfoStruct, XpowerThreadInfoStructOnClick } from '../database/ui-worker/ProcedureWorkerXpowerThreadInfo'; 62import { XpowerGpuFreqStruct, XpowerGpuFreqStructOnClick } from '../database/ui-worker/ProcedureWorkerXpowerGpuFreq'; 63 64function timeoutJudge(sp: SpSystemTrace): number { 65 let timeoutJudge = window.setTimeout((): void => { 66 if (SpSystemTrace.wakeupList.length && CpuStruct.selectCpuStruct) { 67 let checkHandlerKey: boolean = true; 68 let saveSelectCpuStruct: unknown = JSON.parse(sessionStorage.getItem('saveselectcpustruct')!); 69 for (const item of SpSystemTrace.wakeupList) { 70 if (item.ts === CpuStruct.selectCpuStruct.startTime && item.dur === CpuStruct.selectCpuStruct.dur) { 71 checkHandlerKey = false; 72 if (SpSystemTrace.wakeupList[0].schedulingDesc) { 73 //@ts-ignore 74 SpSystemTrace.wakeupList.unshift(saveSelectCpuStruct); 75 } 76 sp.refreshCanvas(true); 77 break; 78 } else if ( 79 //@ts-ignore 80 saveSelectCpuStruct.startTime === CpuStruct.selectCpuStruct.startTime && 81 //@ts-ignore 82 saveSelectCpuStruct.dur === CpuStruct.selectCpuStruct.dur 83 ) { 84 // 如果点击的是第一层,保持唤醒树不变 85 checkHandlerKey = false; 86 sp.refreshCanvas(true); 87 break; 88 } 89 } 90 // 点击线程在唤醒树内 91 if (!checkHandlerKey) { 92 // 查询获取tab表格数据 93 window.publish(window.SmartEvent.UI.WakeupList, SpSystemTrace.wakeupList); 94 } else { 95 // 不在唤醒树内,清空数组 96 sp.wakeupListNull(); 97 sp.refreshCanvas(true); 98 } 99 } else { 100 sp.wakeupListNull(); 101 sp.refreshCanvas(true); 102 } 103 clearTimeout(timeoutJudge); 104 }, 10); 105 return timeoutJudge; 106} 107 108function threadClickHandlerFunc(sp: SpSystemTrace): (e: ThreadStruct) => void { 109 let threadClickHandler = (d: ThreadStruct): void => { 110 sp.observerScrollHeightEnable = false; 111 sp.scrollToProcess(`${d.cpu}`, '', 'cpu-data', true); 112 let cpuRow = sp.queryAllTraceRow<TraceRow<CpuStruct>>( 113 `trace-row[row-id='${Utils.getDistributedRowId(d.cpu)}'][row-type='cpu-data']`, 114 (row) => row.rowId === `${Utils.getDistributedRowId(d.cpu)}` && row.rowType === 'cpu-data' 115 )[0]; 116 if (cpuRow) { 117 sp.currentRow = cpuRow; 118 cpuRow.fixedList = [ 119 { 120 startTime: d.startTime, 121 dur: d.dur, 122 tid: d.tid, 123 id: d.id, 124 processId: d.pid, 125 cpu: d.cpu, 126 argSetID: d.argSetID, 127 }, 128 ]; 129 let findEntry = cpuRow!.fixedList[0]; 130 sp.rechargeCpuData( 131 // @ts-ignore 132 findEntry, // @ts-ignore 133 cpuRow.dataListCache.find((it) => it.startTime > findEntry.startTime) 134 ); 135 if ( 136 // @ts-ignore 137 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || // @ts-ignore 138 findEntry!.startTime! > TraceRow.range!.endNS 139 ) { 140 sp.timerShaftEL?.setRangeNS( 141 // @ts-ignore 142 findEntry!.startTime! - findEntry!.dur! * 2, // @ts-ignore 143 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 144 ); 145 } 146 sp.hoverStructNull().selectStructNull().wakeupListNull(); // @ts-ignore 147 CpuStruct.hoverCpuStruct = findEntry; // @ts-ignore 148 CpuStruct.selectCpuStruct = findEntry; // @ts-ignore 149 sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 150 sp.traceSheetEL?.displayCpuData( 151 CpuStruct.selectCpuStruct!, 152 (wakeUpBean) => { 153 sp.removeLinkLinesByBusinessType('thread'); 154 CpuStruct.wakeupBean = wakeUpBean; 155 sp.refreshCanvas(true); 156 }, 157 cpuClickHandlerFunc(sp) 158 ); 159 } 160 }; 161 return threadClickHandler; 162} 163 164//点击prio箭头刷新canvas 165function prioClickHandlerFunc(sp: SpSystemTrace): (d: unknown) => void { 166 return function (d: unknown): void { 167 // @ts-ignore 168 ThreadStruct.prioCount = d; 169 ThreadStruct.isClickPrio = true; 170 sp.refreshCanvas(true); 171 }; 172} 173 174function scrollToFuncHandlerFunc(sp: SpSystemTrace): Function { 175 let funClickHandle = (funcStruct: unknown): void => { 176 // @ts-ignore 177 if (funcStruct.chainId) { 178 } 179 sp.observerScrollHeightEnable = true; 180 // @ts-ignore 181 sp.moveRangeToCenter(funcStruct.startTs!, funcStruct.dur!); 182 sp.scrollToActFunc(funcStruct, false); 183 }; 184 return funClickHandle; 185} 186 187function scrollToFunc(sp: SpSystemTrace): Function { 188 let funClickHandle = (funcStruct: unknown): void => { 189 // @ts-ignore 190 if (funcStruct.chainId) { 191 } 192 sp.observerScrollHeightEnable = true; 193 // @ts-ignore 194 sp.scrollToActFunc(funcStruct, false); 195 }; 196 return funClickHandle; 197} 198 199function jankClickHandlerFunc(sp: SpSystemTrace): Function { 200 let jankClickHandler = (d: unknown): void => { 201 sp.observerScrollHeightEnable = true; 202 let jankRowParent: unknown; 203 //@ts-ignore 204 if (d.rowId === 'actual frameTime') { 205 jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>("trace-row[row-id='frameTime']"); 206 } else { 207 jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>( 208 //@ts-ignore 209 `trace-row[row-type='process'][row-id='${d.pid}']` 210 ); 211 } 212 //@ts-ignore 213 jankRowParent!.expansion = true; 214 let jankRow: unknown; 215 //@ts-ignore 216 jankRowParent.childrenList.forEach((item: TraceRow<JankStruct>) => { 217 //@ts-ignore 218 if (`${item.rowId}` === `${d.rowId}` && `${item.rowType}` === 'janks') { 219 jankRow = item; 220 } 221 }); 222 //@ts-ignore 223 sp.currentRow = jankRow; 224 if (jankRow) { 225 JankStruct.selectJankStructList.length = 0; 226 //@ts-ignore 227 let findJankEntry = jankRow!.dataListCache!.find( 228 //@ts-ignore 229 (dat: unknown) => `${dat.name}` === `${d.name}` && `${dat.pid}` === `${d.pid}` 230 ); 231 if (findJankEntry) { 232 if ( 233 findJankEntry!.ts! + findJankEntry!.dur! < TraceRow.range!.startNS || 234 findJankEntry!.ts! > TraceRow.range!.endNS 235 ) { 236 sp.timerShaftEL?.setRangeNS( 237 findJankEntry!.ts! - findJankEntry!.dur! * 2, 238 findJankEntry!.ts! + findJankEntry!.dur! + findJankEntry!.dur! * 2 239 ); 240 } 241 sp.hoverStructNull().selectStructNull().wakeupListNull(); 242 JankStruct.hoverJankStruct = findJankEntry; 243 JankStruct.selectJankStruct = findJankEntry; 244 sp.timerShaftEL?.drawTriangle(findJankEntry!.ts || 0, 'inverted'); 245 sp.traceSheetEL?.displayJankData( 246 JankStruct.selectJankStruct!, 247 (datas) => { 248 sp.removeLinkLinesByBusinessType('janks'); 249 // 绘制跟自己关联的线 250 datas.forEach((data) => { 251 //@ts-ignore 252 let endParentRow = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>( // @ts-ignore 253 `trace-row[row-type='process'][row-id='${data.pid}'][folder]` 254 ); 255 sp.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data, true); 256 }); 257 }, 258 jankClickHandler 259 ); 260 } 261 //@ts-ignore 262 sp.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, true); 263 } 264 }; 265 return jankClickHandler; 266} 267 268function snapshotClickHandlerFunc(sp: SpSystemTrace): Function { 269 let snapshotClickHandler = (d: HeapSnapshotStruct): void => { 270 sp.observerScrollHeightEnable = true; 271 let snapshotRow = sp.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>(`trace-row[row-id='heapsnapshot']`); 272 let task = (): void => { 273 if (snapshotRow) { 274 let findEntry = snapshotRow!.dataListCache!.find((dat) => dat.startTs === d.startTs); 275 sp.hoverStructNull(); 276 sp.selectStructNull(); 277 sp.wakeupListNull(); 278 HeapSnapshotStruct.hoverSnapshotStruct = findEntry; 279 HeapSnapshotStruct.selectSnapshotStruct = findEntry; 280 } 281 }; 282 if (snapshotRow) { 283 if (snapshotRow!.isComplete) { 284 task(); 285 } else { 286 snapshotRow!.onComplete = task; 287 } 288 } 289 }; 290 return snapshotClickHandler; 291} 292 293//@ts-ignore 294function cpuClickHandlerTask(threadRow: TraceRow<unknown>, sp: SpSystemTrace, d: CpuStruct): void { 295 if (threadRow) { 296 let findEntry = threadRow!.fixedList[0]; 297 if ( 298 //@ts-ignore 299 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || 300 //@ts-ignore 301 findEntry!.startTime! > TraceRow.range!.endNS 302 ) { 303 sp.timerShaftEL?.setRangeNS( 304 //@ts-ignore 305 findEntry!.startTime! - findEntry!.dur! * 2, 306 //@ts-ignore 307 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 308 ); 309 } 310 ThreadStruct.firstselectThreadStruct = ThreadStruct.selectThreadStruct; 311 sp.hoverStructNull().selectStructNull().wakeupListNull(); 312 //@ts-ignore 313 ThreadStruct.hoverThreadStruct = findEntry; 314 //@ts-ignore 315 ThreadStruct.selectThreadStruct = findEntry; 316 //@ts-ignore 317 sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 318 sp.traceSheetEL?.displayThreadData( 319 ThreadStruct.selectThreadStruct!, 320 threadClickHandlerFunc(sp), // @ts-ignore 321 cpuClickHandlerFunc(sp), 322 prioClickHandlerFunc(sp), 323 (datas, str): void => { 324 sp.removeLinkLinesByBusinessType('thread'); 325 if (str === 'wakeup tid') { 326 datas.forEach((data) => { 327 //@ts-ignore 328 let endParentRow = sp.shadowRoot?.querySelector<TraceRow<unknown>>( //@ts-ignore 329 `trace-row[row-id='${data.pid}'][folder]` 330 ); 331 sp.drawThreadLine(endParentRow, ThreadStruct.firstselectThreadStruct, data); 332 }); 333 } 334 sp.refreshCanvas(true); 335 } 336 ); 337 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 338 } 339} 340 341function cpuClickHandlerFunc(sp: SpSystemTrace) { 342 return function (d: CpuStruct): void { 343 //@ts-ignore 344 let traceRow = sp.shadowRoot?.querySelector<TraceRow<unknown>>( 345 `trace-row[row-id='${Utils.getDistributedRowId(d.processId)}'][row-type='process']` 346 ); 347 if (traceRow) { 348 traceRow.expansion = true; 349 } 350 sp.observerScrollHeightEnable = true; 351 let threadRow = sp.queryAllTraceRow<TraceRow<ThreadStruct>>( 352 `trace-row[row-id='${Utils.getDistributedRowId(d.tid)}'][row-type='thread'][row-parent-id='${traceRow?.rowId}']`, 353 (row) => row.rowId === `${d.tid}` && row.rowType === 'thread' && row.rowParentId === traceRow?.rowId 354 )[0]; 355 sp.currentRow = threadRow; 356 if (threadRow) { 357 threadRow.fixedList = [ 358 { 359 startTime: d.startTime, 360 dur: d.dur, 361 cpu: d.cpu, 362 id: d.id, 363 tid: d.tid, 364 state: d.state, 365 pid: d.processId, 366 argSetID: d.argSetID, 367 }, 368 ]; 369 if (threadRow!.isComplete) { 370 cpuClickHandlerTask(threadRow, sp, d); 371 } else { 372 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'process', false); 373 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 374 threadRow!.onComplete = (): void => cpuClickHandlerTask(threadRow, sp, d); 375 } 376 } 377 }; 378} 379 380 381function allStructOnClick(clickRowType: string, sp: SpSystemTrace, row?: TraceRow<BaseStruct>, entry?: unknown): void { 382 CpuStructOnClick(clickRowType, sp, cpuClickHandlerFunc(sp), entry as CpuStruct) 383 .then(() => ThreadStructOnClick(clickRowType, sp, threadClickHandlerFunc(sp), cpuClickHandlerFunc(sp), 384 prioClickHandlerFunc(sp), entry as ThreadStruct)) 385 .then(() => funcStructOnClick(clickRowType, sp, row as TraceRow<FuncStruct>, 386 scrollToFuncHandlerFunc(sp), entry as FuncStruct)) 387 .then(() => CpuFreqStructOnClick(clickRowType, sp, entry as CpuFreqStruct)) 388 .then(() => CpuStateStructOnClick(clickRowType, sp, entry as CpuStateStruct)) 389 .then(() => CpuFreqLimitsStructOnClick(clickRowType, sp, entry as CpuFreqLimitsStruct)) 390 .then(() => ClockStructOnClick(clickRowType, sp, entry as ClockStruct)) 391 .then(() => XpowerStructOnClick(clickRowType, sp, entry as XpowerStruct)) 392 .then(() => XpowerStatisticStructOnClick(clickRowType, sp, row as TraceRow<XpowerStatisticStruct>, entry as XpowerStatisticStruct)) 393 .then(() => XpowerAppDetailStructOnClick(clickRowType, sp, entry as XpowerAppDetailStruct)) 394 .then(() => XpowerWifiBytesStructOnClick(clickRowType, sp, entry as XpowerWifiStruct)) 395 .then(() => XpowerWifiPacketsStructOnClick(clickRowType, sp, entry as XpowerWifiStruct)) 396 .then(() => XpowerThreadInfoStructOnClick(clickRowType, sp, entry as XpowerThreadInfoStruct)) 397 .then(() => XpowerGpuFreqStructOnClick(clickRowType, sp, entry as XpowerGpuFreqStruct)) 398 .then(() => HangStructOnClick(clickRowType, sp, scrollToFunc(sp))) 399 .then(() => DmaFenceStructOnClick(clickRowType, sp, entry as DmaFenceStruct)) 400 .then(() => SnapshotStructOnClick(clickRowType, sp, row as TraceRow<SnapshotStruct>, entry as SnapshotStruct)) 401 .then(() => IrqStructOnClick(clickRowType, sp, entry as IrqStruct)) 402 .then(() => HeapStructOnClick(clickRowType, sp, row as TraceRow<HeapStruct>, entry as HeapStruct)) 403 .then(() => JankStructOnClick(clickRowType, sp, row as TraceRow<JankStruct>, 404 jankClickHandlerFunc(sp), entry as JankStruct)) 405 .then(() => HeapSnapshotStructOnClick(clickRowType, sp, row as TraceRow<HeapSnapshotStruct>, 406 snapshotClickHandlerFunc(sp), entry as HeapSnapshotStruct)) 407 .then(() => JsCpuProfilerStructOnClick(clickRowType, sp, row as TraceRow<JsCpuProfilerStruct>, 408 entry as JsCpuProfilerStruct)) 409 .then(() => AppStartupStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as AppStartupStruct)) 410 .then(() => allAppStartupStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as AllAppStartupStruct)) 411 .then(() => SoStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as SoStruct)) 412 .then(() => FrameAnimationStructOnClick(clickRowType, sp, 413 scrollToFuncHandlerFunc(sp), row as TraceRow<FrameAnimationStruct>, entry as FrameAnimationStruct)) 414 .then(() => FrameDynamicStructOnClick(clickRowType, sp, row, entry as FrameDynamicStruct)) 415 .then(() => FrameSpacingStructOnClick(clickRowType, sp, row!, entry as FrameSpacingStruct)) 416 .then(() => sampleStructOnClick(clickRowType, sp, row as TraceRow<SampleStruct>, entry as SampleStruct)) 417 .then(() => gpuCounterStructOnClick(clickRowType, sp, entry as GpuCounterStruct)) 418 .then(() => PerfToolsStructOnClick(clickRowType, sp, entry as PerfToolStruct)) 419 .then(() => { 420 if (!JankStruct.hoverJankStruct && JankStruct.delJankLineFlag) { 421 sp.removeLinkLinesByBusinessType('janks'); 422 } 423 sp.observerScrollHeightEnable = false; 424 sp.selectFlag = null; 425 sp.timerShaftEL?.removeTriangle('inverted'); 426 if (!SportRuler.isMouseInSportRuler) { 427 sp.traceSheetEL?.setMode('hidden'); 428 sp.refreshCanvas(true, 'click'); 429 } 430 }) 431 .catch((e): void => { }); 432 SpAiAnalysisPage.selectChangeListener(TraceRow.range?.startNS!, TraceRow.range?.endNS!); 433} 434export default function spSystemTraceOnClickHandler( 435 sp: SpSystemTrace, 436 clickRowType: string, 437 row?: TraceRow<BaseStruct>, 438 entry?: unknown 439): void { 440 if (row) { 441 sp.currentRow = row; 442 sp.setAttribute('clickRow', clickRowType); 443 sp.setAttribute('rowName', row.name!); 444 sp.setAttribute('rowId', row.rowId!); 445 } 446 if (!sp.loadTraceCompleted) { 447 return; 448 } 449 sp.queryAllTraceRow().forEach(it => { 450 it.checkType = '-1'; 451 it.rangeSelect = false; 452 }); 453 sp.selectStructNull(); 454 sp._slicesList.forEach((slice: { selected: boolean }): void => { 455 slice.selected = false; 456 }); 457 // 判断点击的线程是否在唤醒树内 458 timeoutJudge(sp); 459 allStructOnClick(clickRowType, sp, row, entry); 460 if (!JankStruct.selectJankStruct) { 461 sp.removeLinkLinesByBusinessType('janks'); 462 } 463 if (!ThreadStruct.selectThreadStruct) { 464 sp.removeLinkLinesByBusinessType('thread'); 465 } 466 if (!FuncStruct.selectFuncStruct) { 467 sp.removeLinkLinesByBusinessType('distributed', 'func'); 468 } 469 if (row) { 470 let pointEvent = sp.createPointEvent(row); 471 SpStatisticsHttpUtil.addOrdinaryVisitAction({ 472 action: 'trace_row', // @ts-ignore 473 event: pointEvent, 474 }); 475 } 476} 477 478//@ts-ignore 479function handleActions(sp: SpSystemTrace, rows: Array<TraceRow<unknown>>, ev: MouseEvent): void { 480 if (sp.rangeSelect.isMouseDown && sp.rangeSelect.drag) { 481 let downRow = sp.visibleRows.find((row) => row.containPoint(ev)); 482 if (downRow && downRow.traceId !== Utils.currentSelectTrace) { 483 spSystemTraceDocumentOnMouseMoveMouseUp(sp, rows, ev); 484 return; 485 } 486 } 487 sp.rangeSelect.mouseMove(rows, ev); 488 if (sp.rangeSelect.rangeTraceRow!.length > 0) { 489 sp.tabCpuFreq!.rangeTraceRow = sp.rangeSelect.rangeTraceRow; 490 sp.tabCpuState!.rangeTraceRow = sp.rangeSelect.rangeTraceRow; 491 } 492 let search = document.querySelector('body > sp-application')!.shadowRoot!.querySelector<LitSearch>('#lit-search'); 493 if (sp.rangeSelect.isMouseDown && search?.isClearValue) { 494 spSystemTraceDocumentOnMouseMoveMouseDown(sp, search); 495 } else { 496 spSystemTraceDocumentOnMouseMoveMouseUp(sp, rows, ev); 497 } 498} 499 500function handleMouseInTimeShaft(sp: SpSystemTrace, ev: MouseEvent): boolean | undefined { 501 let isMouseInTimeShaft = sp.timerShaftEL?.containPoint(ev); 502 if (isMouseInTimeShaft) { 503 sp.tipEL!.style.display = 'none'; 504 sp.hoverStructNull(); 505 } 506 return isMouseInTimeShaft; 507} 508 509export function spSystemTraceDocumentOnMouseMove(sp: SpSystemTrace, ev: MouseEvent): void { 510 //@ts-ignore 511 if (!sp.loadTraceCompleted || !sp.mouseEventEnable) { 512 return; 513 } 514 //@ts-ignore 515 if ((window as unknown).collectResize) { 516 sp.style.cursor = 'row-resize'; 517 sp.cancelDrag(); 518 return; 519 } 520 if (sp.isWASDKeyPress()) { 521 sp.hoverFlag = null; 522 ev.preventDefault(); 523 return; 524 } 525 if (ev.ctrlKey && ev.button === 0 && SpSystemTrace.isMouseLeftDown) { 526 // 计算当前tab组件的高度 527 let tabHeight: number = 528 sp.shadowRoot?.querySelector('trace-sheet')!.shadowRoot?.querySelector('lit-tabs')!.clientHeight! + 1; 529 // 计算当前屏幕内高与鼠标位置坐标高度的差值 530 let diffHeight: number = window.innerHeight - ev.clientY; 531 // 如果差值大于面板高度,意味着鼠标位于泳道区域,可以通过ctrl+鼠标左键移动。否则不予生效 532 if (diffHeight > tabHeight) { 533 sp.translateByMouseMove(ev); 534 } else { 535 // 若鼠标位于tab面板区,则将其中标志位置成false 536 SpSystemTrace.isMouseLeftDown = false; 537 } 538 } 539 sp.inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev); 540 //@ts-ignore 541 if ((window as unknown).isSheetMove || sp.isMouseInSheet(ev)) { 542 sp.hoverStructNull(); 543 sp.tipEL!.style.display = 'none'; 544 return; 545 } 546 let isMouseInTimeShaft = handleMouseInTimeShaft(sp, ev); 547 let rows = sp.visibleRows; 548 sp.timerShaftEL?.documentOnMouseMove(ev, sp); 549 550 if (isMouseInTimeShaft) { 551 return; 552 } 553 handleActions(sp, rows, ev); 554} 555 556export function spSystemTraceDocumentOnMouseMoveMouseDown(sp: SpSystemTrace, search: LitSearch): void { 557 sp.refreshCanvas(true, 'sp move down'); 558 if (TraceRow.rangeSelectObject) { 559 if (search && search.searchValue !== '') { 560 search.clear(); 561 search.valueChangeHandler?.(''); 562 } 563 } 564} 565 566function spSystemTraceDocumentOnMouseMoveMouseUp( 567 sp: SpSystemTrace, //@ts-ignore 568 rows: Array<TraceRow<unknown>>, 569 ev: MouseEvent 570): void { 571 if (!sp.rowsPaneEL!.containPoint(ev, { left: 248 })) { 572 sp.hoverStructNull(); 573 } 574 const transformYMatch = sp.canvasPanel?.style.transform.match(/\((\d+)[^\)]+\)/); 575 const transformY = transformYMatch![1]; 576 let favoriteHeight = sp.favoriteChartListEL!.getBoundingClientRect().height; 577 // @ts-ignore 578 let memTr = rows.filter((item: unknown) => item.rowType === TraceRow.ROW_TYPE_MEM); 579 rows 580 .filter((it) => it.focusContain(ev, sp.inFavoriteArea!, Number(transformY), favoriteHeight) && it.collect === sp.inFavoriteArea) 581 .filter((it) => { 582 if (it.collect) { 583 return true; 584 } else { 585 return ( 586 it.getBoundingClientRect().bottom + it.getBoundingClientRect().height > 587 sp.favoriteChartListEL!.getBoundingClientRect().bottom 588 ); 589 } 590 }) 591 .forEach((tr): void => { 592 if (tr.rowType !== TraceRow.ROW_TYPE_CPU) { 593 CpuStruct.hoverCpuStruct = undefined; 594 } 595 if (tr.rowType !== TraceRow.ROW_TYPE_MEM) { 596 ProcessMemStruct.hoverProcessMemStruct = undefined; 597 memTr.forEach((i: unknown) => { 598 // @ts-ignore 599 i.focusHandler(ev); 600 }); 601 } 602 if (sp.currentRowType !== tr.rowType) { 603 sp.currentRowType = tr.rowType || ''; 604 } 605 tr.findHoverStruct?.(); 606 tr.focusHandler?.(ev); 607 }); 608 requestAnimationFrame(() => sp.refreshCanvas(true, 'sp move up')); 609} 610 611export function spSystemTraceDocumentOnMouseOut(sp: SpSystemTrace, ev: MouseEvent): void { 612 if (!sp.loadTraceCompleted) { 613 return; 614 } 615 CpuStruct.hoverCpuStruct = undefined; 616 TraceRow.isUserInteraction = false; 617 SpSystemTrace.isMouseLeftDown = false; 618 if (!sp.keyboardEnable) { 619 return; 620 } 621 if (sp.isMouseInSheet(ev)) { 622 return; 623 } 624 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 625 sp.rangeSelect.mouseOut(ev); 626 sp.timerShaftEL?.documentOnMouseOut(ev); 627 } 628} 629 630export function spSystemTraceDocumentOnKeyPress(this: unknown, sp: SpSystemTrace, ev: KeyboardEvent): void { 631 if (!sp.loadTraceCompleted || SpSystemTrace.isAiAsk) { 632 return; 633 } 634 let keyPress = ev.key.toLocaleLowerCase(); 635 TraceRow.isUserInteraction = true; 636 if (sp.isMousePointInSheet) { 637 return; 638 } 639 sp.observerScrollHeightEnable = false; 640 if (sp.keyboardEnable) { 641 if (keyPress === 'm') { 642 if (sp.selectFlag) { 643 sp.selectFlag!.selected = false; 644 } 645 sp.slicestime = sp.setSLiceMark(ev.shiftKey); 646 if (sp.slicestime) { 647 if (TraceRow.rangeSelectObject) { 648 let showTab = sp.getShowTab(); 649 sp.traceSheetEL 650 ?.displayTab<TabPaneCurrent>('tabpane-current', ...showTab) 651 .setCurrentSlicesTime(sp.slicestime); 652 } else { 653 sp.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current').setCurrentSlicesTime(sp.slicestime); 654 } 655 } 656 } 657 if (keyPress === 'f') { 658 let search = document.querySelector('body > sp-application')!.shadowRoot!.querySelector<LitSearch>('#lit-search'); 659 if (search && search.searchValue !== '' && sp.currentRow !== undefined) { 660 sp.copyCurrentRow = sp.currentRow; 661 sp.currentRow = undefined; 662 } 663 let isSelectSliceOrFlag = false; 664 // 设置当前选中的slicetime 665 let selectSlice: unknown = undefined; 666 sp._slicesList.forEach((slice: { selected: boolean }): void => { 667 if (slice.selected) { 668 selectSlice = slice; 669 } 670 }); 671 if (!!selectSlice) { 672 //@ts-ignore 673 sp.currentSlicesTime.startTime = selectSlice.startTime; 674 //@ts-ignore 675 sp.currentSlicesTime.endTime = selectSlice.endTime; 676 isSelectSliceOrFlag = true; 677 } 678 679 if (sp.selectFlag && sp.selectFlag.selected) { 680 sp.currentSlicesTime.startTime = sp.selectFlag?.time; 681 sp.currentSlicesTime.endTime = sp.selectFlag?.time; 682 isSelectSliceOrFlag = true; 683 } 684 // 设置当前的slicesTime 685 !isSelectSliceOrFlag && sp.setCurrentSlicesTime(); 686 } 687 let keyPressWASD = keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd'; 688 if (keyPressWASD) { 689 sp.keyPressMap.set(keyPress, true); 690 if (sp.rangeSelect.isMouseDown && sp.rangeSelect.drag) { 691 sp.rangeSelect.mouseUp(); 692 } 693 sp.hoverFlag = null; 694 } 695 sp.timerShaftEL!.documentOnKeyPress(ev, sp.currentSlicesTime); 696 if (keyPress === 'f') { 697 sp.verticalScrollToRow(); 698 } 699 } else { 700 sp.stopWASD(); 701 } 702} 703 704export function spSystemTraceDocumentOnMouseDown(sp: SpSystemTrace, ev: MouseEvent): void { 705 if (!sp.loadTraceCompleted || !sp.mouseEventEnable) { 706 return; 707 } 708 if (sp.isWASDKeyPress()) { 709 ev.preventDefault(); 710 ev.stopPropagation(); 711 return; 712 } 713 if (ev.button === 0) { 714 SpSystemTrace.isMouseLeftDown = true; 715 if (ev.ctrlKey) { 716 ev.preventDefault(); 717 sp.style.cursor = 'move'; 718 sp.mouseCurrentPosition = ev.clientX; 719 return; 720 } 721 } 722 723 TraceRow.isUserInteraction = true; 724 if (sp.isMouseInSheet(ev)) { 725 return; 726 } 727 sp.observerScrollHeightEnable = false; 728 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 729 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 730 let y = ev.offsetY; 731 sp.timerShaftEL?.documentOnMouseDown(ev); 732 if (y > sp.timerShaftEL!.offsetHeight) { 733 sp.rangeSelect.mouseDown(ev); 734 sp.rangeSelect.drag = true; 735 let downRow = sp.visibleRows.find((row) => row.containPoint(ev)); 736 Utils.currentSelectTrace = downRow?.traceId; 737 } 738 // 如果鼠标摁下事件发生在traceRow范围或时间轴(sportRuler除外)范围内,清除上次点击调用栈产生的所有的三角旗子 739 // ev.offsetY:鼠标在SpSystemTrace元素的y轴偏移量 740 if ( 741 ev.offsetY > sp.timerShaftEL!.clientHeight || 742 ev.offsetY < sp.timerShaftEL!.clientHeight - sp.timerShaftEL!.sportRuler!.frame.height 743 ) { 744 sp.clearTriangle(sp.timerShaftEL!.sportRuler!.flagList); 745 } 746 } else { 747 sp.rangeSelect.drag = false; 748 } 749} 750 751function handleTimerShaftActions(ev: MouseEvent, sp: SpSystemTrace): void { 752 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 753 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 754 let y = ev.offsetY; 755 if ( 756 sp.timerShaftEL!.sportRuler!.frame.contains(x, y) && 757 x > (TraceRow.rangeSelectObject?.startX || 0) && 758 x < (TraceRow.rangeSelectObject?.endX || 0) 759 ) { 760 let findSlicestime = sp.timerShaftEL!.sportRuler?.findSlicesTime(x, y); // 查找帽子 761 if (!findSlicestime) { 762 // 如果没有找到帽子,则绘制一个旗子 763 let time = Math.round( 764 (x * (TraceRow.range?.endNS! - TraceRow.range?.startNS!)) / sp.timerShaftEL!.canvas!.offsetWidth + 765 TraceRow.range?.startNS! 766 ); 767 sp.timerShaftEL!.sportRuler!.drawTriangle(time, 'squre'); 768 } 769 } 770 } 771} 772 773export function spSystemTraceDocumentOnMouseUp(sp: SpSystemTrace, ev: MouseEvent): void { 774 //@ts-ignore 775 if ((window as unknown).collectResize) { 776 return; 777 } 778 if (!sp.loadTraceCompleted || !sp.mouseEventEnable) { 779 return; 780 } 781 //@ts-ignore 782 if ((window as unknown).isSheetMove) { 783 return; 784 } 785 if (sp.isWASDKeyPress()) { 786 ev.preventDefault(); 787 ev.stopPropagation(); 788 return; 789 } 790 SpSystemTrace.isMouseLeftDown = false; 791 if (ev.ctrlKey) { 792 ev.preventDefault(); 793 sp.offsetMouse = 0; 794 sp.mouseCurrentPosition = 0; 795 sp.style.cursor = 'default'; 796 return; 797 } 798 TraceRow.isUserInteraction = false; 799 sp.rangeSelect.isMouseDown = false; 800 if (sp.isMouseInSheet(ev)) { 801 return; 802 } 803 handleTimerShaftActions(ev, sp); 804 if (!SportRuler.isMouseInSportRuler) { 805 sp.rangeSelect.mouseUp(ev); 806 } 807 sp.timerShaftEL?.documentOnMouseUp(ev); 808} 809 810export function spSystemTraceDocumentOnKeyUp(sp: SpSystemTrace, ev: KeyboardEvent): void { 811 if (SpSystemTrace.isAiAsk) { 812 return; 813 } 814 if (sp.times.size > 0) { 815 for (let timerId of sp.times) { 816 clearTimeout(timerId); 817 } 818 } 819 if (!sp.keyboardEnable) { 820 return; 821 } 822 let recordTraceElement = sp.parentElement?.querySelector('sp-record-trace'); 823 let menuItemElement = recordTraceElement?.shadowRoot?.querySelector('lit-main-menu-item[icon="file-config"]'); 824 let flag: boolean = menuItemElement ? menuItemElement.hasAttribute('back') : false; 825 if (ev.key.toLocaleLowerCase() === String.fromCharCode(47) && !flag && !SpSystemTrace.isAiAsk) { 826 if (SpSystemTrace.keyboardFlar) { 827 document 828 .querySelector('body > sp-application')! 829 .shadowRoot!.querySelector<SpKeyboard>('#sp-keyboard')!.style.visibility = 'visible'; 830 SpSystemTrace.keyboardFlar = false; 831 } else { 832 document 833 .querySelector('body > sp-application')! 834 .shadowRoot!.querySelector<SpKeyboard>('#sp-keyboard')!.style.visibility = 'hidden'; 835 SpSystemTrace.keyboardFlar = true; 836 } 837 } 838 if (!sp.loadTraceCompleted) { 839 return; 840 } 841 let flagsItem = window.localStorage.getItem(FlagsConfig.FLAGS_CONFIG_KEY); 842 let flagsItemJson = JSON.parse(flagsItem!); 843 if (flagsItemJson.VSync === 'Enabled') { 844 enableVSync(false, ev, () => sp.refreshCanvas(true, 'sp key up')); 845 } 846 let keyPress = ev.key.toLocaleLowerCase(); 847 if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') { 848 sp.keyPressMap.set(keyPress, false); 849 } 850 if (keyPress === 'f' && sp.copyCurrentRow) { 851 sp.currentRow = sp.copyCurrentRow; 852 } 853 TraceRow.isUserInteraction = false; 854 sp.observerScrollHeightEnable = false; 855 sp.keyboardEnable && sp.timerShaftEL!.documentOnKeyUp(ev); 856 if (ev.code === 'Enter' || ev.code === 'NumpadEnter') { 857 document.removeEventListener('keydown', sp.documentOnKeyDown); 858 if (ev.shiftKey) { 859 sp.dispatchEvent( 860 new CustomEvent('trace-previous-data', { 861 detail: {}, 862 composed: false, 863 }) 864 ); 865 } else { 866 sp.dispatchEvent( 867 new CustomEvent('trace-next-data', { 868 detail: {}, 869 composed: false, 870 }) 871 ); 872 } 873 document.addEventListener('keydown', sp.documentOnKeyDown); 874 } 875 876 if (ev.ctrlKey) { 877 spSystemTraceDocumentOnKeyUpCtrlKey(keyPress, sp, ev); 878 } 879} 880 881function spSystemTraceDocumentOnKeyUpCtrlKey(keyPress: string, sp: SpSystemTrace, ev: KeyboardEvent): void { 882 if (keyPress === 'b') { 883 let menuBox = document 884 .querySelector('body > sp-application')! 885 .shadowRoot?.querySelector('#main-menu') as LitMainMenu; 886 let searchBox = document 887 .querySelector('body > sp-application') 888 ?.shadowRoot?.querySelector('div > div.search-vessel') as HTMLDivElement; 889 let appContent = document 890 .querySelector('body > sp-application') 891 ?.shadowRoot?.querySelector('div > #app-content') as HTMLDivElement; 892 let rowPane = appContent 893 ?.querySelector('#sp-system-trace') 894 ?.shadowRoot?.querySelector('div > div.rows-pane') as HTMLDivElement; 895 let timerShaft = appContent 896 ?.querySelector('#sp-system-trace') 897 ?.shadowRoot?.querySelector('div > timer-shaft-element') as HTMLDivElement; 898 let spChartList = appContent 899 ?.querySelector('#sp-system-trace') 900 ?.shadowRoot?.querySelector('div > sp-chart-list') as HTMLDivElement; 901 let canvasEle = spChartList.shadowRoot?.querySelector('canvas') as unknown as HTMLDivElement; 902 let sidebarButton = searchBox!.querySelector('div > div.sidebar-button') as HTMLDivElement; 903 let importConfigDiv = searchBox!.querySelector('div > #import-key-path') as HTMLDivElement; 904 if (menuBox.style.zIndex! === '2000' || searchBox!.style.display !== 'none') { 905 SpSystemTrace.isHiddenMenu = true; 906 menuBox.style.width = '0px'; 907 menuBox.style.display = 'flex'; 908 menuBox.style.zIndex = '0'; 909 sidebarButton.style.width = '48px'; 910 importConfigDiv!.style.left = '45px'; 911 searchBox!.style.display = 'none'; 912 rowPane.style.maxHeight = '100%'; 913 } else { 914 SpSystemTrace.isHiddenMenu = false; 915 menuBox.style.width = '248px'; 916 menuBox.style.zIndex = '2000'; 917 menuBox.style.display = 'flex'; 918 sidebarButton.style.width = '0px'; 919 importConfigDiv!.style.left = '5px'; 920 searchBox!.style.display = ''; 921 rowPane.style.maxHeight = '100%'; 922 } 923 } 924 if (keyPress === '[' && sp._slicesList.length > 1) { 925 sp.selectFlag = undefined; 926 sp.MarkJump(sp._slicesList, 'slice', 'previous', ev); 927 } else if (keyPress === ',' && sp._flagList.length > 1) { 928 sp.MarkJump(sp._flagList, 'flag', 'previous', ev); 929 } else if (keyPress === ']' && sp._slicesList.length > 1) { 930 sp.selectFlag = undefined; 931 sp.MarkJump(sp._slicesList, 'slice', 'next', ev); 932 } else if (keyPress === '.' && sp._flagList.length > 1) { 933 sp.MarkJump(sp._flagList, 'flag', 'next', ev); 934 } else { 935 return; 936 } 937} 938 939function handleClickActions(sp: SpSystemTrace, x: number, y: number, ev: MouseEvent): void { 940 if ( 941 !( 942 sp.timerShaftEL!.sportRuler!.frame.contains(x, y) && 943 x > (TraceRow.rangeSelectObject?.startX || 0) && 944 x < (TraceRow.rangeSelectObject?.endX || 0) 945 ) 946 ) { 947 const transformYMatch = sp.canvasPanel?.style.transform.match(/\((\d+)[^\)]+\)/); 948 const transformY = transformYMatch![1]; 949 let inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev); 950 let favoriteHeight = sp.favoriteChartListEL!.getBoundingClientRect().height; 951 let rows = sp.visibleRows.filter((it) => 952 it.focusContain(ev, inFavoriteArea!, Number(transformY), favoriteHeight) && it.collect === inFavoriteArea); 953 if (JankStruct.delJankLineFlag) { 954 sp.removeLinkLinesByBusinessType('janks'); 955 } 956 let strict = true; 957 let offset = false; 958 if ( 959 rows[0] && 960 (rows[0].rowType === TraceRow.ROW_TYPE_FRAME_DYNAMIC || rows[0].rowType === TraceRow.ROW_TYPE_FRAME_SPACING) 961 ) { 962 strict = false; 963 offset = true; 964 } 965 let skip = false; 966 if ( 967 rows[0].rowType === TraceRow.ROW_TYPE_XPOWER_WIFI_BYTES || 968 rows[0].rowType === TraceRow.ROW_TYPE_XPOWER_WIFI_PACKETS || 969 rows[0].rowType === TraceRow.ROW_TYPE_XPOWER_APP_DETAIL_DISPLAY || 970 rows[0].rowType === TraceRow.ROW_TYPE_XPOWER_STATISTIC 971 ) { 972 skip = true; 973 } 974 if (rows && rows[0] && (rows[0].getHoverStruct(strict, offset) || 975 (rows[0].rowType === TraceRow.ROW_TYPE_GPU_COUNTER && rows[0].getHoverStruct(false) || skip)) 976 ) { 977 sp.onClickHandler(rows[0]!.rowType!, rows[0], rows[0].getHoverStruct(strict, offset)); 978 sp.documentOnMouseMove(ev); 979 } else { 980 sp.clickEmptyArea(); 981 } 982 } 983} 984 985export function spSystemTraceDocumentOnClick(sp: SpSystemTrace, ev: MouseEvent): void { 986 if (!sp.loadTraceCompleted) { 987 return; 988 } 989 if (sp.isWASDKeyPress()) { 990 sp.hoverFlag = null; 991 ev.preventDefault(); 992 ev.stopPropagation(); 993 return; 994 } 995 //@ts-ignore 996 if ((window as unknown).isSheetMove) { 997 return; 998 } 999 if (sp.isMouseInSheet(ev)) { 1000 return; 1001 } 1002 //@ts-ignore 1003 if ((window as unknown).isPackUpTable) { 1004 //@ts-ignore 1005 (window as unknown).isPackUpTable = false; 1006 return; 1007 } 1008 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 1009 let y = ev.offsetY; 1010 if (sp.timerShaftEL?.getRangeRuler()?.frame.contains(x, y)) { 1011 sp.clickEmptyArea(); 1012 return; 1013 } 1014 if (sp.rangeSelect.isDrag()) { 1015 return; 1016 } 1017 handleClickActions(sp, x, y, ev); 1018 ev.preventDefault(); 1019} 1020 1021export function spSystemTraceDocumentOnKeyDown(sp: SpSystemTrace, ev: KeyboardEvent): void { 1022 document.removeEventListener('keyup', sp.documentOnKeyUp); 1023 sp.debounce(sp.continueSearch, 250, ev)(); 1024 document.addEventListener('keyup', sp.documentOnKeyUp); 1025} 1026