15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.IPAddressRegexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CacheableResponseCodes = 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 200: true, 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 203: true, 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 206: true, 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 300: true, 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 301: true, 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 410: true, 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 304: true // Underlying request is cacheable 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 47a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {?Array.<!WebInspector.resourceTypes>} types 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {boolean} needFullResources 49a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @return {!Object.<string, !Array.<!WebInspector.NetworkRequest|string>>} 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.getDomainToResourcesMap = function(requests, types, needFullResources) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainToResourcesMap = {}; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0, size = requests.length; i < size; ++i) { 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var request = requests[i]; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (types && types.indexOf(request.type) === -1) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var parsedURL = request.url.asParsedURL(); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parsedURL) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domain = parsedURL.host; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainResources = domainToResourcesMap[domain]; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (domainResources === undefined) { 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) domainResources = []; 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) domainToResourcesMap[domain] = domainResources; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) domainResources.push(needFullResources ? request : request.url); 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return domainToResourcesMap; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.GzipRule = function() 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRule.call(this, "network-gzip", WebInspector.UIString("Enable gzip compression")); 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.GzipRule.prototype = { 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 83aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 86a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 89aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var totalSavings = 0; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var compressedSize = 0; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var candidateSize = 0; 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var summary = result.addChild("", true); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0, length = requests.length; i < length; ++i) { 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var request = requests[i]; 9751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (request.cached || request.statusCode === 304) 9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) continue; // Do not test cached resources. 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this._shouldCompress(request)) { 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var size = request.resourceSize; 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) candidateSize += size; 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this._isCompressed(request)) { 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) compressedSize += size; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var savings = 2 * size / 3; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalSavings += savings; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) summary.addFormatted("%r could save ~%s", request.url, Number.bytesToString(savings)); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount++; 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!totalSavings) { 11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) callback(null); 11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) summary.value = WebInspector.UIString("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):", Number.bytesToString(totalSavings)); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _isCompressed: function(request) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var encodingHeader = request.responseHeaderValue("Content-Encoding"); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!encodingHeader) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return /\b(?:gzip|deflate)\b/.test(encodingHeader); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _shouldCompress: function(request) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request.type.isTextType() && request.parsedURL.host && request.resourceSize !== undefined && request.resourceSize > 150; 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CombineExternalResourcesRule = function(id, name, type, resourceTypeName, allowedPerDomain) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebInspector.AuditRule.call(this, id, name); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._type = type; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._resourceTypeName = resourceTypeName; 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._allowedPerDomain = allowedPerDomain; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CombineExternalResourcesRule.prototype = { 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 157aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 160a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 163aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, [this._type], false); 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var penalizedResourceCount = 0; 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TODO: refactor according to the chosen i18n approach 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var summary = result.addChild("", true); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var domain in domainToResourcesMap) { 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainResources = domainToResourcesMap[domain]; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var extraResourceCount = domainResources.length - this._allowedPerDomain; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (extraResourceCount <= 0) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) penalizedResourceCount += extraResourceCount - 1; 17509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) summary.addChild(WebInspector.UIString("%d %s resources served from %s.", domainResources.length, this._resourceTypeName, WebInspector.AuditRuleResult.resourceDomain(domain))); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += domainResources.length; 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!penalizedResourceCount) { 17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) callback(null); 18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) summary.value = WebInspector.UIString("There are multiple resources served from same domain. Consider combining them into as few files as possible."); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRules.CombineExternalResourcesRule} 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CombineJsResourcesRule = function(allowedPerDomain) { 19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externaljs", WebInspector.UIString("Combine external JavaScript"), WebInspector.resourceTypes.Script, "JavaScript", allowedPerDomain); 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CombineJsResourcesRule.prototype = { 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRules.CombineExternalResourcesRule.prototype 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRules.CombineExternalResourcesRule} 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CombineCssResourcesRule = function(allowedPerDomain) { 20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externalcss", WebInspector.UIString("Combine external CSS"), WebInspector.resourceTypes.Stylesheet, "CSS", allowedPerDomain); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CombineCssResourcesRule.prototype = { 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRules.CombineExternalResourcesRule.prototype 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.MinimizeDnsLookupsRule = function(hostCountThreshold) { 21909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRule.call(this, "network-minimizelookups", WebInspector.UIString("Minimize DNS lookups")); 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._hostCountThreshold = hostCountThreshold; 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype = { 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 225aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 228a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 231aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var summary = result.addChild(""); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, null, false); 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var domain in domainToResourcesMap) { 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (domainToResourcesMap[domain].length > 1) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var parsedURL = domain.asParsedURL(); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parsedURL) 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!parsedURL.host.search(WebInspector.AuditRules.IPAddressRegexp)) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; // an IP address 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) summary.addSnippet(domain); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount++; 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!summary.children || summary.children.length <= this._hostCountThreshold) { 24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) callback(null); 24809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 24909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 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."); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.ParallelizeDownloadRule = function(optimalHostnameCount, minRequestThreshold, minBalanceThreshold) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 26409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRule.call(this, "network-parallelizehosts", WebInspector.UIString("Parallelize downloads across hostnames")); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._optimalHostnameCount = optimalHostnameCount; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._minRequestThreshold = minRequestThreshold; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._minBalanceThreshold = minBalanceThreshold; 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.ParallelizeDownloadRule.prototype = { 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 272aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 275a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 278aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 280d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {string} a 282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {string} b 283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function hostSorter(a, b) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var aCount = domainToResourcesMap[a].length; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var bCount = domainToResourcesMap[b].length; 288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return (aCount < bCount) ? 1 : (aCount === bCount) ? 0 : -1; 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap( 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) requests, 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) [WebInspector.resourceTypes.Stylesheet, WebInspector.resourceTypes.Image], 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) true); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var hosts = []; 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var url in domainToResourcesMap) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hosts.push(url); 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 30009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!hosts.length) { 30109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) callback(null); // no hosts (local file or something) 30209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 30309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hosts.sort(hostSorter); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var optimalHostnameCount = this._optimalHostnameCount; 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hosts.length > optimalHostnameCount) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hosts.splice(optimalHostnameCount); 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var busiestHostResourceCount = domainToResourcesMap[hosts[0]].length; 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var requestCountAboveThreshold = busiestHostResourceCount - this._minRequestThreshold; 31309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (requestCountAboveThreshold <= 0) { 31409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) callback(null); 31509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 31609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var avgResourcesPerHost = 0; 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0, size = hosts.length; i < size; ++i) 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) avgResourcesPerHost += domainToResourcesMap[hosts[i]].length; 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Assume optimal parallelization. 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) avgResourcesPerHost /= optimalHostnameCount; 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) avgResourcesPerHost = Math.max(avgResourcesPerHost, 1); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var pctAboveAvg = (requestCountAboveThreshold / avgResourcesPerHost) - 1.0; 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var minBalanceThreshold = this._minBalanceThreshold; 32809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (pctAboveAvg < minBalanceThreshold) { 32909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) callback(null); 33009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 33109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var requestsOnBusiestHost = domainToResourcesMap[hosts[0]]; 33409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 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); 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < requestsOnBusiestHost.length; ++i) 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addURL(requestsOnBusiestHost[i].url); 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount = requestsOnBusiestHost.length; 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * The reported CSS rule size is incorrect (parsed != original in WebKit), 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * so use percentages instead, which gives a better approximation. 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.UnusedCssRule = function() 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 35309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRule.call(this, "page-unusedcss", WebInspector.UIString("Remove unused CSS rules")); 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.UnusedCssRule.prototype = { 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 358aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 361a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 364aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 36651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) /** 367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets 36851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) */ 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function evalCallback(styleSheets) { 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!styleSheets.length) 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return callback(null); 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectors = []; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testedSelectors = {}; 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < styleSheets.length; ++i) { 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var styleSheet = styleSheets[i]; 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) { 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectorText = styleSheet.rules[curRule].selectorText; 37993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (testedSelectors[selectorText]) 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectors.push(selectorText); 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testedSelectors[selectorText] = 1; 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 38651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) var foundSelectors = {}; 38751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 38851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) /** 389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets 39051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) */ 39151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) function selectorsCallback(styleSheets) 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var inlineBlockOrdinal = 0; 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var totalStylesheetSize = 0; 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var totalUnusedStylesheetSize = 0; 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var summary; 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < styleSheets.length; ++i) { 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var styleSheet = styleSheets[i]; 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var unusedRules = []; 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) { 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var rule = styleSheet.rules[curRule]; 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!testedSelectors[rule.selectorText] || foundSelectors[rule.selectorText]) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unusedRules.push(rule.selectorText); 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 410926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) totalStylesheetSize += styleSheet.rules.length; 411926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) totalUnusedStylesheetSize += unusedRules.length; 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!unusedRules.length) 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var resource = WebInspector.resourceForURL(styleSheet.sourceURL); 417d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var isInlineBlock = resource && resource.request && resource.request.type === WebInspector.resourceTypes.Document; 41809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : WebInspector.UIString("Inline block #%d", ++inlineBlockOrdinal); 419926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) var pctUnused = Math.round(100 * unusedRules.length / styleSheet.rules.length); 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!summary) 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) summary = result.addChild("", true); 422926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) var entry = summary.addFormatted("%s: %d% is not used by the current page.", url, pctUnused); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var j = 0; j < unusedRules.length; ++j) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addSnippet(unusedRules[j]); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += unusedRules.length; 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!totalUnusedStylesheetSize) 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return callback(null); 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var totalUnusedPercent = Math.round(100 * totalUnusedStylesheetSize / totalStylesheetSize); 43409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) summary.value = WebInspector.UIString("%s rules (%d%) of CSS not used by the current page.", totalUnusedStylesheetSize, totalUnusedPercent); 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 43951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) /** 44051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * @param {?function()} boundSelectorsCallback 44151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * @param {string} selector 44251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * @param {?DOMAgent.NodeId} nodeId 44351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) */ 44451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) function queryCallback(boundSelectorsCallback, selector, nodeId) 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (nodeId) 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) foundSelectors[selector] = true; 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (boundSelectorsCallback) 44951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) boundSelectorsCallback(); 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 45251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) /** 453a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!Array.<string>} selectors 454a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!WebInspector.DOMDocument} document 45551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) */ 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function documentLoaded(selectors, document) { 45793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var pseudoSelectorRegexp = /::?(?:[\w-]+)(?:\(.*?\))?/g; 45851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (!selectors.length) { 45951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) selectorsCallback([]); 46051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return; 46151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < selectors.length; ++i) { 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 46593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) var effectiveSelector = selectors[i].replace(pseudoSelectorRegexp, ""); 466aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.querySelector(document.id, effectiveSelector, queryCallback.bind(null, i === selectors.length - 1 ? selectorsCallback.bind(null, styleSheets) : null, selectors[i])); 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 470aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.requestDocument(documentLoaded.bind(null, selectors)); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 473aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch var styleSheetInfos = target.cssModel.allStyleSheets(); 47409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!styleSheetInfos || !styleSheetInfos.length) { 47509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) evalCallback([]); 47609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 47709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 478d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(styleSheetInfos, progress, evalCallback); 479d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) styleSheetProcessor.run(); 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 486d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @typedef {!{sourceURL: string, rules: !Array.<!WebInspector.CSSParser.StyleRule>}} 487d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 488d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)WebInspector.AuditRules.ParsedStyleSheet; 489d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 490d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)/** 491d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @constructor 492d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!Array.<!WebInspector.CSSStyleSheetHeader>} styleSheetHeaders 493d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.Progress} progress 494d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!function(!Array.<!WebInspector.AuditRules.ParsedStyleSheet>)} styleSheetsParsedCallback 495d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 496d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)WebInspector.AuditRules.StyleSheetProcessor = function(styleSheetHeaders, progress, styleSheetsParsedCallback) 497d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 498d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._styleSheetHeaders = styleSheetHeaders; 499d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._progress = progress; 500d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._styleSheets = []; 501d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._styleSheetsParsedCallback = styleSheetsParsedCallback; 502d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 503d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 504d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)WebInspector.AuditRules.StyleSheetProcessor.prototype = { 505d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) run: function() 506d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 507d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._parser = new WebInspector.CSSParser(); 508d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._processNextStyleSheet(); 509d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) }, 510d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 511d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) _terminateWorker: function() 512d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 513d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (this._parser) { 514d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._parser.dispose(); 515d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) delete this._parser; 516d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 517d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) }, 518d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 519d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) _finish: function() 520d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 521d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._terminateWorker(); 522d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._styleSheetsParsedCallback(this._styleSheets); 523d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) }, 524d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 525d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) _processNextStyleSheet: function() 526d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 527d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!this._styleSheetHeaders.length) { 528d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._finish(); 529d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 530d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 531d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._currentStyleSheetHeader = this._styleSheetHeaders.shift(); 532d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._parser.fetchAndParse(this._currentStyleSheetHeader, this._onStyleSheetParsed.bind(this)); 533d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) }, 534d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 535d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 536d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!Array.<!WebInspector.CSSParser.Rule>} rules 537d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 538d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) _onStyleSheetParsed: function(rules) 539d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 540d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (this._progress.isCanceled()) { 541d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._terminateWorker(); 542d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 543d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 544d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 545d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var styleRules = []; 546d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (var i = 0; i < rules.length; ++i) { 547d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var rule = rules[i]; 548d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (rule.selectorText) 549d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) styleRules.push(rule); 550d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 551d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._styleSheets.push({ 552d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) sourceURL: this._currentStyleSheetHeader.sourceURL, 553d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) rules: styleRules 554d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) }); 555d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._processNextStyleSheet(); 556d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) }, 557d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 558d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 559d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)/** 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CacheControlRule = function(id, name) 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebInspector.AuditRule.call(this, id, name); 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CacheControlRule.MillisPerMonth = 1000 * 60 * 60 * 24 * 30; 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CacheControlRule.prototype = { 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 572aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 575a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(!WebInspector.AuditRuleResult)} callback 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 578aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var cacheableAndNonCacheableResources = this._cacheableAndNonCacheableResources(requests); 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cacheableAndNonCacheableResources[0].length) 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.runChecks(cacheableAndNonCacheableResources[0], result); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.handleNonCacheableResources(cacheableAndNonCacheableResources[1], result); 5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) handleNonCacheableResources: function(requests, result) 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _cacheableAndNonCacheableResources: function(requests) 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var processedResources = [[], []]; 5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < requests.length; ++i) { 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var request = requests[i]; 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!this.isCacheableResource(request)) 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this._isExplicitlyNonCacheable(request)) 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) processedResources[1].push(request); 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) processedResources[0].push(request); 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return processedResources; 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) execCheck: function(messageText, requestCheckFunction, requests, result) 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var requestCount = requests.length; 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var urls = []; 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < requestCount; ++i) { 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (requestCheckFunction.call(this, requests[i])) 6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) urls.push(requests[i].url); 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (urls.length) { 6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var entry = result.addChild(messageText, true); 6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addURLs(urls); 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += urls.length; 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 62209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 62309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 62409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {number} timeMs 62509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {boolean} 62609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) freshnessLifetimeGreaterThan: function(request, timeMs) 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var dateHeader = this.responseHeader(request, "Date"); 6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!dateHeader) 6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var dateHeaderMs = Date.parse(dateHeader); 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isNaN(dateHeaderMs)) 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var freshnessLifetimeMs; 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var maxAgeMatch = this.responseHeaderMatch(request, "Cache-Control", "max-age=(\\d+)"); 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (maxAgeMatch) 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) freshnessLifetimeMs = (maxAgeMatch[1]) ? 1000 * maxAgeMatch[1] : 0; 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expiresHeader = this.responseHeader(request, "Expires"); 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (expiresHeader) { 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expDate = Date.parse(expiresHeader); 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isNaN(expDate)) 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) freshnessLifetimeMs = expDate - dateHeaderMs; 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (isNaN(freshnessLifetimeMs)) ? false : freshnessLifetimeMs > timeMs; 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 65409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 65509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 65609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {string} header 65709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {string|undefined} 65809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) responseHeader: function(request, header) 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request.responseHeaderValue(header); 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 66409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 66509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 66609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {string} header 66709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {boolean} 66809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasResponseHeader: function(request, header) 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request.responseHeaderValue(header) !== undefined; 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 67409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 67509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 67609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {boolean} 67709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isCompressible: function(request) 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request.type.isTextType(); 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 68309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 68409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 68509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {boolean} 68609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isPubliclyCacheable: function(request) 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this._isExplicitlyNonCacheable(request)) 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this.responseHeaderMatch(request, "Cache-Control", "public")) 6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return request.url.indexOf("?") === -1 && !this.responseHeaderMatch(request, "Cache-Control", "private"); 6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 69809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 69909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 70009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {string} header 70109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {string} regexp 70209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {?Array.<string>} 70309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) responseHeaderMatch: function(request, header, regexp) 7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request.responseHeaderValue(header) 7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ? request.responseHeaderValue(header).match(new RegExp(regexp, "im")) 70809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) : null; 7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 71109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 71209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 71309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {boolean} 71409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hasExplicitExpiration: function(request) 7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.hasResponseHeader(request, "Date") && 71809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) (this.hasResponseHeader(request, "Expires") || !!this.responseHeaderMatch(request, "Cache-Control", "max-age")); 7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 72109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 72209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 72309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {boolean} 72409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _isExplicitlyNonCacheable: function(request) 7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var hasExplicitExp = this.hasExplicitExpiration(request); 72809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return !!this.responseHeaderMatch(request, "Cache-Control", "(no-cache|no-store|must-revalidate)") || 72909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) !!this.responseHeaderMatch(request, "Pragma", "no-cache") || 7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (hasExplicitExp && !this.freshnessLifetimeGreaterThan(request, 0)) || 73109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) (!hasExplicitExp && !!request.url && request.url.indexOf("?") >= 0) || 7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (!hasExplicitExp && !this.isCacheableResource(request)); 7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 73509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) /** 73609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @param {!WebInspector.NetworkRequest} request 73709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * @return {boolean} 73809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */ 7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) isCacheableResource: function(request) 7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request.statusCode !== undefined && WebInspector.AuditRules.CacheableResponseCodes[request.statusCode]; 7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRules.CacheControlRule} 7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.BrowserCacheControlRule = function() 7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 75309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRules.CacheControlRule.call(this, "http-browsercache", WebInspector.UIString("Leverage browser caching")); 7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.BrowserCacheControlRule.prototype = { 7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) handleNonCacheableResources: function(requests, result) 7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (requests.length) { 76009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) var entry = result.addChild(WebInspector.UIString("The following resources are explicitly non-cacheable. Consider making them cacheable if possible:"), true); 7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += requests.length; 7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < requests.length; ++i) 7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addURL(requests[i].url); 7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) runChecks: function(requests, result, callback) 7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 76909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 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:"), 7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._missingExpirationCheck, requests, result); 77109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) this.execCheck(WebInspector.UIString("The following resources specify a \"Vary\" header that disables caching in most versions of Internet Explorer:"), 7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._varyCheck, requests, result); 77309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) this.execCheck(WebInspector.UIString("The following cacheable resources have a short freshness lifetime:"), 7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._oneMonthExpirationCheck, requests, result); 7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Unable to implement the favicon check due to the WebKit limitations. 77709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) this.execCheck(WebInspector.UIString("To further improve cache hit rate, specify an expiration one year in the future for the following cacheable resources:"), 7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._oneYearExpirationCheck, requests, result); 7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _missingExpirationCheck: function(request) 7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.isCacheableResource(request) && !this.hasResponseHeader(request, "Set-Cookie") && !this.hasExplicitExpiration(request); 7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _varyCheck: function(request) 7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var varyHeader = this.responseHeader(request, "Vary"); 7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (varyHeader) { 7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) varyHeader = varyHeader.replace(/User-Agent/gi, ""); 7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) varyHeader = varyHeader.replace(/Accept-Encoding/gi, ""); 7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) varyHeader = varyHeader.replace(/[, ]*/g, ""); 7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return varyHeader && varyHeader.length && this.isCacheableResource(request) && this.freshnessLifetimeGreaterThan(request, 0); 7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _oneMonthExpirationCheck: function(request) 7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.isCacheableResource(request) && 8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !this.hasResponseHeader(request, "Set-Cookie") && 8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !this.freshnessLifetimeGreaterThan(request, WebInspector.AuditRules.CacheControlRule.MillisPerMonth) && 8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.freshnessLifetimeGreaterThan(request, 0); 8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _oneYearExpirationCheck: function(request) 8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.isCacheableResource(request) && 8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !this.hasResponseHeader(request, "Set-Cookie") && 8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !this.freshnessLifetimeGreaterThan(request, 11 * WebInspector.AuditRules.CacheControlRule.MillisPerMonth) && 8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.freshnessLifetimeGreaterThan(request, WebInspector.AuditRules.CacheControlRule.MillisPerMonth); 8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRules.CacheControlRule.prototype 8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRules.CacheControlRule} 8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.ProxyCacheControlRule = function() { 82109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRules.CacheControlRule.call(this, "http-proxycache", WebInspector.UIString("Leverage proxy caching")); 8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.ProxyCacheControlRule.prototype = { 8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) runChecks: function(requests, result, callback) 8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 82709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) this.execCheck(WebInspector.UIString("Resources with a \"?\" in the URL are not cached by most proxy caching servers:"), 8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._questionMarkCheck, requests, result); 82909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) this.execCheck(WebInspector.UIString("Consider adding a \"Cache-Control: public\" header to the following resources:"), 8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._publicCachingCheck, requests, result); 83109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 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."), 8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._setCookieCacheableCheck, requests, result); 8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _questionMarkCheck: function(request) 8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request.url.indexOf("?") >= 0 && !this.hasResponseHeader(request, "Set-Cookie") && this.isPubliclyCacheable(request); 8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _publicCachingCheck: function(request) 8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.isCacheableResource(request) && 8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !this.isCompressible(request) && 8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !this.responseHeaderMatch(request, "Cache-Control", "public") && 8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !this.hasResponseHeader(request, "Set-Cookie"); 8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _setCookieCacheableCheck: function(request) 8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.hasResponseHeader(request, "Set-Cookie") && this.isPubliclyCacheable(request); 8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRules.CacheControlRule.prototype 8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.ImageDimensionsRule = function() 8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 86209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRule.call(this, "page-imagedims", WebInspector.UIString("Specify image dimensions")); 8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.ImageDimensionsRule.prototype = { 8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 867aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 870a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 873aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var urlToNoDimensionCount = {}; 8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function doneCallback() 8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var url in urlToNoDimensionCount) { 88009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 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); 8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var format = "%r"; 8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (urlToNoDimensionCount[url] > 1) 8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) format += " (%d uses)"; 8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addFormatted(format, url, urlToNoDimensionCount[url]); 8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount++; 8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(entry ? result : null); 8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function imageStylesReady(imageId, styles, isLastStyle, computedStyle) 8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch const node = target.domModel.nodeForId(imageId); 8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var src = node.getAttribute("src"); 8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!src.asParsedURL()) { 8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) { 8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (frameOwnerCandidate.baseURL) { 9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var completeSrc = WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL, src); 9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (completeSrc) 9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) src = completeSrc; 9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (computedStyle.getPropertyValue("position") === "absolute") { 9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isLastStyle) 9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doneCallback(); 9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (styles.attributesStyle) { 9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var widthFound = !!styles.attributesStyle.getLiveProperty("width"); 9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var heightFound = !!styles.attributesStyle.getLiveProperty("height"); 9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var inlineStyle = styles.inlineStyle; 9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inlineStyle) { 9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inlineStyle.getPropertyValue("width") !== "") 9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) widthFound = true; 9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inlineStyle.getPropertyValue("height") !== "") 9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heightFound = true; 9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = styles.matchedCSSRules.length - 1; i >= 0 && !(widthFound && heightFound); --i) { 9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var style = styles.matchedCSSRules[i].style; 9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style.getPropertyValue("width") !== "") 9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) widthFound = true; 9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style.getPropertyValue("height") !== "") 9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) heightFound = true; 9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!widthFound || !heightFound) { 9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (src in urlToNoDimensionCount) 9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++urlToNoDimensionCount[src]; 9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) urlToNoDimensionCount[src] = 1; 9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isLastStyle) 9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doneCallback(); 9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 946a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) /** 947a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!Array.<!DOMAgent.NodeId>=} nodeIds 948a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) */ 9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function getStyles(nodeIds) 9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var targetResult = {}; 9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function inlineCallback(inlineStyle, attributesStyle) 9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) targetResult.inlineStyle = inlineStyle; 9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) targetResult.attributesStyle = attributesStyle; 9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function matchedCallback(result) 9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result) 9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) targetResult.matchedCSSRules = result.matchedCSSRules; 9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nodeIds || !nodeIds.length) 9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) doneCallback(); 9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; nodeIds && i < nodeIds.length; ++i) { 971aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.cssModel.getMatchedStylesAsync(nodeIds[i], false, false, matchedCallback); 972aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.cssModel.getInlineStylesAsync(nodeIds[i], inlineCallback); 973aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.cssModel.getComputedStyleAsync(nodeIds[i], imageStylesReady.bind(null, nodeIds[i], targetResult, i === nodeIds.length - 1)); 9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function onDocumentAvailable(root) 9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 981aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.querySelectorAll(root.id, "img[src]", getStyles); 9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 986aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.requestDocument(onDocumentAvailable); 9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CssInHeadRule = function() 9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 99809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRule.call(this, "page-cssinhead", WebInspector.UIString("Put CSS in the document head")); 9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CssInHeadRule.prototype = { 10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 1003aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1006a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1009aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function evalCallback(evalResult) 10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!evalResult) 10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return callback(null); 10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var summary = result.addChild(""); 10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var outputMessages = []; 10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var url in evalResult) { 10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var urlViolations = evalResult[url]; 10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (urlViolations[0]) { 10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.addFormatted("%s style block(s) in the %r body should be moved to the document head.", urlViolations[0], url); 10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += urlViolations[0]; 10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < urlViolations[1].length; ++i) 10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.addFormatted("Link node %r should be moved to the document head in %r", urlViolations[1][i], url); 10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += urlViolations[1].length; 10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 103209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) summary.value = WebInspector.UIString("CSS in the document body adversely impacts rendering performance."); 10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1036a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) /** 1037f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) * @param {!WebInspector.DOMNode} root 1038f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) * @param {!Array.<!DOMAgent.NodeId>=} inlineStyleNodeIds 1039a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!Array.<!DOMAgent.NodeId>=} nodeIds 1040a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) */ 10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function externalStylesheetsReceived(root, inlineStyleNodeIds, nodeIds) 10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nodeIds) 10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var externalStylesheetNodeIds = nodeIds; 10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var result = null; 10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (inlineStyleNodeIds.length || externalStylesheetNodeIds.length) { 10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var urlToViolationsArray = {}; 10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var externalStylesheetHrefs = []; 10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var j = 0; j < externalStylesheetNodeIds.length; ++j) { 1054aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch var linkNode = target.domModel.nodeForId(externalStylesheetNodeIds[j]); 10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var completeHref = WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.baseURL, linkNode.getAttribute("href")); 10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) externalStylesheetHrefs.push(completeHref || "<empty>"); 10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) urlToViolationsArray[root.documentURL] = [inlineStyleNodeIds.length, externalStylesheetHrefs]; 10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = urlToViolationsArray; 10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evalCallback(result); 10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1064a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) /** 1065f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) * @param {!WebInspector.DOMNode} root 1066a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!Array.<!DOMAgent.NodeId>=} nodeIds 1067a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) */ 10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function inlineStylesReceived(root, nodeIds) 10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nodeIds) 10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1075aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.querySelectorAll(root.id, "body link[rel~='stylesheet'][href]", externalStylesheetsReceived.bind(null, root, nodeIds)); 10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1078f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) /** 1079f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) * @param {!WebInspector.DOMNode} root 1080f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) */ 10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function onDocumentAvailable(root) 10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1086aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.querySelectorAll(root.id, "body style", inlineStylesReceived.bind(null, root)); 10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1089aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.requestDocument(onDocumentAvailable); 10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.StylesScriptsOrderRule = function() 11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 110109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRule.call(this, "page-stylescriptorder", WebInspector.UIString("Optimize the order of styles and scripts")); 11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.StylesScriptsOrderRule.prototype = { 11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 1106aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1109a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1112aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function evalCallback(resultValue) 11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 11185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!resultValue) 11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return callback(null); 11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var lateCssUrls = resultValue[0]; 11235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var cssBeforeInlineCount = resultValue[1]; 11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 112506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (lateCssUrls.length) { 112609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) var entry = result.addChild(WebInspector.UIString("The following external CSS files were included after an external JavaScript file in the document head. To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript."), true); 112706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) entry.addURLs(lateCssUrls); 112806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) result.violationCount += lateCssUrls.length; 112906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) } 11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cssBeforeInlineCount) { 113209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) result.addChild(WebInspector.UIString(" %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.", cssBeforeInlineCount, cssBeforeInlineCount > 1 ? "s were" : " was")); 11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += cssBeforeInlineCount; 11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1138a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) /** 1139a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!Array.<!DOMAgent.NodeId>} lateStyleIds 1140a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!Array.<!DOMAgent.NodeId>=} nodeIds 1141a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) */ 11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function cssBeforeInlineReceived(lateStyleIds, nodeIds) 11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nodeIds) 11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var cssBeforeInlineCount = nodeIds.length; 11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var result = null; 11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (lateStyleIds.length || cssBeforeInlineCount) { 11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var lateStyleUrls = []; 11545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < lateStyleIds.length; ++i) { 1155aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch var lateStyleNode = target.domModel.nodeForId(lateStyleIds[i]); 11565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var completeHref = WebInspector.ParsedURL.completeURL(lateStyleNode.ownerDocument.baseURL, lateStyleNode.getAttribute("href")); 11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lateStyleUrls.push(completeHref || "<empty>"); 11585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = [ lateStyleUrls, cssBeforeInlineCount ]; 11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evalCallback(result); 11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) /** 1166a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!WebInspector.DOMDocument} root 1167a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!Array.<!DOMAgent.NodeId>=} nodeIds 1168a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) */ 11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function lateStylesReceived(root, nodeIds) 11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!nodeIds) 11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1177aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.querySelectorAll(root.id, "head link[rel~='stylesheet'][href] ~ script:not([src])", cssBeforeInlineReceived.bind(null, nodeIds)); 11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1180a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) /** 1181a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {!WebInspector.DOMDocument} root 1182a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) */ 11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function onDocumentAvailable(root) 11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 11855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 11875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1188aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.querySelectorAll(root.id, "head script[src] ~ link[rel~='stylesheet'][href]", lateStylesReceived.bind(null, root)); 11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1191aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch target.domModel.requestDocument(onDocumentAvailable); 11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CSSRuleBase = function(id, name) 12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebInspector.AuditRule.call(this, id, name); 12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CSSRuleBase.prototype = { 12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 1208aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1211a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(?WebInspector.AuditRuleResult)} callback 12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1214aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1216aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch var headers = target.cssModel.allStyleSheets(); 12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 121809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!headers.length) { 121909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) callback(null); 122009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return; 122109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 1222d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var activeHeaders = [] 122309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) for (var i = 0; i < headers.length; ++i) { 1224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!headers[i].disabled) 1225d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) activeHeaders.push(headers[i]); 12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1228d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(activeHeaders, progress, this._styleSheetsLoaded.bind(this, result, callback, progress)); 1229d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) styleSheetProcessor.run(); 12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1233d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1234d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {function(!WebInspector.AuditRuleResult)} callback 1235d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.Progress} progress 1236d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets 1237d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 1238d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) _styleSheetsLoaded: function(result, callback, progress, styleSheets) 12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1240d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (var i = 0; i < styleSheets.length; ++i) 1241d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._visitStyleSheet(styleSheets[i], result); 1242d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) callback(result); 1243d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) }, 12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1246d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1248d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 1249d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) _visitStyleSheet: function(styleSheet, result) 1250d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 1251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this.visitStyleSheet(styleSheet, result); 12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (var i = 0; i < styleSheet.rules.length; ++i) 1254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._visitRule(styleSheet, styleSheet.rules[i], result); 12555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1256d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this.didVisitStyleSheet(styleSheet, result); 12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1259d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1260d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.StyleRule} rule 1262d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _visitRule: function(styleSheet, rule, result) 12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.visitRule(styleSheet, rule, result); 1267d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var allProperties = rule.properties; 12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < allProperties.length; ++i) 1269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this.visitProperty(styleSheet, rule, allProperties[i], result); 12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.didVisitRule(styleSheet, rule, result); 12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1273d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1276d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visitStyleSheet: function(styleSheet, result) 12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Subclasses can implement. 12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1285d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didVisitStyleSheet: function(styleSheet, result) 12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Subclasses can implement. 12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 1290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 1291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1292d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.StyleRule} rule 1294d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1295d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visitRule: function(styleSheet, rule, result) 12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Subclasses can implement. 12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1302d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.StyleRule} rule 1304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didVisitRule: function(styleSheet, rule, result) 13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Subclasses can implement. 13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 1310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 1311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.StyleRule} rule 1314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.Property} property 1315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1316d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 1317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) visitProperty: function(styleSheet, rule, property, result) 13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Subclasses can implement. 13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRules.CSSRuleBase} 13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.VendorPrefixedCSSProperties = function() 13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 133109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRules.CSSRuleBase.call(this, "page-vendorprefixedcss", WebInspector.UIString("Use normal CSS property names instead of vendor-prefixed ones")); 13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._webkitPrefix = "-webkit-"; 13335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.VendorPrefixedCSSProperties.supportedProperties = [ 13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "background-clip", "background-origin", "background-size", 13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "border-radius", "border-bottom-left-radius", "border-bottom-right-radius", "border-top-left-radius", "border-top-right-radius", 13385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "box-shadow", "box-sizing", "opacity", "text-shadow" 13395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)].keySet(); 13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.VendorPrefixedCSSProperties.prototype = { 1342d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1344d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didVisitStyleSheet: function(styleSheet) 13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete this._styleSheetResult; 13485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1350d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1351d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.StyleRule} rule 1352d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visitRule: function(rule) 13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._mentionedProperties = {}; 13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didVisitRule: function() 13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete this._ruleResult; 13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) delete this._mentionedProperties; 13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /** 1365d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.StyleRule} rule 1367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.CSSParser.Property} property 1368d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1369d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) */ 1370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) visitProperty: function(styleSheet, rule, property, result) 13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!property.name.startsWith(this._webkitPrefix)) 13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var normalPropertyName = property.name.substring(this._webkitPrefix.length).toLowerCase(); // Start just after the "-webkit-" prefix. 13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (WebInspector.AuditRules.VendorPrefixedCSSProperties.supportedProperties[normalPropertyName] && !this._mentionedProperties[normalPropertyName]) { 13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._mentionedProperties[normalPropertyName] = true; 13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!this._styleSheetResult) 1379d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) this._styleSheetResult = result.addChild(styleSheet.sourceURL ? WebInspector.linkifyResourceAsNode(styleSheet.sourceURL) : WebInspector.UIString("<unknown>")); 13805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!this._ruleResult) { 1381d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) var anchor = WebInspector.linkifyURLAsNode(styleSheet.sourceURL, rule.selectorText); 1382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) anchor.lineNumber = rule.lineNumber; 13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._ruleResult = this._styleSheetResult.addChild(anchor); 13845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++result.violationCount; 138609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) this._ruleResult.addSnippet(WebInspector.UIString("\"%s%s\" is used, but \"%s\" is supported.", this._webkitPrefix, normalPropertyName, normalPropertyName)); 13875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRules.CSSRuleBase.prototype 13915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRule} 13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CookieRuleBase = function(id, name) 13985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebInspector.AuditRule.call(this, id, name); 14005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CookieRuleBase.prototype = { 14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /** 1404aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch * @param {!WebInspector.Target} target 14055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!Array.<!WebInspector.NetworkRequest>} requests 14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.AuditRuleResult} result 1407a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) * @param {function(!WebInspector.AuditRuleResult)} callback 14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {!WebInspector.Progress} progress 14095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1410aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch doRun: function(target, requests, result, callback, progress) 14115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var self = this; 141353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) function resultCallback(receivedCookies) { 14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (progress.isCanceled()) 14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 141753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) self.processCookies(receivedCookies, requests, result); 14185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(result); 14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebInspector.Cookies.getCookiesAsync(resultCallback); 14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) mapResourceCookies: function(requestsByDomain, allCookies, callback) 14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < allCookies.length; ++i) { 14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var requestDomain in requestsByDomain) { 14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (WebInspector.Cookies.cookieDomainMatchesResourceDomain(allCookies[i].domain(), requestDomain)) 14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._callbackForResourceCookiePairs(requestsByDomain[requestDomain], allCookies[i], callback); 14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _callbackForResourceCookiePairs: function(requests, cookie, callback) 14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!requests) 14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < requests.length; ++i) { 14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (WebInspector.Cookies.cookieMatchesResourceURL(cookie, requests[i].url)) 14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(requests[i], cookie); 14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRule.prototype 14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRules.CookieRuleBase} 14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CookieSizeRule = function(avgBytesThreshold) 14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 145309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRules.CookieRuleBase.call(this, "http-cookiesize", WebInspector.UIString("Minimize cookie size")); 14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._avgBytesThreshold = avgBytesThreshold; 14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._maxBytesThreshold = 1000; 14565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.CookieSizeRule.prototype = { 14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _average: function(cookieArray) 14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var total = 0; 14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < cookieArray.length; ++i) 14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) total += cookieArray[i].size(); 14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return cookieArray.length ? Math.round(total / cookieArray.length) : 0; 14655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _max: function(cookieArray) 14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var result = 0; 14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < cookieArray.length; ++i) 14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = Math.max(cookieArray[i].size(), result); 14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 14735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 14745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) processCookies: function(allCookies, requests, result) 14765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function maxSizeSorter(a, b) 14785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return b.maxCookieSize - a.maxCookieSize; 14805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function avgSizeSorter(a, b) 14835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return b.avgCookieSize - a.avgCookieSize; 14855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var cookiesPerResourceDomain = {}; 14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function collectorCallback(request, cookie) 14905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var cookies = cookiesPerResourceDomain[request.parsedURL.host]; 14925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!cookies) { 14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cookies = []; 14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cookiesPerResourceDomain[request.parsedURL.host] = cookies; 14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cookies.push(cookie); 14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!allCookies.length) 15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var sortedCookieSizes = []; 15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, 15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) null, 15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) true); 15075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var matchingResourceData = {}; 150843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles) this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback); 15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var requestDomain in cookiesPerResourceDomain) { 15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var cookies = cookiesPerResourceDomain[requestDomain]; 15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sortedCookieSizes.push({ 15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) domain: requestDomain, 15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) avgCookieSize: this._average(cookies), 15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) maxCookieSize: this._max(cookies) 15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var avgAllCookiesSize = this._average(allCookies); 15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var hugeCookieDomains = []; 15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sortedCookieSizes.sort(maxSizeSorter); 15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) { 15245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var maxCookieSize = sortedCookieSizes[i].maxCookieSize; 15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (maxCookieSize > this._maxBytesThreshold) 15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hugeCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(sortedCookieSizes[i].domain) + ": " + Number.bytesToString(maxCookieSize)); 15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var bigAvgCookieDomains = []; 15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sortedCookieSizes.sort(avgSizeSorter); 15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) { 15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domain = sortedCookieSizes[i].domain; 15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var avgCookieSize = sortedCookieSizes[i].avgCookieSize; 15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (avgCookieSize > this._avgBytesThreshold && avgCookieSize < this._maxBytesThreshold) 15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bigAvgCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(domain) + ": " + Number.bytesToString(avgCookieSize)); 15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 153709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) result.addChild(WebInspector.UIString("The average cookie size for all requests on this page is %s", Number.bytesToString(avgAllCookiesSize))); 15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var message; 15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hugeCookieDomains.length) { 154109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) var entry = result.addChild(WebInspector.UIString("The following domains have a cookie size in excess of 1KB. This is harmful because requests with cookies larger than 1KB typically cannot fit into a single network packet."), true); 15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addURLs(hugeCookieDomains); 15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += hugeCookieDomains.length; 15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (bigAvgCookieDomains.length) { 154709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) var entry = result.addChild(WebInspector.UIString("The following domains have an average cookie size in excess of %d bytes. Reducing the size of cookies for these domains can reduce the time it takes to send requests.", this._avgBytesThreshold), true); 15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addURLs(bigAvgCookieDomains); 15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount += bigAvgCookieDomains.length; 15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRules.CookieRuleBase.prototype 15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @extends {WebInspector.AuditRules.CookieRuleBase} 15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.StaticCookielessRule = function(minResources) 15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 156209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) WebInspector.AuditRules.CookieRuleBase.call(this, "http-staticcookieless", WebInspector.UIString("Serve static content from a cookieless domain")); 15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this._minResources = minResources; 15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WebInspector.AuditRules.StaticCookielessRule.prototype = { 15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) processCookies: function(allCookies, requests, result) 15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, 15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) [WebInspector.resourceTypes.Stylesheet, 15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebInspector.resourceTypes.Image], 15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) true); 15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var totalStaticResources = 0; 15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var domain in domainToResourcesMap) 15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalStaticResources += domainToResourcesMap[domain].length; 15765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (totalStaticResources < this._minResources) 15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var matchingResourceData = {}; 15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.mapResourceCookies(domainToResourcesMap, allCookies, this._collectorCallback.bind(this, matchingResourceData)); 15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var badUrls = []; 15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var cookieBytes = 0; 15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var url in matchingResourceData) { 15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) badUrls.push(url); 15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cookieBytes += matchingResourceData[url] 15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (badUrls.length < this._minResources) 15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 159009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) var entry = result.addChild(WebInspector.UIString("%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:", Number.bytesToString(cookieBytes)), true); 15915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) entry.addURLs(badUrls); 15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.violationCount = badUrls.length; 15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) _collectorCallback: function(matchingResourceData, request, cookie) 15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) matchingResourceData[request.url] = (matchingResourceData[request.url] || 0) + cookie.size(); 15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }, 15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) __proto__: WebInspector.AuditRules.CookieRuleBase.prototype 16015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1602