Home | History | Annotate | Download | only in front_end
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     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.
     29  */
     30 
     31 /**
     32  * @constructor
     33  * @extends {WebInspector.AuditCategory}
     34  * @param {string} extensionOrigin
     35  * @param {string} id
     36  * @param {string} displayName
     37  * @param {number=} ruleCount
     38  */
     39 WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName, ruleCount)
     40 {
     41     this._extensionOrigin = extensionOrigin;
     42     this._id = id;
     43     this._displayName = displayName;
     44     this._ruleCount  = ruleCount;
     45 }
     46 
     47 WebInspector.ExtensionAuditCategory.prototype = {
     48     // AuditCategory interface
     49     get id()
     50     {
     51         return this._id;
     52     },
     53 
     54     get displayName()
     55     {
     56         return this._displayName;
     57     },
     58 
     59     /**
     60      * @param {!Array.<!WebInspector.NetworkRequest>} requests
     61      * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
     62      * @param {function()} categoryDoneCallback
     63      * @param {!WebInspector.Progress} progress
     64      */
     65     run: function(requests, ruleResultCallback, categoryDoneCallback, progress)
     66     {
     67         var results = new WebInspector.ExtensionAuditCategoryResults(this, ruleResultCallback, categoryDoneCallback, progress);
     68         WebInspector.extensionServer.startAuditRun(this, results);
     69     }
     70 }
     71 
     72 /**
     73  * @constructor
     74  * @param {!WebInspector.ExtensionAuditCategory} category
     75  * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
     76  * @param {function()} categoryDoneCallback
     77  * @param {!WebInspector.Progress} progress
     78  */
     79 WebInspector.ExtensionAuditCategoryResults = function(category, ruleResultCallback, categoryDoneCallback, progress)
     80 {
     81     this._category = category;
     82     this._ruleResultCallback = ruleResultCallback;
     83     this._categoryDoneCallback = categoryDoneCallback;
     84     this._progress = progress;
     85     this._progress.setTotalWork(1);
     86     this._expectedResults = category._ruleCount;
     87     this._actualResults = 0;
     88 
     89     this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId;
     90 }
     91 
     92 WebInspector.ExtensionAuditCategoryResults.prototype = {
     93     done: function()
     94     {
     95         WebInspector.extensionServer.stopAuditRun(this);
     96         this._progress.done();
     97         this._categoryDoneCallback();
     98     },
     99 
    100     addResult: function(displayName, description, severity, details)
    101     {
    102         var result = new WebInspector.AuditRuleResult(displayName);
    103         result.addChild(description);
    104         result.severity = severity;
    105         if (details)
    106             this._addNode(result, details);
    107         this._addResult(result);
    108     },
    109 
    110     _addNode: function(parent, node)
    111     {
    112         var contents = WebInspector.auditFormatters.partiallyApply(WebInspector.ExtensionAuditFormatters, this, node.contents);
    113         var addedNode = parent.addChild(contents, node.expanded);
    114         if (node.children) {
    115             for (var i = 0; i < node.children.length; ++i)
    116                 this._addNode(addedNode, node.children[i]);
    117         }
    118     },
    119 
    120     _addResult: function(result)
    121     {
    122         this._ruleResultCallback(result);
    123         ++this._actualResults;
    124         if (typeof this._expectedResults === "number") {
    125             this._progress.setWorked(this._actualResults / this._expectedResults);
    126             if (this._actualResults === this._expectedResults)
    127                 this.done();
    128         }
    129     },
    130 
    131     /**
    132      * @param {number} progress
    133      */
    134     updateProgress: function(progress)
    135     {
    136         this._progress.setWorked(progress);
    137     },
    138 
    139     /**
    140      * @param {string} expression
    141      * @param {?Object} evaluateOptions
    142      * @param {function(!WebInspector.RemoteObject)} callback
    143      */
    144     evaluate: function(expression, evaluateOptions, callback)
    145     {
    146         /**
    147          * @param {?string} error
    148          * @param {!RuntimeAgent.RemoteObject} result
    149          * @param {boolean=} wasThrown
    150          */
    151         function onEvaluate(error, result, wasThrown)
    152         {
    153             if (wasThrown)
    154                 return;
    155             var object = WebInspector.RemoteObject.fromPayload(result);
    156             callback(object);
    157         }
    158         WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate);
    159     }
    160 }
    161 
    162 WebInspector.ExtensionAuditFormatters = {
    163     /**
    164      * @this {WebInspector.ExtensionAuditCategoryResults}
    165      * @param {string} expression
    166      * @param {string} title
    167      * @param {?Object} evaluateOptions
    168      */
    169     object: function(expression, title, evaluateOptions)
    170     {
    171         var parentElement = document.createElement("div");
    172         function onEvaluate(remoteObject)
    173         {
    174             var section = new WebInspector.ObjectPropertiesSection(remoteObject, title);
    175             section.expanded = true;
    176             section.editable = false;
    177             parentElement.appendChild(section.element);
    178         }
    179         this.evaluate(expression, evaluateOptions, onEvaluate);
    180         return parentElement;
    181     },
    182 
    183     /**
    184      * @this {WebInspector.ExtensionAuditCategoryResults}
    185      * @param {string} expression
    186      * @param {?Object} evaluateOptions
    187      */
    188     node: function(expression, evaluateOptions)
    189     {
    190         var parentElement = document.createElement("div");
    191         /**
    192          * @param {?number} nodeId
    193          */
    194         function onNodeAvailable(nodeId)
    195         {
    196             if (!nodeId)
    197                 return;
    198             var treeOutline = new WebInspector.ElementsTreeOutline(false, false);
    199             treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
    200             treeOutline.element.classList.add("outline-disclosure");
    201             treeOutline.setVisible(true);
    202             parentElement.appendChild(treeOutline.element);
    203         }
    204         /**
    205          * @param {!WebInspector.RemoteObject} remoteObject
    206          */
    207         function onEvaluate(remoteObject)
    208         {
    209             remoteObject.pushNodeToFrontend(onNodeAvailable);
    210         }
    211         this.evaluate(expression, evaluateOptions, onEvaluate);
    212         return parentElement;
    213     }
    214 }
    215 
    216 WebInspector.ExtensionAuditCategoryResults._lastId = 0;
    217