Home | History | Annotate | Download | only in audits
      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