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 * @implements {WebInspector.AuditCategory} 34 * @param {string} extensionOrigin 35 * @param {string} id 36 * @param {string} displayName 37 * @param {number=} ruleCount 38 */ 39WebInspector.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 47WebInspector.ExtensionAuditCategory.prototype = { 48 /** 49 * @override 50 */ 51 get id() 52 { 53 return this._id; 54 }, 55 56 /** 57 * @override 58 */ 59 get displayName() 60 { 61 return this._displayName; 62 }, 63 64 /** 65 * @override 66 * @param {!WebInspector.Target} target 67 * @param {!Array.<!WebInspector.NetworkRequest>} requests 68 * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback 69 * @param {function()} categoryDoneCallback 70 * @param {!WebInspector.Progress} progress 71 */ 72 run: function(target, requests, ruleResultCallback, categoryDoneCallback, progress) 73 { 74 var results = new WebInspector.ExtensionAuditCategoryResults(this, target, ruleResultCallback, categoryDoneCallback, progress); 75 WebInspector.extensionServer.startAuditRun(this, results); 76 } 77} 78 79/** 80 * @constructor 81 * @param {!WebInspector.ExtensionAuditCategory} category 82 * @param {!WebInspector.Target} target 83 * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback 84 * @param {function()} categoryDoneCallback 85 * @param {!WebInspector.Progress} progress 86 */ 87WebInspector.ExtensionAuditCategoryResults = function(category, target, ruleResultCallback, categoryDoneCallback, progress) 88{ 89 this._target = target; 90 this._category = category; 91 this._ruleResultCallback = ruleResultCallback; 92 this._categoryDoneCallback = categoryDoneCallback; 93 this._progress = progress; 94 this._progress.setTotalWork(1); 95 this._expectedResults = category._ruleCount; 96 this._actualResults = 0; 97 98 this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId; 99} 100 101WebInspector.ExtensionAuditCategoryResults.prototype = { 102 done: function() 103 { 104 WebInspector.extensionServer.stopAuditRun(this); 105 this._progress.done(); 106 this._categoryDoneCallback(); 107 }, 108 109 addResult: function(displayName, description, severity, details) 110 { 111 var result = new WebInspector.AuditRuleResult(displayName); 112 result.addChild(description); 113 result.severity = severity; 114 if (details) 115 this._addNode(result, details); 116 this._addResult(result); 117 }, 118 119 _addNode: function(parent, node) 120 { 121 var contents = WebInspector.auditFormatters.partiallyApply(WebInspector.ExtensionAuditFormatters, this, node.contents); 122 var addedNode = parent.addChild(contents, node.expanded); 123 if (node.children) { 124 for (var i = 0; i < node.children.length; ++i) 125 this._addNode(addedNode, node.children[i]); 126 } 127 }, 128 129 _addResult: function(result) 130 { 131 this._ruleResultCallback(result); 132 ++this._actualResults; 133 if (typeof this._expectedResults === "number") { 134 this._progress.setWorked(this._actualResults / this._expectedResults); 135 if (this._actualResults === this._expectedResults) 136 this.done(); 137 } 138 }, 139 140 /** 141 * @param {number} progress 142 */ 143 updateProgress: function(progress) 144 { 145 this._progress.setWorked(progress); 146 }, 147 148 /** 149 * @param {string} expression 150 * @param {?Object} evaluateOptions 151 * @param {function(!WebInspector.RemoteObject)} callback 152 */ 153 evaluate: function(expression, evaluateOptions, callback) 154 { 155 /** 156 * @param {?string} error 157 * @param {!RuntimeAgent.RemoteObject} result 158 * @param {boolean=} wasThrown 159 * @this {WebInspector.ExtensionAuditCategoryResults} 160 */ 161 function onEvaluate(error, result, wasThrown) 162 { 163 if (wasThrown) 164 return; 165 var object = this._target.runtimeModel.createRemoteObject(result); 166 callback(object); 167 } 168 WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate.bind(this)); 169 } 170} 171 172WebInspector.ExtensionAuditFormatters = { 173 /** 174 * @this {WebInspector.ExtensionAuditCategoryResults} 175 * @param {string} expression 176 * @param {string} title 177 * @param {?Object} evaluateOptions 178 * @return {!Element} 179 */ 180 object: function(expression, title, evaluateOptions) 181 { 182 var parentElement = document.createElement("div"); 183 function onEvaluate(remoteObject) 184 { 185 var section = new WebInspector.ObjectPropertiesSection(remoteObject, title); 186 section.expanded = true; 187 section.editable = false; 188 parentElement.appendChild(section.element); 189 } 190 this.evaluate(expression, evaluateOptions, onEvaluate); 191 return parentElement; 192 }, 193 194 /** 195 * @this {WebInspector.ExtensionAuditCategoryResults} 196 * @param {string} expression 197 * @param {?Object} evaluateOptions 198 * @return {!Element} 199 */ 200 node: function(expression, evaluateOptions) 201 { 202 var parentElement = document.createElement("div"); 203 /** 204 * @param {?WebInspector.DOMNode} node 205 */ 206 function onNodeAvailable(node) 207 { 208 if (!node) 209 return; 210 var renderer = WebInspector.moduleManager.instance(WebInspector.Renderer, node); 211 if (renderer) 212 parentElement.appendChild(renderer.render(node)); 213 else 214 console.error("No renderer for node found"); 215 } 216 /** 217 * @param {!WebInspector.RemoteObject} remoteObject 218 */ 219 function onEvaluate(remoteObject) 220 { 221 remoteObject.pushNodeToFrontend(onNodeAvailable); 222 } 223 this.evaluate(expression, evaluateOptions, onEvaluate); 224 return parentElement; 225 } 226} 227 228WebInspector.ExtensionAuditCategoryResults._lastId = 0; 229