| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview Tools is a main class that wires all components of the | 6 * @fileoverview Tools is a main class that wires all components of the |
| 7 * DevTools frontend together. It is also responsible for overriding existing | 7 * DevTools frontend together. It is also responsible for overriding existing |
| 8 * WebInspector functionality while it is getting upstreamed into WebCore. | 8 * WebInspector functionality while it is getting upstreamed into WebCore. |
| 9 */ | 9 */ |
| 10 goog.provide('devtools.Tools'); | 10 goog.provide('devtools.Tools'); |
| 11 | 11 |
| 12 goog.require('devtools.DebuggerAgent'); | 12 goog.require('devtools.DebuggerAgent'); |
| 13 goog.require('devtools.DomAgent'); | |
| 14 goog.require('devtools.NetAgent'); | |
| 15 | 13 |
| 16 | 14 |
| 17 /** | 15 /** |
| 18 * Dispatches raw message from the host. | 16 * Dispatches raw message from the host. |
| 19 * @param {Object} msg Message to dispatch. | 17 * @param {string} remoteName |
| 18 * @prama {string} methodName |
| 19 * @param {string} param1, param2, param3 Arguments to dispatch. |
| 20 */ | 20 */ |
| 21 devtools.dispatch = function(msg) { | 21 devtools$$dispatch = function(remoteName, methodName, param1, param2, param3) { |
| 22 var delegate = msg[0]; | 22 remoteName = 'Remote' + remoteName.substring(0, remoteName.length - 8); |
| 23 var methodName = msg[1]; | |
| 24 var remoteName = 'Remote' + delegate.substring(0, delegate.length - 8); | |
| 25 var agent = window[remoteName]; | 23 var agent = window[remoteName]; |
| 26 if (!agent) { | 24 if (!agent) { |
| 27 debugPrint('No remote agent "' + remoteName + '" found.'); | 25 debugPrint('No remote agent "' + remoteName + '" found.'); |
| 28 return; | 26 return; |
| 29 } | 27 } |
| 30 var method = agent[methodName]; | 28 var method = agent[methodName]; |
| 31 if (!method) { | 29 if (!method) { |
| 32 debugPrint('No method "' + remoteName + '.' + methodName + '" found.'); | 30 debugPrint('No method "' + remoteName + '.' + methodName + '" found.'); |
| 33 return; | 31 return; |
| 34 } | 32 } |
| 35 method.apply(this, msg.slice(2)); | 33 method.call(this, param1, param2, param3); |
| 36 }; | 34 }; |
| 37 | 35 |
| 38 | 36 |
| 39 devtools.ToolsAgent = function() { | 37 devtools.ToolsAgent = function() { |
| 40 RemoteToolsAgent.DidEvaluateJavaScript = devtools.Callback.processCallback; | |
| 41 RemoteToolsAgent.DidExecuteUtilityFunction = | 38 RemoteToolsAgent.DidExecuteUtilityFunction = |
| 42 devtools.Callback.processCallback; | 39 devtools.Callback.processCallback; |
| 43 RemoteToolsAgent.UpdateFocusedNode = | |
| 44 goog.bind(this.updateFocusedNode, this); | |
| 45 RemoteToolsAgent.FrameNavigate = | 40 RemoteToolsAgent.FrameNavigate = |
| 46 goog.bind(this.frameNavigate, this); | 41 goog.bind(this.frameNavigate_, this); |
| 47 RemoteToolsAgent.AddMessageToConsole = | 42 RemoteToolsAgent.DispatchOnClient = |
| 48 goog.bind(this.addMessageToConsole, this); | 43 goog.bind(this.dispatchOnClient_, this); |
| 49 this.debuggerAgent_ = new devtools.DebuggerAgent(); | 44 this.debuggerAgent_ = new devtools.DebuggerAgent(); |
| 50 this.domAgent_ = new devtools.DomAgent(); | |
| 51 this.netAgent_ = new devtools.NetAgent(); | |
| 52 }; | 45 }; |
| 53 | 46 |
| 54 | 47 |
| 55 /** | 48 /** |
| 56 * Resets tools agent to its initial state. | 49 * Resets tools agent to its initial state. |
| 57 */ | 50 */ |
| 58 devtools.ToolsAgent.prototype.reset = function() { | 51 devtools.ToolsAgent.prototype.reset = function() { |
| 59 this.domAgent_.reset(); | 52 DevToolsHost.reset(); |
| 60 this.netAgent_.reset(); | |
| 61 this.debuggerAgent_.reset(); | 53 this.debuggerAgent_.reset(); |
| 62 | |
| 63 this.domAgent_.getDocumentElementAsync(); | |
| 64 }; | 54 }; |
| 65 | 55 |
| 66 | 56 |
| 67 /** | 57 /** |
| 68 * @param {string} script Script exression to be evaluated in the context of the | 58 * @param {string} script Script exression to be evaluated in the context of the |
| 69 * inspected page. | 59 * inspected page. |
| 70 * @param {function(string):undefined} callback Function to call with the | 60 * @param {function(Object|string, boolean):undefined} opt_callback Function to |
| 71 * result. | 61 * call with the result. |
| 72 */ | 62 */ |
| 73 devtools.ToolsAgent.prototype.evaluateJavaScript = function(script, callback) { | 63 devtools.ToolsAgent.prototype.evaluateJavaScript = function(script, |
| 74 var callbackId = devtools.Callback.wrap(callback); | 64 opt_callback) { |
| 75 RemoteToolsAgent.EvaluateJavaScript(callbackId, script); | 65 InspectorController.evaluate(script, opt_callback || function() {}); |
| 76 }; | 66 }; |
| 77 | 67 |
| 78 | 68 |
| 79 /** | 69 /** |
| 80 * @return {devtools.DebuggerAgent} Debugger agent instance. | 70 * @return {devtools.DebuggerAgent} Debugger agent instance. |
| 81 */ | 71 */ |
| 82 devtools.ToolsAgent.prototype.getDebuggerAgent = function() { | 72 devtools.ToolsAgent.prototype.getDebuggerAgent = function() { |
| 83 return this.debuggerAgent_; | 73 return this.debuggerAgent_; |
| 84 }; | 74 }; |
| 85 | 75 |
| 86 /** | |
| 87 * DomAgent accessor. | |
| 88 * @return {devtools.DomAgent} Dom agent instance. | |
| 89 */ | |
| 90 devtools.ToolsAgent.prototype.getDomAgent = function() { | |
| 91 return this.domAgent_; | |
| 92 }; | |
| 93 | |
| 94 | |
| 95 /** | |
| 96 * NetAgent accessor. | |
| 97 * @return {devtools.NetAgent} Net agent instance. | |
| 98 */ | |
| 99 devtools.ToolsAgent.prototype.getNetAgent = function() { | |
| 100 return this.netAgent_; | |
| 101 }; | |
| 102 | |
| 103 | |
| 104 /** | |
| 105 * @see tools_agent.h | |
| 106 */ | |
| 107 devtools.ToolsAgent.prototype.updateFocusedNode = function(nodeId) { | |
| 108 var node = this.domAgent_.getNodeForId(nodeId); | |
| 109 WebInspector.updateFocusedNode(node); | |
| 110 }; | |
| 111 | |
| 112 | 76 |
| 113 /** | 77 /** |
| 114 * @param {string} url Url frame navigated to. | 78 * @param {string} url Url frame navigated to. |
| 115 * @param {bool} topLevel True iff top level navigation occurred. | |
| 116 * @see tools_agent.h | 79 * @see tools_agent.h |
| 80 * @private |
| 117 */ | 81 */ |
| 118 devtools.ToolsAgent.prototype.frameNavigate = function(url, topLevel) { | 82 devtools.ToolsAgent.prototype.frameNavigate_ = function(url) { |
| 119 if (topLevel) { | 83 this.reset(); |
| 120 this.reset(); | 84 // Do not reset Profiles panel. |
| 121 WebInspector.reset(); | 85 var profiles = null; |
| 86 if ('profiles' in WebInspector.panels) { |
| 87 profiles = WebInspector.panels['profiles']; |
| 88 delete WebInspector.panels['profiles']; |
| 89 } |
| 90 WebInspector.reset(); |
| 91 if (profiles != null) { |
| 92 WebInspector.panels['profiles'] = profiles; |
| 122 } | 93 } |
| 123 }; | 94 }; |
| 124 | 95 |
| 125 | 96 |
| 126 /** | 97 /** |
| 127 * @param {Object} message Message object to add. | 98 * @param {string} message Serialized call to be dispatched on WebInspector. |
| 128 * @see tools_agent.h | 99 * @private |
| 129 */ | 100 */ |
| 130 devtools.ToolsAgent.prototype.addMessageToConsole = function(message) { | 101 devtools.ToolsAgent.prototype.dispatchOnClient_ = function(message) { |
| 131 var console = WebInspector.console; | 102 WebInspector.dispatch.apply(WebInspector, JSON.parse(message)); |
| 132 if (console) { | |
| 133 console.addMessage(new WebInspector.ConsoleMessage( | |
| 134 message.source, message.level, message.line, message.sourceId, | |
| 135 undefined, 1, message.text)); | |
| 136 } | |
| 137 }; | 103 }; |
| 138 | 104 |
| 139 | 105 |
| 140 /** | 106 /** |
| 141 * Evaluates js expression. | 107 * Evaluates js expression. |
| 142 * @param {string} expr | 108 * @param {string} expr |
| 143 */ | 109 */ |
| 144 devtools.ToolsAgent.prototype.evaluate = function(expr) { | 110 devtools.ToolsAgent.prototype.evaluate = function(expr) { |
| 145 RemoteToolsAgent.evaluate(expr); | 111 RemoteToolsAgent.evaluate(expr); |
| 146 }; | 112 }; |
| 147 | 113 |
| 148 | 114 |
| 149 /** | 115 /** |
| 116 * Enables / disables resources panel in the ui. |
| 117 * @param {boolean} enabled New panel status. |
| 118 */ |
| 119 WebInspector.setResourcesPanelEnabled = function(enabled) { |
| 120 InspectorController.resourceTrackingEnabled_ = enabled; |
| 121 WebInspector.panels.resources.reset(); |
| 122 }; |
| 123 |
| 124 |
| 125 /** |
| 150 * Prints string to the inspector console or shows alert if the console doesn't | 126 * Prints string to the inspector console or shows alert if the console doesn't |
| 151 * exist. | 127 * exist. |
| 152 * @param {string} text | 128 * @param {string} text |
| 153 */ | 129 */ |
| 154 function debugPrint(text) { | 130 function debugPrint(text) { |
| 155 var console = WebInspector.console; | 131 var console = WebInspector.console; |
| 156 if (console) { | 132 if (console) { |
| 157 console.addMessage(new WebInspector.ConsoleMessage( | 133 console.addMessage(new WebInspector.ConsoleMessage( |
| 158 '', undefined, 1, '', undefined, 1, text)); | 134 WebInspector.ConsoleMessage.MessageSource.JS, |
| 135 WebInspector.ConsoleMessage.MessageType.Log, |
| 136 WebInspector.ConsoleMessage.MessageLevel.Log, |
| 137 1, 'chrome://devtools/<internal>', undefined, -1, text)); |
| 159 } else { | 138 } else { |
| 160 alert(text); | 139 alert(text); |
| 161 } | 140 } |
| 162 } | 141 } |
| 163 | 142 |
| 164 | 143 |
| 165 /** | 144 /** |
| 166 * Global instance of the tools agent. | 145 * Global instance of the tools agent. |
| 167 * @type {devtools.ToolsAgent} | 146 * @type {devtools.ToolsAgent} |
| 168 */ | 147 */ |
| 169 devtools.tools = null; | 148 devtools.tools = null; |
| 170 | 149 |
| 171 | 150 |
| 172 var context = {}; // Used by WebCore's inspector routines. | 151 var context = {}; // Used by WebCore's inspector routines. |
| 173 | 152 |
| 174 | |
| 175 /////////////////////////////////////////////////////////////////////////////// | 153 /////////////////////////////////////////////////////////////////////////////// |
| 176 // Here and below are overrides to existing WebInspector methods only. | 154 // Here and below are overrides to existing WebInspector methods only. |
| 177 // TODO(pfeldman): Patch WebCore and upstream changes. | 155 // TODO(pfeldman): Patch WebCore and upstream changes. |
| 178 var oldLoaded = WebInspector.loaded; | 156 var oldLoaded = WebInspector.loaded; |
| 179 WebInspector.loaded = function() { | 157 WebInspector.loaded = function() { |
| 180 devtools.tools = new devtools.ToolsAgent(); | 158 devtools.tools = new devtools.ToolsAgent(); |
| 181 devtools.tools.reset(); | 159 devtools.tools.reset(); |
| 182 | 160 |
| 183 Preferences.ignoreWhitespace = false; | 161 Preferences.ignoreWhitespace = false; |
| 184 oldLoaded.call(this); | 162 oldLoaded.call(this); |
| 185 | 163 |
| 164 // Hide dock button on Mac OS. |
| 165 // TODO(pfeldman): remove once Mac OS docking is implemented. |
| 166 if (InspectorController.platform().indexOf('mac') == 0) { |
| 167 document.getElementById('dock-status-bar-item').addStyleClass('hidden'); |
| 168 } |
| 169 |
| 170 // Mute refresh action. |
| 171 document.addEventListener("keydown", function(event) { |
| 172 if (event.keyIdentifier == 'F5') { |
| 173 event.preventDefault(); |
| 174 } else if (event.keyIdentifier == 'U+0052' /* 'R' */ && |
| 175 (event.ctrlKey || event.metaKey)) { |
| 176 event.preventDefault(); |
| 177 } |
| 178 }, true); |
| 179 |
| 186 DevToolsHost.loaded(); | 180 DevToolsHost.loaded(); |
| 187 }; | 181 }; |
| 188 | 182 |
| 189 | 183 |
| 190 var webkitUpdateChildren = | |
| 191 WebInspector.ElementsTreeElement.prototype.updateChildren; | |
| 192 | |
| 193 | |
| 194 /** | |
| 195 * @override | |
| 196 */ | |
| 197 WebInspector.ElementsTreeElement.prototype.updateChildren = function() { | |
| 198 var self = this; | |
| 199 devtools.tools.getDomAgent().getChildNodesAsync(this.representedObject, | |
| 200 function() { | |
| 201 webkitUpdateChildren.call(self); | |
| 202 }); | |
| 203 }; | |
| 204 | |
| 205 | |
| 206 /** | |
| 207 * @override | |
| 208 */ | |
| 209 WebInspector.ElementsPanel.prototype.performSearch = function(query) { | |
| 210 this.searchCanceled(); | |
| 211 devtools.tools.getDomAgent().performSearch(query, | |
| 212 goog.bind(this.performSearchCallback_, this)); | |
| 213 }; | |
| 214 | |
| 215 | |
| 216 WebInspector.ElementsPanel.prototype.performSearchCallback_ = function(nodes) { | |
| 217 for (var i = 0; i < nodes.length; ++i) { | |
| 218 var treeElement = this.treeOutline.findTreeElement(nodes[i]); | |
| 219 if (treeElement) | |
| 220 treeElement.highlighted = true; | |
| 221 } | |
| 222 | |
| 223 if (nodes.length) { | |
| 224 this.currentSearchResultIndex_ = 0; | |
| 225 this.focusedDOMNode = nodes[0]; | |
| 226 } | |
| 227 | |
| 228 this.searchResultCount_ = nodes.length; | |
| 229 }; | |
| 230 | |
| 231 | |
| 232 /** | |
| 233 * @override | |
| 234 */ | |
| 235 WebInspector.ElementsPanel.prototype.searchCanceled = function() { | |
| 236 this.currentSearchResultIndex_ = 0; | |
| 237 this.searchResultCount_ = 0; | |
| 238 devtools.tools.getDomAgent().searchCanceled( | |
| 239 goog.bind(this.searchCanceledCallback_, this)); | |
| 240 }; | |
| 241 | |
| 242 | |
| 243 WebInspector.ElementsPanel.prototype.searchCanceledCallback_ = function(nodes) { | |
| 244 for (var i = 0; i < nodes.length; i++) { | |
| 245 var treeElement = this.treeOutline.findTreeElement(nodes[i]); | |
| 246 if (treeElement) | |
| 247 treeElement.highlighted = false; | |
| 248 } | |
| 249 }; | |
| 250 | |
| 251 | |
| 252 /** | |
| 253 * @override | |
| 254 */ | |
| 255 WebInspector.ElementsPanel.prototype.jumpToNextSearchResult = function() { | |
| 256 if (!this.searchResultCount_) | |
| 257 return; | |
| 258 | |
| 259 if (++this.currentSearchResultIndex_ >= this.searchResultCount_) | |
| 260 this.currentSearchResultIndex_ = 0; | |
| 261 | |
| 262 this.focusedDOMNode = devtools.tools.getDomAgent(). | |
| 263 getSearchResultNode(this.currentSearchResultIndex_); | |
| 264 }; | |
| 265 | |
| 266 | |
| 267 /** | |
| 268 * @override | |
| 269 */ | |
| 270 WebInspector.ElementsPanel.prototype.jumpToPreviousSearchResult = function() { | |
| 271 if (!this.searchResultCount_) | |
| 272 return; | |
| 273 | |
| 274 if (--this.currentSearchResultIndex_ < 0) | |
| 275 this.currentSearchResultIndex_ = this.searchResultCount_ - 1; | |
| 276 | |
| 277 this.focusedDOMNode = devtools.tools.getDomAgent(). | |
| 278 getSearchResultNode(this.currentSearchResultIndex_); | |
| 279 }; | |
| 280 | |
| 281 | |
| 282 /** | |
| 283 * @override | |
| 284 */ | |
| 285 WebInspector.Console.prototype._evalInInspectedWindow = function(expr) { | |
| 286 return devtools.tools.evaluate(expr); | |
| 287 }; | |
| 288 | |
| 289 | |
| 290 /** | |
| 291 * Disable autocompletion in the console. | |
| 292 * TODO(yurys): change WebKit implementation to allow asynchronous completion. | |
| 293 * @override | |
| 294 */ | |
| 295 WebInspector.Console.prototype.completions = function( | |
| 296 wordRange, bestMatchOnly) { | |
| 297 return null; | |
| 298 }; | |
| 299 | |
| 300 | |
| 301 /** | |
| 302 * @override | |
| 303 */ | |
| 304 WebInspector.ElementsPanel.prototype.updateStyles = function(forceUpdate) { | |
| 305 var stylesSidebarPane = this.sidebarPanes.styles; | |
| 306 if (!stylesSidebarPane.expanded || !stylesSidebarPane.needsUpdate) { | |
| 307 return; | |
| 308 } | |
| 309 this.invokeWithStyleSet_(function(node) { | |
| 310 stylesSidebarPane.needsUpdate = !!node; | |
| 311 stylesSidebarPane.update(node, null, forceUpdate); | |
| 312 }); | |
| 313 }; | |
| 314 | |
| 315 | |
| 316 /** | |
| 317 * @override | |
| 318 */ | |
| 319 WebInspector.ElementsPanel.prototype.updateMetrics = function() { | |
| 320 var metricsSidebarPane = this.sidebarPanes.metrics; | |
| 321 if (!metricsSidebarPane.expanded || !metricsSidebarPane.needsUpdate) { | |
| 322 return; | |
| 323 } | |
| 324 this.invokeWithStyleSet_(function(node) { | |
| 325 metricsSidebarPane.needsUpdate = !!node; | |
| 326 metricsSidebarPane.update(node); | |
| 327 }); | |
| 328 }; | |
| 329 | |
| 330 | |
| 331 /** | |
| 332 * Temporarily sets style fetched from the inspectable tab to the currently | |
| 333 * focused node, invokes updateUI callback and clears the styles. | |
| 334 * @param {function(Node):undefined} updateUI Callback to call while styles are | |
| 335 * set. | |
| 336 */ | |
| 337 WebInspector.ElementsPanel.prototype.invokeWithStyleSet_ = | |
| 338 function(updateUI) { | |
| 339 var node = this.focusedDOMNode; | |
| 340 if (node && node.nodeType === Node.TEXT_NODE && node.parentNode) | |
| 341 node = node.parentNode; | |
| 342 | |
| 343 if (node && node.nodeType == Node.ELEMENT_NODE) { | |
| 344 var callback = function(stylesStr) { | |
| 345 var styles = JSON.parse(stylesStr); | |
| 346 if (!styles.computedStyle) { | |
| 347 return; | |
| 348 } | |
| 349 node.setStyles(styles.computedStyle, styles.inlineStyle, | |
| 350 styles.styleAttributes, styles.matchedCSSRules); | |
| 351 updateUI(node); | |
| 352 node.clearStyles(); | |
| 353 }; | |
| 354 devtools.tools.getDomAgent().getNodeStylesAsync( | |
| 355 node, | |
| 356 !Preferences.showUserAgentStyles, | |
| 357 callback); | |
| 358 } else { | |
| 359 updateUI(null); | |
| 360 } | |
| 361 }; | |
| 362 | |
| 363 | |
| 364 /** | |
| 365 * @override | |
| 366 */ | |
| 367 WebInspector.MetricsSidebarPane.prototype.editingCommitted = | |
| 368 function(element, userInput, previousContent, context) { | |
| 369 if (userInput === previousContent) { | |
| 370 // nothing changed, so cancel | |
| 371 return this.editingCancelled(element, context); | |
| 372 } | |
| 373 | |
| 374 if (context.box !== "position" && (!userInput || userInput === "\u2012")) { | |
| 375 userInput = "0px"; | |
| 376 } else if (context.box === "position" && | |
| 377 (!userInput || userInput === "\u2012")) { | |
| 378 userInput = "auto"; | |
| 379 } | |
| 380 | |
| 381 // Append a "px" unit if the user input was just a number. | |
| 382 if (/^\d+$/.test(userInput)) { | |
| 383 userInput += "px"; | |
| 384 } | |
| 385 devtools.tools.getDomAgent().setStylePropertyAsync( | |
| 386 this.node, | |
| 387 context.styleProperty, | |
| 388 userInput, | |
| 389 WebInspector.updateStylesAndMetrics_); | |
| 390 }; | |
| 391 | |
| 392 | |
| 393 /** | |
| 394 * @override | |
| 395 */ | |
| 396 WebInspector.PropertiesSidebarPane.prototype.update = function(object) { | |
| 397 var body = this.bodyElement; | |
| 398 body.removeChildren(); | |
| 399 | |
| 400 this.sections = []; | |
| 401 | |
| 402 if (!object) { | |
| 403 return; | |
| 404 } | |
| 405 | |
| 406 | |
| 407 var self = this; | |
| 408 devtools.tools.getDomAgent().getNodePrototypesAsync(object.id_, | |
| 409 function(json) { | |
| 410 // Get array of prototype user-friendly names. | |
| 411 var prototypes = JSON.parse(json); | |
| 412 for (var i = 0; i < prototypes.length; ++i) { | |
| 413 var prototype = {}; | |
| 414 prototype.id_ = object.id_; | |
| 415 prototype.protoDepth_ = i; | |
| 416 var section = new WebInspector.SidebarObjectPropertiesSection( | |
| 417 prototype, | |
| 418 prototypes[i]); | |
| 419 self.sections.push(section); | |
| 420 body.appendChild(section.element); | |
| 421 } | |
| 422 }); | |
| 423 }; | |
| 424 | |
| 425 | |
| 426 /** | |
| 427 * Our implementation of ObjectPropertiesSection for Elements tab. | |
| 428 * @constructor | |
| 429 */ | |
| 430 WebInspector.SidebarObjectPropertiesSection = function(object, title) { | |
| 431 WebInspector.ObjectPropertiesSection.call(this, object, title, | |
| 432 null /* subtitle */, null /* emptyPlaceholder */, | |
| 433 null /* ignoreHasOwnProperty */, null /* extraProperties */, | |
| 434 WebInspector.SidebarObjectPropertyTreeElement /* treeElementConstructor */ | |
| 435 ); | |
| 436 }; | |
| 437 goog.inherits(WebInspector.SidebarObjectPropertiesSection, | |
| 438 WebInspector.ObjectPropertiesSection); | |
| 439 | |
| 440 | |
| 441 /** | |
| 442 * @override | |
| 443 */ | |
| 444 WebInspector.SidebarObjectPropertiesSection.prototype.onpopulate = function() { | |
| 445 var nodeId = this.object.id_; | |
| 446 var protoDepth = this.object.protoDepth_; | |
| 447 var path = []; | |
| 448 devtools.tools.getDomAgent().getNodePropertiesAsync(nodeId, path, protoDepth, | |
| 449 goog.partial(WebInspector.didGetNodePropertiesAsync_, | |
| 450 this.propertiesTreeOutline, | |
| 451 this.treeElementConstructor, | |
| 452 nodeId, | |
| 453 path)); | |
| 454 }; | |
| 455 | |
| 456 | |
| 457 /** | |
| 458 * Our implementation of ObjectPropertyTreeElement for Elements tab. | |
| 459 * @constructor | |
| 460 */ | |
| 461 WebInspector.SidebarObjectPropertyTreeElement = function(parentObject, | |
| 462 propertyName) { | |
| 463 WebInspector.ObjectPropertyTreeElement.call(this, parentObject, | |
| 464 propertyName); | |
| 465 }; | |
| 466 goog.inherits(WebInspector.SidebarObjectPropertyTreeElement, | |
| 467 WebInspector.ObjectPropertyTreeElement); | |
| 468 | |
| 469 | |
| 470 /** | |
| 471 * @override | |
| 472 */ | |
| 473 WebInspector.SidebarObjectPropertyTreeElement.prototype.onpopulate = | |
| 474 function() { | |
| 475 var nodeId = this.parentObject.devtools$$nodeId_; | |
| 476 var path = this.parentObject.devtools$$path_.slice(0); | |
| 477 path.push(this.propertyName); | |
| 478 devtools.tools.getDomAgent().getNodePropertiesAsync(nodeId, path, -1, | |
| 479 goog.partial( | |
| 480 WebInspector.didGetNodePropertiesAsync_, | |
| 481 this, | |
| 482 this.treeOutline.section.treeElementConstructor, | |
| 483 nodeId, path)); | |
| 484 }; | |
| 485 | |
| 486 | |
| 487 /** | |
| 488 * This override is necessary for starting highlighting after the resource | |
| 489 * was added into the frame. | |
| 490 * @override | |
| 491 */ | |
| 492 WebInspector.SourceView.prototype.setupSourceFrameIfNeeded = function() { | |
| 493 if (!this._frameNeedsSetup) { | |
| 494 return; | |
| 495 } | |
| 496 | |
| 497 this.attach(); | |
| 498 | |
| 499 var self = this; | |
| 500 var identifier = this.resource.identifier; | |
| 501 var element = this.sourceFrame.element; | |
| 502 var netAgent = devtools.tools.getNetAgent(); | |
| 503 | |
| 504 netAgent.getResourceContentAsync(identifier, function(source) { | |
| 505 var resource = WebInspector.resources[identifier]; | |
| 506 if (InspectorController.addSourceToFrame(resource.mimeType, source, | |
| 507 element)) { | |
| 508 delete self._frameNeedsSetup; | |
| 509 if (resource.type === WebInspector.Resource.Type.Script) { | |
| 510 self.sourceFrame.addEventListener('syntax highlighting complete', | |
| 511 self._syntaxHighlightingComplete, self); | |
| 512 self.sourceFrame.syntaxHighlightJavascript(); | |
| 513 } else { | |
| 514 self._sourceFrameSetupFinished(); | |
| 515 } | |
| 516 } | |
| 517 }); | |
| 518 return true; | |
| 519 }; | |
| 520 | |
| 521 | |
| 522 /** | 184 /** |
| 523 * This override is necessary for adding script source asynchronously. | 185 * This override is necessary for adding script source asynchronously. |
| 524 * @override | 186 * @override |
| 525 */ | 187 */ |
| 526 WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function() { | 188 WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function() { |
| 527 if (!this._frameNeedsSetup) { | 189 if (!this._frameNeedsSetup) { |
| 528 return; | 190 return; |
| 529 } | 191 } |
| 530 | 192 |
| 531 this.attach(); | 193 this.attach(); |
| 532 | 194 |
| 533 if (this.script.source) { | 195 if (this.script.source) { |
| 534 this.didResolveScriptSource_(); | 196 this.didResolveScriptSource_(); |
| 535 } else { | 197 } else { |
| 536 var self = this; | 198 var self = this; |
| 537 devtools.tools.getDebuggerAgent().resolveScriptSource( | 199 devtools.tools.getDebuggerAgent().resolveScriptSource( |
| 538 this.script.sourceID, | 200 this.script.sourceID, |
| 539 function(source) { | 201 function(source) { |
| 540 self.script.source = source || '<source is not available>'; | 202 self.script.source = source || |
| 203 WebInspector.UIString('<source is not available>'); |
| 541 self.didResolveScriptSource_(); | 204 self.didResolveScriptSource_(); |
| 542 }); | 205 }); |
| 543 } | 206 } |
| 544 }; | 207 }; |
| 545 | 208 |
| 546 | 209 |
| 547 /** | 210 /** |
| 548 * Performs source frame setup when script source is aready resolved. | 211 * Performs source frame setup when script source is aready resolved. |
| 549 */ | 212 */ |
| 550 WebInspector.ScriptView.prototype.didResolveScriptSource_ = function() { | 213 WebInspector.ScriptView.prototype.didResolveScriptSource_ = function() { |
| 551 if (!InspectorController.addSourceToFrame( | 214 if (!InspectorController.addSourceToFrame( |
| 552 "text/javascript", this.script.source, this.sourceFrame.element)) { | 215 "text/javascript", this.script.source, this.sourceFrame.element)) { |
| 553 return; | 216 return; |
| 554 } | 217 } |
| 555 | 218 |
| 556 delete this._frameNeedsSetup; | 219 delete this._frameNeedsSetup; |
| 557 | 220 |
| 558 this.sourceFrame.addEventListener( | 221 this.sourceFrame.addEventListener( |
| 559 "syntax highlighting complete", this._syntaxHighlightingComplete, this); | 222 "syntax highlighting complete", this._syntaxHighlightingComplete, this); |
| 560 this.sourceFrame.syntaxHighlightJavascript(); | 223 this.sourceFrame.syntaxHighlightJavascript(); |
| 561 }; | 224 }; |
| 562 | 225 |
| 563 | 226 |
| 564 /** | 227 /** |
| 565 * Dummy object used during properties inspection. | 228 * @param {string} type Type of the the property value('object' or 'function'). |
| 566 * @see WebInspector.didGetNodePropertiesAsync_ | 229 * @param {string} className Class name of the property value. |
| 230 * @constructor |
| 567 */ | 231 */ |
| 568 WebInspector.dummyObject_ = { 'foo' : 'bar' }; | 232 WebInspector.UnresolvedPropertyValue = function(type, className) { |
| 569 | 233 this.type = type; |
| 570 | 234 this.className = className; |
| 571 /** | |
| 572 * Dummy function used during properties inspection. | |
| 573 * @see WebInspector.didGetNodePropertiesAsync_ | |
| 574 */ | |
| 575 WebInspector.dummyFunction_ = function() {}; | |
| 576 | |
| 577 | |
| 578 /** | |
| 579 * Callback function used with the getNodeProperties. | |
| 580 */ | |
| 581 WebInspector.didGetNodePropertiesAsync_ = function(treeOutline, constructor, | |
| 582 nodeId, path, json) { | |
| 583 var props = JSON.parse(json); | |
| 584 var properties = []; | |
| 585 var obj = {}; | |
| 586 obj.devtools$$nodeId_ = nodeId; | |
| 587 obj.devtools$$path_ = path; | |
| 588 for (var i = 0; i < props.length; i += 3) { | |
| 589 var type = props[i]; | |
| 590 var name = props[i + 1]; | |
| 591 var value = props[i + 2]; | |
| 592 properties.push(name); | |
| 593 if (type == 'object') { | |
| 594 // fake object is going to be replaced on expand. | |
| 595 obj[name] = WebInspector.dummyObject_; | |
| 596 } else if (type == 'function') { | |
| 597 // fake function is going to be replaced on expand. | |
| 598 obj[name] = WebInspector.dummyFunction_; | |
| 599 } else { | |
| 600 obj[name] = value; | |
| 601 } | |
| 602 } | |
| 603 properties.sort(); | |
| 604 | |
| 605 treeOutline.removeChildren(); | |
| 606 | |
| 607 for (var i = 0; i < properties.length; ++i) { | |
| 608 var propertyName = properties[i]; | |
| 609 treeOutline.appendChild(new constructor(obj, propertyName)); | |
| 610 } | |
| 611 }; | 235 }; |
| 612 | 236 |
| 613 | 237 |
| 614 /** | |
| 615 * Replace WebKit method with our own implementation to use our call stack | |
| 616 * representation. Original method uses Object.prototype.toString.call to | |
| 617 * learn if scope object is a JSActivation which doesn't work in Chrome. | |
| 618 */ | |
| 619 WebInspector.ScopeChainSidebarPane.prototype.update = function(callFrame) { | |
| 620 this.bodyElement.removeChildren(); | |
| 621 | |
| 622 this.sections = []; | |
| 623 this.callFrame = callFrame; | |
| 624 | |
| 625 if (!callFrame) { | |
| 626 var infoElement = document.createElement('div'); | |
| 627 infoElement.className = 'info'; | |
| 628 infoElement.textContent = WebInspector.UIString('Not Paused'); | |
| 629 this.bodyElement.appendChild(infoElement); | |
| 630 return; | |
| 631 } | |
| 632 | |
| 633 if (!callFrame._expandedProperties) { | |
| 634 callFrame._expandedProperties = {}; | |
| 635 } | |
| 636 | |
| 637 var scopeObject = callFrame.localScope; | |
| 638 var title = WebInspector.UIString('Local'); | |
| 639 var subtitle = Object.describe(scopeObject, true); | |
| 640 var emptyPlaceholder = null; | |
| 641 var extraProperties = null; | |
| 642 | |
| 643 var section = new WebInspector.ObjectPropertiesSection(scopeObject, title, | |
| 644 subtitle, emptyPlaceholder, true, extraProperties, | |
| 645 WebInspector.ScopeChainSidebarPane.TreeElement); | |
| 646 section.editInSelectedCallFrameWhenPaused = true; | |
| 647 section.pane = this; | |
| 648 | |
| 649 section.expanded = true; | |
| 650 | |
| 651 this.sections.push(section); | |
| 652 this.bodyElement.appendChild(section.element); | |
| 653 }; | |
| 654 | |
| 655 | |
| 656 /** | |
| 657 * Custom implementation of TreeElement that asynchronously resolves children | |
| 658 * using the debugger agent. | |
| 659 * @constructor | |
| 660 */ | |
| 661 WebInspector.ScopeChainSidebarPane.TreeElement = function(parentObject, | |
| 662 propertyName) { | |
| 663 WebInspector.ScopeVariableTreeElement.call(this, parentObject, propertyName); | |
| 664 } | |
| 665 WebInspector.ScopeChainSidebarPane.TreeElement.inherits( | |
| 666 WebInspector.ScopeVariableTreeElement); | |
| 667 | |
| 668 | |
| 669 /** | |
| 670 * @override | |
| 671 */ | |
| 672 WebInspector.ScopeChainSidebarPane.TreeElement.prototype.onpopulate = | |
| 673 function() { | |
| 674 var obj = this.parentObject[this.propertyName]; | |
| 675 devtools.tools.getDebuggerAgent().resolveChildren(obj, | |
| 676 goog.bind(this.didResolveChildren_, this)); | |
| 677 }; | |
| 678 | |
| 679 | |
| 680 /** | |
| 681 * Callback function used with the resolveChildren. | |
| 682 */ | |
| 683 WebInspector.ScopeChainSidebarPane.TreeElement.prototype.didResolveChildren_ = | |
| 684 function(object) { | |
| 685 this.removeChildren(); | |
| 686 var constructor = this.treeOutline.section.treeElementConstructor; | |
| 687 object = object.resolvedValue; | |
| 688 for (var name in object) { | |
| 689 this.appendChild(new constructor(object, name)); | |
| 690 } | |
| 691 }; | |
| 692 | |
| 693 | |
| 694 /** | |
| 695 * @override | |
| 696 */ | |
| 697 WebInspector.StylePropertyTreeElement.prototype.toggleEnabled = | |
| 698 function(event) { | |
| 699 var enabled = event.target.checked; | |
| 700 devtools.tools.getDomAgent().toggleNodeStyleAsync( | |
| 701 this.style, | |
| 702 enabled, | |
| 703 this.name, | |
| 704 WebInspector.updateStylesAndMetrics_); | |
| 705 }; | |
| 706 | |
| 707 | |
| 708 /** | |
| 709 * @override | |
| 710 */ | |
| 711 WebInspector.StylePropertyTreeElement.prototype.applyStyleText = function( | |
| 712 styleText, updateInterface) { | |
| 713 devtools.tools.getDomAgent().applyStyleTextAsync(this.style, this.name, | |
| 714 styleText, | |
| 715 function() { | |
| 716 if (updateInterface) { | |
| 717 WebInspector.updateStylesAndMetrics_(); | |
| 718 } | |
| 719 }); | |
| 720 }; | |
| 721 | |
| 722 | |
| 723 /** | |
| 724 * Forces update of styles and metrics sidebar panes. | |
| 725 */ | |
| 726 WebInspector.updateStylesAndMetrics_ = function() { | |
| 727 WebInspector.panels.elements.sidebarPanes.metrics.needsUpdate = true; | |
| 728 WebInspector.panels.elements.updateMetrics(); | |
| 729 WebInspector.panels.elements.sidebarPanes.styles.needsUpdate = true; | |
| 730 WebInspector.panels.elements.updateStyles(true); | |
| 731 }; | |
| 732 | |
| 733 | |
| 734 /** | 238 /** |
| 735 * This function overrides standard searchableViews getters to perform search | 239 * This function overrides standard searchableViews getters to perform search |
| 736 * only in the current view (other views are loaded asynchronously, no way to | 240 * only in the current view (other views are loaded asynchronously, no way to |
| 737 * search them yet). | 241 * search them yet). |
| 738 */ | 242 */ |
| 739 WebInspector.searchableViews_ = function() { | 243 WebInspector.searchableViews_ = function() { |
| 740 var views = []; | 244 var views = []; |
| 741 const visibleView = this.visibleView; | 245 const visibleView = this.visibleView; |
| 742 if (visibleView && visibleView.performSearch) { | 246 if (visibleView && visibleView.performSearch) { |
| 743 views.push(visibleView); | 247 views.push(visibleView); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 755 | 259 |
| 756 | 260 |
| 757 /** | 261 /** |
| 758 * @override | 262 * @override |
| 759 */ | 263 */ |
| 760 WebInspector.ScriptsPanel.prototype.__defineGetter__( | 264 WebInspector.ScriptsPanel.prototype.__defineGetter__( |
| 761 'searchableViews', | 265 'searchableViews', |
| 762 WebInspector.searchableViews_); | 266 WebInspector.searchableViews_); |
| 763 | 267 |
| 764 | 268 |
| 765 /** | |
| 766 * @override | |
| 767 */ | |
| 768 WebInspector.Console.prototype._evalInInspectedWindow = function(expression) { | |
| 769 if (WebInspector.panels.scripts.paused) | |
| 770 return WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression); | |
| 771 | |
| 772 var console = this; | |
| 773 devtools.tools.evaluateJavaScript(expression, function(response) { | |
| 774 // TODO(yurys): send exception information along with the response | |
| 775 var exception = false; | |
| 776 console.addMessage(new WebInspector.ConsoleCommandResult( | |
| 777 response, exception, null /* commandMessage */)); | |
| 778 }); | |
| 779 // TODO(yurys): refactor WebInspector.Console so that the result is added into | |
| 780 // the command log message. | |
| 781 return 'evaluating...'; | |
| 782 }; | |
| 783 | |
| 784 | |
| 785 (function() { | 269 (function() { |
| 786 var oldShow = WebInspector.ScriptsPanel.prototype.show; | 270 var oldShow = WebInspector.ScriptsPanel.prototype.show; |
| 787 WebInspector.ScriptsPanel.prototype.show = function() { | 271 WebInspector.ScriptsPanel.prototype.show = function() { |
| 788 devtools.tools.getDebuggerAgent().initializeScriptsCache(); | 272 devtools.tools.getDebuggerAgent().initUI(); |
| 273 this.enableToggleButton.visible = false; |
| 789 oldShow.call(this); | 274 oldShow.call(this); |
| 790 }; | 275 }; |
| 791 })(); | 276 })(); |
| 792 | 277 |
| 793 | 278 |
| 794 /** | |
| 795 * We don't use WebKit's BottomUpProfileDataGridTree, instead using | |
| 796 * our own (because BottomUpProfileDataGridTree's functionality is | |
| 797 * implemented in profile_view.js for V8's Tick Processor). | |
| 798 * | |
| 799 * @param {WebInspector.ProfileView} profileView Profile view. | |
| 800 * @param {devtools.profiler.ProfileView} profile Profile. | |
| 801 */ | |
| 802 WebInspector.BottomUpProfileDataGridTree = function(profileView, profile) { | |
| 803 return WebInspector.buildProfileDataGridTree_( | |
| 804 profileView, profile.heavyProfile); | |
| 805 }; | |
| 806 | |
| 807 | |
| 808 /** | |
| 809 * We don't use WebKit's TopDownProfileDataGridTree, instead using | |
| 810 * our own (because TopDownProfileDataGridTree's functionality is | |
| 811 * implemented in profile_view.js for V8's Tick Processor). | |
| 812 * | |
| 813 * @param {WebInspector.ProfileView} profileView Profile view. | |
| 814 * @param {devtools.profiler.ProfileView} profile Profile. | |
| 815 */ | |
| 816 WebInspector.TopDownProfileDataGridTree = function(profileView, profile) { | |
| 817 return WebInspector.buildProfileDataGridTree_( | |
| 818 profileView, profile.treeProfile); | |
| 819 }; | |
| 820 | |
| 821 | |
| 822 /** | |
| 823 * A helper function, checks whether a profile node has visible children. | |
| 824 * | |
| 825 * @param {devtools.profiler.ProfileView.Node} profileNode Profile node. | |
| 826 * @return {boolean} Whether a profile node has visible children. | |
| 827 */ | |
| 828 WebInspector.nodeHasChildren_ = function(profileNode) { | |
| 829 var children = profileNode.children; | |
| 830 for (var i = 0, n = children.length; i < n; ++i) { | |
| 831 if (children[i].visible) { | |
| 832 return true; | |
| 833 } | |
| 834 } | |
| 835 return false; | |
| 836 }; | |
| 837 | |
| 838 | |
| 839 /** | |
| 840 * Common code for populating a profiler grid node or a tree with | |
| 841 * given profile nodes. | |
| 842 * | |
| 843 * @param {WebInspector.ProfileDataGridNode| | |
| 844 * WebInspector.ProfileDataGridTree} viewNode Grid node or a tree. | |
| 845 * @param {WebInspector.ProfileView} profileView Profile view. | |
| 846 * @param {Array<devtools.profiler.ProfileView.Node>} children Profile nodes. | |
| 847 * @param {WebInspector.ProfileDataGridTree} owningTree Grid tree. | |
| 848 */ | |
| 849 WebInspector.populateNode_ = function( | |
| 850 viewNode, profileView, children, owningTree) { | |
| 851 for (var i = 0, n = children.length; i < n; ++i) { | |
| 852 var child = children[i]; | |
| 853 if (child.visible) { | |
| 854 viewNode.appendChild( | |
| 855 new WebInspector.ProfileDataGridNode( | |
| 856 profileView, child, owningTree, | |
| 857 WebInspector.nodeHasChildren_(child))); | |
| 858 } | |
| 859 } | |
| 860 }; | |
| 861 | |
| 862 | |
| 863 /** | |
| 864 * A helper function for building a profile grid tree. | |
| 865 * | |
| 866 * @param {WebInspector.ProfileView} profileview Profile view. | |
| 867 * @param {devtools.profiler.ProfileView} profile Profile. | |
| 868 * @return {WebInspector.ProfileDataGridTree} Profile grid tree. | |
| 869 */ | |
| 870 WebInspector.buildProfileDataGridTree_ = function(profileView, profile) { | |
| 871 var children = profile.head.children; | |
| 872 var dataGridTree = new WebInspector.ProfileDataGridTree( | |
| 873 profileView, profile.head); | |
| 874 WebInspector.populateNode_(dataGridTree, profileView, children, dataGridTree); | |
| 875 return dataGridTree; | |
| 876 }; | |
| 877 | |
| 878 | |
| 879 /** | |
| 880 * @override | |
| 881 */ | |
| 882 WebInspector.ProfileDataGridNode.prototype._populate = function(event) { | |
| 883 var children = this.profileNode.children; | |
| 884 WebInspector.populateNode_(this, this.profileView, children, this.tree); | |
| 885 this.removeEventListener("populate", this._populate, this); | |
| 886 }; | |
| 887 | |
| 888 | |
| 889 // As columns in data grid can't be changed after initialization, | 279 // As columns in data grid can't be changed after initialization, |
| 890 // we need to intercept the constructor and modify columns upon creation. | 280 // we need to intercept the constructor and modify columns upon creation. |
| 891 (function InterceptDataGridForProfiler() { | 281 (function InterceptDataGridForProfiler() { |
| 892 var originalDataGrid = WebInspector.DataGrid; | 282 var originalDataGrid = WebInspector.DataGrid; |
| 893 WebInspector.DataGrid = function(columns) { | 283 WebInspector.DataGrid = function(columns) { |
| 894 if (('average' in columns) && ('calls' in columns)) { | 284 if (('average' in columns) && ('calls' in columns)) { |
| 895 delete columns['average']; | 285 delete columns['average']; |
| 896 delete columns['calls']; | 286 delete columns['calls']; |
| 897 } | 287 } |
| 898 return new originalDataGrid(columns); | 288 return new originalDataGrid(columns); |
| 899 }; | 289 }; |
| 900 })(); | 290 })(); |
| 901 | 291 |
| 902 | 292 |
| 903 /** | 293 // WebKit's profiler displays milliseconds with high resolution (shows |
| 904 * @override | 294 // three digits after the decimal point). We never have such resolution, |
| 905 * TODO(pfeldman): Add l10n. | 295 // as our minimal sampling rate is 1 ms. So we are disabling high resolution |
| 906 */ | 296 // to avoid visual clutter caused by meaningless ".000" parts. |
| 907 WebInspector.UIString = function(string) | 297 (function InterceptTimeDisplayInProfiler() { |
| 298 var originalDataGetter = |
| 299 WebInspector.ProfileDataGridNode.prototype.__lookupGetter__('data'); |
| 300 WebInspector.ProfileDataGridNode.prototype.__defineGetter__('data', |
| 301 function() { |
| 302 var oldNumberSecondsToString = Number.secondsToString; |
| 303 Number.secondsToString = function(seconds, formatterFunction) { |
| 304 return oldNumberSecondsToString(seconds, formatterFunction, false); |
| 305 }; |
| 306 var data = originalDataGetter.call(this); |
| 307 Number.secondsToString = oldNumberSecondsToString; |
| 308 return data; |
| 309 }); |
| 310 })(); |
| 311 |
| 312 |
| 313 (function InterceptProfilesPanelEvents() { |
| 314 var oldShow = WebInspector.ProfilesPanel.prototype.show; |
| 315 WebInspector.ProfilesPanel.prototype.show = function() { |
| 316 devtools.tools.getDebuggerAgent().initializeProfiling(); |
| 317 this.enableToggleButton.visible = false; |
| 318 oldShow.call(this); |
| 319 // Show is called on every show event of a panel, so |
| 320 // we only need to intercept it once. |
| 321 WebInspector.ProfilesPanel.prototype.show = oldShow; |
| 322 }; |
| 323 })(); |
| 324 |
| 325 |
| 326 /* |
| 327 * @override» |
| 328 * TODO(mnaganov): Restore l10n when it will be agreed that it is needed.» |
| 329 */» |
| 330 WebInspector.UIString = function(string) {» |
| 331 return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));» |
| 332 }; |
| 333 |
| 334 |
| 335 // There is no clear way of setting frame title yet. So sniffing main resource |
| 336 // load. |
| 337 (function OverrideUpdateResource() { |
| 338 var originalUpdateResource = WebInspector.updateResource; |
| 339 WebInspector.updateResource = function(identifier, payload) { |
| 340 originalUpdateResource.call(this, identifier, payload); |
| 341 var resource = this.resources[identifier]; |
| 342 if (resource && resource.mainResource && resource.finished) { |
| 343 document.title = |
| 344 WebInspector.UIString('Developer Tools - %s', resource.url); |
| 345 } |
| 346 }; |
| 347 })(); |
| 348 |
| 349 |
| 350 // Highlight extension content scripts in the scripts list. |
| 351 (function () { |
| 352 var original = WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu; |
| 353 WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu = function(script) { |
| 354 var result = original.apply(this, arguments); |
| 355 var debuggerAgent = devtools.tools.getDebuggerAgent(); |
| 356 var type = debuggerAgent.getScriptContextType(script.sourceID); |
| 357 var option = script.filesSelectOption; |
| 358 if (type == 'injected' && option) { |
| 359 option.addStyleClass('injected'); |
| 360 } |
| 361 return result; |
| 362 }; |
| 363 })(); |
| 364 |
| 365 |
| 366 /** Pending WebKit upstream by apavlov). Fixes iframe vs drag problem. */ |
| 367 (function() { |
| 368 var originalDragStart = WebInspector.elementDragStart; |
| 369 WebInspector.elementDragStart = function(element) { |
| 370 var glassPane = document.createElement("div"); |
| 371 glassPane.style.cssText = |
| 372 'position:absolute;width:100%;height:100%;opacity:0;z-index:1'; |
| 373 glassPane.id = 'glass-pane-for-drag'; |
| 374 element.parentElement.appendChild(glassPane); |
| 375 |
| 376 originalDragStart.apply(this, arguments); |
| 377 }; |
| 378 |
| 379 var originalDragEnd = WebInspector.elementDragEnd; |
| 380 WebInspector.elementDragEnd = function() { |
| 381 originalDragEnd.apply(this, arguments); |
| 382 |
| 383 var glassPane = document.getElementById('glass-pane-for-drag'); |
| 384 glassPane.parentElement.removeChild(glassPane); |
| 385 }; |
| 386 })(); |
| 387 |
| 388 |
| 389 (function() { |
| 390 var originalCreatePanels = WebInspector._createPanels; |
| 391 WebInspector._createPanels = function() { |
| 392 originalCreatePanels.apply(this, arguments); |
| 393 this.panels.heap = new WebInspector.HeapProfilerPanel(); |
| 394 }; |
| 395 })(); |
| 396 |
| 397 |
| 398 WebInspector.resourceTrackingWasEnabled = function() |
| 908 { | 399 { |
| 909 return String.vsprintf(string, Array.prototype.slice.call(arguments, 1)); | 400 InspectorController.resourceTrackingEnabled_ = true; |
| 401 this.panels.resources.resourceTrackingWasEnabled(); |
| 910 } | 402 } |
| 403 |
| 404 WebInspector.resourceTrackingWasDisabled = function() |
| 405 { |
| 406 InspectorController.resourceTrackingEnabled_ = false; |
| 407 this.panels.resources.resourceTrackingWasDisabled(); |
| 408 } |
| OLD | NEW |