UNPKG

devil-windows

Version:

Debugger, profiler and runtime with embedded WebKit DevTools client (for Windows).

377 lines 62.6 kB
WebInspector.AuditsPanel=function() {WebInspector.PanelWithSidebarTree.call(this,"audits");this.registerRequiredCSS("panelEnablerView.css");this.registerRequiredCSS("auditsPanel.css");this.auditsTreeElement=new WebInspector.SidebarSectionTreeElement("",{},true);this.sidebarTree.appendChild(this.auditsTreeElement);this.auditsTreeElement.listItemElement.classList.add("hidden");this.auditsItemTreeElement=new WebInspector.AuditsSidebarTreeElement(this);this.auditsTreeElement.appendChild(this.auditsItemTreeElement);this.auditResultsTreeElement=new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("RESULTS"),{},true);this.sidebarTree.appendChild(this.auditResultsTreeElement);this.auditResultsTreeElement.expand();this._constructCategories();var target=(WebInspector.targetManager.mainTarget());this._auditController=new WebInspector.AuditController(target,this);this._launcherView=new WebInspector.AuditLauncherView(this._auditController);for(var id in this.categoriesById) this._launcherView.addCategory(this.categoriesById[id]);} WebInspector.AuditsPanel.prototype={canSearch:function() {return false;},get categoriesById() {return this._auditCategoriesById;},addCategory:function(category) {this.categoriesById[category.id]=category;this._launcherView.addCategory(category);},getCategory:function(id) {return this.categoriesById[id];},_constructCategories:function() {this._auditCategoriesById={};for(var categoryCtorID in WebInspector.AuditCategories){var auditCategory=new WebInspector.AuditCategories[categoryCtorID]();auditCategory._id=categoryCtorID;this.categoriesById[categoryCtorID]=auditCategory;}},auditFinishedCallback:function(mainResourceURL,results) {var children=this.auditResultsTreeElement.children;var ordinal=1;for(var i=0;i<children.length;++i){if(children[i].mainResourceURL===mainResourceURL) ordinal++;} var resultTreeElement=new WebInspector.AuditResultSidebarTreeElement(this,results,mainResourceURL,ordinal);this.auditResultsTreeElement.appendChild(resultTreeElement);resultTreeElement.revealAndSelect();},showResults:function(categoryResults) {if(!categoryResults._resultView) categoryResults._resultView=new WebInspector.AuditResultView(categoryResults);this.visibleView=categoryResults._resultView;},showLauncherView:function() {this.visibleView=this._launcherView;},get visibleView() {return this._visibleView;},set visibleView(x) {if(this._visibleView===x) return;if(this._visibleView) this._visibleView.detach();this._visibleView=x;if(x) x.show(this.mainElement());},wasShown:function() {WebInspector.Panel.prototype.wasShown.call(this);if(!this._visibleView) this.auditsItemTreeElement.select();},clearResults:function() {this.auditsItemTreeElement.revealAndSelect();this.auditResultsTreeElement.removeChildren();},__proto__:WebInspector.PanelWithSidebarTree.prototype} WebInspector.AuditCategoryImpl=function(displayName) {this._displayName=displayName;this._rules=[];} WebInspector.AuditCategoryImpl.prototype={get id() {return this._id;},get displayName() {return this._displayName;},addRule:function(rule,severity) {rule.severity=severity;this._rules.push(rule);},run:function(target,requests,ruleResultCallback,categoryDoneCallback,progress) {this._ensureInitialized();var remainingRulesCount=this._rules.length;progress.setTotalWork(remainingRulesCount);function callbackWrapper(result) {ruleResultCallback(result);progress.worked();if(!--remainingRulesCount) categoryDoneCallback();} for(var i=0;i<this._rules.length;++i) this._rules[i].run(target,requests,callbackWrapper,progress);},_ensureInitialized:function() {if(!this._initialized){if("initialize"in this) this.initialize();this._initialized=true;}}} WebInspector.AuditRule=function(id,displayName) {this._id=id;this._displayName=displayName;} WebInspector.AuditRule.Severity={Info:"info",Warning:"warning",Severe:"severe"} WebInspector.AuditRule.SeverityOrder={"info":3,"warning":2,"severe":1} WebInspector.AuditRule.prototype={get id() {return this._id;},get displayName() {return this._displayName;},set severity(severity) {this._severity=severity;},run:function(target,requests,callback,progress) {if(progress.isCanceled()) return;var result=new WebInspector.AuditRuleResult(this.displayName);result.severity=this._severity;this.doRun(target,requests,result,callback,progress);},doRun:function(target,requests,result,callback,progress) {throw new Error("doRun() not implemented");}} WebInspector.AuditCategoryResult=function(category) {this.title=category.displayName;this.ruleResults=[];} WebInspector.AuditCategoryResult.prototype={addRuleResult:function(ruleResult) {this.ruleResults.push(ruleResult);}} WebInspector.AuditRuleResult=function(value,expanded,className) {this.value=value;this.className=className;this.expanded=expanded;this.violationCount=0;this._formatters={r:WebInspector.AuditRuleResult.linkifyDisplayName};var standardFormatters=Object.keys(String.standardFormatters);for(var i=0;i<standardFormatters.length;++i) this._formatters[standardFormatters[i]]=String.standardFormatters[standardFormatters[i]];} WebInspector.AuditRuleResult.linkifyDisplayName=function(url) {return WebInspector.linkifyURLAsNode(url,WebInspector.displayNameForURL(url));} WebInspector.AuditRuleResult.resourceDomain=function(domain) {return domain||WebInspector.UIString("[empty domain]");} WebInspector.AuditRuleResult.prototype={addChild:function(value,expanded,className) {if(!this.children) this.children=[];var entry=new WebInspector.AuditRuleResult(value,expanded,className);this.children.push(entry);return entry;},addURL:function(url) {this.addChild(WebInspector.AuditRuleResult.linkifyDisplayName(url));},addURLs:function(urls) {for(var i=0;i<urls.length;++i) this.addURL(urls[i]);},addSnippet:function(snippet) {this.addChild(snippet,false,"source-code");},addFormatted:function(format,vararg) {var substitutions=Array.prototype.slice.call(arguments,1);var fragment=document.createDocumentFragment();function append(a,b) {if(!(b instanceof Node)) b=document.createTextNode(b);a.appendChild(b);return a;} var formattedResult=String.format(format,substitutions,this._formatters,fragment,append).formattedResult;if(formattedResult instanceof Node) formattedResult.normalize();return this.addChild(formattedResult);}} WebInspector.AuditsSidebarTreeElement=function(panel) {this._panel=panel;this.small=false;WebInspector.SidebarTreeElement.call(this,"audits-sidebar-tree-item",WebInspector.UIString("Audits"),"",null,false);} WebInspector.AuditsSidebarTreeElement.prototype={onattach:function() {WebInspector.SidebarTreeElement.prototype.onattach.call(this);},onselect:function() {this._panel.showLauncherView();},get selectable() {return true;},refresh:function() {this.refreshTitles();},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.AuditResultSidebarTreeElement=function(panel,results,mainResourceURL,ordinal) {this._panel=panel;this.results=results;this.mainResourceURL=mainResourceURL;WebInspector.SidebarTreeElement.call(this,"audit-result-sidebar-tree-item",String.sprintf("%s (%d)",mainResourceURL,ordinal),"",{},false);} WebInspector.AuditResultSidebarTreeElement.prototype={onselect:function() {this._panel.showResults(this.results);},get selectable() {return true;},__proto__:WebInspector.SidebarTreeElement.prototype} WebInspector.AuditRules={};WebInspector.AuditCategories={};;WebInspector.AuditCategory=function() {} WebInspector.AuditCategory.prototype={get id() {},get displayName() {},run:function(target,requests,ruleResultCallback,categoryDoneCallback,progress) {}};WebInspector.AuditCategories.PagePerformance=function(){WebInspector.AuditCategoryImpl.call(this,WebInspector.AuditCategories.PagePerformance.AuditCategoryName);} WebInspector.AuditCategories.PagePerformance.AuditCategoryName=WebInspector.UIString("Web Page Performance");WebInspector.AuditCategories.PagePerformance.prototype={initialize:function() {this.addRule(new WebInspector.AuditRules.UnusedCssRule(),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.CssInHeadRule(),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.StylesScriptsOrderRule(),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.VendorPrefixedCSSProperties(),WebInspector.AuditRule.Severity.Warning);},__proto__:WebInspector.AuditCategoryImpl.prototype} WebInspector.AuditCategories.NetworkUtilization=function(){WebInspector.AuditCategoryImpl.call(this,WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName);} WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName=WebInspector.UIString("Network Utilization");WebInspector.AuditCategories.NetworkUtilization.prototype={initialize:function() {this.addRule(new WebInspector.AuditRules.GzipRule(),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.ImageDimensionsRule(),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.CookieSizeRule(400),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.StaticCookielessRule(5),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.CombineJsResourcesRule(2),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.CombineCssResourcesRule(2),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.MinimizeDnsLookupsRule(4),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.ParallelizeDownloadRule(4,10,0.5),WebInspector.AuditRule.Severity.Warning);this.addRule(new WebInspector.AuditRules.BrowserCacheControlRule(),WebInspector.AuditRule.Severity.Severe);this.addRule(new WebInspector.AuditRules.ProxyCacheControlRule(),WebInspector.AuditRule.Severity.Warning);},__proto__:WebInspector.AuditCategoryImpl.prototype};WebInspector.AuditController=function(target,auditsPanel) {WebInspector.SDKObject.call(this,target);this._auditsPanel=auditsPanel;this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load,this._didMainResourceLoad,this);} WebInspector.AuditController.prototype={_executeAudit:function(categories,resultCallback) {this._progress.setTitle(WebInspector.UIString("Running audit"));function ruleResultReadyCallback(categoryResult,ruleResult) {if(ruleResult&&ruleResult.children) categoryResult.addRuleResult(ruleResult);if(this._progress.isCanceled()) this._progress.done();} var results=[];var mainResourceURL=this.target().resourceTreeModel.inspectedPageURL();var categoriesDone=0;function categoryDoneCallback() {if(++categoriesDone!==categories.length) return;this._progress.done();resultCallback(mainResourceURL,results)} var requests=this.target().networkLog.requests.slice();var compositeProgress=new WebInspector.CompositeProgress(this._progress);var subprogresses=[];for(var i=0;i<categories.length;++i) subprogresses.push(compositeProgress.createSubProgress());for(var i=0;i<categories.length;++i){var category=categories[i];var result=new WebInspector.AuditCategoryResult(category);results.push(result);category.run(this.target(),requests,ruleResultReadyCallback.bind(this,result),categoryDoneCallback.bind(this),subprogresses[i]);}},_auditFinishedCallback:function(launcherCallback,mainResourceURL,results) {this._auditsPanel.auditFinishedCallback(mainResourceURL,results);if(!this._progress.isCanceled()) launcherCallback();},initiateAudit:function(categoryIds,progress,runImmediately,startedCallback,finishedCallback) {if(!categoryIds||!categoryIds.length) return;this._progress=progress;var categories=[];for(var i=0;i<categoryIds.length;++i) categories.push(this._auditsPanel.categoriesById[categoryIds[i]]);function startAuditWhenResourcesReady() {startedCallback();this._executeAudit(categories,this._auditFinishedCallback.bind(this,finishedCallback));} if(runImmediately) startAuditWhenResourcesReady.call(this);else this._reloadResources(startAuditWhenResourcesReady.bind(this));WebInspector.userMetrics.AuditsStarted.record();},_reloadResources:function(callback) {this._pageReloadCallback=callback;this.target().resourceTreeModel.reloadPage();},_didMainResourceLoad:function() {if(this._pageReloadCallback){var callback=this._pageReloadCallback;delete this._pageReloadCallback;callback();}},clearResults:function() {this._auditsPanel.clearResults();},__proto__:WebInspector.SDKObject.prototype};WebInspector.AuditFormatters=function() {} WebInspector.AuditFormatters.Registry={text:function(text) {return document.createTextNode(text);},snippet:function(snippetText) {var div=document.createElement("div");div.textContent=snippetText;div.className="source-code";return div;},concat:function() {var parent=document.createElement("span");for(var arg=0;arg<arguments.length;++arg) parent.appendChild(WebInspector.auditFormatters.apply(arguments[arg]));return parent;},url:function(url,displayText,allowExternalNavigation) {var a=document.createElement("a");a.href=sanitizeHref(url);a.title=url;a.textContent=displayText||url;if(allowExternalNavigation) a.target="_blank";return a;},resourceLink:function(url,line) {return WebInspector.linkifyResourceAsNode(url,line,"console-message-url webkit-html-resource-link");}};WebInspector.AuditFormatters.prototype={apply:function(value) {var formatter;var type=typeof value;var args;switch(type){case"string":case"boolean":case"number":formatter=WebInspector.AuditFormatters.Registry.text;args=[value.toString()];break;case"object":if(value instanceof Node) return value;if(value instanceof Array){formatter=WebInspector.AuditFormatters.Registry.concat;args=value;}else if(value.type&&value.arguments){formatter=WebInspector.AuditFormatters.Registry[value.type];args=value.arguments;}} if(!formatter) throw"Invalid value or formatter: "+type+JSON.stringify(value);return formatter.apply(null,args);},partiallyApply:function(formatters,thisArgument,value) {if(value instanceof Array) return value.map(this.partiallyApply.bind(this,formatters,thisArgument));if(typeof value==="object"&&typeof formatters[value.type]==="function"&&value.arguments) return formatters[value.type].apply(thisArgument,value.arguments);return value;}} WebInspector.auditFormatters=new WebInspector.AuditFormatters();;WebInspector.AuditLauncherView=function(auditController) {WebInspector.VBox.call(this);this.setMinimumSize(100,25);this._auditController=auditController;this._categoryIdPrefix="audit-category-item-";this._auditRunning=false;this.element.classList.add("audit-launcher-view");this.element.classList.add("panel-enabler-view");this._contentElement=document.createElement("div");this._contentElement.className="audit-launcher-view-content";this.element.appendChild(this._contentElement);this._boundCategoryClickListener=this._categoryClicked.bind(this);this._resetResourceCount();this._sortedCategories=[];this._headerElement=document.createElement("h1");this._headerElement.className="no-audits";this._headerElement.textContent=WebInspector.UIString("No audits to run");this._contentElement.appendChild(this._headerElement);var target=this._auditController.target();target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted,this._onRequestStarted,this);target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished,this._onRequestFinished,this);WebInspector.profilingLock().addEventListener(WebInspector.Lock.Events.StateChanged,this._updateButton,this);var defaultSelectedAuditCategory={};defaultSelectedAuditCategory[WebInspector.AuditLauncherView.AllCategoriesKey]=true;this._selectedCategoriesSetting=WebInspector.settings.createSetting("selectedAuditCategories",defaultSelectedAuditCategory);} WebInspector.AuditLauncherView.AllCategoriesKey="__AllCategories";WebInspector.AuditLauncherView.prototype={_resetResourceCount:function() {this._loadedResources=0;this._totalResources=0;},_onRequestStarted:function(event) {var request=(event.data);if(request.type===WebInspector.resourceTypes.WebSocket) return;++this._totalResources;this._updateResourceProgress();},_onRequestFinished:function(event) {var request=(event.data);if(request.type===WebInspector.resourceTypes.WebSocket) return;++this._loadedResources;this._updateResourceProgress();},addCategory:function(category) {if(!this._sortedCategories.length) this._createLauncherUI();var selectedCategories=this._selectedCategoriesSetting.get();var categoryElement=this._createCategoryElement(category.displayName,category.id);category._checkboxElement=categoryElement.firstChild;if(this._selectAllCheckboxElement.checked||selectedCategories[category.displayName]){category._checkboxElement.checked=true;++this._currentCategoriesCount;} function compareCategories(a,b) {var aTitle=a.displayName||"";var bTitle=b.displayName||"";return aTitle.localeCompare(bTitle);} var insertBefore=insertionIndexForObjectInListSortedByFunction(category,this._sortedCategories,compareCategories);this._categoriesElement.insertBefore(categoryElement,this._categoriesElement.children[insertBefore]);this._sortedCategories.splice(insertBefore,0,category);this._selectedCategoriesUpdated();},_setAuditRunning:function(auditRunning) {if(this._auditRunning===auditRunning) return;this._auditRunning=auditRunning;this._updateButton();this._toggleUIComponents(this._auditRunning);var target=this._auditController.target();if(this._auditRunning){WebInspector.profilingLock().acquire();this._startAudit();}else{this._stopAudit();WebInspector.profilingLock().release();}},_startAudit:function() {var catIds=[];for(var category=0;category<this._sortedCategories.length;++category){if(this._sortedCategories[category]._checkboxElement.checked) catIds.push(this._sortedCategories[category].id);} this._resetResourceCount();this._progressIndicator=new WebInspector.ProgressIndicator();this._buttonContainerElement.appendChild(this._progressIndicator.element);this._displayResourceLoadingProgress=true;function onAuditStarted() {this._displayResourceLoadingProgress=false;} this._auditController.initiateAudit(catIds,this._progressIndicator,this._auditPresentStateElement.checked,onAuditStarted.bind(this),this._setAuditRunning.bind(this,false));},_stopAudit:function() {this._displayResourceLoadingProgress=false;this._progressIndicator.cancel();this._progressIndicator.done();delete this._progressIndicator;},_toggleUIComponents:function(disable) {this._selectAllCheckboxElement.disabled=disable;this._categoriesElement.disabled=disable;this._auditPresentStateElement.disabled=disable;this._auditReloadedStateElement.disabled=disable;},_launchButtonClicked:function(event) {this._setAuditRunning(!this._auditRunning);},_clearButtonClicked:function() {this._auditController.clearResults();},_selectAllClicked:function(checkCategories,userGesture) {var childNodes=this._categoriesElement.childNodes;for(var i=0,length=childNodes.length;i<length;++i) childNodes[i].firstChild.checked=checkCategories;this._currentCategoriesCount=checkCategories?this._sortedCategories.length:0;this._selectedCategoriesUpdated(userGesture);},_categoryClicked:function(event) {this._currentCategoriesCount+=event.target.checked?1:-1;this._selectAllCheckboxElement.checked=this._currentCategoriesCount===this._sortedCategories.length;this._selectedCategoriesUpdated(true);},_createCategoryElement:function(title,id) {var labelElement=document.createElement("label");labelElement.id=this._categoryIdPrefix+id;var element=document.createElement("input");element.type="checkbox";if(id!=="") element.addEventListener("click",this._boundCategoryClickListener,false);labelElement.appendChild(element);labelElement.appendChild(document.createTextNode(title));labelElement.__displayName=title;return labelElement;},_createLauncherUI:function() {this._headerElement=document.createElement("h1");this._headerElement.textContent=WebInspector.UIString("Select audits to run");for(var child=0;child<this._contentElement.children.length;++child) this._contentElement.removeChild(this._contentElement.children[child]);this._contentElement.appendChild(this._headerElement);function handleSelectAllClick(event) {this._selectAllClicked(event.target.checked,true);} var categoryElement=this._createCategoryElement(WebInspector.UIString("Select All"),"");categoryElement.id="audit-launcher-selectall";this._selectAllCheckboxElement=categoryElement.firstChild;this._selectAllCheckboxElement.checked=this._selectedCategoriesSetting.get()[WebInspector.AuditLauncherView.AllCategoriesKey];this._selectAllCheckboxElement.addEventListener("click",handleSelectAllClick.bind(this),false);this._contentElement.appendChild(categoryElement);this._categoriesElement=this._contentElement.createChild("fieldset","audit-categories-container");this._currentCategoriesCount=0;this._contentElement.createChild("div","flexible-space");this._buttonContainerElement=this._contentElement.createChild("div","button-container");var labelElement=this._buttonContainerElement.createChild("label");this._auditPresentStateElement=labelElement.createChild("input");this._auditPresentStateElement.name="audit-mode";this._auditPresentStateElement.type="radio";this._auditPresentStateElement.checked=true;this._auditPresentStateLabelElement=document.createTextNode(WebInspector.UIString("Audit Present State"));labelElement.appendChild(this._auditPresentStateLabelElement);labelElement=this._buttonContainerElement.createChild("label");this._auditReloadedStateElement=labelElement.createChild("input");this._auditReloadedStateElement.name="audit-mode";this._auditReloadedStateElement.type="radio";labelElement.appendChild(document.createTextNode("Reload Page and Audit on Load"));this._launchButton=this._buttonContainerElement.createChild("button","text-button");this._launchButton.textContent=WebInspector.UIString("Run");this._launchButton.addEventListener("click",this._launchButtonClicked.bind(this),false);this._clearButton=this._buttonContainerElement.createChild("button","text-button");this._clearButton.textContent=WebInspector.UIString("Clear");this._clearButton.addEventListener("click",this._clearButtonClicked.bind(this),false);this._selectAllClicked(this._selectAllCheckboxElement.checked);},_updateResourceProgress:function() {if(this._displayResourceLoadingProgress) this._progressIndicator.setTitle(WebInspector.UIString("Loading (%d of %d)",this._loadedResources,this._totalResources));},_selectedCategoriesUpdated:function(userGesture) {var selectedCategories=userGesture?{}:this._selectedCategoriesSetting.get();var childNodes=this._categoriesElement.childNodes;for(var i=0,length=childNodes.length;i<length;++i) selectedCategories[childNodes[i].__displayName]=childNodes[i].firstChild.checked;selectedCategories[WebInspector.AuditLauncherView.AllCategoriesKey]=this._selectAllCheckboxElement.checked;this._selectedCategoriesSetting.set(selectedCategories);this._updateButton();},_updateButton:function() {var target=this._auditController.target();var enable=this._auditRunning||(this._currentCategoriesCount&&!WebInspector.profilingLock().isAcquired());this._launchButton.textContent=this._auditRunning?WebInspector.UIString("Stop"):WebInspector.UIString("Run");this._launchButton.disabled=!enable;this._launchButton.title=enable?"":WebInspector.anotherProfilerActiveLabel();},__proto__:WebInspector.VBox.prototype};WebInspector.AuditResultView=function(categoryResults) {WebInspector.SidebarPaneStack.call(this);this.setMinimumSize(100,25);this.element.classList.add("audit-result-view","fill");function categorySorter(a,b){return(a.title||"").localeCompare(b.title||"");} categoryResults.sort(categorySorter);for(var i=0;i<categoryResults.length;++i) this.addPane(new WebInspector.AuditCategoryResultPane(categoryResults[i]));} WebInspector.AuditResultView.prototype={__proto__:WebInspector.SidebarPaneStack.prototype} WebInspector.AuditCategoryResultPane=function(categoryResult) {WebInspector.SidebarPane.call(this,categoryResult.title);var treeOutlineElement=document.createElement("ol");this.bodyElement.classList.add("audit-result-tree");this.bodyElement.appendChild(treeOutlineElement);this._treeOutline=new TreeOutline(treeOutlineElement);this._treeOutline.expandTreeElementsWhenArrowing=true;function ruleSorter(a,b) {var result=WebInspector.AuditRule.SeverityOrder[a.severity||0]-WebInspector.AuditRule.SeverityOrder[b.severity||0];if(!result) result=(a.value||"").localeCompare(b.value||"");return result;} categoryResult.ruleResults.sort(ruleSorter);for(var i=0;i<categoryResult.ruleResults.length;++i){var ruleResult=categoryResult.ruleResults[i];var treeElement=this._appendResult(this._treeOutline,ruleResult,ruleResult.severity);treeElement.listItemElement.classList.add("audit-result");} this.expand();} WebInspector.AuditCategoryResultPane.prototype={_appendResult:function(parentTreeElement,result,severity) {var title="";if(typeof result.value==="string"){title=result.value;if(result.violationCount) title=String.sprintf("%s (%d)",title,result.violationCount);} var titleFragment=document.createDocumentFragment();if(severity){var severityElement=document.createElement("div");severityElement.className="severity-"+severity;titleFragment.appendChild(severityElement);} titleFragment.appendChild(document.createTextNode(title));var treeElement=new TreeElement(titleFragment,null,!!result.children);parentTreeElement.appendChild(treeElement);if(result.className) treeElement.listItemElement.classList.add(result.className);if(typeof result.value!=="string") treeElement.listItemElement.appendChild(WebInspector.auditFormatters.apply(result.value));if(result.children){for(var i=0;i<result.children.length;++i) this._appendResult(treeElement,result.children[i]);} if(result.expanded){treeElement.listItemElement.classList.remove("parent");treeElement.listItemElement.classList.add("parent-expanded");treeElement.expand();} return treeElement;},__proto__:WebInspector.SidebarPane.prototype};WebInspector.AuditRules.IPAddressRegexp=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;WebInspector.AuditRules.CacheableResponseCodes={200:true,203:true,206:true,300:true,301:true,410:true,304:true} WebInspector.AuditRules.getDomainToResourcesMap=function(requests,types,needFullResources) {var domainToResourcesMap={};for(var i=0,size=requests.length;i<size;++i){var request=requests[i];if(types&&types.indexOf(request.type)===-1) continue;var parsedURL=request.url.asParsedURL();if(!parsedURL) continue;var domain=parsedURL.host;var domainResources=domainToResourcesMap[domain];if(domainResources===undefined){domainResources=[];domainToResourcesMap[domain]=domainResources;} domainResources.push(needFullResources?request:request.url);} return domainToResourcesMap;} WebInspector.AuditRules.GzipRule=function() {WebInspector.AuditRule.call(this,"network-gzip",WebInspector.UIString("Enable gzip compression"));} WebInspector.AuditRules.GzipRule.prototype={doRun:function(target,requests,result,callback,progress) {var totalSavings=0;var compressedSize=0;var candidateSize=0;var summary=result.addChild("",true);for(var i=0,length=requests.length;i<length;++i){var request=requests[i];if(request.cached||request.statusCode===304) continue;if(this._shouldCompress(request)){var size=request.resourceSize;candidateSize+=size;if(this._isCompressed(request)){compressedSize+=size;continue;} var savings=2*size/3;totalSavings+=savings;summary.addFormatted("%r could save ~%s",request.url,Number.bytesToString(savings));result.violationCount++;}} if(!totalSavings){callback(null);return;} summary.value=WebInspector.UIString("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):",Number.bytesToString(totalSavings));callback(result);},_isCompressed:function(request) {var encodingHeader=request.responseHeaderValue("Content-Encoding");if(!encodingHeader) return false;return/\b(?:gzip|deflate)\b/.test(encodingHeader);},_shouldCompress:function(request) {return request.type.isTextType()&&request.parsedURL.host&&request.resourceSize!==undefined&&request.resourceSize>150;},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CombineExternalResourcesRule=function(id,name,type,resourceTypeName,allowedPerDomain) {WebInspector.AuditRule.call(this,id,name);this._type=type;this._resourceTypeName=resourceTypeName;this._allowedPerDomain=allowedPerDomain;} WebInspector.AuditRules.CombineExternalResourcesRule.prototype={doRun:function(target,requests,result,callback,progress) {var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,[this._type],false);var penalizedResourceCount=0;var summary=result.addChild("",true);for(var domain in domainToResourcesMap){var domainResources=domainToResourcesMap[domain];var extraResourceCount=domainResources.length-this._allowedPerDomain;if(extraResourceCount<=0) continue;penalizedResourceCount+=extraResourceCount-1;summary.addChild(WebInspector.UIString("%d %s resources served from %s.",domainResources.length,this._resourceTypeName,WebInspector.AuditRuleResult.resourceDomain(domain)));result.violationCount+=domainResources.length;} if(!penalizedResourceCount){callback(null);return;} summary.value=WebInspector.UIString("There are multiple resources served from same domain. Consider combining them into as few files as possible.");callback(result);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CombineJsResourcesRule=function(allowedPerDomain){WebInspector.AuditRules.CombineExternalResourcesRule.call(this,"page-externaljs",WebInspector.UIString("Combine external JavaScript"),WebInspector.resourceTypes.Script,"JavaScript",allowedPerDomain);} WebInspector.AuditRules.CombineJsResourcesRule.prototype={__proto__:WebInspector.AuditRules.CombineExternalResourcesRule.prototype} WebInspector.AuditRules.CombineCssResourcesRule=function(allowedPerDomain){WebInspector.AuditRules.CombineExternalResourcesRule.call(this,"page-externalcss",WebInspector.UIString("Combine external CSS"),WebInspector.resourceTypes.Stylesheet,"CSS",allowedPerDomain);} WebInspector.AuditRules.CombineCssResourcesRule.prototype={__proto__:WebInspector.AuditRules.CombineExternalResourcesRule.prototype} WebInspector.AuditRules.MinimizeDnsLookupsRule=function(hostCountThreshold){WebInspector.AuditRule.call(this,"network-minimizelookups",WebInspector.UIString("Minimize DNS lookups"));this._hostCountThreshold=hostCountThreshold;} WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype={doRun:function(target,requests,result,callback,progress) {var summary=result.addChild("");var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,null,false);for(var domain in domainToResourcesMap){if(domainToResourcesMap[domain].length>1) continue;var parsedURL=domain.asParsedURL();if(!parsedURL) continue;if(!parsedURL.host.search(WebInspector.AuditRules.IPAddressRegexp)) continue;summary.addSnippet(domain);result.violationCount++;} if(!summary.children||summary.children.length<=this._hostCountThreshold){callback(null);return;} summary.value=WebInspector.UIString("The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.");callback(result);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.ParallelizeDownloadRule=function(optimalHostnameCount,minRequestThreshold,minBalanceThreshold) {WebInspector.AuditRule.call(this,"network-parallelizehosts",WebInspector.UIString("Parallelize downloads across hostnames"));this._optimalHostnameCount=optimalHostnameCount;this._minRequestThreshold=minRequestThreshold;this._minBalanceThreshold=minBalanceThreshold;} WebInspector.AuditRules.ParallelizeDownloadRule.prototype={doRun:function(target,requests,result,callback,progress) {function hostSorter(a,b) {var aCount=domainToResourcesMap[a].length;var bCount=domainToResourcesMap[b].length;return(aCount<bCount)?1:(aCount===bCount)?0:-1;} var domainToResourcesMap=WebInspector.AuditRules.getDomainToResourcesMap(requests,[WebInspector.resourceTypes.Stylesheet,WebInspector.resourceTypes.Image],true);var hosts=[];for(var url in domainToResourcesMap) hosts.push(url);if(!hosts.length){callback(null);return;} hosts.sort(hostSorter);var optimalHostnameCount=this._optimalHostnameCount;if(hosts.length>optimalHostnameCount) hosts.splice(optimalHostnameCount);var busiestHostResourceCount=domainToResourcesMap[hosts[0]].length;var requestCountAboveThreshold=busiestHostResourceCount-this._minRequestThreshold;if(requestCountAboveThreshold<=0){callback(null);return;} var avgResourcesPerHost=0;for(var i=0,size=hosts.length;i<size;++i) avgResourcesPerHost+=domainToResourcesMap[hosts[i]].length;avgResourcesPerHost/=optimalHostnameCount;avgResourcesPerHost=Math.max(avgResourcesPerHost,1);var pctAboveAvg=(requestCountAboveThreshold/avgResourcesPerHost)-1.0;var minBalanceThreshold=this._minBalanceThreshold;if(pctAboveAvg<minBalanceThreshold){callback(null);return;} var requestsOnBusiestHost=domainToResourcesMap[hosts[0]];var entry=result.addChild(WebInspector.UIString("This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostnames.",busiestHostResourceCount,hosts[0]),true);for(var i=0;i<requestsOnBusiestHost.length;++i) entry.addURL(requestsOnBusiestHost[i].url);result.violationCount=requestsOnBusiestHost.length;callback(result);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.UnusedCssRule=function() {WebInspector.AuditRule.call(this,"page-unusedcss",WebInspector.UIString("Remove unused CSS rules"));} WebInspector.AuditRules.UnusedCssRule.prototype={doRun:function(target,requests,result,callback,progress) {function evalCallback(styleSheets){if(!styleSheets.length) return callback(null);var selectors=[];var testedSelectors={};for(var i=0;i<styleSheets.length;++i){var styleSheet=styleSheets[i];for(var curRule=0;curRule<styleSheet.rules.length;++curRule){var selectorText=styleSheet.rules[curRule].selectorText;if(testedSelectors[selectorText]) continue;selectors.push(selectorText);testedSelectors[selectorText]=1;}} var foundSelectors={};function selectorsCallback(styleSheets) {if(progress.isCanceled()) return;var inlineBlockOrdinal=0;var totalStylesheetSize=0;var totalUnusedStylesheetSize=0;var summary;for(var i=0;i<styleSheets.length;++i){var styleSheet=styleSheets[i];var unusedRules=[];for(var curRule=0;curRule<styleSheet.rules.length;++curRule){var rule=styleSheet.rules[curRule];if(!testedSelectors[rule.selectorText]||foundSelectors[rule.selectorText]) continue;unusedRules.push(rule.selectorText);} totalStylesheetSize+=styleSheet.rules.length;totalUnusedStylesheetSize+=unusedRules.length;if(!unusedRules.length) continue;var resource=WebInspector.resourceForURL(styleSheet.sourceURL);var isInlineBlock=resource&&resource.request&&resource.request.type===WebInspector.resourceTypes.Document;var url=!isInlineBlock?WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL):WebInspector.UIString("Inline block #%d",++inlineBlockOrdinal);var pctUnused=Math.round(100*unusedRules.length/styleSheet.rules.length);if(!summary) summary=result.addChild("",true);var entry=summary.addFormatted("%s: %d% is not used by the current page.",url,pctUnused);for(var j=0;j<unusedRules.length;++j) entry.addSnippet(unusedRules[j]);result.violationCount+=unusedRules.length;} if(!totalUnusedStylesheetSize) return callback(null);var totalUnusedPercent=Math.round(100*totalUnusedStylesheetSize/totalStylesheetSize);summary.value=WebInspector.UIString("%s rules (%d%) of CSS not used by the current page.",totalUnusedStylesheetSize,totalUnusedPercent);callback(result);} function queryCallback(boundSelectorsCallback,selector,nodeId) {if(nodeId) foundSelectors[selector]=true;if(boundSelectorsCallback) boundSelectorsCallback();} function documentLoaded(selectors,document){var pseudoSelectorRegexp=/::?(?:[\w-]+)(?:\(.*?\))?/g;if(!selectors.length){selectorsCallback([]);return;} for(var i=0;i<selectors.length;++i){if(progress.isCanceled()) return;var effectiveSelector=selectors[i].replace(pseudoSelectorRegexp,"");target.domModel.querySelector(document.id,effectiveSelector,queryCallback.bind(null,i===selectors.length-1?selectorsCallback.bind(null,styleSheets):null,selectors[i]));}} target.domModel.requestDocument(documentLoaded.bind(null,selectors));} var styleSheetInfos=target.cssModel.allStyleSheets();if(!styleSheetInfos||!styleSheetInfos.length){evalCallback([]);return;} var styleSheetProcessor=new WebInspector.AuditRules.StyleSheetProcessor(styleSheetInfos,progress,evalCallback);styleSheetProcessor.run();},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.ParsedStyleSheet;WebInspector.AuditRules.StyleSheetProcessor=function(styleSheetHeaders,progress,styleSheetsParsedCallback) {this._styleSheetHeaders=styleSheetHeaders;this._progress=progress;this._styleSheets=[];this._styleSheetsParsedCallback=styleSheetsParsedCallback;} WebInspector.AuditRules.StyleSheetProcessor.prototype={run:function() {this._parser=new WebInspector.CSSParser();this._processNextStyleSheet();},_terminateWorker:function() {if(this._parser){this._parser.dispose();delete this._parser;}},_finish:function() {this._terminateWorker();this._styleSheetsParsedCallback(this._styleSheets);},_processNextStyleSheet:function() {if(!this._styleSheetHeaders.length){this._finish();return;} this._currentStyleSheetHeader=this._styleSheetHeaders.shift();this._parser.fetchAndParse(this._currentStyleSheetHeader,this._onStyleSheetParsed.bind(this));},_onStyleSheetParsed:function(rules) {if(this._progress.isCanceled()){this._terminateWorker();return;} var styleRules=[];for(var i=0;i<rules.length;++i){var rule=rules[i];if(rule.selectorText) styleRules.push(rule);} this._styleSheets.push({sourceURL:this._currentStyleSheetHeader.sourceURL,rules:styleRules});this._processNextStyleSheet();},} WebInspector.AuditRules.CacheControlRule=function(id,name) {WebInspector.AuditRule.call(this,id,name);} WebInspector.AuditRules.CacheControlRule.MillisPerMonth=1000*60*60*24*30;WebInspector.AuditRules.CacheControlRule.prototype={doRun:function(target,requests,result,callback,progress) {var cacheableAndNonCacheableResources=this._cacheableAndNonCacheableResources(requests);if(cacheableAndNonCacheableResources[0].length) this.runChecks(cacheableAndNonCacheableResources[0],result);this.handleNonCacheableResources(cacheableAndNonCacheableResources[1],result);callback(result);},handleNonCacheableResources:function(requests,result) {},_cacheableAndNonCacheableResources:function(requests) {var processedResources=[[],[]];for(var i=0;i<requests.length;++i){var request=requests[i];if(!this.isCacheableResource(request)) continue;if(this._isExplicitlyNonCacheable(request)) processedResources[1].push(request);else processedResources[0].push(request);} return processedResources;},execCheck:function(messageText,requestCheckFunction,requests,result) {var requestCount=requests.length;var urls=[];for(var i=0;i<requestCount;++i){if(requestCheckFunction.call(this,requests[i])) urls.push(requests[i].url);} if(urls.length){var entry=result.addChild(messageText,true);entry.addURLs(urls);result.violationCount+=urls.length;}},freshnessLifetimeGreaterThan:function(request,timeMs) {var dateHeader=this.responseHeader(request,"Date");if(!dateHeader) return false;var dateHeaderMs=Date.parse(dateHeader);if(isNaN(dateHeaderMs)) return false;var freshnessLifetimeMs;var maxAgeMatch=this.responseHeaderMatch(request,"Cache-Control","max-age=(\\d+)");if(maxAgeMatch) freshnessLifetimeMs=(maxAgeMatch[1])?1000*maxAgeMatch[1]:0;else{var expiresHeader=this.responseHeader(request,"Expires");if(expiresHeader){var expDate=Date.parse(expiresHeader);if(!isNaN(expDate)) freshnessLifetimeMs=expDate-dateHeaderMs;}} return(isNaN(freshnessLifetimeMs))?false:freshnessLifetimeMs>timeMs;},responseHeader:function(request,header) {return request.responseHeaderValue(header);},hasResponseHeader:function(request,header) {return request.responseHeaderValue(header)!==undefined;},isCompressible:function(request) {return request.type.isTextType();},isPubliclyCacheable:function(request) {if(this._isExplicitlyNonCacheable(request)) return false;if(this.responseHeaderMatch(request,"Cache-Control","public")) return true;return request.url.indexOf("?")===-1&&!this.responseHeaderMatch(request,"Cache-Control","private");},responseHeaderMatch:function(request,header,regexp) {return request.responseHeaderValue(header)?request.responseHeaderValue(header).match(new RegExp(regexp,"im")):null;},hasExplicitExpiration:function(request) {return this.hasResponseHeader(request,"Date")&&(this.hasResponseHeader(request,"Expires")||!!this.responseHeaderMatch(request,"Cache-Control","max-age"));},_isExplicitlyNonCacheable:function(request) {var hasExplicitExp=this.hasExplicitExpiration(request);return!!this.responseHeaderMatch(request,"Cache-Control","(no-cache|no-store|must-revalidate)")||!!this.responseHeaderMatch(request,"Pragma","no-cache")||(hasExplicitExp&&!this.freshnessLifetimeGreaterThan(request,0))||(!hasExplicitExp&&!!request.url&&request.url.indexOf("?")>=0)||(!hasExplicitExp&&!this.isCacheableResource(request));},isCacheableResource:function(request) {return request.statusCode!==undefined&&WebInspector.AuditRules.CacheableResponseCodes[request.statusCode];},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.BrowserCacheControlRule=function() {WebInspector.AuditRules.CacheControlRule.call(this,"http-browsercache",WebInspector.UIString("Leverage browser caching"));} WebInspector.AuditRules.BrowserCacheControlRule.prototype={handleNonCacheableResources:function(requests,result) {if(requests.length){var entry=result.addChild(WebInspector.UIString("The following resources are explicitly non-cacheable. Consider making them cacheable if possible:"),true);result.violationCount+=requests.length;for(var i=0;i<requests.length;++i) entry.addURL(requests[i].url);}},runChecks:function(requests,result,callback) {this.execCheck(WebInspector.UIString("The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:"),this._missingExpirationCheck,requests,result);this.execCheck(WebInspector.UIString("The following resources specify a \"Vary\" header that disables caching in most versions of Internet Explorer:"),this._varyCheck,requests,result);this.execCheck(WebInspector.UIString("The following cacheable resources have a short freshness lifetime:"),this._oneMonthExpirationCheck,requests,result);this.execCheck(WebInspector.UIString("To further improve cache hit rate, specify an expiration one year in the future for the following cacheable resources:"),this._oneYearExpirationCheck,requests,result);},_missingExpirationCheck:function(request) {return this.isCacheableResource(request)&&!this.hasResponseHeader(request,"Set-Cookie")&&!this.hasExplicitExpiration(request);},_varyCheck:function(request) {var varyHeader=this.responseHeader(request,"Vary");if(varyHeader){varyHeader=varyHeader.replace(/User-Agent/gi,"");varyHeader=varyHeader.replace(/Accept-Encoding/gi,"");varyHeader=varyHeader.replace(/[, ]*/g,"");} return varyHeader&&varyHeader.length&&this.isCacheableResource(request)&&this.freshnessLifetimeGreaterThan(request,0);},_oneMonthExpirationCheck:function(request) {return this.isCacheableResource(request)&&!this.hasResponseHeader(request,"Set-Cookie")&&!this.freshnessLifetimeGreaterThan(request,WebInspector.AuditRules.CacheControlRule.MillisPerMonth)&&this.freshnessLifetimeGreaterThan(request,0);},_oneYearExpirationCheck:function(request) {return this.isCacheableResource(request)&&!this.hasResponseHeader(request,"Set-Cookie")&&!this.freshnessLifetimeGreaterThan(request,11*WebInspector.AuditRules.CacheControlRule.MillisPerMonth)&&this.freshnessLifetimeGreaterThan(request,WebInspector.AuditRules.CacheControlRule.MillisPerMonth);},__proto__:WebInspector.AuditRules.CacheControlRule.prototype} WebInspector.AuditRules.ProxyCacheControlRule=function(){WebInspector.AuditRules.CacheControlRule.call(this,"http-proxycache",WebInspector.UIString("Leverage proxy caching"));} WebInspector.AuditRules.ProxyCacheControlRule.prototype={runChecks:function(requests,result,callback) {this.execCheck(WebInspector.UIString("Resources with a \"?\" in the URL are not cached by most proxy caching servers:"),this._questionMarkCheck,requests,result);this.execCheck(WebInspector.UIString("Consider adding a \"Cache-Control: public\" header to the following resources:"),this._publicCachingCheck,requests,result);this.execCheck(WebInspector.UIString("The following publicly cacheable resources contain a Set-Cookie header. This security vulnerability can cause cookies to be shared by multiple users."),this._setCookieCacheableCheck,requests,result);},_questionMarkCheck:function(request) {return request.url.indexOf("?")>=0&&!this.hasResponseHeader(request,"Set-Cookie")&&this.isPubliclyCacheable(request);},_publicCachingCheck:function(request) {return this.isCacheableResource(request)&&!this.isCompressible(request)&&!this.responseHeaderMatch(request,"Cache-Control","public")&&!this.hasResponseHeader(request,"Set-Cookie");},_setCookieCacheableCheck:function(request) {return this.hasResponseHeader(request,"Set-Cookie")&&this.isPubliclyCacheable(request);},__proto__:WebInspector.AuditRules.CacheControlRule.prototype} WebInspector.AuditRules.ImageDimensionsRule=function() {WebInspector.AuditRule.call(this,"page-imagedims",WebInspector.UIString("Specify image dimensions"));} WebInspector.AuditRules.ImageDimensionsRule.prototype={doRun:function(target,requests,result,callback,progress) {var urlToNoDimensionCount={};function doneCallback() {for(var url in urlToNoDimensionCount){var entry=entry||result.addChild(WebInspector.UIString("A width and height should be specified for all images in order to speed up page display. The following image(s) are missing a width and/or height:"),true);var format="%r";if(urlToNoDimensionCount[url]>1) format+=" (%d uses)";entry.addFormatted(format,url,urlToNoDimensionCount[url]);result.violationCount++;} callback(entry?result:null);} function imageStylesReady(imageId,styles,isLastStyle,computedStyle) {if(progress.isCanceled()) return;const node=target.domModel.nodeForId(imageId);var src=node.getAttribute("src");if(!src.asParsedURL()){for(var frameOwnerCandidate=node;frameOwnerCandidate;frameOwnerCandidate=frameOwnerCandidate.parentNode){if(frameOwnerCandidate.baseURL){var completeSrc=WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL,src);break;}}} if(completeSrc) src=completeSrc;if(computedStyle.getPropertyValue("position")==="absolute"){if(isLastStyle) doneCallback();return;} if(styles.attributesStyle){var widthFound=!!styles.attributesStyle.getLiveProperty("width");var heightFound=!!styles.attributesStyle.getLiveProperty("height");} var inlineStyle=styles.inlineStyle;if(inlineStyle){if(inlineStyle.getPropertyValue("width")!=="") widthFound=true;if(inlineStyle.getPropertyValue("height")!=="") heightFound=true;} for(var i=styles.matchedCSSRules.length-1;i>=0&&!(widthFound&&heightFound);--i){var style=styles.matchedCSSRules[i].style;if(style.getPropertyValue("width")!=="") widthFound=true;if(style.getPropertyValue("height")!=="") heightFound=true;} if(!widthFound||!heightFound){if(src in urlToNoDimensionCount) ++urlToNoDimensionCount[src];else urlToNoDimensionCount[src]=1;} if(isLastStyle) doneCallback();} function getStyles(nodeIds) {if(progress.isCanceled()) return;var targetResult={};function inlineCallback(inlineStyle,attributesStyle) {targetResult.inlineStyle=inlineStyle;targetResult.attributesStyle=attributesStyle;} function matchedCallback(result) {if(result) targetResult.matchedCSSRules=result.matchedCSSRules;} if(!nodeIds||!nodeIds.length) doneCallback();for(var i=0;nodeIds&&i<nodeIds.length;++i){target.cssModel.getMatchedStylesAsync(nodeIds[i],false,false,matchedCallback);target.cssModel.getInlineStylesAsync(nodeIds[i],inlineCallback);target.cssModel.getComputedStyleAsync(nodeIds[i],imageStylesReady.bind(null,nodeIds[i],targetResult,i===nodeIds.length-1));}} function onDocumentAvailable(root) {if(progress.isCanceled()) return;target.domModel.querySelectorAll(root.id,"img[src]",getStyles);} if(progress.isCanceled()) return;target.domModel.requestDocument(onDocumentAvailable);},__proto__:WebInspector.AuditRule.prototype} WebInspector.AuditRules.CssInHeadRule=function() {WebInspector.AuditRule.call(this,"page-cssinhead",WebInspector.UIString("Put CSS in the document head"));} WebInspector.AuditRules.CssInHeadRule.prototype={doRun:function(target,requests,result,callback,progress) {function evalCallback(evalResult) {if(progress.isCanceled()) return;if(!evalResult) return callback(null);var summary=result.addChild("");var outputMessages=[];for(var url in evalResult){var urlViolations=evalResult[url];if(urlViolations[0]){result.addFormatted("%s style block(s) in the %r body should be moved to the document head.",urlViolations[0],url);result.violationCount+=urlViolations[0];} for(var i=0;i<urlViolations[1].length;++i) result.addFormatted("Link node %r should be moved to the document head in %r",urlViolations[1][i],url);result.violationCount+=urlViolations[1].length;} summary.value=WebInspector.UIString("CSS in the document body adversely impacts rendering performance.");callback(result);} function externalStylesheetsReceived(root,inlineStyleNodeIds,nodeIds) {if(progress.isCanceled()) return;if(!nodeIds) return;var externalStylesheetNodeIds=nodeIds;var result=null;if(inlineStyleNodeIds.length||externalStylesheetNodeIds.length){var urlToViolationsArray={};var externalStylesheetHrefs=[];for(va