'a'
mh-two-thousand-and-two
2024-04-12 44d2c92345cd156a59fc327b3060292a282d2893
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
Coverage.RangeUseCount;Coverage.CoverageSegment;Coverage.CoverageType={CSS:(1<<0),JavaScript:(1<<1),JavaScriptCoarse:(1<<2),};Coverage.CoverageModel=class extends SDK.SDKModel{constructor(target){super(target);this._cpuProfilerModel=target.model(SDK.CPUProfilerModel);this._cssModel=target.model(SDK.CSSModel);this._debuggerModel=target.model(SDK.DebuggerModel);this._coverageByURL=new Map();this._coverageByContentProvider=new Map();this._bestEffortCoveragePromise=null;}
start(){if(this._cssModel){this._clearCSS();this._cssModel.startCoverage();}
if(this._cpuProfilerModel){this._bestEffortCoveragePromise=this._cpuProfilerModel.bestEffortCoverage();this._cpuProfilerModel.startPreciseCoverage();}
return!!(this._cssModel||this._cpuProfilerModel);}
stop(){const pollPromise=this.poll();if(this._cpuProfilerModel)
this._cpuProfilerModel.stopPreciseCoverage();if(this._cssModel)
this._cssModel.stopCoverage();return pollPromise;}
reset(){this._coverageByURL=new Map();this._coverageByContentProvider=new Map();}
async poll(){const updates=await Promise.all([this._takeCSSCoverage(),this._takeJSCoverage()]);return updates[0].concat(updates[1]);}
entries(){return Array.from(this._coverageByURL.values());}
usageForRange(contentProvider,startOffset,endOffset){const coverageInfo=this._coverageByContentProvider.get(contentProvider);return coverageInfo&&coverageInfo.usageForRange(startOffset,endOffset);}
_clearCSS(){for(const entry of this._coverageByContentProvider.values()){if(entry.type()!==Coverage.CoverageType.CSS)
continue;const contentProvider=(entry.contentProvider());this._coverageByContentProvider.delete(contentProvider);const key=`${contentProvider.startLine}:${contentProvider.startColumn}`;const urlEntry=this._coverageByURL.get(entry.url());if(!urlEntry||!urlEntry._coverageInfoByLocation.delete(key))
continue;urlEntry._size-=entry._size;urlEntry._usedSize-=entry._usedSize;if(!urlEntry._coverageInfoByLocation.size)
this._coverageByURL.delete(entry.url());}}
async _takeJSCoverage(){if(!this._cpuProfilerModel)
return[];let rawCoverageData=await this._cpuProfilerModel.takePreciseCoverage();if(this._bestEffortCoveragePromise){const bestEffortCoverage=await this._bestEffortCoveragePromise;this._bestEffortCoveragePromise=null;rawCoverageData=bestEffortCoverage.concat(rawCoverageData);}
return this._processJSCoverage(rawCoverageData);}
_processJSCoverage(scriptsCoverage){const updatedEntries=[];for(const entry of scriptsCoverage){const script=this._debuggerModel.scriptForId(entry.scriptId);if(!script)
continue;const ranges=[];let type=Coverage.CoverageType.JavaScript;for(const func of entry.functions){if(func.isBlockCoverage===false&&!(func.ranges.length===1&&!func.ranges[0].count))
type|=Coverage.CoverageType.JavaScriptCoarse;for(const range of func.ranges)
ranges.push(range);}
const subentry=this._addCoverage(script,script.contentLength,script.lineOffset,script.columnOffset,ranges,type);if(subentry)
updatedEntries.push(subentry);}
return updatedEntries;}
async _takeCSSCoverage(){if(!this._cssModel)
return[];const rawCoverageData=await this._cssModel.takeCoverageDelta();return this._processCSSCoverage(rawCoverageData);}
_processCSSCoverage(ruleUsageList){const updatedEntries=[];const rulesByStyleSheet=new Map();for(const rule of ruleUsageList){const styleSheetHeader=this._cssModel.styleSheetHeaderForId(rule.styleSheetId);if(!styleSheetHeader)
continue;let ranges=rulesByStyleSheet.get(styleSheetHeader);if(!ranges){ranges=[];rulesByStyleSheet.set(styleSheetHeader,ranges);}
ranges.push({startOffset:rule.startOffset,endOffset:rule.endOffset,count:Number(rule.used)});}
for(const entry of rulesByStyleSheet){const styleSheetHeader=(entry[0]);const ranges=(entry[1]);const subentry=this._addCoverage(styleSheetHeader,styleSheetHeader.contentLength,styleSheetHeader.startLine,styleSheetHeader.startColumn,ranges,Coverage.CoverageType.CSS);if(subentry)
updatedEntries.push(subentry);}
return updatedEntries;}
static _convertToDisjointSegments(ranges){ranges.sort((a,b)=>a.startOffset-b.startOffset);const result=[];const stack=[];for(const entry of ranges){let top=stack.peekLast();while(top&&top.endOffset<=entry.startOffset){append(top.endOffset,top.count);stack.pop();top=stack.peekLast();}
append(entry.startOffset,top?top.count:undefined);stack.push(entry);}
while(stack.length){const top=stack.pop();append(top.endOffset,top.count);}
function append(end,count){const last=result.peekLast();if(last){if(last.end===end)
return;if(last.count===count){last.end=end;return;}}
result.push({end:end,count:count});}
return result;}
_addCoverage(contentProvider,contentLength,startLine,startColumn,ranges,type){const url=contentProvider.contentURL();if(!url)
return null;let urlCoverage=this._coverageByURL.get(url);if(!urlCoverage){urlCoverage=new Coverage.URLCoverageInfo(url);this._coverageByURL.set(url,urlCoverage);}
const coverageInfo=urlCoverage._ensureEntry(contentProvider,contentLength,startLine,startColumn,type);this._coverageByContentProvider.set(contentProvider,coverageInfo);const segments=Coverage.CoverageModel._convertToDisjointSegments(ranges);if(segments.length&&segments.peekLast().end<contentLength)
segments.push({end:contentLength});const oldUsedSize=coverageInfo._usedSize;coverageInfo.mergeCoverage(segments);if(coverageInfo._usedSize===oldUsedSize)
return null;urlCoverage._usedSize+=coverageInfo._usedSize-oldUsedSize;return coverageInfo;}};Coverage.URLCoverageInfo=class{constructor(url){this._url=url;this._coverageInfoByLocation=new Map();this._size=0;this._usedSize=0;this._type;this._isContentScript=false;}
url(){return this._url;}
type(){return this._type;}
size(){return this._size;}
usedSize(){return this._usedSize;}
unusedSize(){return this._size-this._usedSize;}
isContentScript(){return this._isContentScript;}
_ensureEntry(contentProvider,contentLength,lineOffset,columnOffset,type){const key=`${lineOffset}:${columnOffset}`;let entry=this._coverageInfoByLocation.get(key);if((type&Coverage.CoverageType.JavaScript)&&!this._coverageInfoByLocation.size)
this._isContentScript=(contentProvider).isContentScript();this._type|=type;if(entry){entry._coverageType|=type;return entry;}
if((type&Coverage.CoverageType.JavaScript)&&!this._coverageInfoByLocation.size)
this._isContentScript=(contentProvider).isContentScript();entry=new Coverage.CoverageInfo(contentProvider,contentLength,type);this._coverageInfoByLocation.set(key,entry);this._size+=contentLength;return entry;}};Coverage.CoverageInfo=class{constructor(contentProvider,size,type){this._contentProvider=contentProvider;this._size=size;this._usedSize=0;this._coverageType=type;this._segments=[];}
contentProvider(){return this._contentProvider;}
url(){return this._contentProvider.contentURL();}
type(){return this._coverageType;}
mergeCoverage(segments){this._segments=Coverage.CoverageInfo._mergeCoverage(this._segments,segments);this._updateStats();}
usageForRange(start,end){let index=this._segments.upperBound(start,(position,segment)=>position-segment.end);for(;index<this._segments.length&&this._segments[index].end<end;++index){if(this._segments[index].count)
return true;}
return index<this._segments.length&&!!this._segments[index].count;}
static _mergeCoverage(segmentsA,segmentsB){const result=[];let indexA=0;let indexB=0;while(indexA<segmentsA.length&&indexB<segmentsB.length){const a=segmentsA[indexA];const b=segmentsB[indexB];const count=typeof a.count==='number'||typeof b.count==='number'?(a.count||0)+(b.count||0):undefined;const end=Math.min(a.end,b.end);const last=result.peekLast();if(!last||last.count!==count)
result.push({end:end,count:count});else
last.end=end;if(a.end<=b.end)
indexA++;if(a.end>=b.end)
indexB++;}
for(;indexA<segmentsA.length;indexA++)
result.push(segmentsA[indexA]);for(;indexB<segmentsB.length;indexB++)
result.push(segmentsB[indexB]);return result;}
_updateStats(){this._usedSize=0;let last=0;for(const segment of this._segments){if(segment.count)
this._usedSize+=segment.end-last;last=segment.end;}}};;Coverage.CoverageListView=class extends UI.VBox{constructor(filterCallback){super(true);this._nodeForCoverageInfo=new Map();this._filterCallback=filterCallback;this._highlightRegExp=null;this.registerRequiredCSS('coverage/coverageListView.css');const columns=[{id:'url',title:Common.UIString('URL'),width:'250px',fixedWidth:false,sortable:true},{id:'type',title:Common.UIString('Type'),width:'45px',fixedWidth:true,sortable:true},{id:'size',title:Common.UIString('Total Bytes'),width:'60px',fixedWidth:true,sortable:true,align:DataGrid.DataGrid.Align.Right},{id:'unusedSize',title:Common.UIString('Unused Bytes'),width:'100px',fixedWidth:true,sortable:true,align:DataGrid.DataGrid.Align.Right,sort:DataGrid.DataGrid.Order.Descending},{id:'bars',title:'',width:'250px',fixedWidth:false,sortable:true}];this._dataGrid=new DataGrid.SortableDataGrid(columns);this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);this._dataGrid.element.classList.add('flex-auto');this._dataGrid.element.addEventListener('keydown',this._onKeyDown.bind(this),false);this._dataGrid.addEventListener(DataGrid.DataGrid.Events.OpenedNode,this._onOpenedNode,this);this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged,this._sortingChanged,this);const dataGridWidget=this._dataGrid.asWidget();dataGridWidget.show(this.contentElement);}
update(coverageInfo){let hadUpdates=false;const maxSize=coverageInfo.reduce((acc,entry)=>Math.max(acc,entry.size()),0);const rootNode=this._dataGrid.rootNode();for(const entry of coverageInfo){let node=this._nodeForCoverageInfo.get(entry);if(node){if(this._filterCallback(node._coverageInfo))
hadUpdates=node._refreshIfNeeded(maxSize)||hadUpdates;continue;}
node=new Coverage.CoverageListView.GridNode(entry,maxSize);this._nodeForCoverageInfo.set(entry,node);if(this._filterCallback(node._coverageInfo)){rootNode.appendChild(node);hadUpdates=true;}}
if(hadUpdates)
this._sortingChanged();}
reset(){this._nodeForCoverageInfo.clear();this._dataGrid.rootNode().removeChildren();}
updateFilterAndHighlight(highlightRegExp){this._highlightRegExp=highlightRegExp;let hadTreeUpdates=false;for(const node of this._nodeForCoverageInfo.values()){const shouldBeVisible=this._filterCallback(node._coverageInfo);const isVisible=!!node.parent;if(shouldBeVisible)
node._setHighlight(this._highlightRegExp);if(shouldBeVisible===isVisible)
continue;hadTreeUpdates=true;if(!shouldBeVisible)
node.remove();else
this._dataGrid.rootNode().appendChild(node);}
if(hadTreeUpdates)
this._sortingChanged();}
_onOpenedNode(){this._revealSourceForSelectedNode();}
_onKeyDown(event){if(!isEnterKey(event))
return;event.consume(true);this._revealSourceForSelectedNode();}
async _revealSourceForSelectedNode(){const node=this._dataGrid.selectedNode;if(!node)
return;const coverageInfo=(node)._coverageInfo;let sourceCode=Workspace.workspace.uiSourceCodeForURL(coverageInfo.url());if(!sourceCode)
return;const content=await sourceCode.requestContent();if(TextUtils.isMinified(content)){const formatData=await Sources.sourceFormatter.format(sourceCode);sourceCode=formatData.formattedSourceCode;}
if(this._dataGrid.selectedNode!==node)
return;Common.Revealer.reveal(sourceCode);}
_sortingChanged(){const columnId=this._dataGrid.sortColumnId();if(!columnId)
return;let sortFunction;switch(columnId){case'url':sortFunction=compareURL;break;case'type':sortFunction=compareType;break;case'size':sortFunction=compareNumericField.bind(null,'size');break;case'bars':case'unusedSize':sortFunction=compareNumericField.bind(null,'unusedSize');break;default:console.assert(false,'Unknown sort field: '+columnId);return;}
this._dataGrid.sortNodes(sortFunction,!this._dataGrid.isSortOrderAscending());function compareURL(a,b){const nodeA=(a);const nodeB=(b);return nodeA._url.localeCompare(nodeB._url);}
function compareNumericField(fieldName,a,b){const nodeA=(a);const nodeB=(b);return nodeA._coverageInfo[fieldName]()-nodeB._coverageInfo[fieldName]()||compareURL(a,b);}
function compareType(a,b){const nodeA=(a);const nodeB=(b);const typeA=Coverage.CoverageListView._typeToString(nodeA._coverageInfo.type());const typeB=Coverage.CoverageListView._typeToString(nodeB._coverageInfo.type());return typeA.localeCompare(typeB)||compareURL(a,b);}}
static _typeToString(type){const types=[];if(type&Coverage.CoverageType.CSS)
types.push(Common.UIString('CSS'));if(type&Coverage.CoverageType.JavaScriptCoarse)
types.push(Common.UIString('JS (coarse)'));else if(type&Coverage.CoverageType.JavaScript)
types.push(Common.UIString('JS'));return types.join('+');}};Coverage.CoverageListView.GridNode=class extends DataGrid.SortableDataGridNode{constructor(coverageInfo,maxSize){super();this._coverageInfo=coverageInfo;this._lastUsedSize;this._url=coverageInfo.url();this._maxSize=maxSize;this._highlightDOMChanges=[];this._highlightRegExp=null;}
_setHighlight(highlightRegExp){if(this._highlightRegExp===highlightRegExp)
return;this._highlightRegExp=highlightRegExp;this.refresh();}
_refreshIfNeeded(maxSize){if(this._lastUsedSize===this._coverageInfo.usedSize()&&maxSize===this._maxSize)
return false;this._lastUsedSize=this._coverageInfo.usedSize();this._maxSize=maxSize;this.refresh();return true;}
createCell(columnId){const cell=this.createTD(columnId);switch(columnId){case'url':cell.title=this._url;const outer=cell.createChild('div','url-outer');const prefix=outer.createChild('div','url-prefix');const suffix=outer.createChild('div','url-suffix');const splitURL=/^(.*)(\/[^/]*)$/.exec(this._url);prefix.textContent=splitURL?splitURL[1]:this._url;suffix.textContent=splitURL?splitURL[2]:'';if(this._highlightRegExp)
this._highlight(outer,this._url);break;case'type':cell.textContent=Coverage.CoverageListView._typeToString(this._coverageInfo.type());if(this._coverageInfo.type()&Coverage.CoverageType.JavaScriptCoarse)
cell.title=Common.UIString('JS coverage is function-level only. Reload the page for block-level coverage.');break;case'size':cell.textContent=Number.withThousandsSeparator(this._coverageInfo.size()||0);break;case'unusedSize':const unusedSize=this._coverageInfo.unusedSize()||0;const unusedSizeSpan=cell.createChild('span');const unusedPercentsSpan=cell.createChild('span','percent-value');unusedSizeSpan.textContent=Number.withThousandsSeparator(unusedSize);unusedPercentsSpan.textContent=Common.UIString('%.1f\xa0%%',unusedSize/this._coverageInfo.size()*100);break;case'bars':const barContainer=cell.createChild('div','bar-container');const unusedSizeBar=barContainer.createChild('div','bar bar-unused-size');unusedSizeBar.style.width=(100*this._coverageInfo.unusedSize()/this._maxSize).toFixed(4)+'%';const usedSizeBar=barContainer.createChild('div','bar bar-used-size');usedSizeBar.style.width=(100*this._coverageInfo.usedSize()/this._maxSize).toFixed(4)+'%';}
return cell;}
_highlight(element,textContent){const matches=this._highlightRegExp.exec(textContent);if(!matches||!matches.length)
return;const range=new TextUtils.SourceRange(matches.index,matches[0].length);UI.highlightRangesWithStyleClass(element,[range],'filter-highlight');}};;Coverage.CoverageView=class extends UI.VBox{constructor(){super(true);this._model=null;this._pollTimer;this._decorationManager=null;this._resourceTreeModel=null;this.registerRequiredCSS('coverage/coverageView.css');const toolbarContainer=this.contentElement.createChild('div','coverage-toolbar-container');const toolbar=new UI.Toolbar('coverage-toolbar',toolbarContainer);this._toggleRecordAction=(UI.actionRegistry.action('coverage.toggle-recording'));this._toggleRecordButton=UI.Toolbar.createActionButton(this._toggleRecordAction);toolbar.appendToolbarItem(this._toggleRecordButton);const mainTarget=SDK.targetManager.mainTarget();if(mainTarget&&mainTarget.model(SDK.ResourceTreeModel)){const startWithReloadAction=(UI.actionRegistry.action('coverage.start-with-reload'));this._startWithReloadButton=UI.Toolbar.createActionButton(startWithReloadAction);toolbar.appendToolbarItem(this._startWithReloadButton);}
this._clearButton=new UI.ToolbarButton(Common.UIString('Clear all'),'largeicon-clear');this._clearButton.addEventListener(UI.ToolbarButton.Events.Click,this._clear.bind(this));toolbar.appendToolbarItem(this._clearButton);this._textFilterRegExp=null;toolbar.appendSeparator();this._filterInput=new UI.ToolbarInput(Common.UIString('URL filter'),0.4,1);this._filterInput.setEnabled(false);this._filterInput.addEventListener(UI.ToolbarInput.Event.TextChanged,this._onFilterChanged,this);toolbar.appendToolbarItem(this._filterInput);toolbar.appendSeparator();this._showContentScriptsSetting=Common.settings.createSetting('showContentScripts',false);this._showContentScriptsSetting.addChangeListener(this._onFilterChanged,this);const contentScriptsCheckbox=new UI.ToolbarSettingCheckbox(this._showContentScriptsSetting,Common.UIString('Include extension content scripts'),Common.UIString('Content scripts'));toolbar.appendToolbarItem(contentScriptsCheckbox);this._coverageResultsElement=this.contentElement.createChild('div','coverage-results');this._landingPage=this._buildLandingPage();this._listView=new Coverage.CoverageListView(this._isVisible.bind(this,false));this._statusToolbarElement=this.contentElement.createChild('div','coverage-toolbar-summary');this._statusMessageElement=this._statusToolbarElement.createChild('div','coverage-message');this._landingPage.show(this._coverageResultsElement);}
_buildLandingPage(){const recordButton=UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));const widget=new UI.VBox();let message;if(this._startWithReloadButton){const reloadButton=UI.createInlineButton(UI.Toolbar.createActionButtonForId('coverage.start-with-reload'));message=UI.formatLocalized('Click the record button %s to start capturing coverage.\n'+'Click the reload button %s to reload and start capturing coverage.',[recordButton,reloadButton]);}else{message=UI.formatLocalized('Click the record button %s to start capturing coverage.',[recordButton]);}
message.classList.add('message');widget.contentElement.appendChild(message);widget.element.classList.add('landing-page');return widget;}
_clear(){this._model=null;this._reset();}
_reset(){if(this._decorationManager){this._decorationManager.dispose();this._decorationManager=null;}
this._listView.reset();this._listView.detach();this._landingPage.show(this._coverageResultsElement);this._statusMessageElement.textContent='';this._filterInput.setEnabled(false);}
_toggleRecording(){const enable=!this._toggleRecordAction.toggled();if(enable)
this._startRecording(false);else
this._stopRecording();}
_startRecording(reload){this._reset();const mainTarget=SDK.targetManager.mainTarget();if(!mainTarget)
return;if(!this._model||reload)
this._model=new Coverage.CoverageModel(mainTarget);Host.userMetrics.actionTaken(Host.UserMetrics.Action.CoverageStarted);if(!this._model.start())
return;this._resourceTreeModel=(mainTarget.model(SDK.ResourceTreeModel));if(this._resourceTreeModel){this._resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated,this._onMainFrameNavigated,this);}
this._decorationManager=new Coverage.CoverageDecorationManager(this._model);this._toggleRecordAction.setToggled(true);this._clearButton.setEnabled(false);if(this._startWithReloadButton)
this._startWithReloadButton.setEnabled(false);this._filterInput.setEnabled(true);if(this._landingPage.isShowing())
this._landingPage.detach();this._listView.show(this._coverageResultsElement);if(reload&&this._resourceTreeModel)
this._resourceTreeModel.reloadPage();else
this._poll();}
async _poll(){delete this._pollTimer;const updates=await this._model.poll();this._updateViews(updates);this._pollTimer=setTimeout(()=>this._poll(),700);}
async _stopRecording(){if(this._pollTimer){clearTimeout(this._pollTimer);delete this._pollTimer;}
if(this._resourceTreeModel){this._resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated,this._onMainFrameNavigated,this);this._resourceTreeModel=null;}
const updatedEntries=await this._model.stop();this._updateViews(updatedEntries);this._toggleRecordAction.setToggled(false);if(this._startWithReloadButton)
this._startWithReloadButton.setEnabled(true);this._clearButton.setEnabled(true);}
_onMainFrameNavigated(){this._model.reset();this._decorationManager.reset();this._listView.reset();this._poll();}
async _updateViews(updatedEntries){this._updateStats();this._listView.update(this._model.entries());this._decorationManager.update(updatedEntries);}
_updateStats(){let total=0;let unused=0;for(const info of this._model.entries()){if(!this._isVisible(true,info))
continue;total+=info.size();unused+=info.unusedSize();}
const percentUnused=total?Math.round(100*unused/total):0;this._statusMessageElement.textContent=Common.UIString('%s of %s bytes are not used. (%d%%)',Number.bytesToString(unused),Number.bytesToString(total),percentUnused);}
_onFilterChanged(){if(!this._listView)
return;const text=this._filterInput.value();this._textFilterRegExp=text?createPlainTextSearchRegex(text,'i'):null;this._listView.updateFilterAndHighlight(this._textFilterRegExp);this._updateStats();}
_isVisible(ignoreTextFilter,coverageInfo){const url=coverageInfo.url();if(url.startsWith(Coverage.CoverageView._extensionBindingsURLPrefix))
return false;if(coverageInfo.isContentScript()&&!this._showContentScriptsSetting.get())
return false;return ignoreTextFilter||!this._textFilterRegExp||this._textFilterRegExp.test(url);}};Coverage.CoverageView._extensionBindingsURLPrefix='extensions::';Coverage.CoverageView.ActionDelegate=class{handleAction(context,actionId){const coverageViewId='coverage';UI.viewManager.showView(coverageViewId).then(()=>UI.viewManager.view(coverageViewId).widget()).then(widget=>this._innerHandleAction((widget),actionId));return true;}
_innerHandleAction(coverageView,actionId){switch(actionId){case'coverage.toggle-recording':coverageView._toggleRecording();break;case'coverage.start-with-reload':coverageView._startRecording(true);break;default:console.assert(false,`Unknown action: ${actionId}`);}}};;Coverage.RawLocation;Coverage.CoverageDecorationManager=class{constructor(coverageModel){this._coverageModel=coverageModel;this._textByProvider=new Map();this._uiSourceCodeByContentProvider=new Multimap();this._documentUISouceCodeToStylesheets=new WeakMap();for(const uiSourceCode of Workspace.workspace.uiSourceCodes())
uiSourceCode.addLineDecoration(0,Coverage.CoverageDecorationManager._decoratorType,this);Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded,this._onUISourceCodeAdded,this);}
reset(){for(const uiSourceCode of Workspace.workspace.uiSourceCodes())
uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager._decoratorType);}
dispose(){this.reset();Workspace.workspace.removeEventListener(Workspace.Workspace.Events.UISourceCodeAdded,this._onUISourceCodeAdded,this);}
update(updatedEntries){for(const entry of updatedEntries){for(const uiSourceCode of this._uiSourceCodeByContentProvider.get(entry.contentProvider())){uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager._decoratorType);uiSourceCode.addLineDecoration(0,Coverage.CoverageDecorationManager._decoratorType,this);}}}
async usageByLine(uiSourceCode){const result=[];const sourceText=new TextUtils.Text(uiSourceCode.content()||'');await this._updateTexts(uiSourceCode,sourceText);const lineEndings=sourceText.lineEndings();for(let line=0;line<sourceText.lineCount();++line){const lineLength=lineEndings[line]-(line?lineEndings[line-1]:0)-1;if(!lineLength){result.push(undefined);continue;}
const startLocations=this._rawLocationsForSourceLocation(uiSourceCode,line,0);const endLocations=this._rawLocationsForSourceLocation(uiSourceCode,line,lineLength);let used=undefined;for(let startIndex=0,endIndex=0;startIndex<startLocations.length;++startIndex){const start=startLocations[startIndex];while(endIndex<endLocations.length&&Coverage.CoverageDecorationManager._compareLocations(start,endLocations[endIndex])>=0)
++endIndex;if(endIndex>=endLocations.length||endLocations[endIndex].id!==start.id)
continue;const end=endLocations[endIndex++];const text=this._textByProvider.get(end.contentProvider);if(!text)
continue;const textValue=text.value();let startOffset=Math.min(text.offsetFromPosition(start.line,start.column),textValue.length-1);let endOffset=Math.min(text.offsetFromPosition(end.line,end.column),textValue.length-1);while(startOffset<=endOffset&&/\s/.test(textValue[startOffset]))
++startOffset;while(startOffset<=endOffset&&/\s/.test(textValue[endOffset]))
--endOffset;if(startOffset<=endOffset)
used=this._coverageModel.usageForRange(end.contentProvider,startOffset,endOffset);if(used)
break;}
result.push(used);}
return result;}
_updateTexts(uiSourceCode,text){const promises=[];for(let line=0;line<text.lineCount();++line){for(const entry of this._rawLocationsForSourceLocation(uiSourceCode,line,0)){if(this._textByProvider.has(entry.contentProvider))
continue;this._textByProvider.set(entry.contentProvider,null);this._uiSourceCodeByContentProvider.set(entry.contentProvider,uiSourceCode);promises.push(this._updateTextForProvider(entry.contentProvider));}}
return Promise.all(promises);}
async _updateTextForProvider(contentProvider){const content=await contentProvider.requestContent();this._textByProvider.set(contentProvider,new TextUtils.Text(content));}
_rawLocationsForSourceLocation(uiSourceCode,line,column){const result=[];const contentType=uiSourceCode.contentType();if(contentType.hasScripts()){let location=Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode,line,column);if(location&&location.script()){const script=location.script();if(script.isInlineScript()&&contentType.isDocument()){if(comparePositions(script.lineOffset,script.columnOffset,location.lineNumber,location.columnNumber)>0||comparePositions(script.endLine,script.endColumn,location.lineNumber,location.columnNumber)<=0){location=null;}else{location.lineNumber-=script.lineOffset;if(!location.lineNumber)
location.columnNumber-=script.columnOffset;}}
if(location){result.push({id:`js:${location.scriptId}`,contentProvider:location.script(),line:location.lineNumber,column:location.columnNumber});}}}
if(contentType.isStyleSheet()||contentType.isDocument()){const rawStyleLocations=contentType.isDocument()?this._documentUILocationToCSSRawLocations(uiSourceCode,line,column):Bindings.cssWorkspaceBinding.uiLocationToRawLocations(new Workspace.UILocation(uiSourceCode,line,column));for(const location of rawStyleLocations){const header=location.header();if(!header)
continue;if(header.isInline&&contentType.isDocument()){location.lineNumber-=header.startLine;if(!location.lineNumber)
location.columnNumber-=header.startColumn;}
result.push({id:`css:${location.styleSheetId}`,contentProvider:location.header(),line:location.lineNumber,column:location.columnNumber});}}
result.sort(Coverage.CoverageDecorationManager._compareLocations);function comparePositions(aLine,aColumn,bLine,bColumn){return aLine-bLine||aColumn-bColumn;}
return result;}
_documentUILocationToCSSRawLocations(uiSourceCode,line,column){let stylesheets=this._documentUISouceCodeToStylesheets.get(uiSourceCode);if(!stylesheets){stylesheets=[];const cssModel=this._coverageModel.target().model(SDK.CSSModel);if(!cssModel)
return[];for(const headerId of cssModel.styleSheetIdsForURL(uiSourceCode.url())){const header=cssModel.styleSheetHeaderForId(headerId);if(header)
stylesheets.push(header);}
stylesheets.sort(stylesheetComparator);this._documentUISouceCodeToStylesheets.set(uiSourceCode,stylesheets);}
const endIndex=stylesheets.upperBound(undefined,(unused,header)=>line-header.startLine||column-header.startColumn);if(!endIndex)
return[];const locations=[];const last=stylesheets[endIndex-1];for(let index=endIndex-1;index>=0&&stylesheets[index].startLine===last.startLine&&stylesheets[index].startColumn===last.startColumn;--index)
locations.push(new SDK.CSSLocation(stylesheets[index],line,column));return locations;function stylesheetComparator(a,b){return a.startLine-b.startLine||a.startColumn-b.startColumn||a.id.localeCompare(b.id);}}
static _compareLocations(a,b){return a.id.localeCompare(b.id)||a.line-b.line||a.column-b.column;}
_onUISourceCodeAdded(event){const uiSourceCode=(event.data);uiSourceCode.addLineDecoration(0,Coverage.CoverageDecorationManager._decoratorType,this);}};Coverage.CoverageDecorationManager._decoratorType='coverage';Coverage.CoverageView.LineDecorator=class{decorate(uiSourceCode,textEditor){const decorations=uiSourceCode.decorationsForType(Coverage.CoverageDecorationManager._decoratorType);if(!decorations||!decorations.size){textEditor.uninstallGutter(Coverage.CoverageView.LineDecorator._gutterType);return;}
const decorationManager=(decorations.values().next().value.data());decorationManager.usageByLine(uiSourceCode).then(lineUsage=>{textEditor.operation(()=>this._innerDecorate(textEditor,lineUsage));});}
_innerDecorate(textEditor,lineUsage){const gutterType=Coverage.CoverageView.LineDecorator._gutterType;textEditor.uninstallGutter(gutterType);textEditor.installGutter(gutterType,false);for(let line=0;line<lineUsage.length;++line){if(typeof lineUsage[line]!=='boolean')
continue;const className=lineUsage[line]?'text-editor-coverage-used-marker':'text-editor-coverage-unused-marker';textEditor.setGutterDecoration(line,gutterType,createElementWithClass('div',className));}}};Coverage.CoverageView.LineDecorator._gutterType='CodeMirror-gutter-coverage';;Runtime.cachedResources["coverage/coverageListView.css"]=".data-grid {\n  border: none;\n}\n\n.data-grid td .url-outer {\n  width: 100%;\n  display: inline-flex;\n  justify-content: flex-start;\n}\n\n.data-grid td .url-outer .filter-highlight {\n  font-weight: bold;\n}\n\n.data-grid td .url-prefix {\n  overflow-x: hidden;\n  text-overflow: ellipsis;\n}\n\n.data-grid td .url-suffix {\n  flex: none;\n}\n\n.data-grid td .bar {\n  display: inline-block;\n  height: 8px;\n}\n\n.data-grid .selected td .bar {\n  border-top: 1px white solid;\n  border-bottom: 1px white solid;\n}\n\n.data-grid .selected td .bar:last-child {\n  border-right: 1px white solid;\n}\n\n.data-grid .selected td .bar:first-child {\n  border-left: 1px white solid;\n}\n\n.data-grid td .bar-container {\n}\n\n.data-grid td .bar-unused-size {\n  background-color: #E57373;\n}\n\n.data-grid td .bar-used-size {\n  background-color: #81C784;\n}\n\n.data-grid td .percent-value {\n  color: #888;\n  width: 45px;\n  display: inline-block;\n}\n\n.data-grid:focus tr.selected span.percent-value {\n  color: #eee;\n}\n\n/*# sourceURL=coverage/coverageListView.css */";Runtime.cachedResources["coverage/coverageView.css"]="/*\n * Copyright (c) 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n    overflow: hidden;\n}\n\n.coverage-toolbar-container {\n    display: flex;\n    border-bottom: 1px solid #ccc;\n    flex: 0 0;\n}\n\n.coverage-toolbar {\n    display: inline-block;\n}\n\n.coverage-toolbar-summary {\n    background-color: #eee;\n    border-top: 1px solid #ccc;\n    padding-left: 5px;\n    flex: 0 0 19px;\n    display: flex;\n    padding-right: 5px;\n}\n\n.coverage-toolbar-summary .coverage-message {\n    padding-top: 2px;\n    padding-left: 1ex;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    overflow: hidden;\n}\n\n.coverage-results {\n    overflow-y: auto;\n    display: flex;\n    flex: auto;\n}\n\n.landing-page {\n    justify-content: center;\n    align-items:  center;\n    padding: 20px;\n}\n\n.landing-page .message {\n    white-space: pre-line;\n}\n\n/*# sourceURL=coverage/coverageView.css */";