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.targetManager.addEventListener(WebInspector.TargetManager.Events.Load, this._didMainResourceLoad, this); 40 } 41 42 WebInspector.AuditController.prototype = { 43 /** 44 * @param {!WebInspector.Target} target 45 * @param {!Array.<!WebInspector.AuditCategory>} categories 46 * @param {function(string, !Array.<!WebInspector.AuditCategoryResult>)} resultCallback 47 */ 48 _executeAudit: function(target, categories, resultCallback) 49 { 50 this._progress.setTitle(WebInspector.UIString("Running audit")); 51 52 /** 53 * @param {!WebInspector.AuditCategoryResult} categoryResult 54 * @param {!WebInspector.AuditRuleResult} ruleResult 55 * @this {WebInspector.AuditController} 56 */ 57 function ruleResultReadyCallback(categoryResult, ruleResult) 58 { 59 if (ruleResult && ruleResult.children) 60 categoryResult.addRuleResult(ruleResult); 61 62 if (this._progress.isCanceled()) 63 this._progress.done(); 64 } 65 66 var results = []; 67 var mainResourceURL = target.resourceTreeModel.inspectedPageURL(); 68 var categoriesDone = 0; 69 70 /** 71 * @this {WebInspector.AuditController} 72 */ 73 function categoryDoneCallback() 74 { 75 if (++categoriesDone !== categories.length) 76 return; 77 this._progress.done(); 78 resultCallback(mainResourceURL, results) 79 } 80 81 var requests = target.networkLog.requests.slice(); 82 var compositeProgress = new WebInspector.CompositeProgress(this._progress); 83 var subprogresses = []; 84 for (var i = 0; i < categories.length; ++i) 85 subprogresses.push(compositeProgress.createSubProgress()); 86 for (var i = 0; i < categories.length; ++i) { 87 var category = categories[i]; 88 var result = new WebInspector.AuditCategoryResult(category); 89 results.push(result); 90 category.run(target, requests, ruleResultReadyCallback.bind(this, result), categoryDoneCallback.bind(this), subprogresses[i]); 91 } 92 }, 93 94 /** 95 * @param {function()} launcherCallback 96 * @param {string} mainResourceURL 97 * @param {!Array.<!WebInspector.AuditCategoryResult>} results 98 */ 99 _auditFinishedCallback: function(launcherCallback, mainResourceURL, results) 100 { 101 this._auditsPanel.auditFinishedCallback(mainResourceURL, results); 102 if (!this._progress.isCanceled()) 103 launcherCallback(); 104 }, 105 106 /** 107 * @param {!Array.<string>} categoryIds 108 * @param {!WebInspector.Progress} progress 109 * @param {boolean} runImmediately 110 * @param {function()} startedCallback 111 * @param {function()} finishedCallback 112 */ 113 initiateAudit: function(categoryIds, progress, runImmediately, startedCallback, finishedCallback) 114 { 115 var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.mainTarget()); 116 if (!categoryIds || !categoryIds.length || !target) 117 return; 118 119 this._progress = progress; 120 121 var categories = []; 122 for (var i = 0; i < categoryIds.length; ++i) 123 categories.push(this._auditsPanel.categoriesById[categoryIds[i]]); 124 125 /** 126 * @this {WebInspector.AuditController} 127 */ 128 function startAuditWhenResourcesReady() 129 { 130 startedCallback(); 131 this._executeAudit(target, categories, this._auditFinishedCallback.bind(this, finishedCallback)); 132 } 133 134 if (runImmediately) 135 startAuditWhenResourcesReady.call(this); 136 else 137 this._reloadResources(startAuditWhenResourcesReady.bind(this)); 138 139 WebInspector.userMetrics.AuditsStarted.record(); 140 }, 141 142 /** 143 * @param {function()=} callback 144 */ 145 _reloadResources: function(callback) 146 { 147 this._pageReloadCallback = callback; 148 WebInspector.targetManager.reloadPage(); 149 }, 150 151 _didMainResourceLoad: function() 152 { 153 if (this._pageReloadCallback) { 154 var callback = this._pageReloadCallback; 155 delete this._pageReloadCallback; 156 callback(); 157 } 158 }, 159 160 clearResults: function() 161 { 162 this._auditsPanel.clearResults(); 163 } 164 } 165