Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/audits/AuditRules.js

Issue 2493373002: DevTools: rename WebInspector into modules. (Closed)
Patch Set: for bots Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer 11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the 12 * in the documentation and/or other materials provided with the
13 * distribution. 13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its 14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from 15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission. 16 * this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 WebInspector.AuditRules.IPAddressRegexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ ; 30 Audits.AuditRules.IPAddressRegexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
31 31
32 WebInspector.AuditRules.CacheableResponseCodes = { 32 Audits.AuditRules.CacheableResponseCodes = {
33 200: true, 33 200: true,
34 203: true, 34 203: true,
35 206: true, 35 206: true,
36 300: true, 36 300: true,
37 301: true, 37 301: true,
38 410: true, 38 410: true,
39 39
40 304: true // Underlying request is cacheable 40 304: true // Underlying request is cacheable
41 }; 41 };
42 42
43 /** 43 /**
44 * @param {!Array.<!WebInspector.NetworkRequest>} requests 44 * @param {!Array.<!SDK.NetworkRequest>} requests
45 * @param {?Array.<!WebInspector.ResourceType>} types 45 * @param {?Array.<!Common.ResourceType>} types
46 * @param {boolean} needFullResources 46 * @param {boolean} needFullResources
47 * @return {!Object.<string, !Array.<!WebInspector.NetworkRequest|string>>} 47 * @return {!Object.<string, !Array.<!SDK.NetworkRequest|string>>}
48 */ 48 */
49 WebInspector.AuditRules.getDomainToResourcesMap = function(requests, types, need FullResources) { 49 Audits.AuditRules.getDomainToResourcesMap = function(requests, types, needFullRe sources) {
50 var domainToResourcesMap = {}; 50 var domainToResourcesMap = {};
51 for (var i = 0, size = requests.length; i < size; ++i) { 51 for (var i = 0, size = requests.length; i < size; ++i) {
52 var request = requests[i]; 52 var request = requests[i];
53 if (types && types.indexOf(request.resourceType()) === -1) 53 if (types && types.indexOf(request.resourceType()) === -1)
54 continue; 54 continue;
55 var parsedURL = request.url.asParsedURL(); 55 var parsedURL = request.url.asParsedURL();
56 if (!parsedURL) 56 if (!parsedURL)
57 continue; 57 continue;
58 var domain = parsedURL.host; 58 var domain = parsedURL.host;
59 var domainResources = domainToResourcesMap[domain]; 59 var domainResources = domainToResourcesMap[domain];
60 if (domainResources === undefined) { 60 if (domainResources === undefined) {
61 domainResources = []; 61 domainResources = [];
62 domainToResourcesMap[domain] = domainResources; 62 domainToResourcesMap[domain] = domainResources;
63 } 63 }
64 domainResources.push(needFullResources ? request : request.url); 64 domainResources.push(needFullResources ? request : request.url);
65 } 65 }
66 return domainToResourcesMap; 66 return domainToResourcesMap;
67 }; 67 };
68 68
69 /** 69 /**
70 * @unrestricted 70 * @unrestricted
71 */ 71 */
72 WebInspector.AuditRules.GzipRule = class extends WebInspector.AuditRule { 72 Audits.AuditRules.GzipRule = class extends Audits.AuditRule {
73 constructor() { 73 constructor() {
74 super('network-gzip', WebInspector.UIString('Enable gzip compression')); 74 super('network-gzip', Common.UIString('Enable gzip compression'));
75 } 75 }
76 76
77 /** 77 /**
78 * @override 78 * @override
79 * @param {!WebInspector.Target} target 79 * @param {!SDK.Target} target
80 * @param {!Array.<!WebInspector.NetworkRequest>} requests 80 * @param {!Array.<!SDK.NetworkRequest>} requests
81 * @param {!WebInspector.AuditRuleResult} result 81 * @param {!Audits.AuditRuleResult} result
82 * @param {function(?WebInspector.AuditRuleResult)} callback 82 * @param {function(?Audits.AuditRuleResult)} callback
83 * @param {!WebInspector.Progress} progress 83 * @param {!Common.Progress} progress
84 */ 84 */
85 doRun(target, requests, result, callback, progress) { 85 doRun(target, requests, result, callback, progress) {
86 var totalSavings = 0; 86 var totalSavings = 0;
87 var compressedSize = 0; 87 var compressedSize = 0;
88 var candidateSize = 0; 88 var candidateSize = 0;
89 var summary = result.addChild('', true); 89 var summary = result.addChild('', true);
90 for (var i = 0, length = requests.length; i < length; ++i) { 90 for (var i = 0, length = requests.length; i < length; ++i) {
91 var request = requests[i]; 91 var request = requests[i];
92 if (request.cached() || request.statusCode === 304) 92 if (request.cached() || request.statusCode === 304)
93 continue; // Do not test cached resources. 93 continue; // Do not test cached resources.
94 if (this._shouldCompress(request)) { 94 if (this._shouldCompress(request)) {
95 var size = request.resourceSize; 95 var size = request.resourceSize;
96 candidateSize += size; 96 candidateSize += size;
97 if (this._isCompressed(request)) { 97 if (this._isCompressed(request)) {
98 compressedSize += size; 98 compressedSize += size;
99 continue; 99 continue;
100 } 100 }
101 var savings = 2 * size / 3; 101 var savings = 2 * size / 3;
102 totalSavings += savings; 102 totalSavings += savings;
103 summary.addFormatted('%r could save ~%s', request.url, Number.bytesToStr ing(savings)); 103 summary.addFormatted('%r could save ~%s', request.url, Number.bytesToStr ing(savings));
104 result.violationCount++; 104 result.violationCount++;
105 } 105 }
106 } 106 }
107 if (!totalSavings) { 107 if (!totalSavings) {
108 callback(null); 108 callback(null);
109 return; 109 return;
110 } 110 }
111 summary.value = WebInspector.UIString( 111 summary.value = Common.UIString(
112 'Compressing the following resources with gzip could reduce their transf er size by about two thirds (~%s):', 112 'Compressing the following resources with gzip could reduce their transf er size by about two thirds (~%s):',
113 Number.bytesToString(totalSavings)); 113 Number.bytesToString(totalSavings));
114 callback(result); 114 callback(result);
115 } 115 }
116 116
117 /** 117 /**
118 * @param {!WebInspector.NetworkRequest} request 118 * @param {!SDK.NetworkRequest} request
119 */ 119 */
120 _isCompressed(request) { 120 _isCompressed(request) {
121 var encodingHeader = request.responseHeaderValue('Content-Encoding'); 121 var encodingHeader = request.responseHeaderValue('Content-Encoding');
122 if (!encodingHeader) 122 if (!encodingHeader)
123 return false; 123 return false;
124 124
125 return /\b(?:gzip|deflate)\b/.test(encodingHeader); 125 return /\b(?:gzip|deflate)\b/.test(encodingHeader);
126 } 126 }
127 127
128 /** 128 /**
129 * @param {!WebInspector.NetworkRequest} request 129 * @param {!SDK.NetworkRequest} request
130 */ 130 */
131 _shouldCompress(request) { 131 _shouldCompress(request) {
132 return request.resourceType().isTextType() && request.parsedURL.host && requ est.resourceSize !== undefined && 132 return request.resourceType().isTextType() && request.parsedURL.host && requ est.resourceSize !== undefined &&
133 request.resourceSize > 150; 133 request.resourceSize > 150;
134 } 134 }
135 }; 135 };
136 136
137 /** 137 /**
138 * @unrestricted 138 * @unrestricted
139 */ 139 */
140 WebInspector.AuditRules.CombineExternalResourcesRule = class extends WebInspecto r.AuditRule { 140 Audits.AuditRules.CombineExternalResourcesRule = class extends Audits.AuditRule {
141 /** 141 /**
142 * @param {string} id 142 * @param {string} id
143 * @param {string} name 143 * @param {string} name
144 * @param {!WebInspector.ResourceType} type 144 * @param {!Common.ResourceType} type
145 * @param {string} resourceTypeName 145 * @param {string} resourceTypeName
146 * @param {boolean} allowedPerDomain 146 * @param {boolean} allowedPerDomain
147 */ 147 */
148 constructor(id, name, type, resourceTypeName, allowedPerDomain) { 148 constructor(id, name, type, resourceTypeName, allowedPerDomain) {
149 super(id, name); 149 super(id, name);
150 this._type = type; 150 this._type = type;
151 this._resourceTypeName = resourceTypeName; 151 this._resourceTypeName = resourceTypeName;
152 this._allowedPerDomain = allowedPerDomain; 152 this._allowedPerDomain = allowedPerDomain;
153 } 153 }
154 154
155 /** 155 /**
156 * @override 156 * @override
157 * @param {!WebInspector.Target} target 157 * @param {!SDK.Target} target
158 * @param {!Array.<!WebInspector.NetworkRequest>} requests 158 * @param {!Array.<!SDK.NetworkRequest>} requests
159 * @param {!WebInspector.AuditRuleResult} result 159 * @param {!Audits.AuditRuleResult} result
160 * @param {function(?WebInspector.AuditRuleResult)} callback 160 * @param {function(?Audits.AuditRuleResult)} callback
161 * @param {!WebInspector.Progress} progress 161 * @param {!Common.Progress} progress
162 */ 162 */
163 doRun(target, requests, result, callback, progress) { 163 doRun(target, requests, result, callback, progress) {
164 var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(r equests, [this._type], false); 164 var domainToResourcesMap = Audits.AuditRules.getDomainToResourcesMap(request s, [this._type], false);
165 var penalizedResourceCount = 0; 165 var penalizedResourceCount = 0;
166 // TODO: refactor according to the chosen i18n approach 166 // TODO: refactor according to the chosen i18n approach
167 var summary = result.addChild('', true); 167 var summary = result.addChild('', true);
168 for (var domain in domainToResourcesMap) { 168 for (var domain in domainToResourcesMap) {
169 var domainResources = domainToResourcesMap[domain]; 169 var domainResources = domainToResourcesMap[domain];
170 var extraResourceCount = domainResources.length - this._allowedPerDomain; 170 var extraResourceCount = domainResources.length - this._allowedPerDomain;
171 if (extraResourceCount <= 0) 171 if (extraResourceCount <= 0)
172 continue; 172 continue;
173 penalizedResourceCount += extraResourceCount - 1; 173 penalizedResourceCount += extraResourceCount - 1;
174 summary.addChild(WebInspector.UIString( 174 summary.addChild(Common.UIString(
175 '%d %s resources served from %s.', domainResources.length, this._resou rceTypeName, 175 '%d %s resources served from %s.', domainResources.length, this._resou rceTypeName,
176 WebInspector.AuditRuleResult.resourceDomain(domain))); 176 Audits.AuditRuleResult.resourceDomain(domain)));
177 result.violationCount += domainResources.length; 177 result.violationCount += domainResources.length;
178 } 178 }
179 if (!penalizedResourceCount) { 179 if (!penalizedResourceCount) {
180 callback(null); 180 callback(null);
181 return; 181 return;
182 } 182 }
183 183
184 summary.value = WebInspector.UIString( 184 summary.value = Common.UIString(
185 'There are multiple resources served from same domain. Consider combinin g them into as few files as possible.'); 185 'There are multiple resources served from same domain. Consider combinin g them into as few files as possible.');
186 callback(result); 186 callback(result);
187 } 187 }
188 }; 188 };
189 189
190 /** 190 /**
191 * @unrestricted 191 * @unrestricted
192 */ 192 */
193 WebInspector.AuditRules.CombineJsResourcesRule = class extends WebInspector.Audi tRules.CombineExternalResourcesRule { 193 Audits.AuditRules.CombineJsResourcesRule = class extends Audits.AuditRules.Combi neExternalResourcesRule {
194 constructor(allowedPerDomain) { 194 constructor(allowedPerDomain) {
195 super( 195 super(
196 'page-externaljs', WebInspector.UIString('Combine external JavaScript'), WebInspector.resourceTypes.Script, 196 'page-externaljs', Common.UIString('Combine external JavaScript'), Commo n.resourceTypes.Script,
197 'JavaScript', allowedPerDomain); 197 'JavaScript', allowedPerDomain);
198 } 198 }
199 }; 199 };
200 200
201 /** 201 /**
202 * @unrestricted 202 * @unrestricted
203 */ 203 */
204 WebInspector.AuditRules.CombineCssResourcesRule = class extends WebInspector.Aud itRules.CombineExternalResourcesRule { 204 Audits.AuditRules.CombineCssResourcesRule = class extends Audits.AuditRules.Comb ineExternalResourcesRule {
205 constructor(allowedPerDomain) { 205 constructor(allowedPerDomain) {
206 super( 206 super(
207 'page-externalcss', WebInspector.UIString('Combine external CSS'), WebIn spector.resourceTypes.Stylesheet, 'CSS', 207 'page-externalcss', Common.UIString('Combine external CSS'), Common.reso urceTypes.Stylesheet, 'CSS',
208 allowedPerDomain); 208 allowedPerDomain);
209 } 209 }
210 }; 210 };
211 211
212 /** 212 /**
213 * @unrestricted 213 * @unrestricted
214 */ 214 */
215 WebInspector.AuditRules.MinimizeDnsLookupsRule = class extends WebInspector.Audi tRule { 215 Audits.AuditRules.MinimizeDnsLookupsRule = class extends Audits.AuditRule {
216 constructor(hostCountThreshold) { 216 constructor(hostCountThreshold) {
217 super('network-minimizelookups', WebInspector.UIString('Minimize DNS lookups ')); 217 super('network-minimizelookups', Common.UIString('Minimize DNS lookups'));
218 this._hostCountThreshold = hostCountThreshold; 218 this._hostCountThreshold = hostCountThreshold;
219 } 219 }
220 220
221 /** 221 /**
222 * @override 222 * @override
223 * @param {!WebInspector.Target} target 223 * @param {!SDK.Target} target
224 * @param {!Array.<!WebInspector.NetworkRequest>} requests 224 * @param {!Array.<!SDK.NetworkRequest>} requests
225 * @param {!WebInspector.AuditRuleResult} result 225 * @param {!Audits.AuditRuleResult} result
226 * @param {function(?WebInspector.AuditRuleResult)} callback 226 * @param {function(?Audits.AuditRuleResult)} callback
227 * @param {!WebInspector.Progress} progress 227 * @param {!Common.Progress} progress
228 */ 228 */
229 doRun(target, requests, result, callback, progress) { 229 doRun(target, requests, result, callback, progress) {
230 var summary = result.addChild(''); 230 var summary = result.addChild('');
231 var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(r equests, null, false); 231 var domainToResourcesMap = Audits.AuditRules.getDomainToResourcesMap(request s, null, false);
232 for (var domain in domainToResourcesMap) { 232 for (var domain in domainToResourcesMap) {
233 if (domainToResourcesMap[domain].length > 1) 233 if (domainToResourcesMap[domain].length > 1)
234 continue; 234 continue;
235 var parsedURL = domain.asParsedURL(); 235 var parsedURL = domain.asParsedURL();
236 if (!parsedURL) 236 if (!parsedURL)
237 continue; 237 continue;
238 if (!parsedURL.host.search(WebInspector.AuditRules.IPAddressRegexp)) 238 if (!parsedURL.host.search(Audits.AuditRules.IPAddressRegexp))
239 continue; // an IP address 239 continue; // an IP address
240 summary.addSnippet(domain); 240 summary.addSnippet(domain);
241 result.violationCount++; 241 result.violationCount++;
242 } 242 }
243 if (!summary.children || summary.children.length <= this._hostCountThreshold ) { 243 if (!summary.children || summary.children.length <= this._hostCountThreshold ) {
244 callback(null); 244 callback(null);
245 return; 245 return;
246 } 246 }
247 247
248 summary.value = WebInspector.UIString( 248 summary.value = Common.UIString(
249 'The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.'); 249 'The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.');
250 callback(result); 250 callback(result);
251 } 251 }
252 }; 252 };
253 253
254 /** 254 /**
255 * @unrestricted 255 * @unrestricted
256 */ 256 */
257 WebInspector.AuditRules.ParallelizeDownloadRule = class extends WebInspector.Aud itRule { 257 Audits.AuditRules.ParallelizeDownloadRule = class extends Audits.AuditRule {
258 constructor(optimalHostnameCount, minRequestThreshold, minBalanceThreshold) { 258 constructor(optimalHostnameCount, minRequestThreshold, minBalanceThreshold) {
259 super('network-parallelizehosts', WebInspector.UIString('Parallelize downloa ds across hostnames')); 259 super('network-parallelizehosts', Common.UIString('Parallelize downloads acr oss hostnames'));
260 this._optimalHostnameCount = optimalHostnameCount; 260 this._optimalHostnameCount = optimalHostnameCount;
261 this._minRequestThreshold = minRequestThreshold; 261 this._minRequestThreshold = minRequestThreshold;
262 this._minBalanceThreshold = minBalanceThreshold; 262 this._minBalanceThreshold = minBalanceThreshold;
263 } 263 }
264 264
265 /** 265 /**
266 * @override 266 * @override
267 * @param {!WebInspector.Target} target 267 * @param {!SDK.Target} target
268 * @param {!Array.<!WebInspector.NetworkRequest>} requests 268 * @param {!Array.<!SDK.NetworkRequest>} requests
269 * @param {!WebInspector.AuditRuleResult} result 269 * @param {!Audits.AuditRuleResult} result
270 * @param {function(?WebInspector.AuditRuleResult)} callback 270 * @param {function(?Audits.AuditRuleResult)} callback
271 * @param {!WebInspector.Progress} progress 271 * @param {!Common.Progress} progress
272 */ 272 */
273 doRun(target, requests, result, callback, progress) { 273 doRun(target, requests, result, callback, progress) {
274 /** 274 /**
275 * @param {string} a 275 * @param {string} a
276 * @param {string} b 276 * @param {string} b
277 */ 277 */
278 function hostSorter(a, b) { 278 function hostSorter(a, b) {
279 var aCount = domainToResourcesMap[a].length; 279 var aCount = domainToResourcesMap[a].length;
280 var bCount = domainToResourcesMap[b].length; 280 var bCount = domainToResourcesMap[b].length;
281 return (aCount < bCount) ? 1 : (aCount === bCount) ? 0 : -1; 281 return (aCount < bCount) ? 1 : (aCount === bCount) ? 0 : -1;
282 } 282 }
283 283
284 var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap( 284 var domainToResourcesMap = Audits.AuditRules.getDomainToResourcesMap(
285 requests, [WebInspector.resourceTypes.Stylesheet, WebInspector.resourceT ypes.Image], true); 285 requests, [Common.resourceTypes.Stylesheet, Common.resourceTypes.Image], true);
286 286
287 var hosts = []; 287 var hosts = [];
288 for (var url in domainToResourcesMap) 288 for (var url in domainToResourcesMap)
289 hosts.push(url); 289 hosts.push(url);
290 290
291 if (!hosts.length) { 291 if (!hosts.length) {
292 callback(null); // no hosts (local file or something) 292 callback(null); // no hosts (local file or something)
293 return; 293 return;
294 } 294 }
295 295
(...skipping 20 matching lines...) Expand all
316 316
317 var pctAboveAvg = (requestCountAboveThreshold / avgResourcesPerHost) - 1.0; 317 var pctAboveAvg = (requestCountAboveThreshold / avgResourcesPerHost) - 1.0;
318 var minBalanceThreshold = this._minBalanceThreshold; 318 var minBalanceThreshold = this._minBalanceThreshold;
319 if (pctAboveAvg < minBalanceThreshold) { 319 if (pctAboveAvg < minBalanceThreshold) {
320 callback(null); 320 callback(null);
321 return; 321 return;
322 } 322 }
323 323
324 var requestsOnBusiestHost = domainToResourcesMap[hosts[0]]; 324 var requestsOnBusiestHost = domainToResourcesMap[hosts[0]];
325 var entry = result.addChild( 325 var entry = result.addChild(
326 WebInspector.UIString( 326 Common.UIString(
327 'This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostname s.', 327 'This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostname s.',
328 busiestHostResourceCount, hosts[0]), 328 busiestHostResourceCount, hosts[0]),
329 true); 329 true);
330 for (var i = 0; i < requestsOnBusiestHost.length; ++i) 330 for (var i = 0; i < requestsOnBusiestHost.length; ++i)
331 entry.addURL(requestsOnBusiestHost[i].url); 331 entry.addURL(requestsOnBusiestHost[i].url);
332 332
333 result.violationCount = requestsOnBusiestHost.length; 333 result.violationCount = requestsOnBusiestHost.length;
334 callback(result); 334 callback(result);
335 } 335 }
336 }; 336 };
337 337
338 /** 338 /**
339 * @unrestricted 339 * @unrestricted
340 */ 340 */
341 WebInspector.AuditRules.UnusedCssRule = class extends WebInspector.AuditRule { 341 Audits.AuditRules.UnusedCssRule = class extends Audits.AuditRule {
342 /** 342 /**
343 * The reported CSS rule size is incorrect (parsed != original in WebKit), 343 * The reported CSS rule size is incorrect (parsed != original in WebKit),
344 * so use percentages instead, which gives a better approximation. 344 * so use percentages instead, which gives a better approximation.
345 */ 345 */
346 constructor() { 346 constructor() {
347 super('page-unusedcss', WebInspector.UIString('Remove unused CSS rules')); 347 super('page-unusedcss', Common.UIString('Remove unused CSS rules'));
348 } 348 }
349 349
350 /** 350 /**
351 * @override 351 * @override
352 * @param {!WebInspector.Target} target 352 * @param {!SDK.Target} target
353 * @param {!Array.<!WebInspector.NetworkRequest>} requests 353 * @param {!Array.<!SDK.NetworkRequest>} requests
354 * @param {!WebInspector.AuditRuleResult} result 354 * @param {!Audits.AuditRuleResult} result
355 * @param {function(?WebInspector.AuditRuleResult)} callback 355 * @param {function(?Audits.AuditRuleResult)} callback
356 * @param {!WebInspector.Progress} progress 356 * @param {!Common.Progress} progress
357 */ 357 */
358 doRun(target, requests, result, callback, progress) { 358 doRun(target, requests, result, callback, progress) {
359 var domModel = WebInspector.DOMModel.fromTarget(target); 359 var domModel = SDK.DOMModel.fromTarget(target);
360 var cssModel = WebInspector.CSSModel.fromTarget(target); 360 var cssModel = SDK.CSSModel.fromTarget(target);
361 if (!domModel || !cssModel) { 361 if (!domModel || !cssModel) {
362 callback(null); 362 callback(null);
363 return; 363 return;
364 } 364 }
365 365
366 /** 366 /**
367 * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets 367 * @param {!Array.<!Audits.AuditRules.ParsedStyleSheet>} styleSheets
368 */ 368 */
369 function evalCallback(styleSheets) { 369 function evalCallback(styleSheets) {
370 if (!styleSheets.length) 370 if (!styleSheets.length)
371 return callback(null); 371 return callback(null);
372 372
373 var selectors = []; 373 var selectors = [];
374 var testedSelectors = {}; 374 var testedSelectors = {};
375 for (var i = 0; i < styleSheets.length; ++i) { 375 for (var i = 0; i < styleSheets.length; ++i) {
376 var styleSheet = styleSheets[i]; 376 var styleSheet = styleSheets[i];
377 for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) { 377 for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) {
378 var selectorText = styleSheet.rules[curRule].selectorText; 378 var selectorText = styleSheet.rules[curRule].selectorText;
379 if (testedSelectors[selectorText]) 379 if (testedSelectors[selectorText])
380 continue; 380 continue;
381 selectors.push(selectorText); 381 selectors.push(selectorText);
382 testedSelectors[selectorText] = 1; 382 testedSelectors[selectorText] = 1;
383 } 383 }
384 } 384 }
385 385
386 var foundSelectors = {}; 386 var foundSelectors = {};
387 387
388 /** 388 /**
389 * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets 389 * @param {!Array.<!Audits.AuditRules.ParsedStyleSheet>} styleSheets
390 */ 390 */
391 function selectorsCallback(styleSheets) { 391 function selectorsCallback(styleSheets) {
392 if (progress.isCanceled()) { 392 if (progress.isCanceled()) {
393 callback(null); 393 callback(null);
394 return; 394 return;
395 } 395 }
396 396
397 var inlineBlockOrdinal = 0; 397 var inlineBlockOrdinal = 0;
398 var totalStylesheetSize = 0; 398 var totalStylesheetSize = 0;
399 var totalUnusedStylesheetSize = 0; 399 var totalUnusedStylesheetSize = 0;
400 var summary; 400 var summary;
401 401
402 for (var i = 0; i < styleSheets.length; ++i) { 402 for (var i = 0; i < styleSheets.length; ++i) {
403 var styleSheet = styleSheets[i]; 403 var styleSheet = styleSheets[i];
404 var unusedRules = []; 404 var unusedRules = [];
405 for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) { 405 for (var curRule = 0; curRule < styleSheet.rules.length; ++curRule) {
406 var rule = styleSheet.rules[curRule]; 406 var rule = styleSheet.rules[curRule];
407 if (!testedSelectors[rule.selectorText] || foundSelectors[rule.selec torText]) 407 if (!testedSelectors[rule.selectorText] || foundSelectors[rule.selec torText])
408 continue; 408 continue;
409 unusedRules.push(rule.selectorText); 409 unusedRules.push(rule.selectorText);
410 } 410 }
411 totalStylesheetSize += styleSheet.rules.length; 411 totalStylesheetSize += styleSheet.rules.length;
412 totalUnusedStylesheetSize += unusedRules.length; 412 totalUnusedStylesheetSize += unusedRules.length;
413 413
414 if (!unusedRules.length) 414 if (!unusedRules.length)
415 continue; 415 continue;
416 416
417 var resource = WebInspector.resourceForURL(styleSheet.sourceURL); 417 var resource = Bindings.resourceForURL(styleSheet.sourceURL);
418 var isInlineBlock = 418 var isInlineBlock =
419 resource && resource.request && resource.request.resourceType() == = WebInspector.resourceTypes.Document; 419 resource && resource.request && resource.request.resourceType() == = Common.resourceTypes.Document;
420 var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplay Name(styleSheet.sourceURL) : 420 var url = !isInlineBlock ? Audits.AuditRuleResult.linkifyDisplayName(s tyleSheet.sourceURL) :
421 WebInspector.UIString('Inline block #%d', + +inlineBlockOrdinal); 421 Common.UIString('Inline block #%d', ++inlin eBlockOrdinal);
422 var pctUnused = Math.round(100 * unusedRules.length / styleSheet.rules .length); 422 var pctUnused = Math.round(100 * unusedRules.length / styleSheet.rules .length);
423 if (!summary) 423 if (!summary)
424 summary = result.addChild('', true); 424 summary = result.addChild('', true);
425 var entry = summary.addFormatted('%s: %d% is not used by the current p age.', url, pctUnused); 425 var entry = summary.addFormatted('%s: %d% is not used by the current p age.', url, pctUnused);
426 426
427 for (var j = 0; j < unusedRules.length; ++j) 427 for (var j = 0; j < unusedRules.length; ++j)
428 entry.addSnippet(unusedRules[j]); 428 entry.addSnippet(unusedRules[j]);
429 429
430 result.violationCount += unusedRules.length; 430 result.violationCount += unusedRules.length;
431 } 431 }
432 432
433 if (!totalUnusedStylesheetSize) 433 if (!totalUnusedStylesheetSize)
434 return callback(null); 434 return callback(null);
435 435
436 var totalUnusedPercent = Math.round(100 * totalUnusedStylesheetSize / to talStylesheetSize); 436 var totalUnusedPercent = Math.round(100 * totalUnusedStylesheetSize / to talStylesheetSize);
437 summary.value = WebInspector.UIString( 437 summary.value = Common.UIString(
438 '%s rules (%d%) of CSS not used by the current page.', totalUnusedSt ylesheetSize, totalUnusedPercent); 438 '%s rules (%d%) of CSS not used by the current page.', totalUnusedSt ylesheetSize, totalUnusedPercent);
439 439
440 callback(result); 440 callback(result);
441 } 441 }
442 442
443 /** 443 /**
444 * @param {?function()} boundSelectorsCallback 444 * @param {?function()} boundSelectorsCallback
445 * @param {string} selector 445 * @param {string} selector
446 * @param {?Protocol.DOM.NodeId} nodeId 446 * @param {?Protocol.DOM.NodeId} nodeId
447 */ 447 */
448 function queryCallback(boundSelectorsCallback, selector, nodeId) { 448 function queryCallback(boundSelectorsCallback, selector, nodeId) {
449 if (nodeId) 449 if (nodeId)
450 foundSelectors[selector] = true; 450 foundSelectors[selector] = true;
451 if (boundSelectorsCallback) 451 if (boundSelectorsCallback)
452 boundSelectorsCallback(); 452 boundSelectorsCallback();
453 } 453 }
454 454
455 /** 455 /**
456 * @param {!Array.<string>} selectors 456 * @param {!Array.<string>} selectors
457 * @param {!WebInspector.DOMDocument} document 457 * @param {!SDK.DOMDocument} document
458 */ 458 */
459 function documentLoaded(selectors, document) { 459 function documentLoaded(selectors, document) {
460 var pseudoSelectorRegexp = /::?(?:[\w-]+)(?:\(.*?\))?/g; 460 var pseudoSelectorRegexp = /::?(?:[\w-]+)(?:\(.*?\))?/g;
461 if (!selectors.length) { 461 if (!selectors.length) {
462 selectorsCallback([]); 462 selectorsCallback([]);
463 return; 463 return;
464 } 464 }
465 for (var i = 0; i < selectors.length; ++i) { 465 for (var i = 0; i < selectors.length; ++i) {
466 if (progress.isCanceled()) { 466 if (progress.isCanceled()) {
467 callback(null); 467 callback(null);
468 return; 468 return;
469 } 469 }
470 var effectiveSelector = selectors[i].replace(pseudoSelectorRegexp, '') ; 470 var effectiveSelector = selectors[i].replace(pseudoSelectorRegexp, '') ;
471 domModel.querySelector( 471 domModel.querySelector(
472 document.id, effectiveSelector, 472 document.id, effectiveSelector,
473 queryCallback.bind( 473 queryCallback.bind(
474 null, i === selectors.length - 1 ? selectorsCallback.bind(null , styleSheets) : null, selectors[i])); 474 null, i === selectors.length - 1 ? selectorsCallback.bind(null , styleSheets) : null, selectors[i]));
475 } 475 }
476 } 476 }
477 477
478 domModel.requestDocument(documentLoaded.bind(null, selectors)); 478 domModel.requestDocument(documentLoaded.bind(null, selectors));
479 } 479 }
480 480
481 var styleSheetInfos = cssModel.allStyleSheets(); 481 var styleSheetInfos = cssModel.allStyleSheets();
482 if (!styleSheetInfos || !styleSheetInfos.length) { 482 if (!styleSheetInfos || !styleSheetInfos.length) {
483 evalCallback([]); 483 evalCallback([]);
484 return; 484 return;
485 } 485 }
486 var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(st yleSheetInfos, progress, evalCallback); 486 var styleSheetProcessor = new Audits.AuditRules.StyleSheetProcessor(styleShe etInfos, progress, evalCallback);
487 styleSheetProcessor.run(); 487 styleSheetProcessor.run();
488 } 488 }
489 }; 489 };
490 490
491 /** 491 /**
492 * @typedef {!{sourceURL: string, rules: !Array.<!WebInspector.CSSParser.StyleRu le>}} 492 * @typedef {!{sourceURL: string, rules: !Array.<!SDK.CSSParser.StyleRule>}}
493 */ 493 */
494 WebInspector.AuditRules.ParsedStyleSheet; 494 Audits.AuditRules.ParsedStyleSheet;
495 495
496 /** 496 /**
497 * @unrestricted 497 * @unrestricted
498 */ 498 */
499 WebInspector.AuditRules.StyleSheetProcessor = class { 499 Audits.AuditRules.StyleSheetProcessor = class {
500 /** 500 /**
501 * @param {!Array.<!WebInspector.CSSStyleSheetHeader>} styleSheetHeaders 501 * @param {!Array.<!SDK.CSSStyleSheetHeader>} styleSheetHeaders
502 * @param {!WebInspector.Progress} progress 502 * @param {!Common.Progress} progress
503 * @param {function(!Array.<!WebInspector.AuditRules.ParsedStyleSheet>)} style SheetsParsedCallback 503 * @param {function(!Array.<!Audits.AuditRules.ParsedStyleSheet>)} styleSheets ParsedCallback
504 */ 504 */
505 constructor(styleSheetHeaders, progress, styleSheetsParsedCallback) { 505 constructor(styleSheetHeaders, progress, styleSheetsParsedCallback) {
506 this._styleSheetHeaders = styleSheetHeaders; 506 this._styleSheetHeaders = styleSheetHeaders;
507 this._progress = progress; 507 this._progress = progress;
508 this._styleSheets = []; 508 this._styleSheets = [];
509 this._styleSheetsParsedCallback = styleSheetsParsedCallback; 509 this._styleSheetsParsedCallback = styleSheetsParsedCallback;
510 } 510 }
511 511
512 run() { 512 run() {
513 this._parser = new WebInspector.CSSParser(); 513 this._parser = new SDK.CSSParser();
514 this._processNextStyleSheet(); 514 this._processNextStyleSheet();
515 } 515 }
516 516
517 _terminateWorker() { 517 _terminateWorker() {
518 if (this._parser) { 518 if (this._parser) {
519 this._parser.dispose(); 519 this._parser.dispose();
520 delete this._parser; 520 delete this._parser;
521 } 521 }
522 } 522 }
523 523
524 _finish() { 524 _finish() {
525 this._terminateWorker(); 525 this._terminateWorker();
526 this._styleSheetsParsedCallback(this._styleSheets); 526 this._styleSheetsParsedCallback(this._styleSheets);
527 } 527 }
528 528
529 _processNextStyleSheet() { 529 _processNextStyleSheet() {
530 if (!this._styleSheetHeaders.length) { 530 if (!this._styleSheetHeaders.length) {
531 this._finish(); 531 this._finish();
532 return; 532 return;
533 } 533 }
534 this._currentStyleSheetHeader = this._styleSheetHeaders.shift(); 534 this._currentStyleSheetHeader = this._styleSheetHeaders.shift();
535 this._parser.fetchAndParse(this._currentStyleSheetHeader, this._onStyleSheet Parsed.bind(this)); 535 this._parser.fetchAndParse(this._currentStyleSheetHeader, this._onStyleSheet Parsed.bind(this));
536 } 536 }
537 537
538 /** 538 /**
539 * @param {!Array.<!WebInspector.CSSParser.Rule>} rules 539 * @param {!Array.<!SDK.CSSParser.Rule>} rules
540 */ 540 */
541 _onStyleSheetParsed(rules) { 541 _onStyleSheetParsed(rules) {
542 if (this._progress.isCanceled()) { 542 if (this._progress.isCanceled()) {
543 this._finish(); 543 this._finish();
544 return; 544 return;
545 } 545 }
546 546
547 var styleRules = []; 547 var styleRules = [];
548 for (var i = 0; i < rules.length; ++i) { 548 for (var i = 0; i < rules.length; ++i) {
549 var rule = rules[i]; 549 var rule = rules[i];
550 if (rule.selectorText) 550 if (rule.selectorText)
551 styleRules.push(rule); 551 styleRules.push(rule);
552 } 552 }
553 this._styleSheets.push({sourceURL: this._currentStyleSheetHeader.sourceURL, rules: styleRules}); 553 this._styleSheets.push({sourceURL: this._currentStyleSheetHeader.sourceURL, rules: styleRules});
554 this._processNextStyleSheet(); 554 this._processNextStyleSheet();
555 } 555 }
556 }; 556 };
557 557
558 /** 558 /**
559 * @unrestricted 559 * @unrestricted
560 */ 560 */
561 WebInspector.AuditRules.CacheControlRule = class extends WebInspector.AuditRule { 561 Audits.AuditRules.CacheControlRule = class extends Audits.AuditRule {
562 constructor(id, name) { 562 constructor(id, name) {
563 super(id, name); 563 super(id, name);
564 } 564 }
565 565
566 /** 566 /**
567 * @override 567 * @override
568 * @param {!WebInspector.Target} target 568 * @param {!SDK.Target} target
569 * @param {!Array.<!WebInspector.NetworkRequest>} requests 569 * @param {!Array.<!SDK.NetworkRequest>} requests
570 * @param {!WebInspector.AuditRuleResult} result 570 * @param {!Audits.AuditRuleResult} result
571 * @param {function(!WebInspector.AuditRuleResult)} callback 571 * @param {function(!Audits.AuditRuleResult)} callback
572 * @param {!WebInspector.Progress} progress 572 * @param {!Common.Progress} progress
573 */ 573 */
574 doRun(target, requests, result, callback, progress) { 574 doRun(target, requests, result, callback, progress) {
575 var cacheableAndNonCacheableResources = this._cacheableAndNonCacheableResour ces(requests); 575 var cacheableAndNonCacheableResources = this._cacheableAndNonCacheableResour ces(requests);
576 if (cacheableAndNonCacheableResources[0].length) 576 if (cacheableAndNonCacheableResources[0].length)
577 this.runChecks(cacheableAndNonCacheableResources[0], result); 577 this.runChecks(cacheableAndNonCacheableResources[0], result);
578 this.handleNonCacheableResources(cacheableAndNonCacheableResources[1], resul t); 578 this.handleNonCacheableResources(cacheableAndNonCacheableResources[1], resul t);
579 579
580 callback(result); 580 callback(result);
581 } 581 }
582 582
(...skipping 22 matching lines...) Expand all
605 urls.push(requests[i].url); 605 urls.push(requests[i].url);
606 } 606 }
607 if (urls.length) { 607 if (urls.length) {
608 var entry = result.addChild(messageText, true); 608 var entry = result.addChild(messageText, true);
609 entry.addURLs(urls); 609 entry.addURLs(urls);
610 result.violationCount += urls.length; 610 result.violationCount += urls.length;
611 } 611 }
612 } 612 }
613 613
614 /** 614 /**
615 * @param {!WebInspector.NetworkRequest} request 615 * @param {!SDK.NetworkRequest} request
616 * @param {number} timeMs 616 * @param {number} timeMs
617 * @return {boolean} 617 * @return {boolean}
618 */ 618 */
619 freshnessLifetimeGreaterThan(request, timeMs) { 619 freshnessLifetimeGreaterThan(request, timeMs) {
620 var dateHeader = this.responseHeader(request, 'Date'); 620 var dateHeader = this.responseHeader(request, 'Date');
621 if (!dateHeader) 621 if (!dateHeader)
622 return false; 622 return false;
623 623
624 var dateHeaderMs = Date.parse(dateHeader); 624 var dateHeaderMs = Date.parse(dateHeader);
625 if (isNaN(dateHeaderMs)) 625 if (isNaN(dateHeaderMs))
(...skipping 10 matching lines...) Expand all
636 var expDate = Date.parse(expiresHeader); 636 var expDate = Date.parse(expiresHeader);
637 if (!isNaN(expDate)) 637 if (!isNaN(expDate))
638 freshnessLifetimeMs = expDate - dateHeaderMs; 638 freshnessLifetimeMs = expDate - dateHeaderMs;
639 } 639 }
640 } 640 }
641 641
642 return (isNaN(freshnessLifetimeMs)) ? false : freshnessLifetimeMs > timeMs; 642 return (isNaN(freshnessLifetimeMs)) ? false : freshnessLifetimeMs > timeMs;
643 } 643 }
644 644
645 /** 645 /**
646 * @param {!WebInspector.NetworkRequest} request 646 * @param {!SDK.NetworkRequest} request
647 * @param {string} header 647 * @param {string} header
648 * @return {string|undefined} 648 * @return {string|undefined}
649 */ 649 */
650 responseHeader(request, header) { 650 responseHeader(request, header) {
651 return request.responseHeaderValue(header); 651 return request.responseHeaderValue(header);
652 } 652 }
653 653
654 /** 654 /**
655 * @param {!WebInspector.NetworkRequest} request 655 * @param {!SDK.NetworkRequest} request
656 * @param {string} header 656 * @param {string} header
657 * @return {boolean} 657 * @return {boolean}
658 */ 658 */
659 hasResponseHeader(request, header) { 659 hasResponseHeader(request, header) {
660 return request.responseHeaderValue(header) !== undefined; 660 return request.responseHeaderValue(header) !== undefined;
661 } 661 }
662 662
663 /** 663 /**
664 * @param {!WebInspector.NetworkRequest} request 664 * @param {!SDK.NetworkRequest} request
665 * @return {boolean} 665 * @return {boolean}
666 */ 666 */
667 isCompressible(request) { 667 isCompressible(request) {
668 return request.resourceType().isTextType(); 668 return request.resourceType().isTextType();
669 } 669 }
670 670
671 /** 671 /**
672 * @param {!WebInspector.NetworkRequest} request 672 * @param {!SDK.NetworkRequest} request
673 * @return {boolean} 673 * @return {boolean}
674 */ 674 */
675 isPubliclyCacheable(request) { 675 isPubliclyCacheable(request) {
676 if (this._isExplicitlyNonCacheable(request)) 676 if (this._isExplicitlyNonCacheable(request))
677 return false; 677 return false;
678 678
679 if (this.responseHeaderMatch(request, 'Cache-Control', 'public')) 679 if (this.responseHeaderMatch(request, 'Cache-Control', 'public'))
680 return true; 680 return true;
681 681
682 return request.url.indexOf('?') === -1 && !this.responseHeaderMatch(request, 'Cache-Control', 'private'); 682 return request.url.indexOf('?') === -1 && !this.responseHeaderMatch(request, 'Cache-Control', 'private');
683 } 683 }
684 684
685 /** 685 /**
686 * @param {!WebInspector.NetworkRequest} request 686 * @param {!SDK.NetworkRequest} request
687 * @param {string} header 687 * @param {string} header
688 * @param {string} regexp 688 * @param {string} regexp
689 * @return {?Array.<string>} 689 * @return {?Array.<string>}
690 */ 690 */
691 responseHeaderMatch(request, header, regexp) { 691 responseHeaderMatch(request, header, regexp) {
692 return request.responseHeaderValue(header) ? request.responseHeaderValue(hea der).match(new RegExp(regexp, 'im')) : 692 return request.responseHeaderValue(header) ? request.responseHeaderValue(hea der).match(new RegExp(regexp, 'im')) :
693 null; 693 null;
694 } 694 }
695 695
696 /** 696 /**
697 * @param {!WebInspector.NetworkRequest} request 697 * @param {!SDK.NetworkRequest} request
698 * @return {boolean} 698 * @return {boolean}
699 */ 699 */
700 hasExplicitExpiration(request) { 700 hasExplicitExpiration(request) {
701 return this.hasResponseHeader(request, 'Date') && 701 return this.hasResponseHeader(request, 'Date') &&
702 (this.hasResponseHeader(request, 'Expires') || !!this.responseHeaderMatc h(request, 'Cache-Control', 'max-age')); 702 (this.hasResponseHeader(request, 'Expires') || !!this.responseHeaderMatc h(request, 'Cache-Control', 'max-age'));
703 } 703 }
704 704
705 /** 705 /**
706 * @param {!WebInspector.NetworkRequest} request 706 * @param {!SDK.NetworkRequest} request
707 * @return {boolean} 707 * @return {boolean}
708 */ 708 */
709 _isExplicitlyNonCacheable(request) { 709 _isExplicitlyNonCacheable(request) {
710 var hasExplicitExp = this.hasExplicitExpiration(request); 710 var hasExplicitExp = this.hasExplicitExpiration(request);
711 return !!this.responseHeaderMatch(request, 'Cache-Control', '(no-cache|no-st ore)') || 711 return !!this.responseHeaderMatch(request, 'Cache-Control', '(no-cache|no-st ore)') ||
712 !!this.responseHeaderMatch(request, 'Pragma', 'no-cache') || 712 !!this.responseHeaderMatch(request, 'Pragma', 'no-cache') ||
713 (hasExplicitExp && !this.freshnessLifetimeGreaterThan(request, 0)) || 713 (hasExplicitExp && !this.freshnessLifetimeGreaterThan(request, 0)) ||
714 (!hasExplicitExp && !!request.url && request.url.indexOf('?') >= 0) || 714 (!hasExplicitExp && !!request.url && request.url.indexOf('?') >= 0) ||
715 (!hasExplicitExp && !this.isCacheableResource(request)); 715 (!hasExplicitExp && !this.isCacheableResource(request));
716 } 716 }
717 717
718 /** 718 /**
719 * @param {!WebInspector.NetworkRequest} request 719 * @param {!SDK.NetworkRequest} request
720 * @return {boolean} 720 * @return {boolean}
721 */ 721 */
722 isCacheableResource(request) { 722 isCacheableResource(request) {
723 return request.statusCode !== undefined && WebInspector.AuditRules.Cacheable ResponseCodes[request.statusCode]; 723 return request.statusCode !== undefined && Audits.AuditRules.CacheableRespon seCodes[request.statusCode];
724 } 724 }
725 }; 725 };
726 726
727 WebInspector.AuditRules.CacheControlRule.MillisPerMonth = 1000 * 60 * 60 * 24 * 30; 727 Audits.AuditRules.CacheControlRule.MillisPerMonth = 1000 * 60 * 60 * 24 * 30;
728 728
729 /** 729 /**
730 * @unrestricted 730 * @unrestricted
731 */ 731 */
732 WebInspector.AuditRules.BrowserCacheControlRule = class extends WebInspector.Aud itRules.CacheControlRule { 732 Audits.AuditRules.BrowserCacheControlRule = class extends Audits.AuditRules.Cach eControlRule {
733 constructor() { 733 constructor() {
734 super('http-browsercache', WebInspector.UIString('Leverage browser caching') ); 734 super('http-browsercache', Common.UIString('Leverage browser caching'));
735 } 735 }
736 736
737 /** 737 /**
738 * @override 738 * @override
739 */ 739 */
740 handleNonCacheableResources(requests, result) { 740 handleNonCacheableResources(requests, result) {
741 if (requests.length) { 741 if (requests.length) {
742 var entry = result.addChild( 742 var entry = result.addChild(
743 WebInspector.UIString( 743 Common.UIString(
744 'The following resources are explicitly non-cacheable. Consider ma king them cacheable if possible:'), 744 'The following resources are explicitly non-cacheable. Consider ma king them cacheable if possible:'),
745 true); 745 true);
746 result.violationCount += requests.length; 746 result.violationCount += requests.length;
747 for (var i = 0; i < requests.length; ++i) 747 for (var i = 0; i < requests.length; ++i)
748 entry.addURL(requests[i].url); 748 entry.addURL(requests[i].url);
749 } 749 }
750 } 750 }
751 751
752 runChecks(requests, result, callback) { 752 runChecks(requests, result, callback) {
753 this.execCheck( 753 this.execCheck(
754 WebInspector.UIString( 754 Common.UIString(
755 'The following resources are missing a cache expiration. Resources t hat do not specify an expiration may not be cached by browsers:'), 755 'The following resources are missing a cache expiration. Resources t hat do not specify an expiration may not be cached by browsers:'),
756 this._missingExpirationCheck, requests, result); 756 this._missingExpirationCheck, requests, result);
757 this.execCheck( 757 this.execCheck(
758 WebInspector.UIString( 758 Common.UIString(
759 'The following resources specify a "Vary" header that disables cachi ng in most versions of Internet Explorer:'), 759 'The following resources specify a "Vary" header that disables cachi ng in most versions of Internet Explorer:'),
760 this._varyCheck, requests, result); 760 this._varyCheck, requests, result);
761 this.execCheck( 761 this.execCheck(
762 WebInspector.UIString('The following cacheable resources have a short fr eshness lifetime:'), 762 Common.UIString('The following cacheable resources have a short freshnes s lifetime:'),
763 this._oneMonthExpirationCheck, requests, result); 763 this._oneMonthExpirationCheck, requests, result);
764 764
765 // Unable to implement the favicon check due to the WebKit limitations. 765 // Unable to implement the favicon check due to the WebKit limitations.
766 this.execCheck( 766 this.execCheck(
767 WebInspector.UIString( 767 Common.UIString(
768 'To further improve cache hit rate, specify an expiration one year i n the future for the following cacheable resources:'), 768 'To further improve cache hit rate, specify an expiration one year i n the future for the following cacheable resources:'),
769 this._oneYearExpirationCheck, requests, result); 769 this._oneYearExpirationCheck, requests, result);
770 } 770 }
771 771
772 _missingExpirationCheck(request) { 772 _missingExpirationCheck(request) {
773 return this.isCacheableResource(request) && !this.hasResponseHeader(request, 'Set-Cookie') && 773 return this.isCacheableResource(request) && !this.hasResponseHeader(request, 'Set-Cookie') &&
774 !this.hasExplicitExpiration(request); 774 !this.hasExplicitExpiration(request);
775 } 775 }
776 776
777 _varyCheck(request) { 777 _varyCheck(request) {
778 var varyHeader = this.responseHeader(request, 'Vary'); 778 var varyHeader = this.responseHeader(request, 'Vary');
779 if (varyHeader) { 779 if (varyHeader) {
780 varyHeader = varyHeader.replace(/User-Agent/gi, ''); 780 varyHeader = varyHeader.replace(/User-Agent/gi, '');
781 varyHeader = varyHeader.replace(/Accept-Encoding/gi, ''); 781 varyHeader = varyHeader.replace(/Accept-Encoding/gi, '');
782 varyHeader = varyHeader.replace(/[, ]*/g, ''); 782 varyHeader = varyHeader.replace(/[, ]*/g, '');
783 } 783 }
784 return varyHeader && varyHeader.length && this.isCacheableResource(request) && 784 return varyHeader && varyHeader.length && this.isCacheableResource(request) &&
785 this.freshnessLifetimeGreaterThan(request, 0); 785 this.freshnessLifetimeGreaterThan(request, 0);
786 } 786 }
787 787
788 _oneMonthExpirationCheck(request) { 788 _oneMonthExpirationCheck(request) {
789 return this.isCacheableResource(request) && !this.hasResponseHeader(request, 'Set-Cookie') && 789 return this.isCacheableResource(request) && !this.hasResponseHeader(request, 'Set-Cookie') &&
790 !this.freshnessLifetimeGreaterThan(request, WebInspector.AuditRules.Cach eControlRule.MillisPerMonth) && 790 !this.freshnessLifetimeGreaterThan(request, Audits.AuditRules.CacheContr olRule.MillisPerMonth) &&
791 this.freshnessLifetimeGreaterThan(request, 0); 791 this.freshnessLifetimeGreaterThan(request, 0);
792 } 792 }
793 793
794 _oneYearExpirationCheck(request) { 794 _oneYearExpirationCheck(request) {
795 return this.isCacheableResource(request) && !this.hasResponseHeader(request, 'Set-Cookie') && 795 return this.isCacheableResource(request) && !this.hasResponseHeader(request, 'Set-Cookie') &&
796 !this.freshnessLifetimeGreaterThan(request, 11 * WebInspector.AuditRules .CacheControlRule.MillisPerMonth) && 796 !this.freshnessLifetimeGreaterThan(request, 11 * Audits.AuditRules.Cache ControlRule.MillisPerMonth) &&
797 this.freshnessLifetimeGreaterThan(request, WebInspector.AuditRules.Cache ControlRule.MillisPerMonth); 797 this.freshnessLifetimeGreaterThan(request, Audits.AuditRules.CacheContro lRule.MillisPerMonth);
798 } 798 }
799 }; 799 };
800 800
801 /** 801 /**
802 * @unrestricted 802 * @unrestricted
803 */ 803 */
804 WebInspector.AuditRules.ImageDimensionsRule = class extends WebInspector.AuditRu le { 804 Audits.AuditRules.ImageDimensionsRule = class extends Audits.AuditRule {
805 constructor() { 805 constructor() {
806 super('page-imagedims', WebInspector.UIString('Specify image dimensions')); 806 super('page-imagedims', Common.UIString('Specify image dimensions'));
807 } 807 }
808 808
809 /** 809 /**
810 * @override 810 * @override
811 * @param {!WebInspector.Target} target 811 * @param {!SDK.Target} target
812 * @param {!Array.<!WebInspector.NetworkRequest>} requests 812 * @param {!Array.<!SDK.NetworkRequest>} requests
813 * @param {!WebInspector.AuditRuleResult} result 813 * @param {!Audits.AuditRuleResult} result
814 * @param {function(?WebInspector.AuditRuleResult)} callback 814 * @param {function(?Audits.AuditRuleResult)} callback
815 * @param {!WebInspector.Progress} progress 815 * @param {!Common.Progress} progress
816 */ 816 */
817 doRun(target, requests, result, callback, progress) { 817 doRun(target, requests, result, callback, progress) {
818 var domModel = WebInspector.DOMModel.fromTarget(target); 818 var domModel = SDK.DOMModel.fromTarget(target);
819 var cssModel = WebInspector.CSSModel.fromTarget(target); 819 var cssModel = SDK.CSSModel.fromTarget(target);
820 if (!domModel || !cssModel) { 820 if (!domModel || !cssModel) {
821 callback(null); 821 callback(null);
822 return; 822 return;
823 } 823 }
824 824
825 var urlToNoDimensionCount = {}; 825 var urlToNoDimensionCount = {};
826 826
827 function doneCallback() { 827 function doneCallback() {
828 for (var url in urlToNoDimensionCount) { 828 for (var url in urlToNoDimensionCount) {
829 var entry = entry || 829 var entry = entry ||
830 result.addChild( 830 result.addChild(
831 WebInspector.UIString( 831 Common.UIString(
832 'A width and height should be specified for all images in or der to speed up page display. The following image(s) are missing a width and/or height:'), 832 'A width and height should be specified for all images in or der to speed up page display. The following image(s) are missing a width and/or height:'),
833 true); 833 true);
834 var format = '%r'; 834 var format = '%r';
835 if (urlToNoDimensionCount[url] > 1) 835 if (urlToNoDimensionCount[url] > 1)
836 format += ' (%d uses)'; 836 format += ' (%d uses)';
837 entry.addFormatted(format, url, urlToNoDimensionCount[url]); 837 entry.addFormatted(format, url, urlToNoDimensionCount[url]);
838 result.violationCount++; 838 result.violationCount++;
839 } 839 }
840 callback(entry ? result : null); 840 callback(entry ? result : null);
841 } 841 }
842 842
843 function imageStylesReady(imageId, styles) { 843 function imageStylesReady(imageId, styles) {
844 if (progress.isCanceled()) { 844 if (progress.isCanceled()) {
845 callback(null); 845 callback(null);
846 return; 846 return;
847 } 847 }
848 848
849 const node = domModel.nodeForId(imageId); 849 const node = domModel.nodeForId(imageId);
850 var src = node.getAttribute('src'); 850 var src = node.getAttribute('src');
851 if (!src.asParsedURL()) { 851 if (!src.asParsedURL()) {
852 for (var frameOwnerCandidate = node; frameOwnerCandidate; 852 for (var frameOwnerCandidate = node; frameOwnerCandidate;
853 frameOwnerCandidate = frameOwnerCandidate.parentNode) { 853 frameOwnerCandidate = frameOwnerCandidate.parentNode) {
854 if (frameOwnerCandidate.baseURL) { 854 if (frameOwnerCandidate.baseURL) {
855 var completeSrc = WebInspector.ParsedURL.completeURL(frameOwnerCandi date.baseURL, src); 855 var completeSrc = Common.ParsedURL.completeURL(frameOwnerCandidate.b aseURL, src);
856 break; 856 break;
857 } 857 }
858 } 858 }
859 } 859 }
860 if (completeSrc) 860 if (completeSrc)
861 src = completeSrc; 861 src = completeSrc;
862 862
863 if (styles.computedStyle.get('position') === 'absolute') 863 if (styles.computedStyle.get('position') === 'absolute')
864 return; 864 return;
865 865
(...skipping 19 matching lines...) Expand all
885 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds 885 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds
886 */ 886 */
887 function getStyles(nodeIds) { 887 function getStyles(nodeIds) {
888 if (progress.isCanceled()) { 888 if (progress.isCanceled()) {
889 callback(null); 889 callback(null);
890 return; 890 return;
891 } 891 }
892 var targetResult = {}; 892 var targetResult = {};
893 893
894 /** 894 /**
895 * @param {?WebInspector.CSSMatchedStyles} matchedStyleResult 895 * @param {?SDK.CSSMatchedStyles} matchedStyleResult
896 */ 896 */
897 function matchedCallback(matchedStyleResult) { 897 function matchedCallback(matchedStyleResult) {
898 if (!matchedStyleResult) 898 if (!matchedStyleResult)
899 return; 899 return;
900 targetResult.nodeStyles = matchedStyleResult.nodeStyles(); 900 targetResult.nodeStyles = matchedStyleResult.nodeStyles();
901 } 901 }
902 902
903 /** 903 /**
904 * @param {?Map.<string, string>} computedStyle 904 * @param {?Map.<string, string>} computedStyle
905 */ 905 */
(...skipping 28 matching lines...) Expand all
934 callback(null); 934 callback(null);
935 return; 935 return;
936 } 936 }
937 domModel.requestDocument(onDocumentAvailable); 937 domModel.requestDocument(onDocumentAvailable);
938 } 938 }
939 }; 939 };
940 940
941 /** 941 /**
942 * @unrestricted 942 * @unrestricted
943 */ 943 */
944 WebInspector.AuditRules.CssInHeadRule = class extends WebInspector.AuditRule { 944 Audits.AuditRules.CssInHeadRule = class extends Audits.AuditRule {
945 constructor() { 945 constructor() {
946 super('page-cssinhead', WebInspector.UIString('Put CSS in the document head' )); 946 super('page-cssinhead', Common.UIString('Put CSS in the document head'));
947 } 947 }
948 948
949 /** 949 /**
950 * @override 950 * @override
951 * @param {!WebInspector.Target} target 951 * @param {!SDK.Target} target
952 * @param {!Array.<!WebInspector.NetworkRequest>} requests 952 * @param {!Array.<!SDK.NetworkRequest>} requests
953 * @param {!WebInspector.AuditRuleResult} result 953 * @param {!Audits.AuditRuleResult} result
954 * @param {function(?WebInspector.AuditRuleResult)} callback 954 * @param {function(?Audits.AuditRuleResult)} callback
955 * @param {!WebInspector.Progress} progress 955 * @param {!Common.Progress} progress
956 */ 956 */
957 doRun(target, requests, result, callback, progress) { 957 doRun(target, requests, result, callback, progress) {
958 var domModel = WebInspector.DOMModel.fromTarget(target); 958 var domModel = SDK.DOMModel.fromTarget(target);
959 if (!domModel) { 959 if (!domModel) {
960 callback(null); 960 callback(null);
961 return; 961 return;
962 } 962 }
963 963
964 function evalCallback(evalResult) { 964 function evalCallback(evalResult) {
965 if (progress.isCanceled()) { 965 if (progress.isCanceled()) {
966 callback(null); 966 callback(null);
967 return; 967 return;
968 } 968 }
969 969
970 if (!evalResult) 970 if (!evalResult)
971 return callback(null); 971 return callback(null);
972 972
973 var summary = result.addChild(''); 973 var summary = result.addChild('');
974 974
975 for (var url in evalResult) { 975 for (var url in evalResult) {
976 var urlViolations = evalResult[url]; 976 var urlViolations = evalResult[url];
977 if (urlViolations[0]) { 977 if (urlViolations[0]) {
978 result.addFormatted( 978 result.addFormatted(
979 '%s style block(s) in the %r body should be moved to the document head.', urlViolations[0], url); 979 '%s style block(s) in the %r body should be moved to the document head.', urlViolations[0], url);
980 result.violationCount += urlViolations[0]; 980 result.violationCount += urlViolations[0];
981 } 981 }
982 for (var i = 0; i < urlViolations[1].length; ++i) 982 for (var i = 0; i < urlViolations[1].length; ++i)
983 result.addFormatted('Link node %r should be moved to the document head in %r', urlViolations[1][i], url); 983 result.addFormatted('Link node %r should be moved to the document head in %r', urlViolations[1][i], url);
984 result.violationCount += urlViolations[1].length; 984 result.violationCount += urlViolations[1].length;
985 } 985 }
986 summary.value = WebInspector.UIString('CSS in the document body adversely impacts rendering performance.'); 986 summary.value = Common.UIString('CSS in the document body adversely impact s rendering performance.');
987 callback(result); 987 callback(result);
988 } 988 }
989 989
990 /** 990 /**
991 * @param {!WebInspector.DOMNode} root 991 * @param {!SDK.DOMNode} root
992 * @param {!Array.<!Protocol.DOM.NodeId>=} inlineStyleNodeIds 992 * @param {!Array.<!Protocol.DOM.NodeId>=} inlineStyleNodeIds
993 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds 993 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds
994 */ 994 */
995 function externalStylesheetsReceived(root, inlineStyleNodeIds, nodeIds) { 995 function externalStylesheetsReceived(root, inlineStyleNodeIds, nodeIds) {
996 if (progress.isCanceled()) { 996 if (progress.isCanceled()) {
997 callback(null); 997 callback(null);
998 return; 998 return;
999 } 999 }
1000 1000
1001 if (!nodeIds) 1001 if (!nodeIds)
1002 return; 1002 return;
1003 var externalStylesheetNodeIds = nodeIds; 1003 var externalStylesheetNodeIds = nodeIds;
1004 var result = null; 1004 var result = null;
1005 if (inlineStyleNodeIds.length || externalStylesheetNodeIds.length) { 1005 if (inlineStyleNodeIds.length || externalStylesheetNodeIds.length) {
1006 var urlToViolationsArray = {}; 1006 var urlToViolationsArray = {};
1007 var externalStylesheetHrefs = []; 1007 var externalStylesheetHrefs = [];
1008 for (var j = 0; j < externalStylesheetNodeIds.length; ++j) { 1008 for (var j = 0; j < externalStylesheetNodeIds.length; ++j) {
1009 var linkNode = domModel.nodeForId(externalStylesheetNodeIds[j]); 1009 var linkNode = domModel.nodeForId(externalStylesheetNodeIds[j]);
1010 var completeHref = 1010 var completeHref =
1011 WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.baseURL, linkNode.getAttribute('href')); 1011 Common.ParsedURL.completeURL(linkNode.ownerDocument.baseURL, linkN ode.getAttribute('href'));
1012 externalStylesheetHrefs.push(completeHref || '<empty>'); 1012 externalStylesheetHrefs.push(completeHref || '<empty>');
1013 } 1013 }
1014 urlToViolationsArray[root.documentURL] = [inlineStyleNodeIds.length, ext ernalStylesheetHrefs]; 1014 urlToViolationsArray[root.documentURL] = [inlineStyleNodeIds.length, ext ernalStylesheetHrefs];
1015 result = urlToViolationsArray; 1015 result = urlToViolationsArray;
1016 } 1016 }
1017 evalCallback(result); 1017 evalCallback(result);
1018 } 1018 }
1019 1019
1020 /** 1020 /**
1021 * @param {!WebInspector.DOMNode} root 1021 * @param {!SDK.DOMNode} root
1022 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds 1022 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds
1023 */ 1023 */
1024 function inlineStylesReceived(root, nodeIds) { 1024 function inlineStylesReceived(root, nodeIds) {
1025 if (progress.isCanceled()) { 1025 if (progress.isCanceled()) {
1026 callback(null); 1026 callback(null);
1027 return; 1027 return;
1028 } 1028 }
1029 1029
1030 if (!nodeIds) 1030 if (!nodeIds)
1031 return; 1031 return;
1032 domModel.querySelectorAll( 1032 domModel.querySelectorAll(
1033 root.id, 'body link[rel~=\'stylesheet\'][href]', externalStylesheetsRe ceived.bind(null, root, nodeIds)); 1033 root.id, 'body link[rel~=\'stylesheet\'][href]', externalStylesheetsRe ceived.bind(null, root, nodeIds));
1034 } 1034 }
1035 1035
1036 /** 1036 /**
1037 * @param {!WebInspector.DOMNode} root 1037 * @param {!SDK.DOMNode} root
1038 */ 1038 */
1039 function onDocumentAvailable(root) { 1039 function onDocumentAvailable(root) {
1040 if (progress.isCanceled()) { 1040 if (progress.isCanceled()) {
1041 callback(null); 1041 callback(null);
1042 return; 1042 return;
1043 } 1043 }
1044 1044
1045 domModel.querySelectorAll(root.id, 'body style', inlineStylesReceived.bind (null, root)); 1045 domModel.querySelectorAll(root.id, 'body style', inlineStylesReceived.bind (null, root));
1046 } 1046 }
1047 1047
1048 domModel.requestDocument(onDocumentAvailable); 1048 domModel.requestDocument(onDocumentAvailable);
1049 } 1049 }
1050 }; 1050 };
1051 1051
1052 /** 1052 /**
1053 * @unrestricted 1053 * @unrestricted
1054 */ 1054 */
1055 WebInspector.AuditRules.StylesScriptsOrderRule = class extends WebInspector.Audi tRule { 1055 Audits.AuditRules.StylesScriptsOrderRule = class extends Audits.AuditRule {
1056 constructor() { 1056 constructor() {
1057 super('page-stylescriptorder', WebInspector.UIString('Optimize the order of styles and scripts')); 1057 super('page-stylescriptorder', Common.UIString('Optimize the order of styles and scripts'));
1058 } 1058 }
1059 1059
1060 /** 1060 /**
1061 * @override 1061 * @override
1062 * @param {!WebInspector.Target} target 1062 * @param {!SDK.Target} target
1063 * @param {!Array.<!WebInspector.NetworkRequest>} requests 1063 * @param {!Array.<!SDK.NetworkRequest>} requests
1064 * @param {!WebInspector.AuditRuleResult} result 1064 * @param {!Audits.AuditRuleResult} result
1065 * @param {function(?WebInspector.AuditRuleResult)} callback 1065 * @param {function(?Audits.AuditRuleResult)} callback
1066 * @param {!WebInspector.Progress} progress 1066 * @param {!Common.Progress} progress
1067 */ 1067 */
1068 doRun(target, requests, result, callback, progress) { 1068 doRun(target, requests, result, callback, progress) {
1069 var domModel = WebInspector.DOMModel.fromTarget(target); 1069 var domModel = SDK.DOMModel.fromTarget(target);
1070 if (!domModel) { 1070 if (!domModel) {
1071 callback(null); 1071 callback(null);
1072 return; 1072 return;
1073 } 1073 }
1074 1074
1075 function evalCallback(resultValue) { 1075 function evalCallback(resultValue) {
1076 if (progress.isCanceled()) { 1076 if (progress.isCanceled()) {
1077 callback(null); 1077 callback(null);
1078 return; 1078 return;
1079 } 1079 }
1080 1080
1081 if (!resultValue) 1081 if (!resultValue)
1082 return callback(null); 1082 return callback(null);
1083 1083
1084 var lateCssUrls = resultValue[0]; 1084 var lateCssUrls = resultValue[0];
1085 var cssBeforeInlineCount = resultValue[1]; 1085 var cssBeforeInlineCount = resultValue[1];
1086 1086
1087 if (lateCssUrls.length) { 1087 if (lateCssUrls.length) {
1088 var entry = result.addChild( 1088 var entry = result.addChild(
1089 WebInspector.UIString( 1089 Common.UIString(
1090 'The following external CSS files were included after an externa l JavaScript file in the document head. To ensure CSS files are downloaded in pa rallel, always include external CSS before external JavaScript.'), 1090 'The following external CSS files were included after an externa l JavaScript file in the document head. To ensure CSS files are downloaded in pa rallel, always include external CSS before external JavaScript.'),
1091 true); 1091 true);
1092 entry.addURLs(lateCssUrls); 1092 entry.addURLs(lateCssUrls);
1093 result.violationCount += lateCssUrls.length; 1093 result.violationCount += lateCssUrls.length;
1094 } 1094 }
1095 1095
1096 if (cssBeforeInlineCount) { 1096 if (cssBeforeInlineCount) {
1097 result.addChild(WebInspector.UIString( 1097 result.addChild(Common.UIString(
1098 ' %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline scrip t before the external CSS file, or after the next resource.', 1098 ' %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline scrip t before the external CSS file, or after the next resource.',
1099 cssBeforeInlineCount, cssBeforeInlineCount > 1 ? 's were' : ' was')) ; 1099 cssBeforeInlineCount, cssBeforeInlineCount > 1 ? 's were' : ' was')) ;
1100 result.violationCount += cssBeforeInlineCount; 1100 result.violationCount += cssBeforeInlineCount;
1101 } 1101 }
1102 callback(result); 1102 callback(result);
1103 } 1103 }
1104 1104
1105 /** 1105 /**
1106 * @param {!Array.<!Protocol.DOM.NodeId>} lateStyleIds 1106 * @param {!Array.<!Protocol.DOM.NodeId>} lateStyleIds
1107 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds 1107 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds
1108 */ 1108 */
1109 function cssBeforeInlineReceived(lateStyleIds, nodeIds) { 1109 function cssBeforeInlineReceived(lateStyleIds, nodeIds) {
1110 if (progress.isCanceled()) { 1110 if (progress.isCanceled()) {
1111 callback(null); 1111 callback(null);
1112 return; 1112 return;
1113 } 1113 }
1114 1114
1115 if (!nodeIds) 1115 if (!nodeIds)
1116 return; 1116 return;
1117 1117
1118 var cssBeforeInlineCount = nodeIds.length; 1118 var cssBeforeInlineCount = nodeIds.length;
1119 var result = null; 1119 var result = null;
1120 if (lateStyleIds.length || cssBeforeInlineCount) { 1120 if (lateStyleIds.length || cssBeforeInlineCount) {
1121 var lateStyleUrls = []; 1121 var lateStyleUrls = [];
1122 for (var i = 0; i < lateStyleIds.length; ++i) { 1122 for (var i = 0; i < lateStyleIds.length; ++i) {
1123 var lateStyleNode = domModel.nodeForId(lateStyleIds[i]); 1123 var lateStyleNode = domModel.nodeForId(lateStyleIds[i]);
1124 var completeHref = WebInspector.ParsedURL.completeURL( 1124 var completeHref = Common.ParsedURL.completeURL(
1125 lateStyleNode.ownerDocument.baseURL, lateStyleNode.getAttribute('h ref')); 1125 lateStyleNode.ownerDocument.baseURL, lateStyleNode.getAttribute('h ref'));
1126 lateStyleUrls.push(completeHref || '<empty>'); 1126 lateStyleUrls.push(completeHref || '<empty>');
1127 } 1127 }
1128 result = [lateStyleUrls, cssBeforeInlineCount]; 1128 result = [lateStyleUrls, cssBeforeInlineCount];
1129 } 1129 }
1130 1130
1131 evalCallback(result); 1131 evalCallback(result);
1132 } 1132 }
1133 1133
1134 /** 1134 /**
1135 * @param {!WebInspector.DOMDocument} root 1135 * @param {!SDK.DOMDocument} root
1136 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds 1136 * @param {!Array.<!Protocol.DOM.NodeId>=} nodeIds
1137 */ 1137 */
1138 function lateStylesReceived(root, nodeIds) { 1138 function lateStylesReceived(root, nodeIds) {
1139 if (progress.isCanceled()) { 1139 if (progress.isCanceled()) {
1140 callback(null); 1140 callback(null);
1141 return; 1141 return;
1142 } 1142 }
1143 1143
1144 if (!nodeIds) 1144 if (!nodeIds)
1145 return; 1145 return;
1146 1146
1147 domModel.querySelectorAll( 1147 domModel.querySelectorAll(
1148 root.id, 'head link[rel~=\'stylesheet\'][href] ~ script:not([src])', 1148 root.id, 'head link[rel~=\'stylesheet\'][href] ~ script:not([src])',
1149 cssBeforeInlineReceived.bind(null, nodeIds)); 1149 cssBeforeInlineReceived.bind(null, nodeIds));
1150 } 1150 }
1151 1151
1152 /** 1152 /**
1153 * @param {!WebInspector.DOMDocument} root 1153 * @param {!SDK.DOMDocument} root
1154 */ 1154 */
1155 function onDocumentAvailable(root) { 1155 function onDocumentAvailable(root) {
1156 if (progress.isCanceled()) { 1156 if (progress.isCanceled()) {
1157 callback(null); 1157 callback(null);
1158 return; 1158 return;
1159 } 1159 }
1160 1160
1161 domModel.querySelectorAll( 1161 domModel.querySelectorAll(
1162 root.id, 'head script[src] ~ link[rel~=\'stylesheet\'][href]', lateSty lesReceived.bind(null, root)); 1162 root.id, 'head script[src] ~ link[rel~=\'stylesheet\'][href]', lateSty lesReceived.bind(null, root));
1163 } 1163 }
1164 1164
1165 domModel.requestDocument(onDocumentAvailable); 1165 domModel.requestDocument(onDocumentAvailable);
1166 } 1166 }
1167 }; 1167 };
1168 1168
1169 /** 1169 /**
1170 * @unrestricted 1170 * @unrestricted
1171 */ 1171 */
1172 WebInspector.AuditRules.CSSRuleBase = class extends WebInspector.AuditRule { 1172 Audits.AuditRules.CSSRuleBase = class extends Audits.AuditRule {
1173 constructor(id, name) { 1173 constructor(id, name) {
1174 super(id, name); 1174 super(id, name);
1175 } 1175 }
1176 1176
1177 /** 1177 /**
1178 * @override 1178 * @override
1179 * @param {!WebInspector.Target} target 1179 * @param {!SDK.Target} target
1180 * @param {!Array.<!WebInspector.NetworkRequest>} requests 1180 * @param {!Array.<!SDK.NetworkRequest>} requests
1181 * @param {!WebInspector.AuditRuleResult} result 1181 * @param {!Audits.AuditRuleResult} result
1182 * @param {function(?WebInspector.AuditRuleResult)} callback 1182 * @param {function(?Audits.AuditRuleResult)} callback
1183 * @param {!WebInspector.Progress} progress 1183 * @param {!Common.Progress} progress
1184 */ 1184 */
1185 doRun(target, requests, result, callback, progress) { 1185 doRun(target, requests, result, callback, progress) {
1186 var cssModel = WebInspector.CSSModel.fromTarget(target); 1186 var cssModel = SDK.CSSModel.fromTarget(target);
1187 if (!cssModel) { 1187 if (!cssModel) {
1188 callback(null); 1188 callback(null);
1189 return; 1189 return;
1190 } 1190 }
1191 1191
1192 var headers = cssModel.allStyleSheets(); 1192 var headers = cssModel.allStyleSheets();
1193 if (!headers.length) { 1193 if (!headers.length) {
1194 callback(null); 1194 callback(null);
1195 return; 1195 return;
1196 } 1196 }
1197 var activeHeaders = []; 1197 var activeHeaders = [];
1198 for (var i = 0; i < headers.length; ++i) { 1198 for (var i = 0; i < headers.length; ++i) {
1199 if (!headers[i].disabled) 1199 if (!headers[i].disabled)
1200 activeHeaders.push(headers[i]); 1200 activeHeaders.push(headers[i]);
1201 } 1201 }
1202 1202
1203 var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor( 1203 var styleSheetProcessor = new Audits.AuditRules.StyleSheetProcessor(
1204 activeHeaders, progress, this._styleSheetsLoaded.bind(this, result, call back, progress)); 1204 activeHeaders, progress, this._styleSheetsLoaded.bind(this, result, call back, progress));
1205 styleSheetProcessor.run(); 1205 styleSheetProcessor.run();
1206 } 1206 }
1207 1207
1208 /** 1208 /**
1209 * @param {!WebInspector.AuditRuleResult} result 1209 * @param {!Audits.AuditRuleResult} result
1210 * @param {function(!WebInspector.AuditRuleResult)} callback 1210 * @param {function(!Audits.AuditRuleResult)} callback
1211 * @param {!WebInspector.Progress} progress 1211 * @param {!Common.Progress} progress
1212 * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets 1212 * @param {!Array.<!Audits.AuditRules.ParsedStyleSheet>} styleSheets
1213 */ 1213 */
1214 _styleSheetsLoaded(result, callback, progress, styleSheets) { 1214 _styleSheetsLoaded(result, callback, progress, styleSheets) {
1215 for (var i = 0; i < styleSheets.length; ++i) 1215 for (var i = 0; i < styleSheets.length; ++i)
1216 this._visitStyleSheet(styleSheets[i], result); 1216 this._visitStyleSheet(styleSheets[i], result);
1217 callback(result); 1217 callback(result);
1218 } 1218 }
1219 1219
1220 /** 1220 /**
1221 * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1221 * @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
1222 * @param {!WebInspector.AuditRuleResult} result 1222 * @param {!Audits.AuditRuleResult} result
1223 */ 1223 */
1224 _visitStyleSheet(styleSheet, result) { 1224 _visitStyleSheet(styleSheet, result) {
1225 this.visitStyleSheet(styleSheet, result); 1225 this.visitStyleSheet(styleSheet, result);
1226 1226
1227 for (var i = 0; i < styleSheet.rules.length; ++i) 1227 for (var i = 0; i < styleSheet.rules.length; ++i)
1228 this._visitRule(styleSheet, styleSheet.rules[i], result); 1228 this._visitRule(styleSheet, styleSheet.rules[i], result);
1229 1229
1230 this.didVisitStyleSheet(styleSheet, result); 1230 this.didVisitStyleSheet(styleSheet, result);
1231 } 1231 }
1232 1232
1233 /** 1233 /**
1234 * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1234 * @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
1235 * @param {!WebInspector.CSSParser.StyleRule} rule 1235 * @param {!SDK.CSSParser.StyleRule} rule
1236 * @param {!WebInspector.AuditRuleResult} result 1236 * @param {!Audits.AuditRuleResult} result
1237 */ 1237 */
1238 _visitRule(styleSheet, rule, result) { 1238 _visitRule(styleSheet, rule, result) {
1239 this.visitRule(styleSheet, rule, result); 1239 this.visitRule(styleSheet, rule, result);
1240 var allProperties = rule.properties; 1240 var allProperties = rule.properties;
1241 for (var i = 0; i < allProperties.length; ++i) 1241 for (var i = 0; i < allProperties.length; ++i)
1242 this.visitProperty(styleSheet, rule, allProperties[i], result); 1242 this.visitProperty(styleSheet, rule, allProperties[i], result);
1243 this.didVisitRule(styleSheet, rule, result); 1243 this.didVisitRule(styleSheet, rule, result);
1244 } 1244 }
1245 1245
1246 /** 1246 /**
1247 * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1247 * @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
1248 * @param {!WebInspector.AuditRuleResult} result 1248 * @param {!Audits.AuditRuleResult} result
1249 */ 1249 */
1250 visitStyleSheet(styleSheet, result) { 1250 visitStyleSheet(styleSheet, result) {
1251 // Subclasses can implement. 1251 // Subclasses can implement.
1252 } 1252 }
1253 1253
1254 /** 1254 /**
1255 * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1255 * @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
1256 * @param {!WebInspector.AuditRuleResult} result 1256 * @param {!Audits.AuditRuleResult} result
1257 */ 1257 */
1258 didVisitStyleSheet(styleSheet, result) { 1258 didVisitStyleSheet(styleSheet, result) {
1259 // Subclasses can implement. 1259 // Subclasses can implement.
1260 } 1260 }
1261 1261
1262 /** 1262 /**
1263 * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1263 * @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
1264 * @param {!WebInspector.CSSParser.StyleRule} rule 1264 * @param {!SDK.CSSParser.StyleRule} rule
1265 * @param {!WebInspector.AuditRuleResult} result 1265 * @param {!Audits.AuditRuleResult} result
1266 */ 1266 */
1267 visitRule(styleSheet, rule, result) { 1267 visitRule(styleSheet, rule, result) {
1268 // Subclasses can implement. 1268 // Subclasses can implement.
1269 } 1269 }
1270 1270
1271 /** 1271 /**
1272 * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1272 * @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
1273 * @param {!WebInspector.CSSParser.StyleRule} rule 1273 * @param {!SDK.CSSParser.StyleRule} rule
1274 * @param {!WebInspector.AuditRuleResult} result 1274 * @param {!Audits.AuditRuleResult} result
1275 */ 1275 */
1276 didVisitRule(styleSheet, rule, result) { 1276 didVisitRule(styleSheet, rule, result) {
1277 // Subclasses can implement. 1277 // Subclasses can implement.
1278 } 1278 }
1279 1279
1280 /** 1280 /**
1281 * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet 1281 * @param {!Audits.AuditRules.ParsedStyleSheet} styleSheet
1282 * @param {!WebInspector.CSSParser.StyleRule} rule 1282 * @param {!SDK.CSSParser.StyleRule} rule
1283 * @param {!WebInspector.CSSParser.Property} property 1283 * @param {!SDK.CSSParser.Property} property
1284 * @param {!WebInspector.AuditRuleResult} result 1284 * @param {!Audits.AuditRuleResult} result
1285 */ 1285 */
1286 visitProperty(styleSheet, rule, property, result) { 1286 visitProperty(styleSheet, rule, property, result) {
1287 // Subclasses can implement. 1287 // Subclasses can implement.
1288 } 1288 }
1289 }; 1289 };
1290 1290
1291 /** 1291 /**
1292 * @unrestricted 1292 * @unrestricted
1293 */ 1293 */
1294 WebInspector.AuditRules.CookieRuleBase = class extends WebInspector.AuditRule { 1294 Audits.AuditRules.CookieRuleBase = class extends Audits.AuditRule {
1295 constructor(id, name) { 1295 constructor(id, name) {
1296 super(id, name); 1296 super(id, name);
1297 } 1297 }
1298 1298
1299 /** 1299 /**
1300 * @override 1300 * @override
1301 * @param {!WebInspector.Target} target 1301 * @param {!SDK.Target} target
1302 * @param {!Array.<!WebInspector.NetworkRequest>} requests 1302 * @param {!Array.<!SDK.NetworkRequest>} requests
1303 * @param {!WebInspector.AuditRuleResult} result 1303 * @param {!Audits.AuditRuleResult} result
1304 * @param {function(!WebInspector.AuditRuleResult)} callback 1304 * @param {function(!Audits.AuditRuleResult)} callback
1305 * @param {!WebInspector.Progress} progress 1305 * @param {!Common.Progress} progress
1306 */ 1306 */
1307 doRun(target, requests, result, callback, progress) { 1307 doRun(target, requests, result, callback, progress) {
1308 var self = this; 1308 var self = this;
1309 function resultCallback(receivedCookies) { 1309 function resultCallback(receivedCookies) {
1310 if (progress.isCanceled()) { 1310 if (progress.isCanceled()) {
1311 callback(result); 1311 callback(result);
1312 return; 1312 return;
1313 } 1313 }
1314 1314
1315 self.processCookies(receivedCookies, requests, result); 1315 self.processCookies(receivedCookies, requests, result);
1316 callback(result); 1316 callback(result);
1317 } 1317 }
1318 1318
1319 WebInspector.Cookies.getCookiesAsync(resultCallback); 1319 SDK.Cookies.getCookiesAsync(resultCallback);
1320 } 1320 }
1321 1321
1322 mapResourceCookies(requestsByDomain, allCookies, callback) { 1322 mapResourceCookies(requestsByDomain, allCookies, callback) {
1323 for (var i = 0; i < allCookies.length; ++i) { 1323 for (var i = 0; i < allCookies.length; ++i) {
1324 for (var requestDomain in requestsByDomain) { 1324 for (var requestDomain in requestsByDomain) {
1325 if (WebInspector.Cookies.cookieDomainMatchesResourceDomain(allCookies[i] .domain(), requestDomain)) 1325 if (SDK.Cookies.cookieDomainMatchesResourceDomain(allCookies[i].domain() , requestDomain))
1326 this._callbackForResourceCookiePairs(requestsByDomain[requestDomain], allCookies[i], callback); 1326 this._callbackForResourceCookiePairs(requestsByDomain[requestDomain], allCookies[i], callback);
1327 } 1327 }
1328 } 1328 }
1329 } 1329 }
1330 1330
1331 _callbackForResourceCookiePairs(requests, cookie, callback) { 1331 _callbackForResourceCookiePairs(requests, cookie, callback) {
1332 if (!requests) 1332 if (!requests)
1333 return; 1333 return;
1334 for (var i = 0; i < requests.length; ++i) { 1334 for (var i = 0; i < requests.length; ++i) {
1335 if (WebInspector.Cookies.cookieMatchesResourceURL(cookie, requests[i].url) ) 1335 if (SDK.Cookies.cookieMatchesResourceURL(cookie, requests[i].url))
1336 callback(requests[i], cookie); 1336 callback(requests[i], cookie);
1337 } 1337 }
1338 } 1338 }
1339 }; 1339 };
1340 1340
1341 /** 1341 /**
1342 * @unrestricted 1342 * @unrestricted
1343 */ 1343 */
1344 WebInspector.AuditRules.CookieSizeRule = class extends WebInspector.AuditRules.C ookieRuleBase { 1344 Audits.AuditRules.CookieSizeRule = class extends Audits.AuditRules.CookieRuleBas e {
1345 constructor(avgBytesThreshold) { 1345 constructor(avgBytesThreshold) {
1346 super('http-cookiesize', WebInspector.UIString('Minimize cookie size')); 1346 super('http-cookiesize', Common.UIString('Minimize cookie size'));
1347 this._avgBytesThreshold = avgBytesThreshold; 1347 this._avgBytesThreshold = avgBytesThreshold;
1348 this._maxBytesThreshold = 1000; 1348 this._maxBytesThreshold = 1000;
1349 } 1349 }
1350 1350
1351 _average(cookieArray) { 1351 _average(cookieArray) {
1352 var total = 0; 1352 var total = 0;
1353 for (var i = 0; i < cookieArray.length; ++i) 1353 for (var i = 0; i < cookieArray.length; ++i)
1354 total += cookieArray[i].size(); 1354 total += cookieArray[i].size();
1355 return cookieArray.length ? Math.round(total / cookieArray.length) : 0; 1355 return cookieArray.length ? Math.round(total / cookieArray.length) : 0;
1356 } 1356 }
(...skipping 23 matching lines...) Expand all
1380 cookiesPerResourceDomain[request.parsedURL.host] = cookies; 1380 cookiesPerResourceDomain[request.parsedURL.host] = cookies;
1381 } 1381 }
1382 cookies.push(cookie); 1382 cookies.push(cookie);
1383 } 1383 }
1384 1384
1385 if (!allCookies.length) 1385 if (!allCookies.length)
1386 return; 1386 return;
1387 1387
1388 var sortedCookieSizes = []; 1388 var sortedCookieSizes = [];
1389 1389
1390 var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(r equests, null, true); 1390 var domainToResourcesMap = Audits.AuditRules.getDomainToResourcesMap(request s, null, true);
1391 this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback) ; 1391 this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback) ;
1392 1392
1393 for (var requestDomain in cookiesPerResourceDomain) { 1393 for (var requestDomain in cookiesPerResourceDomain) {
1394 var cookies = cookiesPerResourceDomain[requestDomain]; 1394 var cookies = cookiesPerResourceDomain[requestDomain];
1395 sortedCookieSizes.push( 1395 sortedCookieSizes.push(
1396 {domain: requestDomain, avgCookieSize: this._average(cookies), maxCook ieSize: this._max(cookies)}); 1396 {domain: requestDomain, avgCookieSize: this._average(cookies), maxCook ieSize: this._max(cookies)});
1397 } 1397 }
1398 var avgAllCookiesSize = this._average(allCookies); 1398 var avgAllCookiesSize = this._average(allCookies);
1399 1399
1400 var hugeCookieDomains = []; 1400 var hugeCookieDomains = [];
1401 sortedCookieSizes.sort(maxSizeSorter); 1401 sortedCookieSizes.sort(maxSizeSorter);
1402 1402
1403 for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) { 1403 for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) {
1404 var maxCookieSize = sortedCookieSizes[i].maxCookieSize; 1404 var maxCookieSize = sortedCookieSizes[i].maxCookieSize;
1405 if (maxCookieSize > this._maxBytesThreshold) 1405 if (maxCookieSize > this._maxBytesThreshold)
1406 hugeCookieDomains.push( 1406 hugeCookieDomains.push(
1407 WebInspector.AuditRuleResult.resourceDomain(sortedCookieSizes[i].dom ain) + ': ' + 1407 Audits.AuditRuleResult.resourceDomain(sortedCookieSizes[i].domain) + ': ' +
1408 Number.bytesToString(maxCookieSize)); 1408 Number.bytesToString(maxCookieSize));
1409 } 1409 }
1410 1410
1411 var bigAvgCookieDomains = []; 1411 var bigAvgCookieDomains = [];
1412 sortedCookieSizes.sort(avgSizeSorter); 1412 sortedCookieSizes.sort(avgSizeSorter);
1413 for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) { 1413 for (var i = 0, len = sortedCookieSizes.length; i < len; ++i) {
1414 var domain = sortedCookieSizes[i].domain; 1414 var domain = sortedCookieSizes[i].domain;
1415 var avgCookieSize = sortedCookieSizes[i].avgCookieSize; 1415 var avgCookieSize = sortedCookieSizes[i].avgCookieSize;
1416 if (avgCookieSize > this._avgBytesThreshold && avgCookieSize < this._maxBy tesThreshold) 1416 if (avgCookieSize > this._avgBytesThreshold && avgCookieSize < this._maxBy tesThreshold)
1417 bigAvgCookieDomains.push( 1417 bigAvgCookieDomains.push(
1418 WebInspector.AuditRuleResult.resourceDomain(domain) + ': ' + Number. bytesToString(avgCookieSize)); 1418 Audits.AuditRuleResult.resourceDomain(domain) + ': ' + Number.bytesT oString(avgCookieSize));
1419 } 1419 }
1420 result.addChild(WebInspector.UIString( 1420 result.addChild(Common.UIString(
1421 'The average cookie size for all requests on this page is %s', Number.by tesToString(avgAllCookiesSize))); 1421 'The average cookie size for all requests on this page is %s', Number.by tesToString(avgAllCookiesSize)));
1422 1422
1423 if (hugeCookieDomains.length) { 1423 if (hugeCookieDomains.length) {
1424 var entry = result.addChild( 1424 var entry = result.addChild(
1425 WebInspector.UIString( 1425 Common.UIString(
1426 'The following domains have a cookie size in excess of 1KB. This i s harmful because requests with cookies larger than 1KB typically cannot fit int o a single network packet.'), 1426 'The following domains have a cookie size in excess of 1KB. This i s harmful because requests with cookies larger than 1KB typically cannot fit int o a single network packet.'),
1427 true); 1427 true);
1428 entry.addURLs(hugeCookieDomains); 1428 entry.addURLs(hugeCookieDomains);
1429 result.violationCount += hugeCookieDomains.length; 1429 result.violationCount += hugeCookieDomains.length;
1430 } 1430 }
1431 1431
1432 if (bigAvgCookieDomains.length) { 1432 if (bigAvgCookieDomains.length) {
1433 var entry = result.addChild( 1433 var entry = result.addChild(
1434 WebInspector.UIString( 1434 Common.UIString(
1435 '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 ta kes to send requests.', 1435 '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 ta kes to send requests.',
1436 this._avgBytesThreshold), 1436 this._avgBytesThreshold),
1437 true); 1437 true);
1438 entry.addURLs(bigAvgCookieDomains); 1438 entry.addURLs(bigAvgCookieDomains);
1439 result.violationCount += bigAvgCookieDomains.length; 1439 result.violationCount += bigAvgCookieDomains.length;
1440 } 1440 }
1441 } 1441 }
1442 }; 1442 };
1443 1443
1444 /** 1444 /**
1445 * @unrestricted 1445 * @unrestricted
1446 */ 1446 */
1447 WebInspector.AuditRules.StaticCookielessRule = class extends WebInspector.AuditR ules.CookieRuleBase { 1447 Audits.AuditRules.StaticCookielessRule = class extends Audits.AuditRules.CookieR uleBase {
1448 constructor(minResources) { 1448 constructor(minResources) {
1449 super('http-staticcookieless', WebInspector.UIString('Serve static content f rom a cookieless domain')); 1449 super('http-staticcookieless', Common.UIString('Serve static content from a cookieless domain'));
1450 this._minResources = minResources; 1450 this._minResources = minResources;
1451 } 1451 }
1452 1452
1453 processCookies(allCookies, requests, result) { 1453 processCookies(allCookies, requests, result) {
1454 var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap( 1454 var domainToResourcesMap = Audits.AuditRules.getDomainToResourcesMap(
1455 requests, [WebInspector.resourceTypes.Stylesheet, WebInspector.resourceT ypes.Image], true); 1455 requests, [Common.resourceTypes.Stylesheet, Common.resourceTypes.Image], true);
1456 var totalStaticResources = 0; 1456 var totalStaticResources = 0;
1457 for (var domain in domainToResourcesMap) 1457 for (var domain in domainToResourcesMap)
1458 totalStaticResources += domainToResourcesMap[domain].length; 1458 totalStaticResources += domainToResourcesMap[domain].length;
1459 if (totalStaticResources < this._minResources) 1459 if (totalStaticResources < this._minResources)
1460 return; 1460 return;
1461 var matchingResourceData = {}; 1461 var matchingResourceData = {};
1462 this.mapResourceCookies(domainToResourcesMap, allCookies, this._collectorCal lback.bind(this, matchingResourceData)); 1462 this.mapResourceCookies(domainToResourcesMap, allCookies, this._collectorCal lback.bind(this, matchingResourceData));
1463 1463
1464 var badUrls = []; 1464 var badUrls = [];
1465 var cookieBytes = 0; 1465 var cookieBytes = 0;
1466 for (var url in matchingResourceData) { 1466 for (var url in matchingResourceData) {
1467 badUrls.push(url); 1467 badUrls.push(url);
1468 cookieBytes += matchingResourceData[url]; 1468 cookieBytes += matchingResourceData[url];
1469 } 1469 }
1470 if (badUrls.length < this._minResources) 1470 if (badUrls.length < this._minResources)
1471 return; 1471 return;
1472 1472
1473 var entry = result.addChild( 1473 var entry = result.addChild(
1474 WebInspector.UIString( 1474 Common.UIString(
1475 '%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:', 1475 '%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:',
1476 Number.bytesToString(cookieBytes)), 1476 Number.bytesToString(cookieBytes)),
1477 true); 1477 true);
1478 entry.addURLs(badUrls); 1478 entry.addURLs(badUrls);
1479 result.violationCount = badUrls.length; 1479 result.violationCount = badUrls.length;
1480 } 1480 }
1481 1481
1482 _collectorCallback(matchingResourceData, request, cookie) { 1482 _collectorCallback(matchingResourceData, request, cookie) {
1483 matchingResourceData[request.url] = (matchingResourceData[request.url] || 0) + cookie.size(); 1483 matchingResourceData[request.url] = (matchingResourceData[request.url] || 0) + cookie.size();
1484 } 1484 }
1485 }; 1485 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698