1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2013 Samsung Electronics. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /** 33 * @constructor 34 * @param {!WebInspector.AuditsPanel} auditsPanel 35 */ 36 WebInspector.AuditController = function(auditsPanel) 37 { 38 this._auditsPanel = auditsPanel; 39 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._didMainResourceLoad, this); 40 } 41 42 WebInspector.AuditController.prototype = { 43 /** 44 * @param {!Array.<!WebInspector.AuditCategory>} categories 45 * @param {function(string, !Array.<!WebInspector.AuditCategoryResult>)} resultCallback 46 */ 47 _executeAudit: function(categories, resultCallback) 48 { 49 this._progress.setTitle(WebInspector.UIString("Running audit")); 50 51 /** 52 * @param {!WebInspector.AuditCategoryResult} categoryResult 53 * @param {!WebInspector.AuditRuleResult} ruleResult 54 * @this {WebInspector.AuditController} 55 */ 56 function ruleResultReadyCallback(categoryResult, ruleResult) 57 { 58 if (ruleResult && ruleResult.children) 59 categoryResult.addRuleResult(ruleResult); 60 61 if (this._progress.isCanceled()) 62 this._progress.done(); 63 } 64 65 var results = []; 66 var mainResourceURL = WebInspector.inspectedPageURL; 67 var categoriesDone = 0; 68 69 /** 70 * @this {WebInspector.AuditController} 71 */ 72 function categoryDoneCallback() 73 { 74 if (++categoriesDone !== categories.length) 75 return; 76 this._progress.done(); 77 resultCallback(mainResourceURL, results) 78 } 79 80 var requests = WebInspector.networkLog.requests.slice(); 81 var compositeProgress = new WebInspector.CompositeProgress(this._progress); 82 var subprogresses = []; 83 for (var i = 0; i < categories.length; ++i) 84 subprogresses.push(compositeProgress.createSubProgress()); 85 for (var i = 0; i < categories.length; ++i) { 86 var category = categories[i]; 87 var result = new WebInspector.AuditCategoryResult(category); 88 results.push(result); 89 category.run(requests, ruleResultReadyCallback.bind(this, result), categoryDoneCallback.bind(this), subprogresses[i]); 90 } 91 }, 92 93 /** 94 * @param {function()} launcherCallback 95 * @param {string} mainResourceURL 96 * @param {!Array.<!WebInspector.AuditCategoryResult>} results 97 */ 98 _auditFinishedCallback: function(launcherCallback, mainResourceURL, results) 99 { 100 this._auditsPanel.auditFinishedCallback(mainResourceURL, results); 101 if (!this._progress.isCanceled()) 102 launcherCallback(); 103 }, 104 105 /** 106 * @param {!Array.<string>} categoryIds 107 * @param {!WebInspector.Progress} progress 108 * @param {boolean} runImmediately 109 * @param {function()} startedCallback 110 * @param {function()} finishedCallback 111 */ 112 initiateAudit: function(categoryIds, progress, runImmediately, startedCallback, finishedCallback) 113 { 114 if (!categoryIds || !categoryIds.length) 115 return; 116 117 this._progress = progress; 118 119 var categories = []; 120 for (var i = 0; i < categoryIds.length; ++i) 121 categories.push(this._auditsPanel.categoriesById[categoryIds[i]]); 122 123 /** 124 * @this {WebInspector.AuditController} 125 */ 126 function startAuditWhenResourcesReady() 127 { 128 startedCallback(); 129 this._executeAudit(categories, this._auditFinishedCallback.bind(this, finishedCallback)); 130 } 131 132 if (runImmediately) 133 startAuditWhenResourcesReady.call(this); 134 else 135 this._reloadResources(startAuditWhenResourcesReady.bind(this)); 136 137 WebInspector.userMetrics.AuditsStarted.record(); 138 }, 139 140 /** 141 * @param {function()=} callback 142 */ 143 _reloadResources: function(callback) 144 { 145 this._pageReloadCallback = callback; 146 WebInspector.resourceTreeModel.reloadPage(); 147 }, 148 149 _didMainResourceLoad: function() 150 { 151 if (this._pageReloadCallback) { 152 var callback = this._pageReloadCallback; 153 delete this._pageReloadCallback; 154 callback(); 155 } 156 }, 157 158 clearResults: function() 159 { 160 this._auditsPanel.clearResults(); 161 } 162 } 163