diff options
author | yurys@chromium.org <yurys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-09 08:00:00 +0000 |
---|---|---|
committer | yurys@chromium.org <yurys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-09 08:00:00 +0000 |
commit | 2a5ab280301194dd5594c9f76460b20a6755e499 (patch) | |
tree | 0faa87ba8d245c87a1b0f16edca0b31810c611c6 /webkit | |
parent | f93036f0edf5d0d8950b4d14162cc6ca185db6a7 (diff) | |
download | chromium_src-2a5ab280301194dd5594c9f76460b20a6755e499.zip chromium_src-2a5ab280301194dd5594c9f76460b20a6755e499.tar.gz chromium_src-2a5ab280301194dd5594c9f76460b20a6755e499.tar.bz2 |
DevTools: prepare glue/devtools/js/*.js files for upstreaming.
BUG=34411
Review URL: http://codereview.chromium.org/580010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38452 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/devtools/js/debugger_agent.js | 1783 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools.js | 564 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools_host_stub.js | 377 | ||||
-rw-r--r-- | webkit/glue/devtools/js/heap_profiler_panel.js | 52 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inject_dispatch.js | 109 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inspector_controller_impl.js | 283 | ||||
-rw-r--r-- | webkit/glue/devtools/js/profiler_agent.js | 267 | ||||
-rw-r--r-- | webkit/glue/devtools/js/profiler_processor.js | 692 | ||||
-rw-r--r-- | webkit/glue/devtools/js/tests.js | 2660 | ||||
-rw-r--r-- | webkit/webkit.gyp | 1 |
10 files changed, 3464 insertions, 3324 deletions
diff --git a/webkit/glue/devtools/js/debugger_agent.js b/webkit/glue/devtools/js/debugger_agent.js index 28cb9c0..51a1d40 100644 --- a/webkit/glue/devtools/js/debugger_agent.js +++ b/webkit/glue/devtools/js/debugger_agent.js @@ -1,104 +1,127 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** * @fileoverview Provides communication interface to remote v8 debugger. See * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol */ -goog.provide('devtools.DebuggerAgent'); - /** * @constructor */ -devtools.DebuggerAgent = function() { - RemoteDebuggerAgent.debuggerOutput = - goog.bind(this.handleDebuggerOutput_, this); - RemoteDebuggerAgent.setContextId = - goog.bind(this.setContextId_, this); - - /** - * Id of the inspected page global context. It is used for filtering scripts. - * @type {number} - */ - this.contextId_ = null; - - /** - * Mapping from script id to script info. - * @type {Object} - */ - this.parsedScripts_ = null; - - /** - * Mapping from the request id to the devtools.BreakpointInfo for the - * breakpoints whose v8 ids are not set yet. These breakpoints are waiting for - * 'setbreakpoint' responses to learn their ids in the v8 debugger. - * @see #handleSetBreakpointResponse_ - * @type {Object} - */ - this.requestNumberToBreakpointInfo_ = null; - - /** - * Information on current stack frames. - * @type {Array.<devtools.CallFrame>} - */ - this.callFrames_ = []; - - /** - * Whether to stop in the debugger on the exceptions. - * @type {boolean} - */ - this.pauseOnExceptions_ = false; - - /** - * Mapping: request sequence number->callback. - * @type {Object} - */ - this.requestSeqToCallback_ = null; - - /** - * Whether the scripts panel has been shown and initialilzed. - * @type {boolean} - */ - this.scriptsPanelInitialized_ = false; - - /** - * Whether the scripts list should be requested next time when context id is - * set. - * @type {boolean} - */ - this.requestScriptsWhenContextIdSet_ = false; - - /** - * Whether the agent is waiting for initial scripts response. - * @type {boolean} - */ - this.waitingForInitialScriptsResponse_ = false; - - /** - * If backtrace response is received when initial scripts response - * is not yet processed the backtrace handling will be postponed until - * after the scripts response processing. The handler bound to its arguments - * and this agent will be stored in this field then. - * @type {?function()} - */ - this.pendingBacktraceResponseHandler_ = null; - - /** - * Container of all breakpoints set using resource URL. These breakpoints - * survive page reload. Breakpoints set by script id(for scripts that don't - * have URLs) are stored in ScriptInfo objects. - * @type {Object} - */ - this.urlToBreakpoints_ = {}; - - - /** - * Exception message that is shown to user while on exception break. - * @type {WebInspector.ConsoleMessage} - */ - this.currentExceptionMessage_ = null; +devtools.DebuggerAgent = function() +{ + RemoteDebuggerAgent.debuggerOutput = this.handleDebuggerOutput_.bind(this); + RemoteDebuggerAgent.setContextId = this.setContextId_.bind(this); + + /** + * Id of the inspected page global context. It is used for filtering scripts. + * @type {number} + */ + this.contextId_ = null; + + /** + * Mapping from script id to script info. + * @type {Object} + */ + this.parsedScripts_ = null; + + /** + * Mapping from the request id to the devtools.BreakpointInfo for the + * breakpoints whose v8 ids are not set yet. These breakpoints are waiting for + * "setbreakpoint" responses to learn their ids in the v8 debugger. + * @see #handleSetBreakpointResponse_ + * @type {Object} + */ + this.requestNumberToBreakpointInfo_ = null; + + /** + * Information on current stack frames. + * @type {Array.<devtools.CallFrame>} + */ + this.callFrames_ = []; + + /** + * Whether to stop in the debugger on the exceptions. + * @type {boolean} + */ + this.pauseOnExceptions_ = false; + + /** + * Mapping: request sequence number->callback. + * @type {Object} + */ + this.requestSeqToCallback_ = null; + + /** + * Whether the scripts panel has been shown and initialilzed. + * @type {boolean} + */ + this.scriptsPanelInitialized_ = false; + + /** + * Whether the scripts list should be requested next time when context id is + * set. + * @type {boolean} + */ + this.requestScriptsWhenContextIdSet_ = false; + + /** + * Whether the agent is waiting for initial scripts response. + * @type {boolean} + */ + this.waitingForInitialScriptsResponse_ = false; + + /** + * If backtrace response is received when initial scripts response + * is not yet processed the backtrace handling will be postponed until + * after the scripts response processing. The handler bound to its arguments + * and this agent will be stored in this field then. + * @type {?function()} + */ + this.pendingBacktraceResponseHandler_ = null; + + /** + * Container of all breakpoints set using resource URL. These breakpoints + * survive page reload. Breakpoints set by script id(for scripts that don't + * have URLs) are stored in ScriptInfo objects. + * @type {Object} + */ + this.urlToBreakpoints_ = {}; + + + /** + * Exception message that is shown to user while on exception break. + * @type {WebInspector.ConsoleMessage} + */ + this.currentExceptionMessage_ = null; }; @@ -107,28 +130,29 @@ devtools.DebuggerAgent = function() { * @enum {number} */ devtools.DebuggerAgent.ScopeType = { - Global: 0, - Local: 1, - With: 2, - Closure: 3, - Catch: 4 + Global: 0, + Local: 1, + With: 2, + Closure: 3, + Catch: 4 }; /** * Resets debugger agent to its initial state. */ -devtools.DebuggerAgent.prototype.reset = function() { - this.contextId_ = null; - // No need to request scripts since they all will be pushed in AfterCompile - // events. - this.requestScriptsWhenContextIdSet_ = false; - this.waitingForInitialScriptsResponse_ = false; +devtools.DebuggerAgent.prototype.reset = function() +{ + this.contextId_ = null; + // No need to request scripts since they all will be pushed in AfterCompile + // events. + this.requestScriptsWhenContextIdSet_ = false; + this.waitingForInitialScriptsResponse_ = false; - this.parsedScripts_ = {}; - this.requestNumberToBreakpointInfo_ = {}; - this.callFrames_ = []; - this.requestSeqToCallback_ = {}; + this.parsedScripts_ = {}; + this.requestNumberToBreakpointInfo_ = {}; + this.callFrames_ = []; + this.requestSeqToCallback_ = {}; }; @@ -136,30 +160,29 @@ devtools.DebuggerAgent.prototype.reset = function() { * Initializes scripts UI. This method is called every time Scripts panel * is shown. It will send request for context id if it's not set yet. */ -devtools.DebuggerAgent.prototype.initUI = function() { - // Initialize scripts cache when Scripts panel is shown first time. - if (this.scriptsPanelInitialized_) { - return; - } - this.scriptsPanelInitialized_ = true; - if (this.contextId_) { - // We already have context id. This means that we are here from the - // very beginning of the page load cycle and hence will get all scripts - // via after-compile events. No need to request scripts for this session. - // - // There can be a number of scripts from after-compile events that are - // pending addition into the UI. - for (var scriptId in this.parsedScripts_) { - var script = this.parsedScripts_[scriptId]; - WebInspector.parsedScriptSource(scriptId, script.getUrl(), - undefined /* script source */, script.getLineOffset()); +devtools.DebuggerAgent.prototype.initUI = function() +{ + // Initialize scripts cache when Scripts panel is shown first time. + if (this.scriptsPanelInitialized_) + return; + this.scriptsPanelInitialized_ = true; + if (this.contextId_) { + // We already have context id. This means that we are here from the + // very beginning of the page load cycle and hence will get all scripts + // via after-compile events. No need to request scripts for this session. + // + // There can be a number of scripts from after-compile events that are + // pending addition into the UI. + for (var scriptId in this.parsedScripts_) { + var script = this.parsedScripts_[scriptId]; + WebInspector.parsedScriptSource(scriptId, script.getUrl(), undefined /* script source */, script.getLineOffset()); + } + return; } - return; - } - this.waitingForInitialScriptsResponse_ = true; - // Script list should be requested only when current context id is known. - RemoteDebuggerAgent.getContextId(); - this.requestScriptsWhenContextIdSet_ = true; + this.waitingForInitialScriptsResponse_ = true; + // Script list should be requested only when current context id is known. + RemoteDebuggerAgent.getContextId(); + this.requestScriptsWhenContextIdSet_ = true; }; @@ -167,44 +190,44 @@ devtools.DebuggerAgent.prototype.initUI = function() { * Asynchronously requests the debugger for the script source. * @param {number} scriptId Id of the script whose source should be resolved. * @param {function(source:?string):void} callback Function that will be called - * when the source resolution is completed. 'source' parameter will be null + * when the source resolution is completed. "source" parameter will be null * if the resolution fails. */ -devtools.DebuggerAgent.prototype.resolveScriptSource = function( - scriptId, callback) { - var script = this.parsedScripts_[scriptId]; - if (!script || script.isUnresolved()) { - callback(null); - return; - } - - var cmd = new devtools.DebugCommand('scripts', { - 'ids': [scriptId], - 'includeSource': true - }); - devtools.DebuggerAgent.sendCommand_(cmd); - // Force v8 execution so that it gets to processing the requested command. - RemoteToolsAgent.executeVoidJavaScript(); - - this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { - if (msg.isSuccess()) { - var scriptJson = msg.getBody()[0]; - if (scriptJson) - callback(scriptJson.source); - else +devtools.DebuggerAgent.prototype.resolveScriptSource = function(scriptId, callback) +{ + var script = this.parsedScripts_[scriptId]; + if (!script || script.isUnresolved()) { callback(null); - } else { - callback(null); + return; } - }; + + var cmd = new devtools.DebugCommand("scripts", { + "ids": [scriptId], + "includeSource": true + }); + devtools.DebuggerAgent.sendCommand_(cmd); + // Force v8 execution so that it gets to processing the requested command. + RemoteToolsAgent.executeVoidJavaScript(); + + this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { + if (msg.isSuccess()) { + var scriptJson = msg.getBody()[0]; + if (scriptJson) + callback(scriptJson.source); + else + callback(null); + } else + callback(null); + }; }; /** * Tells the v8 debugger to stop on as soon as possible. */ -devtools.DebuggerAgent.prototype.pauseExecution = function() { - RemoteDebuggerCommandExecutor.DebuggerPauseScript(); +devtools.DebuggerAgent.prototype.pauseExecution = function() +{ + RemoteDebuggerCommandExecutor.DebuggerPauseScript(); }; @@ -213,63 +236,60 @@ devtools.DebuggerAgent.prototype.pauseExecution = function() { * @param {number} line Number of the line for the breakpoint. * @param {?string} condition The breakpoint condition. */ -devtools.DebuggerAgent.prototype.addBreakpoint = function( - sourceId, line, condition) { - var script = this.parsedScripts_[sourceId]; - if (!script) { - return; - } - - line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); - - var commandArguments; - if (script.getUrl()) { - var breakpoints = this.urlToBreakpoints_[script.getUrl()]; - if (breakpoints && breakpoints[line]) { - return; - } - if (!breakpoints) { - breakpoints = {}; - this.urlToBreakpoints_[script.getUrl()] = breakpoints; - } - - var breakpointInfo = new devtools.BreakpointInfo(line); - breakpoints[line] = breakpointInfo; - - commandArguments = { - 'groupId': this.contextId_, - 'type': 'script', - 'target': script.getUrl(), - 'line': line, - 'condition': condition - }; - } else { - var breakpointInfo = script.getBreakpointInfo(line); - if (breakpointInfo) { - return; +devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line, condition) +{ + var script = this.parsedScripts_[sourceId]; + if (!script) + return; + + line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); + + var commandArguments; + if (script.getUrl()) { + var breakpoints = this.urlToBreakpoints_[script.getUrl()]; + if (breakpoints && breakpoints[line]) + return; + if (!breakpoints) { + breakpoints = {}; + this.urlToBreakpoints_[script.getUrl()] = breakpoints; + } + + var breakpointInfo = new devtools.BreakpointInfo(line); + breakpoints[line] = breakpointInfo; + + commandArguments = { + "groupId": this.contextId_, + "type": "script", + "target": script.getUrl(), + "line": line, + "condition": condition + }; + } else { + var breakpointInfo = script.getBreakpointInfo(line); + if (breakpointInfo) + return; + + breakpointInfo = new devtools.BreakpointInfo(line); + script.addBreakpointInfo(breakpointInfo); + + commandArguments = { + "groupId": this.contextId_, + "type": "scriptId", + "target": sourceId, + "line": line, + "condition": condition + }; } - breakpointInfo = new devtools.BreakpointInfo(line); - script.addBreakpointInfo(breakpointInfo); + var cmd = new devtools.DebugCommand("setbreakpoint", commandArguments); - commandArguments = { - 'groupId': this.contextId_, - 'type': 'scriptId', - 'target': sourceId, - 'line': line, - 'condition': condition - }; - } + this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo; - var cmd = new devtools.DebugCommand('setbreakpoint', commandArguments); - - this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo; - - devtools.DebuggerAgent.sendCommand_(cmd); - // Force v8 execution so that it gets to processing the requested command. - // It is necessary for being able to change a breakpoint just after it - // has been created (since we need an existing breakpoint id for that). - RemoteToolsAgent.executeVoidJavaScript(); + devtools.DebuggerAgent.sendCommand_(cmd); + // Force v8 execution so that it gets to processing the requested command. + // It is necessary for being able to change a breakpoint just after it + // has been created (since we need an existing breakpoint id for that). + RemoteToolsAgent.executeVoidJavaScript(); }; @@ -277,40 +297,38 @@ devtools.DebuggerAgent.prototype.addBreakpoint = function( * @param {number} sourceId Id of the script for the breakpoint. * @param {number} line Number of the line for the breakpoint. */ -devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) { - var script = this.parsedScripts_[sourceId]; - if (!script) { - return; - } - - line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); - - var breakpointInfo; - if (script.getUrl()) { - var breakpoints = this.urlToBreakpoints_[script.getUrl()]; - breakpointInfo = breakpoints[line]; - delete breakpoints[line]; - } else { - breakpointInfo = script.getBreakpointInfo(line); - if (breakpointInfo) { - script.removeBreakpointInfo(breakpointInfo); +devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) +{ + var script = this.parsedScripts_[sourceId]; + if (!script) + return; + + line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); + + var breakpointInfo; + if (script.getUrl()) { + var breakpoints = this.urlToBreakpoints_[script.getUrl()]; + breakpointInfo = breakpoints[line]; + delete breakpoints[line]; + } else { + breakpointInfo = script.getBreakpointInfo(line); + if (breakpointInfo) + script.removeBreakpointInfo(breakpointInfo); } - } - if (!breakpointInfo) { - return; - } + if (!breakpointInfo) + return; - breakpointInfo.markAsRemoved(); + breakpointInfo.markAsRemoved(); - var id = breakpointInfo.getV8Id(); + var id = breakpointInfo.getV8Id(); - // If we don't know id of this breakpoint in the v8 debugger we cannot send - // 'clearbreakpoint' request. In that case it will be removed in - // 'setbreakpoint' response handler when we learn the id. - if (id != -1) { - this.requestClearBreakpoint_(id); - } + // If we don't know id of this breakpoint in the v8 debugger we cannot send + // "clearbreakpoint" request. In that case it will be removed in + // "setbreakpoint" response handler when we learn the id. + if (id !== -1) { + this.requestClearBreakpoint_(id); + } }; @@ -319,56 +337,57 @@ devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) { * @param {number} line Number of the line for the breakpoint. * @param {?string} condition New breakpoint condition. */ -devtools.DebuggerAgent.prototype.updateBreakpoint = function( - sourceId, line, condition) { - var script = this.parsedScripts_[sourceId]; - if (!script) { - return; - } - - line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); - - var breakpointInfo; - if (script.getUrl()) { - var breakpoints = this.urlToBreakpoints_[script.getUrl()]; - breakpointInfo = breakpoints[line]; - } else { - breakpointInfo = script.getBreakpointInfo(line); - } - - var id = breakpointInfo.getV8Id(); - - // If we don't know id of this breakpoint in the v8 debugger we cannot send - // the 'changebreakpoint' request. - if (id != -1) { - // TODO(apavlov): make use of the real values for 'enabled' and - // 'ignoreCount' when appropriate. - this.requestChangeBreakpoint_(id, true, condition, null); - } +devtools.DebuggerAgent.prototype.updateBreakpoint = function(sourceId, line, condition) +{ + var script = this.parsedScripts_[sourceId]; + if (!script) + return; + + line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); + + var breakpointInfo; + if (script.getUrl()) { + var breakpoints = this.urlToBreakpoints_[script.getUrl()]; + breakpointInfo = breakpoints[line]; + } else + breakpointInfo = script.getBreakpointInfo(line); + + var id = breakpointInfo.getV8Id(); + + // If we don't know id of this breakpoint in the v8 debugger we cannot send + // the "changebreakpoint" request. + if (id !== -1) { + // TODO(apavlov): make use of the real values for "enabled" and + // "ignoreCount" when appropriate. + this.requestChangeBreakpoint_(id, true, condition, null); + } }; /** * Tells the v8 debugger to step into the next statement. */ -devtools.DebuggerAgent.prototype.stepIntoStatement = function() { - this.stepCommand_('in'); +devtools.DebuggerAgent.prototype.stepIntoStatement = function() +{ + this.stepCommand_("in"); }; /** * Tells the v8 debugger to step out of current function. */ -devtools.DebuggerAgent.prototype.stepOutOfFunction = function() { - this.stepCommand_('out'); +devtools.DebuggerAgent.prototype.stepOutOfFunction = function() +{ + this.stepCommand_("out"); }; /** * Tells the v8 debugger to step over the next statement. */ -devtools.DebuggerAgent.prototype.stepOverStatement = function() { - this.stepCommand_('next'); +devtools.DebuggerAgent.prototype.stepOverStatement = function() +{ + this.stepCommand_("next"); }; @@ -376,10 +395,11 @@ devtools.DebuggerAgent.prototype.stepOverStatement = function() { * Tells the v8 debugger to continue execution after it has been stopped on a * breakpoint or an exception. */ -devtools.DebuggerAgent.prototype.resumeExecution = function() { - this.clearExceptionMessage_(); - var cmd = new devtools.DebugCommand('continue'); - devtools.DebuggerAgent.sendCommand_(cmd); +devtools.DebuggerAgent.prototype.resumeExecution = function() +{ + this.clearExceptionMessage_(); + var cmd = new devtools.DebugCommand("continue"); + devtools.DebuggerAgent.sendCommand_(cmd); }; @@ -390,17 +410,17 @@ devtools.DebuggerAgent.prototype.resumeExecution = function() { * @param {number} line Resource line number. * @param {string} message Exception text. */ -devtools.DebuggerAgent.prototype.createExceptionMessage_ = function( - url, line, message) { - this.currentExceptionMessage_ = new WebInspector.ConsoleMessage( - WebInspector.ConsoleMessage.MessageSource.JS, - WebInspector.ConsoleMessage.MessageType.Log, - WebInspector.ConsoleMessage.MessageLevel.Error, - line, - url, - 0 /* group level */, - 1 /* repeat count */, - '[Exception] ' + message); +devtools.DebuggerAgent.prototype.createExceptionMessage_ = function(url, line, message) +{ + this.currentExceptionMessage_ = new WebInspector.ConsoleMessage( + WebInspector.ConsoleMessage.MessageSource.JS, + WebInspector.ConsoleMessage.MessageType.Log, + WebInspector.ConsoleMessage.MessageLevel.Error, + line, + url, + 0 /* group level */, + 1 /* repeat count */, + "[Exception] " + message); }; @@ -408,36 +428,35 @@ devtools.DebuggerAgent.prototype.createExceptionMessage_ = function( * Shows pending exception message that is created with createExceptionMessage_ * earlier. */ -devtools.DebuggerAgent.prototype.showPendingExceptionMessage_ = function() { - if (!this.currentExceptionMessage_) { - return; - } - var msg = this.currentExceptionMessage_; - var resource = WebInspector.resourceURLMap[msg.url]; - if (resource) { - msg.resource = resource; - WebInspector.panels.resources.addMessageToResource(resource, msg); - } else { - this.currentExceptionMessage_ = null; - } +devtools.DebuggerAgent.prototype.showPendingExceptionMessage_ = function() +{ + if (!this.currentExceptionMessage_) + return; + var msg = this.currentExceptionMessage_; + var resource = WebInspector.resourceURLMap[msg.url]; + if (resource) { + msg.resource = resource; + WebInspector.panels.resources.addMessageToResource(resource, msg); + } else + this.currentExceptionMessage_ = null; }; /** * Clears exception message from the resource. */ -devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function() { - if (this.currentExceptionMessage_) { - var messageElement = - this.currentExceptionMessage_._resourceMessageLineElement; - var bubble = messageElement.parentElement; - bubble.removeChild(messageElement); - if (!bubble.firstChild) { - // Last message in bubble removed. - bubble.parentElement.removeChild(bubble); +devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function() +{ + if (this.currentExceptionMessage_) { + var messageElement = this.currentExceptionMessage_._resourceMessageLineElement; + var bubble = messageElement.parentElement; + bubble.removeChild(messageElement); + if (!bubble.firstChild) { + // Last message in bubble removed. + bubble.parentElement.removeChild(bubble); + } + this.currentExceptionMessage_ = null; } - this.currentExceptionMessage_ = null; - } }; @@ -445,8 +464,9 @@ devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function() { * @return {boolean} True iff the debugger will pause execution on the * exceptions. */ -devtools.DebuggerAgent.prototype.pauseOnExceptions = function() { - return this.pauseOnExceptions_; +devtools.DebuggerAgent.prototype.pauseOnExceptions = function() +{ + return this.pauseOnExceptions_; }; @@ -455,27 +475,28 @@ devtools.DebuggerAgent.prototype.pauseOnExceptions = function() { * @param {boolean} value True iff execution should be stopped in the debugger * on the exceptions. */ -devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) { - this.pauseOnExceptions_ = value; +devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) +{ + this.pauseOnExceptions_ = value; }; /** - * Sends 'evaluate' request to the debugger. + * Sends "evaluate" request to the debugger. * @param {Object} arguments Request arguments map. * @param {function(devtools.DebuggerMessage)} callback Callback to be called * when response is received. */ -devtools.DebuggerAgent.prototype.requestEvaluate = function( - arguments, callback) { - var cmd = new devtools.DebugCommand('evaluate', arguments); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; +devtools.DebuggerAgent.prototype.requestEvaluate = function(arguments, callback) +{ + var cmd = new devtools.DebugCommand("evaluate", arguments); + devtools.DebuggerAgent.sendCommand_(cmd); + this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; }; /** - * Sends 'lookup' request for each unresolved property of the object. When + * Sends "lookup" request for each unresolved property of the object. When * response is received the properties will be changed with their resolved * values. * @param {Object} object Object whose properties should be resolved. @@ -483,107 +504,101 @@ devtools.DebuggerAgent.prototype.requestEvaluate = function( * children are resolved. * @param {boolean} noIntrinsic Whether intrinsic properties should be included. */ -devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback, - noIntrinsic) { - if ('handle' in object) { - var result = []; - devtools.DebuggerAgent.formatObjectProperties_(object, result, - noIntrinsic); - callback(result); - } else { - this.requestLookup_([object.ref], function(msg) { - var result = []; - if (msg.isSuccess()) { - var handleToObject = msg.getBody(); - var resolved = handleToObject[object.ref]; - devtools.DebuggerAgent.formatObjectProperties_(resolved, result, - noIntrinsic); +devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback, noIntrinsic) +{ + if ("handle" in object) { + var result = []; + devtools.DebuggerAgent.formatObjectProperties_(object, result, noIntrinsic); callback(result); - } else { - callback([]); - } - }); - } + } else { + this.requestLookup_([object.ref], function(msg) { + var result = []; + if (msg.isSuccess()) { + var handleToObject = msg.getBody(); + var resolved = handleToObject[object.ref]; + devtools.DebuggerAgent.formatObjectProperties_(resolved, result, noIntrinsic); + callback(result); + } else + callback([]); + }); + } }; /** - * Sends 'scope' request for the scope object to resolve its variables. + * Sends "scope" request for the scope object to resolve its variables. * @param {Object} scope Scope to be resolved. * @param {function(Array.<WebInspector.ObjectPropertyProxy>)} callback * Callback to be called when all scope variables are resolved. */ -devtools.DebuggerAgent.prototype.resolveScope = function(scope, callback) { - var cmd = new devtools.DebugCommand('scope', { - 'frameNumber': scope.frameNumber, - 'number': scope.index, - 'compactFormat': true - }); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { - var result = []; - if (msg.isSuccess()) { - var scopeObjectJson = msg.getBody().object; - devtools.DebuggerAgent.formatObjectProperties_(scopeObjectJson, result, - true /* no intrinsic */); - } - callback(result); - }; +devtools.DebuggerAgent.prototype.resolveScope = function(scope, callback) +{ + var cmd = new devtools.DebugCommand("scope", { + "frameNumber": scope.frameNumber, + "number": scope.index, + "compactFormat": true + }); + devtools.DebuggerAgent.sendCommand_(cmd); + this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { + var result = []; + if (msg.isSuccess()) { + var scopeObjectJson = msg.getBody().object; + devtools.DebuggerAgent.formatObjectProperties_(scopeObjectJson, result, true /* no intrinsic */); + } + callback(result); + }; }; /** - * Sends 'scopes' request for the frame object to resolve all variables + * Sends "scopes" request for the frame object to resolve all variables * available in the frame. * @param {number} callFrameId Id of call frame whose variables need to * be resolved. * @param {function(Object)} callback Callback to be called when all frame * variables are resolved. */ -devtools.DebuggerAgent.prototype.resolveFrameVariables_ = function( - callFrameId, callback) { - var result = {}; +devtools.DebuggerAgent.prototype.resolveFrameVariables_ = function(callFrameId, callback) +{ + var result = {}; - var frame = this.callFrames_[callFrameId]; - if (!frame) { - callback(result); - return; - } + var frame = this.callFrames_[callFrameId]; + if (!frame) { + callback(result); + return; + } - var waitingResponses = 0; - function scopeResponseHandler(msg) { - waitingResponses--; + var waitingResponses = 0; + function scopeResponseHandler(msg) { + waitingResponses--; - if (msg.isSuccess()) { - var properties = msg.getBody().object.properties; - for (var j = 0; j < properties.length; j++) { - result[properties[j].name] = true; - } - } + if (msg.isSuccess()) { + var properties = msg.getBody().object.properties; + for (var j = 0; j < properties.length; j++) + result[properties[j].name] = true; + } - // When all scopes are resolved invoke the callback. - if (waitingResponses == 0) { - callback(result); - } - }; - - for (var i = 0; i < frame.scopeChain.length; i++) { - var scope = frame.scopeChain[i].objectId; - if (scope.type == devtools.DebuggerAgent.ScopeType.Global) { - // Do not resolve global scope since it takes for too long. - // TODO(yurys): allow to send only property names in the response. - continue; + // When all scopes are resolved invoke the callback. + if (waitingResponses === 0) + callback(result); + }; + + for (var i = 0; i < frame.scopeChain.length; i++) { + var scope = frame.scopeChain[i].objectId; + if (scope.type === devtools.DebuggerAgent.ScopeType.Global) { + // Do not resolve global scope since it takes for too long. + // TODO(yurys): allow to send only property names in the response. + continue; + } + var cmd = new devtools.DebugCommand("scope", { + "frameNumber": scope.frameNumber, + "number": scope.index, + "compactFormat": true + }); + devtools.DebuggerAgent.sendCommand_(cmd); + this.requestSeqToCallback_[cmd.getSequenceNumber()] = scopeResponseHandler; + waitingResponses++; } - var cmd = new devtools.DebugCommand('scope', { - 'frameNumber': scope.frameNumber, - 'number': scope.index, - 'compactFormat': true - }); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = - scopeResponseHandler; - waitingResponses++; - } }; /** @@ -595,32 +610,31 @@ devtools.DebuggerAgent.prototype.resolveFrameVariables_ = function( * @param{function(Object result,bool isException)} reportCompletions Callback * function. */ -devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame = function( - expressionString, callFrameId, reportCompletions) { - if (expressionString) { - expressionString = 'var obj = ' + expressionString + - '; var names = {}; for (var n in obj) { names[n] = true; };' + - 'names;'; - this.evaluateInCallFrame( - callFrameId, - expressionString, - function(result) { - var names = {}; - if (!result.isException) { - var props = result.value.objectId.properties; - // Put all object properties into the map. - for (var i = 0; i < props.length; i++) { - names[props[i].name] = true; - } - } - reportCompletions(names, result.isException); - }); - } else { - this.resolveFrameVariables_(callFrameId, - function(result) { - reportCompletions(result, false /* isException */); - }); - } +devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame = function(expressionString, callFrameId, reportCompletions) +{ + if (expressionString) { + expressionString = "var obj = " + expressionString + + "; var names = {}; for (var n in obj) { names[n] = true; };" + + "names;"; + this.evaluateInCallFrame( + callFrameId, + expressionString, + function(result) { + var names = {}; + if (!result.isException) { + var props = result.value.objectId.properties; + // Put all object properties into the map. + for (var i = 0; i < props.length; i++) + names[props[i].name] = true; + } + reportCompletions(names, result.isException); + }); + } else { + this.resolveFrameVariables_(callFrameId, + function(result) { + reportCompletions(result, false /* isException */); + }); + } }; @@ -628,8 +642,9 @@ devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame = function( * @param{number} scriptId * @return {string} Type of the context of the script with specified id. */ -devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) { - return this.parsedScripts_[scriptId].getContextType(); +devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) +{ + return this.parsedScripts_[scriptId].getContextType(); }; @@ -637,12 +652,12 @@ devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) { * Removes specified breakpoint from the v8 debugger. * @param {number} breakpointId Id of the breakpoint in the v8 debugger. */ -devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function( - breakpointId) { - var cmd = new devtools.DebugCommand('clearbreakpoint', { - 'breakpoint': breakpointId - }); - devtools.DebuggerAgent.sendCommand_(cmd); +devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function(breakpointId) +{ + var cmd = new devtools.DebugCommand("clearbreakpoint", { + "breakpoint": breakpointId + }); + devtools.DebuggerAgent.sendCommand_(cmd); }; @@ -653,26 +668,27 @@ devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function( * @param {?string} condition New breakpoint condition. * @param {number} ignoreCount New ignore count for the breakpoint. */ -devtools.DebuggerAgent.prototype.requestChangeBreakpoint_ = function( - breakpointId, enabled, condition, ignoreCount) { - var cmd = new devtools.DebugCommand('changebreakpoint', { - 'breakpoint': breakpointId, - 'enabled': enabled, - 'condition': condition, - 'ignoreCount': ignoreCount - }); - devtools.DebuggerAgent.sendCommand_(cmd); +devtools.DebuggerAgent.prototype.requestChangeBreakpoint_ = function(breakpointId, enabled, condition, ignoreCount) +{ + var cmd = new devtools.DebugCommand("changebreakpoint", { + "breakpoint": breakpointId, + "enabled": enabled, + "condition": condition, + "ignoreCount": ignoreCount + }); + devtools.DebuggerAgent.sendCommand_(cmd); }; /** - * Sends 'backtrace' request to v8. + * Sends "backtrace" request to v8. */ -devtools.DebuggerAgent.prototype.requestBacktrace_ = function() { - var cmd = new devtools.DebugCommand('backtrace', { - 'compactFormat':true - }); - devtools.DebuggerAgent.sendCommand_(cmd); +devtools.DebuggerAgent.prototype.requestBacktrace_ = function() +{ + var cmd = new devtools.DebugCommand("backtrace", { + "compactFormat":true + }); + devtools.DebuggerAgent.sendCommand_(cmd); }; @@ -680,36 +696,39 @@ devtools.DebuggerAgent.prototype.requestBacktrace_ = function() { * Sends command to v8 debugger. * @param {devtools.DebugCommand} cmd Command to execute. */ -devtools.DebuggerAgent.sendCommand_ = function(cmd) { - RemoteDebuggerCommandExecutor.DebuggerCommand(cmd.toJSONProtocol()); +devtools.DebuggerAgent.sendCommand_ = function(cmd) +{ + RemoteDebuggerCommandExecutor.DebuggerCommand(cmd.toJSONProtocol()); }; /** * Tells the v8 debugger to make the next execution step. - * @param {string} action 'in', 'out' or 'next' action. - */ -devtools.DebuggerAgent.prototype.stepCommand_ = function(action) { - this.clearExceptionMessage_(); - var cmd = new devtools.DebugCommand('continue', { - 'stepaction': action, - 'stepcount': 1 - }); - devtools.DebuggerAgent.sendCommand_(cmd); + * @param {string} action "in", "out" or "next" action. + */ +devtools.DebuggerAgent.prototype.stepCommand_ = function(action) +{ + this.clearExceptionMessage_(); + var cmd = new devtools.DebugCommand("continue", { + "stepaction": action, + "stepcount": 1 + }); + devtools.DebuggerAgent.sendCommand_(cmd); }; /** - * Sends 'lookup' request to v8. + * Sends "lookup" request to v8. * @param {number} handle Handle to the object to lookup. */ -devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) { - var cmd = new devtools.DebugCommand('lookup', { - 'compactFormat':true, - 'handles': handles - }); - devtools.DebuggerAgent.sendCommand_(cmd); - this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; +devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) +{ + var cmd = new devtools.DebugCommand("lookup", { + "compactFormat":true, + "handles": handles + }); + devtools.DebuggerAgent.sendCommand_(cmd); + this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; }; @@ -717,38 +736,38 @@ devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) { * Sets debugger context id for scripts filtering. * @param {number} contextId Id of the inspected page global context. */ -devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) { - this.contextId_ = contextId; - - // If it's the first time context id is set request scripts list. - if (this.requestScriptsWhenContextIdSet_) { - this.requestScriptsWhenContextIdSet_ = false; - var cmd = new devtools.DebugCommand('scripts', { - 'includeSource': false - }); - devtools.DebuggerAgent.sendCommand_(cmd); - // Force v8 execution so that it gets to processing the requested command. - RemoteToolsAgent.executeVoidJavaScript(); - - var debuggerAgent = this; - this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { - // Handle the response iff the context id hasn't changed since the request - // was issued. Otherwise if the context id did change all up-to-date - // scripts will be pushed in after compile events and there is no need to - // handle the response. - if (contextId == debuggerAgent.contextId_) { - debuggerAgent.handleScriptsResponse_(msg); - } - - // We received initial scripts response so flush the flag and - // see if there is an unhandled backtrace response. - debuggerAgent.waitingForInitialScriptsResponse_ = false; - if (debuggerAgent.pendingBacktraceResponseHandler_) { - debuggerAgent.pendingBacktraceResponseHandler_(); - debuggerAgent.pendingBacktraceResponseHandler_ = null; - } - }; - } +devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) +{ + this.contextId_ = contextId; + + // If it's the first time context id is set request scripts list. + if (this.requestScriptsWhenContextIdSet_) { + this.requestScriptsWhenContextIdSet_ = false; + var cmd = new devtools.DebugCommand("scripts", { + "includeSource": false + }); + devtools.DebuggerAgent.sendCommand_(cmd); + // Force v8 execution so that it gets to processing the requested command. + RemoteToolsAgent.executeVoidJavaScript(); + + var debuggerAgent = this; + this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { + // Handle the response iff the context id hasn't changed since the request + // was issued. Otherwise if the context id did change all up-to-date + // scripts will be pushed in after compile events and there is no need to + // handle the response. + if (contextId === debuggerAgent.contextId_) + debuggerAgent.handleScriptsResponse_(msg); + + // We received initial scripts response so flush the flag and + // see if there is an unhandled backtrace response. + debuggerAgent.waitingForInitialScriptsResponse_ = false; + if (debuggerAgent.pendingBacktraceResponseHandler_) { + debuggerAgent.pendingBacktraceResponseHandler_(); + debuggerAgent.pendingBacktraceResponseHandler_ = null; + } + }; + } }; @@ -758,96 +777,95 @@ devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) { * details on the output format. * @param {string} output */ -devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) { - var msg; - try { - msg = new devtools.DebuggerMessage(output); - } catch(e) { - debugPrint('Failed to handle debugger reponse:\n' + e); - throw e; - } - - if (msg.getType() == 'event') { - if (msg.getEvent() == 'break') { - this.handleBreakEvent_(msg); - } else if (msg.getEvent() == 'exception') { - this.handleExceptionEvent_(msg); - } else if (msg.getEvent() == 'afterCompile') { - this.handleAfterCompileEvent_(msg); +devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) +{ + var msg; + try { + msg = new devtools.DebuggerMessage(output); + } catch(e) { + debugPrint("Failed to handle debugger response:\n" + e); + throw e; } - } else if (msg.getType() == 'response') { - if (msg.getCommand() == 'scripts') { - this.invokeCallbackForResponse_(msg); - } else if (msg.getCommand() == 'setbreakpoint') { - this.handleSetBreakpointResponse_(msg); - } else if (msg.getCommand() == 'clearbreakpoint') { - this.handleClearBreakpointResponse_(msg); - } else if (msg.getCommand() == 'backtrace') { - this.handleBacktraceResponse_(msg); - } else if (msg.getCommand() == 'lookup') { - this.invokeCallbackForResponse_(msg); - } else if (msg.getCommand() == 'evaluate') { - this.invokeCallbackForResponse_(msg); - } else if (msg.getCommand() == 'scope') { - this.invokeCallbackForResponse_(msg); + + if (msg.getType() === "event") { + if (msg.getEvent() === "break") + this.handleBreakEvent_(msg); + else if (msg.getEvent() === "exception") + this.handleExceptionEvent_(msg); + else if (msg.getEvent() === "afterCompile") + this.handleAfterCompileEvent_(msg); + } else if (msg.getType() === "response") { + if (msg.getCommand() === "scripts") + this.invokeCallbackForResponse_(msg); + else if (msg.getCommand() === "setbreakpoint") + this.handleSetBreakpointResponse_(msg); + else if (msg.getCommand() === "clearbreakpoint") + this.handleClearBreakpointResponse_(msg); + else if (msg.getCommand() === "backtrace") + this.handleBacktraceResponse_(msg); + else if (msg.getCommand() === "lookup") + this.invokeCallbackForResponse_(msg); + else if (msg.getCommand() === "evaluate") + this.invokeCallbackForResponse_(msg); + else if (msg.getCommand() === "scope") + this.invokeCallbackForResponse_(msg); } - } }; /** * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) { - // Force scrips panel to be shown first. - WebInspector.currentPanel = WebInspector.panels.scripts; +devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) +{ + // Force scrips panel to be shown first. + WebInspector.currentPanel = WebInspector.panels.scripts; - var body = msg.getBody(); + var body = msg.getBody(); - var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); - this.requestBacktrace_(); + var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); + this.requestBacktrace_(); }; /** * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) { - // Force scrips panel to be shown first. - WebInspector.currentPanel = WebInspector.panels.scripts; +devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) +{ + // Force scrips panel to be shown first. + WebInspector.currentPanel = WebInspector.panels.scripts; - var body = msg.getBody(); - // No script field in the body means that v8 failed to parse the script. We - // resume execution on parser errors automatically. - if (this.pauseOnExceptions_ && body.script) { - var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); - this.createExceptionMessage_(body.script.name, line, body.exception.text); - this.requestBacktrace_(); - } else { - this.resumeExecution(); - } + var body = msg.getBody(); + // No script field in the body means that v8 failed to parse the script. We + // resume execution on parser errors automatically. + if (this.pauseOnExceptions_ && body.script) { + var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); + this.createExceptionMessage_(body.script.name, line, body.exception.text); + this.requestBacktrace_(); + } else + this.resumeExecution(); }; /** * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) { - var scripts = msg.getBody(); - for (var i = 0; i < scripts.length; i++) { - var script = scripts[i]; +devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) +{ + var scripts = msg.getBody(); + for (var i = 0; i < scripts.length; i++) { + var script = scripts[i]; - // Skip scripts from other tabs. - if (!this.isScriptFromInspectedContext_(script, msg)) { - continue; - } + // Skip scripts from other tabs. + if (!this.isScriptFromInspectedContext_(script, msg)) + continue; - // We may already have received the info in an afterCompile event. - if (script.id in this.parsedScripts_) { - continue; + // We may already have received the info in an afterCompile event. + if (script.id in this.parsedScripts_) + continue; + this.addScriptInfo_(script, msg); } - this.addScriptInfo_(script, msg); - } }; @@ -855,74 +873,65 @@ devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) { * @param {Object} script Json object representing script. * @param {devtools.DebuggerMessage} msg Debugger response. */ -devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function( - script, msg) { - if (!script.context) { - // Always ignore scripts from the utility context. - return false; - } - var context = msg.lookup(script.context.ref); - var scriptContextId = context.data; - if (!goog.isDef(scriptContextId)) { - return false; // Always ignore scripts from the utility context. - } - if (this.contextId_ === null) { - return true; - } - if (goog.isString(context.data)) { - // Find the id from context data. The context data has the format "type,id". - var comma = context.data.indexOf(','); - if (comma < 0) { - return false; +devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function(script, msg) +{ + if (!script.context) { + // Always ignore scripts from the utility context. + return false; } - return (parseInt(context.data.substring(comma + 1)) == this.contextId_); - } else { - // TODO(sgjesse) remove this when patch for - // https://bugs.webkit.org/show_bug.cgi?id=31873 has landed in Chromium. - return (scriptContextId.value == this.contextId_); - } + var context = msg.lookup(script.context.ref); + var scriptContextId = context.data; + if (typeof scriptContextId === "undefined") + return false; // Always ignore scripts from the utility context. + if (this.contextId_ === null) + return true; + // Find the id from context data. The context data has the format "type,id". + var comma = context.data.indexOf(","); + if (comma < 0) + return false; + return (context.data.substring(comma + 1) == this.contextId_); }; /** * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) { - var requestSeq = msg.getRequestSeq(); - var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq]; - if (!breakpointInfo) { - // TODO(yurys): handle this case - return; - } - delete this.requestNumberToBreakpointInfo_[requestSeq]; - if (!msg.isSuccess()) { - // TODO(yurys): handle this case - return; - } - var idInV8 = msg.getBody().breakpoint; - breakpointInfo.setV8Id(idInV8); +devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) +{ + var requestSeq = msg.getRequestSeq(); + var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq]; + if (!breakpointInfo) { + // TODO(yurys): handle this case + return; + } + delete this.requestNumberToBreakpointInfo_[requestSeq]; + if (!msg.isSuccess()) { + // TODO(yurys): handle this case + return; + } + var idInV8 = msg.getBody().breakpoint; + breakpointInfo.setV8Id(idInV8); - if (breakpointInfo.isRemoved()) { - this.requestClearBreakpoint_(idInV8); - } + if (breakpointInfo.isRemoved()) + this.requestClearBreakpoint_(idInV8); }; /** * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) { - if (!this.contextId_) { - // Ignore scripts delta if main request has not been issued yet. - return; - } - var script = msg.getBody().script; +devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) +{ + if (!this.contextId_) { + // Ignore scripts delta if main request has not been issued yet. + return; + } + var script = msg.getBody().script; - // Ignore scripts from other tabs. - if (!this.isScriptFromInspectedContext_(script, msg)) { - return; - } - this.addScriptInfo_(script, msg); + // Ignore scripts from other tabs. + if (!this.isScriptFromInspectedContext_(script, msg)) + return; + this.addScriptInfo_(script, msg); }; @@ -933,77 +942,68 @@ devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) { * @param {devtools.DebuggerMessage} msg Debugger message containing the script * data. */ -devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) { - var context = msg.lookup(script.context.ref); - var contextType; - if (goog.isString(context.data)) { +devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) +{ + var context = msg.lookup(script.context.ref); + var contextType; // Find the type from context data. The context data has the format // "type,id". - var comma = context.data.indexOf(','); - if (comma < 0) { - return - } + var comma = context.data.indexOf(","); + if (comma < 0) + return contextType = context.data.substring(0, comma); - } else { - // TODO(sgjesse) remove this when patch for - // https://bugs.webkit.org/show_bug.cgi?id=31873 has landed in Chromium. - contextType = context.data.type; - } - this.parsedScripts_[script.id] = new devtools.ScriptInfo( - script.id, script.name, script.lineOffset, contextType); - if (this.scriptsPanelInitialized_) { - // Only report script as parsed after scripts panel has been shown. - WebInspector.parsedScriptSource( - script.id, script.name, script.source, script.lineOffset); - } + this.parsedScripts_[script.id] = new devtools.ScriptInfo(script.id, script.name, script.lineOffset, contextType); + if (this.scriptsPanelInitialized_) { + // Only report script as parsed after scripts panel has been shown. + WebInspector.parsedScriptSource(script.id, script.name, script.source, script.lineOffset); + } }; /** * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function( - msg) { - // Do nothing. +devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function(msg) +{ + // Do nothing. }; /** - * Handles response to 'backtrace' command. + * Handles response to "backtrace" command. * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) { - if (this.waitingForInitialScriptsResponse_) { - this.pendingBacktraceResponseHandler_ = - this.doHandleBacktraceResponse_.bind(this, msg); - } else { - this.doHandleBacktraceResponse_(msg); - } +devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) +{ + if (this.waitingForInitialScriptsResponse_) + this.pendingBacktraceResponseHandler_ = this.doHandleBacktraceResponse_.bind(this, msg); + else + this.doHandleBacktraceResponse_(msg); }; /** * @param {devtools.DebuggerMessage} msg */ -devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_ = function(msg) { - var frames = msg.getBody().frames; - this.callFrames_ = []; - for (var i = 0; i < frames.length; ++i) { - this.callFrames_.push(this.formatCallFrame_(frames[i])); - } - WebInspector.pausedScript(this.callFrames_); - this.showPendingExceptionMessage_(); - InspectorFrontendHost.activateWindow(); +devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_ = function(msg) +{ + var frames = msg.getBody().frames; + this.callFrames_ = []; + for (var i = 0; i < frames.length; ++i) + this.callFrames_.push(this.formatCallFrame_(frames[i])); + WebInspector.pausedScript(this.callFrames_); + this.showPendingExceptionMessage_(); + InspectorFrontendHost.activateWindow(); }; /** * Evaluates code on given callframe. */ -devtools.DebuggerAgent.prototype.evaluateInCallFrame = function( - callFrameId, code, callback) { - var callFrame = this.callFrames_[callFrameId]; - callFrame.evaluate_(code, callback); +devtools.DebuggerAgent.prototype.evaluateInCallFrame = function(callFrameId, code, callback) +{ + var callFrame = this.callFrames_[callFrameId]; + callFrame.evaluate_(code, callback); }; @@ -1013,71 +1013,68 @@ devtools.DebuggerAgent.prototype.evaluateInCallFrame = function( * @return {boolean} Whether a callback for the given message was found and * excuted. */ -devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) { - var callback = this.requestSeqToCallback_[msg.getRequestSeq()]; - if (!callback) { - // It may happend if reset was called. - return false; - } - delete this.requestSeqToCallback_[msg.getRequestSeq()]; - callback(msg); - return true; +devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) +{ + var callback = this.requestSeqToCallback_[msg.getRequestSeq()]; + if (!callback) { + // It may happend if reset was called. + return false; + } + delete this.requestSeqToCallback_[msg.getRequestSeq()]; + callback(msg); + return true; }; /** - * @param {Object} stackFrame Frame json object from 'backtrace' response. + * @param {Object} stackFrame Frame json object from "backtrace" response. * @return {!devtools.CallFrame} Object containing information related to the * call frame in the format expected by ScriptsPanel and its panes. */ -devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame) { - var func = stackFrame.func; - var sourceId = func.scriptId; - - // Add service script if it does not exist. - var existingScript = this.parsedScripts_[sourceId]; - if (!existingScript) { - this.parsedScripts_[sourceId] = new devtools.ScriptInfo( - sourceId, null /* name */, 0 /* line */, 'unknown' /* type */, - true /* unresolved */); - WebInspector.parsedScriptSource(sourceId, null, null, 0); - } - - var funcName = func.name || func.inferredName || '(anonymous function)'; - var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line); - - // Add basic scope chain info with scope variables. - var scopeChain = []; - var ScopeType = devtools.DebuggerAgent.ScopeType; - for (var i = 0; i < stackFrame.scopes.length; i++) { - var scope = stackFrame.scopes[i]; - scope.frameNumber = stackFrame.index; - var scopeObjectProxy = new WebInspector.ObjectProxy(0, scope, [], 0, '', - true); - scopeObjectProxy.isScope = true; - switch(scope.type) { - case ScopeType.Global: - scopeObjectProxy.isDocument = true; - break; - case ScopeType.Local: - scopeObjectProxy.isLocal = true; - scopeObjectProxy.thisObject = - devtools.DebuggerAgent.formatObjectProxy_(stackFrame.receiver); - break; - case ScopeType.With: - // Catch scope is treated as a regular with scope by WebKit so we - // also treat it this way. - case ScopeType.Catch: - scopeObjectProxy.isWithBlock = true; - break; - case ScopeType.Closure: - scopeObjectProxy.isClosure = true; - break; +devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame) +{ + var func = stackFrame.func; + var sourceId = func.scriptId; + + // Add service script if it does not exist. + var existingScript = this.parsedScripts_[sourceId]; + if (!existingScript) { + this.parsedScripts_[sourceId] = new devtools.ScriptInfo(sourceId, null /* name */, 0 /* line */, "unknown" /* type */, true /* unresolved */); + WebInspector.parsedScriptSource(sourceId, null, null, 0); + } + + var funcName = func.name || func.inferredName || "(anonymous function)"; + var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line); + + // Add basic scope chain info with scope variables. + var scopeChain = []; + var ScopeType = devtools.DebuggerAgent.ScopeType; + for (var i = 0; i < stackFrame.scopes.length; i++) { + var scope = stackFrame.scopes[i]; + scope.frameNumber = stackFrame.index; + var scopeObjectProxy = new WebInspector.ObjectProxy(0, scope, [], 0, "", true); + scopeObjectProxy.isScope = true; + switch(scope.type) { + case ScopeType.Global: + scopeObjectProxy.isDocument = true; + break; + case ScopeType.Local: + scopeObjectProxy.isLocal = true; + scopeObjectProxy.thisObject = devtools.DebuggerAgent.formatObjectProxy_(stackFrame.receiver); + break; + case ScopeType.With: + // Catch scope is treated as a regular with scope by WebKit so we + // also treat it this way. + case ScopeType.Catch: + scopeObjectProxy.isWithBlock = true; + break; + case ScopeType.Closure: + scopeObjectProxy.isClosure = true; + break; + } + scopeChain.push(scopeObjectProxy); } - scopeChain.push(scopeObjectProxy); - } - return new devtools.CallFrame(stackFrame.index, 'function', funcName, - sourceId, line, scopeChain); + return new devtools.CallFrame(stackFrame.index, "function", funcName, sourceId, line, scopeChain); }; @@ -1089,40 +1086,37 @@ devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame) { * @param {boolean} noIntrinsic Whether intrinsic properties should be * included. */ -devtools.DebuggerAgent.formatObjectProperties_ = function(object, result, - noIntrinsic) { - devtools.DebuggerAgent.propertiesToProxies_(object.properties, result); - if (noIntrinsic) { - return; - } +devtools.DebuggerAgent.formatObjectProperties_ = function(object, result, noIntrinsic) +{ + devtools.DebuggerAgent.propertiesToProxies_(object.properties, result); + if (noIntrinsic) + return; - result.push(new WebInspector.ObjectPropertyProxy('__proto__', - devtools.DebuggerAgent.formatObjectProxy_(object.protoObject))); - result.push(new WebInspector.ObjectPropertyProxy('constructor', - devtools.DebuggerAgent.formatObjectProxy_(object.constructorFunction))); - // Don't add 'prototype' property since it is one of the regualar properties. + result.push(new WebInspector.ObjectPropertyProxy("__proto__", devtools.DebuggerAgent.formatObjectProxy_(object.protoObject))); + result.push(new WebInspector.ObjectPropertyProxy("constructor", devtools.DebuggerAgent.formatObjectProxy_(object.constructorFunction))); + // Don't add 'prototype' property since it is one of the regualar properties. }; /** - * For each property in 'properties' creates its proxy representative. + * For each property in "properties" creates its proxy representative. * @param {Array.<Object>} properties Receiver properties or locals array from - * 'backtrace' response. + * "backtrace" response. * @param {Array.<WebInspector.ObjectPropertyProxy>} Results holder. */ -devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result) { - var map = {}; - for (var i = 0; i < properties.length; ++i) { - var property = properties[i]; - var name = String(property.name); - if (name in map) { - continue; +devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result) +{ + var map = {}; + for (var i = 0; i < properties.length; ++i) { + var property = properties[i]; + var name = String(property.name); + if (name in map) + continue; + map[name] = true; + var value = devtools.DebuggerAgent.formatObjectProxy_(property.value); + var propertyProxy = new WebInspector.ObjectPropertyProxy(name, value); + result.push(propertyProxy); } - map[name] = true; - var value = devtools.DebuggerAgent.formatObjectProxy_(property.value); - var propertyProxy = new WebInspector.ObjectPropertyProxy(name, value); - result.push(propertyProxy); - } }; @@ -1130,36 +1124,34 @@ devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result) { * @param {Object} v An object reference from the debugger response. * @return {*} The value representation expected by ScriptsPanel. */ -devtools.DebuggerAgent.formatObjectProxy_ = function(v) { - var description; - var hasChildren = false; - if (v.type == 'object') { - description = v.className; - hasChildren = true; - } else if (v.type == 'function') { - if (v.source) { - description = v.source; - } else { - description = 'function ' + v.name + '()'; - } - hasChildren = true; - } else if (v.type == 'undefined') { - description = 'undefined'; - } else if (v.type == 'null') { - description = 'null'; - } else if (goog.isDef(v.value)) { - // Check for undefined and null types before checking the value, otherwise - // null/undefined may have blank value. - description = v.value; - } else { - description = '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>'; - } - - var proxy = new WebInspector.ObjectProxy(0, v, [], 0, description, - hasChildren); - proxy.type = v.type; - proxy.isV8Ref = true; - return proxy; +devtools.DebuggerAgent.formatObjectProxy_ = function(v) +{ + var description; + var hasChildren = false; + if (v.type === "object") { + description = v.className; + hasChildren = true; + } else if (v.type === "function") { + if (v.source) + description = v.source; + else + description = "function " + v.name + "()"; + hasChildren = true; + } else if (v.type === "undefined") + description = "undefined"; + else if (v.type === "null") + description = "null"; + else if (typeof v.value !== "undefined") { + // Check for undefined and null types before checking the value, otherwise + // null/undefined may have blank value. + description = v.value; + } else + description = "<unresolved ref: " + v.ref + ", type: " + v.type + ">"; + + var proxy = new WebInspector.ObjectProxy(0, v, [], 0, description, hasChildren); + proxy.type = v.type; + proxy.isV8Ref = true; + return proxy; }; @@ -1168,8 +1160,9 @@ devtools.DebuggerAgent.formatObjectProxy_ = function(v) { * @param {number} line Resource line number in Web Inspector UI. * @return {number} The line number in v8. */ -devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line) { - return line - 1; +devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line) +{ + return line - 1; }; @@ -1178,8 +1171,9 @@ devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line) { * @param {number} line Resource line number in v8. * @return {number} The line number in Web Inspector. */ -devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) { - return line + 1; +devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) +{ + return line + 1; }; @@ -1194,47 +1188,51 @@ devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) { * @param {bool} opt_isUnresolved If true, script will not be resolved. * @constructor */ -devtools.ScriptInfo = function( - scriptId, url, lineOffset, contextType, opt_isUnresolved) { - this.scriptId_ = scriptId; - this.lineOffset_ = lineOffset; - this.contextType_ = contextType; - this.url_ = url; - this.isUnresolved_ = opt_isUnresolved; +devtools.ScriptInfo = function(scriptId, url, lineOffset, contextType, opt_isUnresolved) +{ + this.scriptId_ = scriptId; + this.lineOffset_ = lineOffset; + this.contextType_ = contextType; + this.url_ = url; + this.isUnresolved_ = opt_isUnresolved; - this.lineToBreakpointInfo_ = {}; + this.lineToBreakpointInfo_ = {}; }; /** * @return {number} */ -devtools.ScriptInfo.prototype.getLineOffset = function() { - return this.lineOffset_; +devtools.ScriptInfo.prototype.getLineOffset = function() +{ + return this.lineOffset_; }; /** * @return {string} */ -devtools.ScriptInfo.prototype.getContextType = function() { - return this.contextType_; +devtools.ScriptInfo.prototype.getContextType = function() +{ + return this.contextType_; }; /** * @return {?string} */ -devtools.ScriptInfo.prototype.getUrl = function() { - return this.url_; +devtools.ScriptInfo.prototype.getUrl = function() +{ + return this.url_; }; /** * @return {?bool} */ -devtools.ScriptInfo.prototype.isUnresolved = function() { - return this.isUnresolved_; +devtools.ScriptInfo.prototype.isUnresolved = function() +{ + return this.isUnresolved_; }; @@ -1244,8 +1242,9 @@ devtools.ScriptInfo.prototype.isUnresolved = function() { * specified line in the script or undefined if there is no breakpoint at * that line. */ -devtools.ScriptInfo.prototype.getBreakpointInfo = function(line) { - return this.lineToBreakpointInfo_[line]; +devtools.ScriptInfo.prototype.getBreakpointInfo = function(line) +{ + return this.lineToBreakpointInfo_[line]; }; @@ -1253,17 +1252,19 @@ devtools.ScriptInfo.prototype.getBreakpointInfo = function(line) { * Adds breakpoint info to the script. * @param {devtools.BreakpointInfo} breakpoint */ -devtools.ScriptInfo.prototype.addBreakpointInfo = function(breakpoint) { - this.lineToBreakpointInfo_[breakpoint.getLine()] = breakpoint; +devtools.ScriptInfo.prototype.addBreakpointInfo = function(breakpoint) +{ + this.lineToBreakpointInfo_[breakpoint.getLine()] = breakpoint; }; /** * @param {devtools.BreakpointInfo} breakpoint Breakpoint info to be removed. */ -devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) { - var line = breakpoint.getLine(); - delete this.lineToBreakpointInfo_[line]; +devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) +{ + var line = breakpoint.getLine(); + delete this.lineToBreakpointInfo_[line]; }; @@ -1272,26 +1273,29 @@ devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) { * @param {number} line Breakpoint 0-based line number in the containing script. * @constructor */ -devtools.BreakpointInfo = function(line) { - this.line_ = line; - this.v8id_ = -1; - this.removed_ = false; +devtools.BreakpointInfo = function(line) +{ + this.line_ = line; + this.v8id_ = -1; + this.removed_ = false; }; /** * @return {number} */ -devtools.BreakpointInfo.prototype.getLine = function(n) { - return this.line_; +devtools.BreakpointInfo.prototype.getLine = function(n) +{ + return this.line_; }; /** * @return {number} Unique identifier of this breakpoint in the v8 debugger. */ -devtools.BreakpointInfo.prototype.getV8Id = function(n) { - return this.v8id_; +devtools.BreakpointInfo.prototype.getV8Id = function(n) +{ + return this.v8id_; }; @@ -1299,16 +1303,18 @@ devtools.BreakpointInfo.prototype.getV8Id = function(n) { * Sets id of this breakpoint in the v8 debugger. * @param {number} id */ -devtools.BreakpointInfo.prototype.setV8Id = function(id) { - this.v8id_ = id; +devtools.BreakpointInfo.prototype.setV8Id = function(id) +{ + this.v8id_ = id; }; /** * Marks this breakpoint as removed from the front-end. */ -devtools.BreakpointInfo.prototype.markAsRemoved = function() { - this.removed_ = true; +devtools.BreakpointInfo.prototype.markAsRemoved = function() +{ + this.removed_ = true; }; @@ -1316,8 +1322,9 @@ devtools.BreakpointInfo.prototype.markAsRemoved = function() { * @return {boolean} Whether this breakpoint has been removed from the * front-end. */ -devtools.BreakpointInfo.prototype.isRemoved = function() { - return this.removed_; +devtools.BreakpointInfo.prototype.isRemoved = function() +{ + return this.removed_; }; @@ -1331,14 +1338,14 @@ devtools.BreakpointInfo.prototype.isRemoved = function() { * @param {Array.<Object>} scopeChain Array of scoped objects. * @construnctor */ -devtools.CallFrame = function(id, type, functionName, sourceID, line, - scopeChain) { - this.id = id; - this.type = type; - this.functionName = functionName; - this.sourceID = sourceID; - this.line = line; - this.scopeChain = scopeChain; +devtools.CallFrame = function(id, type, functionName, sourceID, line, scopeChain) +{ + this.id = id; + this.type = type; + this.functionName = functionName; + this.sourceID = sourceID; + this.line = line; + this.scopeChain = scopeChain; }; @@ -1349,25 +1356,25 @@ devtools.CallFrame = function(id, type, functionName, sourceID, line, * this call frame. * @param {function(Object):undefined} callback Callback to report result to. */ -devtools.CallFrame.prototype.evaluate_ = function(expression, callback) { - devtools.tools.getDebuggerAgent().requestEvaluate({ - 'expression': expression, - 'frame': this.id, - 'global': false, - 'disable_break': false, - 'compactFormat': true - }, - function(response) { - var result = {}; - if (response.isSuccess()) { - result.value = devtools.DebuggerAgent.formatObjectProxy_( - response.getBody()); - } else { - result.value = response.getMessage(); - result.isException = true; - } - callback(result); - }); +devtools.CallFrame.prototype.evaluate_ = function(expression, callback) +{ + devtools.tools.getDebuggerAgent().requestEvaluate({ + "expression": expression, + "frame": this.id, + "global": false, + "disable_break": false, + "compactFormat": true + }, + function(response) { + var result = {}; + if (response.isSuccess()) + result.value = devtools.DebuggerAgent.formatObjectProxy_(response.getBody()); + else { + result.value = response.getMessage(); + result.isException = true; + } + callback(result); + }); }; @@ -1377,13 +1384,13 @@ devtools.CallFrame.prototype.evaluate_ = function(expression, callback) { * @param {Object} opt_arguments Command-specific arguments map. * @constructor */ -devtools.DebugCommand = function(command, opt_arguments) { - this.command_ = command; - this.type_ = 'request'; - this.seq_ = ++devtools.DebugCommand.nextSeq_; - if (opt_arguments) { - this.arguments_ = opt_arguments; - } +devtools.DebugCommand = function(command, opt_arguments) +{ + this.command_ = command; + this.type_ = "request"; + this.seq_ = ++devtools.DebugCommand.nextSeq_; + if (opt_arguments) + this.arguments_ = opt_arguments; }; @@ -1397,24 +1404,25 @@ devtools.DebugCommand.nextSeq_ = 1; /** * @return {number} */ -devtools.DebugCommand.prototype.getSequenceNumber = function() { - return this.seq_; +devtools.DebugCommand.prototype.getSequenceNumber = function() +{ + return this.seq_; }; /** * @return {string} */ -devtools.DebugCommand.prototype.toJSONProtocol = function() { - var json = { - 'seq': this.seq_, - 'type': this.type_, - 'command': this.command_ - } - if (this.arguments_) { - json.arguments = this.arguments_; - } - return JSON.stringify(json); +devtools.DebugCommand.prototype.toJSONProtocol = function() +{ + var json = { + "seq": this.seq_, + "type": this.type_, + "command": this.command_ + } + if (this.arguments_) + json.arguments = this.arguments_; + return JSON.stringify(json); }; @@ -1424,30 +1432,32 @@ devtools.DebugCommand.prototype.toJSONProtocol = function() { * @param {string} msg Raw protocol packet as JSON string. * @constructor */ -devtools.DebuggerMessage = function(msg) { - this.packet_ = JSON.parse(msg); - this.refs_ = []; - if (this.packet_.refs) { - for (var i = 0; i < this.packet_.refs.length; i++) { - this.refs_[this.packet_.refs[i].handle] = this.packet_.refs[i]; +devtools.DebuggerMessage = function(msg) +{ + this.packet_ = JSON.parse(msg); + this.refs_ = []; + if (this.packet_.refs) { + for (var i = 0; i < this.packet_.refs.length; i++) + this.refs_[this.packet_.refs[i].handle] = this.packet_.refs[i]; } - } }; /** * @return {string} The packet type. */ -devtools.DebuggerMessage.prototype.getType = function() { - return this.packet_.type; +devtools.DebuggerMessage.prototype.getType = function() +{ + return this.packet_.type; }; /** * @return {?string} The packet event if the message is an event. */ -devtools.DebuggerMessage.prototype.getEvent = function() { - return this.packet_.event; +devtools.DebuggerMessage.prototype.getEvent = function() +{ + return this.packet_.event; }; @@ -1455,48 +1465,54 @@ devtools.DebuggerMessage.prototype.getEvent = function() { * @return {?string} The packet command if the message is a response to a * command. */ -devtools.DebuggerMessage.prototype.getCommand = function() { - return this.packet_.command; +devtools.DebuggerMessage.prototype.getCommand = function() +{ + return this.packet_.command; }; /** * @return {number} The packet request sequence. */ -devtools.DebuggerMessage.prototype.getRequestSeq = function() { - return this.packet_.request_seq; +devtools.DebuggerMessage.prototype.getRequestSeq = function() +{ + return this.packet_.request_seq; }; /** * @return {number} Whether the v8 is running after processing the request. */ -devtools.DebuggerMessage.prototype.isRunning = function() { - return this.packet_.running ? true : false; +devtools.DebuggerMessage.prototype.isRunning = function() +{ + return this.packet_.running ? true : false; }; /** * @return {boolean} Whether the request succeeded. */ -devtools.DebuggerMessage.prototype.isSuccess = function() { - return this.packet_.success ? true : false; +devtools.DebuggerMessage.prototype.isSuccess = function() +{ + return this.packet_.success ? true : false; }; /** * @return {string} */ -devtools.DebuggerMessage.prototype.getMessage = function() { - return this.packet_.message; +devtools.DebuggerMessage.prototype.getMessage = function() +{ + return this.packet_.message; }; /** * @return {Object} Parsed message body json. */ -devtools.DebuggerMessage.prototype.getBody = function() { - return this.packet_.body; +devtools.DebuggerMessage.prototype.getBody = function() +{ + return this.packet_.body; }; @@ -1505,6 +1521,7 @@ devtools.DebuggerMessage.prototype.getBody = function() { * @return {?Object} Returns the object with the handle if it was sent in this * message(some objects referenced by handles may be missing in the message). */ -devtools.DebuggerMessage.prototype.lookup = function(handle) { - return this.refs_[handle]; +devtools.DebuggerMessage.prototype.lookup = function(handle) +{ + return this.refs_[handle]; }; diff --git a/webkit/glue/devtools/js/devtools.js b/webkit/glue/devtools/js/devtools.js index 343a644..e759f12 100644 --- a/webkit/glue/devtools/js/devtools.js +++ b/webkit/glue/devtools/js/devtools.js @@ -1,16 +1,38 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** * @fileoverview Tools is a main class that wires all components of the * DevTools frontend together. It is also responsible for overriding existing * WebInspector functionality while it is getting upstreamed into WebCore. */ -goog.provide('devtools.Tools'); - -goog.require('devtools.DebuggerAgent'); - /** * Dispatches raw message from the host. @@ -18,39 +40,39 @@ goog.require('devtools.DebuggerAgent'); * @prama {string} methodName * @param {string} param1, param2, param3 Arguments to dispatch. */ -devtools$$dispatch = function(remoteName, methodName, param1, param2, param3) { - remoteName = 'Remote' + remoteName.substring(0, remoteName.length - 8); - var agent = window[remoteName]; - if (!agent) { - debugPrint('No remote agent "' + remoteName + '" found.'); - return; - } - var method = agent[methodName]; - if (!method) { - debugPrint('No method "' + remoteName + '.' + methodName + '" found.'); - return; - } - method.call(this, param1, param2, param3); +devtools$$dispatch = function(remoteName, methodName, param1, param2, param3) +{ + remoteName = "Remote" + remoteName.substring(0, remoteName.length - 8); + var agent = window[remoteName]; + if (!agent) { + debugPrint("No remote agent '" + remoteName + "' found."); + return; + } + var method = agent[methodName]; + if (!method) { + debugPrint("No method '" + remoteName + "." + methodName + "' found."); + return; + } + method.call(this, param1, param2, param3); }; -devtools.ToolsAgent = function() { - RemoteToolsAgent.didDispatchOn = - WebInspector.Callback.processCallback; - RemoteToolsAgent.frameNavigate = - goog.bind(this.frameNavigate_, this); - RemoteToolsAgent.dispatchOnClient = - goog.bind(this.dispatchOnClient_, this); - this.debuggerAgent_ = new devtools.DebuggerAgent(); - this.profilerAgent_ = new devtools.ProfilerAgent(); +devtools.ToolsAgent = function() +{ + RemoteToolsAgent.didDispatchOn = WebInspector.Callback.processCallback; + RemoteToolsAgent.frameNavigate = this.frameNavigate_.bind(this); + RemoteToolsAgent.dispatchOnClient = this.dispatchOnClient_.bind(this); + this.debuggerAgent_ = new devtools.DebuggerAgent(); + this.profilerAgent_ = new devtools.ProfilerAgent(); }; /** * Resets tools agent to its initial state. */ -devtools.ToolsAgent.prototype.reset = function() { - this.debuggerAgent_.reset(); +devtools.ToolsAgent.prototype.reset = function() +{ + this.debuggerAgent_.reset(); }; @@ -60,25 +82,27 @@ devtools.ToolsAgent.prototype.reset = function() { * @param {function(Object|string, boolean):undefined} opt_callback Function to * call with the result. */ -devtools.ToolsAgent.prototype.evaluateJavaScript = function(script, - opt_callback) { - InspectorBackend.evaluate(script, opt_callback || function() {}); +devtools.ToolsAgent.prototype.evaluateJavaScript = function(script, opt_callback) +{ + InspectorBackend.evaluate(script, opt_callback || function() {}); }; /** * @return {devtools.DebuggerAgent} Debugger agent instance. */ -devtools.ToolsAgent.prototype.getDebuggerAgent = function() { - return this.debuggerAgent_; +devtools.ToolsAgent.prototype.getDebuggerAgent = function() +{ + return this.debuggerAgent_; }; /** * @return {devtools.ProfilerAgent} Profiler agent instance. */ -devtools.ToolsAgent.prototype.getProfilerAgent = function() { - return this.profilerAgent_; +devtools.ToolsAgent.prototype.getProfilerAgent = function() +{ + return this.profilerAgent_; }; @@ -87,18 +111,18 @@ devtools.ToolsAgent.prototype.getProfilerAgent = function() { * @see tools_agent.h * @private */ -devtools.ToolsAgent.prototype.frameNavigate_ = function(url) { - this.reset(); - // Do not reset Profiles panel. - var profiles = null; - if ('profiles' in WebInspector.panels) { - profiles = WebInspector.panels['profiles']; - delete WebInspector.panels['profiles']; - } - WebInspector.reset(); - if (profiles != null) { - WebInspector.panels['profiles'] = profiles; - } +devtools.ToolsAgent.prototype.frameNavigate_ = function(url) +{ + this.reset(); + // Do not reset Profiles panel. + var profiles = null; + if ("profiles" in WebInspector.panels) { + profiles = WebInspector.panels["profiles"]; + delete WebInspector.panels["profiles"]; + } + WebInspector.reset(); + if (profiles !== null) + WebInspector.panels["profiles"] = profiles; }; @@ -106,11 +130,12 @@ devtools.ToolsAgent.prototype.frameNavigate_ = function(url) { * @param {string} message Serialized call to be dispatched on WebInspector. * @private */ -devtools.ToolsAgent.prototype.dispatchOnClient_ = function(message) { - var args = JSON.parse(message); - var methodName = args[0]; - var parameters = args.slice(1); - WebInspector[methodName].apply(WebInspector, parameters); +devtools.ToolsAgent.prototype.dispatchOnClient_ = function(message) +{ + var args = JSON.parse(message); + var methodName = args[0]; + var parameters = args.slice(1); + WebInspector[methodName].apply(WebInspector, parameters); }; @@ -118,8 +143,9 @@ devtools.ToolsAgent.prototype.dispatchOnClient_ = function(message) { * Evaluates js expression. * @param {string} expr */ -devtools.ToolsAgent.prototype.evaluate = function(expr) { - RemoteToolsAgent.evaluate(expr); +devtools.ToolsAgent.prototype.evaluate = function(expr) +{ + RemoteToolsAgent.evaluate(expr); }; @@ -127,9 +153,10 @@ devtools.ToolsAgent.prototype.evaluate = function(expr) { * Enables / disables resources panel in the ui. * @param {boolean} enabled New panel status. */ -WebInspector.setResourcesPanelEnabled = function(enabled) { - InspectorBackend._resourceTrackingEnabled = enabled; - WebInspector.panels.resources.reset(); +WebInspector.setResourcesPanelEnabled = function(enabled) +{ + InspectorBackend._resourceTrackingEnabled = enabled; + WebInspector.panels.resources.reset(); }; @@ -139,16 +166,15 @@ WebInspector.setResourcesPanelEnabled = function(enabled) { * @param {string} text */ function debugPrint(text) { - var console = WebInspector.console; - if (console) { - console.addMessage(new WebInspector.ConsoleMessage( - WebInspector.ConsoleMessage.MessageSource.JS, - WebInspector.ConsoleMessage.MessageType.Log, - WebInspector.ConsoleMessage.MessageLevel.Log, - 1, 'chrome://devtools/<internal>', undefined, -1, text)); - } else { - alert(text); - } + var console = WebInspector.console; + if (console) { + console.addMessage(new WebInspector.ConsoleMessage( + WebInspector.ConsoleMessage.MessageSource.JS, + WebInspector.ConsoleMessage.MessageType.Log, + WebInspector.ConsoleMessage.MessageLevel.Log, + 1, "chrome://devtools/<internal>", undefined, -1, text)); + } else + alert(text); } @@ -165,61 +191,60 @@ var context = {}; // Used by WebCore's inspector routines. // Here and below are overrides to existing WebInspector methods only. // TODO(pfeldman): Patch WebCore and upstream changes. var oldLoaded = WebInspector.loaded; -WebInspector.loaded = function() { - devtools.tools = new devtools.ToolsAgent(); - devtools.tools.reset(); +WebInspector.loaded = function() +{ + devtools.tools = new devtools.ToolsAgent(); + devtools.tools.reset(); - Preferences.ignoreWhitespace = false; - Preferences.samplingCPUProfiler = true; - Preferences.heapProfilerPresent = true; - oldLoaded.call(this); + Preferences.ignoreWhitespace = false; + Preferences.samplingCPUProfiler = true; + Preferences.heapProfilerPresent = true; + oldLoaded.call(this); - InspectorFrontendHost.loaded(); + InspectorFrontendHost.loaded(); }; -(function() { - - /** - * Handles an F3 keydown event to focus the Inspector search box. - * @param {KeyboardEvent} event Event to optionally handle - * @return {boolean} whether the event has been handled - */ - function handleF3Keydown(event) { - if (event.keyIdentifier == 'F3' && !event.altKey && !event.ctrlKey && - !event.shiftKey && !event.metaKey) { - var searchField = document.getElementById("search"); - searchField.focus(); - searchField.select(); - event.preventDefault(); - return true; - } - return false; - } - - - var oldKeyDown = WebInspector.documentKeyDown; - /** - * This override allows to intercept keydown events we want to handle in a - * custom way. Some nested documents (iframes) delegate keydown handling to - * WebInspector.documentKeyDown (e.g. SourceFrame). - * @param {KeyboardEvent} event - * @override - */ - WebInspector.documentKeyDown = function(event) { - var isHandled = handleF3Keydown(event); - if (!isHandled) { - // Mute refresh action. - if (event.keyIdentifier == 'F5') { - event.preventDefault(); - } else if (event.keyIdentifier == 'U+0052' /* 'R' */ && - (event.ctrlKey || event.metaKey)) { - event.preventDefault(); - } else { - oldKeyDown.call(this, event); - } +(function() +{ + + /** + * Handles an F3 keydown event to focus the Inspector search box. + * @param {KeyboardEvent} event Event to optionally handle + * @return {boolean} whether the event has been handled + */ + function handleF3Keydown(event) { + if (event.keyIdentifier === "F3" && !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) { + var searchField = document.getElementById("search"); + searchField.focus(); + searchField.select(); + event.preventDefault(); + return true; + } + return false; } - }; + + + var oldKeyDown = WebInspector.documentKeyDown; + /** + * This override allows to intercept keydown events we want to handle in a + * custom way. Some nested documents (iframes) delegate keydown handling to + * WebInspector.documentKeyDown (e.g. SourceFrame). + * @param {KeyboardEvent} event + * @override + */ + WebInspector.documentKeyDown = function(event) { + var isHandled = handleF3Keydown(event); + if (!isHandled) { + // Mute refresh action. + if (event.keyIdentifier === "F5") + event.preventDefault(); + else if (event.keyIdentifier === "U+0052" /* "R" */ && (event.ctrlKey || event.metaKey)) + event.preventDefault(); + else + oldKeyDown.call(this, event); + } + }; })(); @@ -227,69 +252,74 @@ WebInspector.loaded = function() { * This override is necessary for adding script source asynchronously. * @override */ -WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function() { - if (!this._frameNeedsSetup) { - return; - } - - this.attach(); - - if (this.script.source) { - this.didResolveScriptSource_(); - } else { - var self = this; - devtools.tools.getDebuggerAgent().resolveScriptSource( - this.script.sourceID, - function(source) { - self.script.source = source || - WebInspector.UIString('<source is not available>'); - self.didResolveScriptSource_(); - }); - } +WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function() +{ + if (!this._frameNeedsSetup) + return; + + this.attach(); + + if (this.script.source) + this.didResolveScriptSource_(); + else { + var self = this; + devtools.tools.getDebuggerAgent().resolveScriptSource( + this.script.sourceID, + function(source) { + self.script.source = source || WebInspector.UIString("<source is not available>"); + self.didResolveScriptSource_(); + }); + } }; /** * Performs source frame setup when script source is aready resolved. */ -WebInspector.ScriptView.prototype.didResolveScriptSource_ = function() { - this.sourceFrame.setContent("text/javascript", this.script.source); - this._sourceFrameSetup = true; - delete this._frameNeedsSetup; +WebInspector.ScriptView.prototype.didResolveScriptSource_ = function() +{ + this.sourceFrame.setContent("text/javascript", this.script.source); + this._sourceFrameSetup = true; + delete this._frameNeedsSetup; }; /** - * @param {string} type Type of the the property value('object' or 'function'). + * @param {string} type Type of the the property value("object" or "function"). * @param {string} className Class name of the property value. * @constructor */ -WebInspector.UnresolvedPropertyValue = function(type, className) { - this.type = type; - this.className = className; +WebInspector.UnresolvedPropertyValue = function(type, className) +{ + this.type = type; + this.className = className; }; -(function() { - var oldShow = WebInspector.ScriptsPanel.prototype.show; - WebInspector.ScriptsPanel.prototype.show = function() { - devtools.tools.getDebuggerAgent().initUI(); - this.enableToggleButton.visible = false; - oldShow.call(this); - }; +(function() +{ + var oldShow = WebInspector.ScriptsPanel.prototype.show; + WebInspector.ScriptsPanel.prototype.show = function() + { + devtools.tools.getDebuggerAgent().initUI(); + this.enableToggleButton.visible = false; + oldShow.call(this); + }; })(); -(function InterceptProfilesPanelEvents() { - var oldShow = WebInspector.ProfilesPanel.prototype.show; - WebInspector.ProfilesPanel.prototype.show = function() { - devtools.tools.getProfilerAgent().initializeProfiling(); - this.enableToggleButton.visible = false; - oldShow.call(this); - // Show is called on every show event of a panel, so - // we only need to intercept it once. - WebInspector.ProfilesPanel.prototype.show = oldShow; - }; +(function InterceptProfilesPanelEvents() +{ + var oldShow = WebInspector.ProfilesPanel.prototype.show; + WebInspector.ProfilesPanel.prototype.show = function() + { + devtools.tools.getProfilerAgent().initializeProfiling(); + this.enableToggleButton.visible = false; + oldShow.call(this); + // Show is called on every show event of a panel, so + // we only need to intercept it once. + WebInspector.ProfilesPanel.prototype.show = oldShow; + }; })(); @@ -297,144 +327,141 @@ WebInspector.UnresolvedPropertyValue = function(type, className) { * @override * TODO(mnaganov): Restore l10n when it will be agreed that it is needed. */ -WebInspector.UIString = function(string) { - return String.vsprintf(string, Array.prototype.slice.call(arguments, 1)); +WebInspector.UIString = function(string) +{ + return String.vsprintf(string, Array.prototype.slice.call(arguments, 1)); }; // There is no clear way of setting frame title yet. So sniffing main resource // load. (function OverrideUpdateResource() { - var originalUpdateResource = WebInspector.updateResource; - WebInspector.updateResource = function(identifier, payload) { - originalUpdateResource.call(this, identifier, payload); - var resource = this.resources[identifier]; - if (resource && resource.mainResource && resource.finished) { - document.title = - WebInspector.UIString('Developer Tools - %s', resource.url); - } - }; + var originalUpdateResource = WebInspector.updateResource; + WebInspector.updateResource = function(identifier, payload) + { + originalUpdateResource.call(this, identifier, payload); + var resource = this.resources[identifier]; + if (resource && resource.mainResource && resource.finished) + document.title = WebInspector.UIString("Developer Tools - %s", resource.url); + }; })(); // Highlight extension content scripts in the scripts list. (function () { - var original = WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu; - WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu = function(script) { - var result = original.apply(this, arguments); - var debuggerAgent = devtools.tools.getDebuggerAgent(); - var type = debuggerAgent.getScriptContextType(script.sourceID); - var option = script.filesSelectOption; - if (type == 'injected' && option) { - option.addStyleClass('injected'); - } - return result; - }; + var original = WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu; + WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu = function(script) + { + var result = original.apply(this, arguments); + var debuggerAgent = devtools.tools.getDebuggerAgent(); + var type = debuggerAgent.getScriptContextType(script.sourceID); + var option = script.filesSelectOption; + if (type === "injected" && option) + option.addStyleClass("injected"); + return result; + }; })(); /** Pending WebKit upstream by apavlov). Fixes iframe vs drag problem. */ -(function() { - var originalDragStart = WebInspector.elementDragStart; - WebInspector.elementDragStart = function(element) { - if (element) { - var glassPane = document.createElement("div"); - glassPane.style.cssText = - 'position:absolute;width:100%;height:100%;opacity:0;z-index:1'; - glassPane.id = 'glass-pane-for-drag'; - element.parentElement.appendChild(glassPane); - } - - originalDragStart.apply(this, arguments); - }; - - var originalDragEnd = WebInspector.elementDragEnd; - WebInspector.elementDragEnd = function() { - originalDragEnd.apply(this, arguments); - - var glassPane = document.getElementById('glass-pane-for-drag'); - if (glassPane) { - glassPane.parentElement.removeChild(glassPane); - } - }; +(function() +{ + var originalDragStart = WebInspector.elementDragStart; + WebInspector.elementDragStart = function(element) + { + if (element) { + var glassPane = document.createElement("div"); + glassPane.style.cssText = "position:absolute;width:100%;height:100%;opacity:0;z-index:1"; + glassPane.id = "glass-pane-for-drag"; + element.parentElement.appendChild(glassPane); + } + + originalDragStart.apply(this, arguments); + }; + + var originalDragEnd = WebInspector.elementDragEnd; + WebInspector.elementDragEnd = function() + { + originalDragEnd.apply(this, arguments); + + var glassPane = document.getElementById("glass-pane-for-drag"); + if (glassPane) + glassPane.parentElement.removeChild(glassPane); + }; })(); (function () { var orig = InjectedScriptAccess.prototype.getProperties; -InjectedScriptAccess.prototype.getProperties = function( - objectProxy, ignoreHasOwnProperty, abbreviate, callback) { - if (objectProxy.isScope) { - devtools.tools.getDebuggerAgent().resolveScope(objectProxy.objectId, - callback); - } else if (objectProxy.isV8Ref) { - devtools.tools.getDebuggerAgent().resolveChildren(objectProxy.objectId, - callback, false); - } else { - orig.apply(this, arguments); - } +InjectedScriptAccess.prototype.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback) +{ + if (objectProxy.isScope) + devtools.tools.getDebuggerAgent().resolveScope(objectProxy.objectId, callback); + else if (objectProxy.isV8Ref) + devtools.tools.getDebuggerAgent().resolveChildren(objectProxy.objectId, callback, false); + else + orig.apply(this, arguments); }; })(); -(function() { -InjectedScriptAccess.prototype.evaluateInCallFrame = function(callFrameId, - code, objectGroup, callback) +(function() +{ +InjectedScriptAccess.prototype.evaluateInCallFrame = function(callFrameId, code, objectGroup, callback) { - //TODO(pfeldman): remove once 49084 is rolled. - if (!callback) { - callback = objectGroup; - } - devtools.tools.getDebuggerAgent().evaluateInCallFrame( - callFrameId, code, callback); + //TODO(pfeldman): remove once 49084 is rolled. + if (!callback) + callback = objectGroup; + devtools.tools.getDebuggerAgent().evaluateInCallFrame(callFrameId, code, callback); }; })(); WebInspector.resourceTrackingWasEnabled = function() { - InspectorBackend._resourceTrackingEnabled = true; - this.panels.resources.resourceTrackingWasEnabled(); + InspectorBackend._resourceTrackingEnabled = true; + this.panels.resources.resourceTrackingWasEnabled(); }; WebInspector.resourceTrackingWasDisabled = function() { - InspectorBackend._resourceTrackingEnabled = false; - this.panels.resources.resourceTrackingWasDisabled(); + InspectorBackend._resourceTrackingEnabled = false; + this.panels.resources.resourceTrackingWasDisabled(); }; -(function() { +(function() +{ var orig = WebInspector.ConsoleMessage.prototype.setMessageBody; -WebInspector.ConsoleMessage.prototype.setMessageBody = function(args) { - for (var i = 0; i < args.length; ++i) { - if (typeof args[i] == "string") { - args[i] = WebInspector.ObjectProxy.wrapPrimitiveValue(args[i]); +WebInspector.ConsoleMessage.prototype.setMessageBody = function(args) +{ + for (var i = 0; i < args.length; ++i) { + if (typeof args[i] === "string") + args[i] = WebInspector.ObjectProxy.wrapPrimitiveValue(args[i]); } - } - orig.call(this, args); + orig.call(this, args); }; })(); -(function() { +(function() +{ var orig = InjectedScriptAccess.prototype.getCompletions; -InjectedScriptAccess.prototype.getCompletions = function(expressionString, - includeInspectorCommandLineAPI, callFrameId, reportCompletions) { - if (typeof callFrameId === "number") { - devtools.tools.getDebuggerAgent().resolveCompletionsOnFrame( - expressionString, callFrameId, reportCompletions); - } else { - return orig.apply(this, arguments); - } +InjectedScriptAccess.prototype.getCompletions = function(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions) +{ + if (typeof callFrameId === "number") + devtools.tools.getDebuggerAgent().resolveCompletionsOnFrame(expressionString, callFrameId, reportCompletions); + else + return orig.apply(this, arguments); }; })(); -(function() { -WebInspector.ElementsPanel.prototype._nodeSearchButtonClicked = function( - event) { - InspectorBackend.toggleNodeSearch(); - this.nodeSearchButton.toggled = !this.nodeSearchButton.toggled; +(function() +{ +WebInspector.ElementsPanel.prototype._nodeSearchButtonClicked = function( event) +{ + InspectorBackend.toggleNodeSearch(); + this.nodeSearchButton.toggled = !this.nodeSearchButton.toggled; }; })(); @@ -445,25 +472,28 @@ WebInspector.ElementsPanel.prototype._nodeSearchButtonClicked = function( WebInspector.runAfterPendingDispatchesQueue = []; -WebInspector.TestController.prototype.runAfterPendingDispatches = function(callback) { - WebInspector.runAfterPendingDispatchesQueue.push(callback); +WebInspector.TestController.prototype.runAfterPendingDispatches = function(callback) +{ + WebInspector.runAfterPendingDispatchesQueue.push(callback); }; -WebInspector.queuesAreEmpty = function() { - var copy = this.runAfterPendingDispatchesQueue.slice(); - this.runAfterPendingDispatchesQueue = []; - for (var i = 0; i < copy.length; ++i) - copy[i].call(this); +WebInspector.queuesAreEmpty = function() +{ + var copy = this.runAfterPendingDispatchesQueue.slice(); + this.runAfterPendingDispatchesQueue = []; + for (var i = 0; i < copy.length; ++i) + copy[i].call(this); }; -(function() { +(function() +{ var originalAddToFrame = InspectorFrontendHost.addResourceSourceToFrame; -InspectorFrontendHost.addResourceSourceToFrame = function(identifier, element) { - var resource = WebInspector.resources[identifier]; - if (!resource) { - return; - } - originalAddToFrame.call(this, identifier, resource.mimeType, element); +InspectorFrontendHost.addResourceSourceToFrame = function(identifier, element) +{ + var resource = WebInspector.resources[identifier]; + if (!resource) + return; + originalAddToFrame.call(this, identifier, resource.mimeType, element); }; })(); diff --git a/webkit/glue/devtools/js/devtools_host_stub.js b/webkit/glue/devtools/js/devtools_host_stub.js index bf5ba5b..49a9555 100644 --- a/webkit/glue/devtools/js/devtools_host_stub.js +++ b/webkit/glue/devtools/js/devtools_host_stub.js @@ -1,273 +1,308 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** * @fileoverview These stubs emulate backend functionality and allows * DevTools frontend to function as a standalone web app. */ -if (!window['RemoteDebuggerAgent']) { +if (!window["RemoteDebuggerAgent"]) { /** * @constructor */ -RemoteDebuggerAgentStub = function() { +RemoteDebuggerAgentStub = function() +{ }; -RemoteDebuggerAgentStub.prototype.getContextId = function() { - RemoteDebuggerAgent.setContextId(3); +RemoteDebuggerAgentStub.prototype.getContextId = function() +{ + RemoteDebuggerAgent.setContextId(3); }; /** * @constructor */ -RemoteProfilerAgentStub = function() { +RemoteProfilerAgentStub = function() +{ }; -RemoteProfilerAgentStub.prototype.getActiveProfilerModules = function() { - ProfilerStubHelper.GetInstance().getActiveProfilerModules(); +RemoteProfilerAgentStub.prototype.getActiveProfilerModules = function() +{ + ProfilerStubHelper.GetInstance().getActiveProfilerModules(); }; -RemoteProfilerAgentStub.prototype.getLogLines = function(pos) { - ProfilerStubHelper.GetInstance().getLogLines(pos); +RemoteProfilerAgentStub.prototype.getLogLines = function(pos) +{ + ProfilerStubHelper.GetInstance().getLogLines(pos); }; /** * @constructor */ -RemoteToolsAgentStub = function() { +RemoteToolsAgentStub = function() +{ }; -RemoteToolsAgentStub.prototype.dispatchOnInjectedScript = function() { +RemoteToolsAgentStub.prototype.dispatchOnInjectedScript = function() +{ }; -RemoteToolsAgentStub.prototype.dispatchOnInspectorController = function() { +RemoteToolsAgentStub.prototype.dispatchOnInspectorController = function() +{ }; -RemoteToolsAgentStub.prototype.executeVoidJavaScript = function() { +RemoteToolsAgentStub.prototype.executeVoidJavaScript = function() +{ }; /** * @constructor */ -ProfilerStubHelper = function() { - this.activeProfilerModules_ = - devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; - this.heapProfSample_ = 0; - this.log_ = ''; +ProfilerStubHelper = function() +{ + this.activeProfilerModules_ = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; + this.heapProfSample_ = 0; + this.log_ = ''; }; -ProfilerStubHelper.GetInstance = function() { - if (!ProfilerStubHelper.instance_) { - ProfilerStubHelper.instance_ = new ProfilerStubHelper(); - } - return ProfilerStubHelper.instance_; +ProfilerStubHelper.GetInstance = function() +{ + if (!ProfilerStubHelper.instance_) + ProfilerStubHelper.instance_ = new ProfilerStubHelper(); + return ProfilerStubHelper.instance_; }; -ProfilerStubHelper.prototype.StopProfiling = function(modules) { - this.activeProfilerModules_ &= ~modules; +ProfilerStubHelper.prototype.StopProfiling = function(modules) +{ + this.activeProfilerModules_ &= ~modules; }; -ProfilerStubHelper.prototype.StartProfiling = function(modules) { - var profModules = devtools.ProfilerAgent.ProfilerModules; - if (modules & profModules.PROFILER_MODULE_HEAP_SNAPSHOT) { - if (modules & profModules.PROFILER_MODULE_HEAP_STATS) { - this.log_ += - 'heap-sample-begin,"Heap","allocated",' + - (new Date()).getTime() + '\n' + - 'heap-sample-stats,"Heap","allocated",10000,1000\n'; - this.log_ += - 'heap-sample-item,STRING_TYPE,100,1000\n' + - 'heap-sample-item,CODE_TYPE,10,200\n' + - 'heap-sample-item,MAP_TYPE,20,350\n'; - this.log_ += - ProfilerStubHelper.HeapSamples[this.heapProfSample_++]; - this.heapProfSample_ %= ProfilerStubHelper.HeapSamples.length; - this.log_ += - 'heap-sample-end,"Heap","allocated"\n'; - } - } else { - if (modules & profModules.PROFILER_MODULE_CPU) { - this.log_ += ProfilerStubHelper.ProfilerLogBuffer; +ProfilerStubHelper.prototype.StartProfiling = function(modules) +{ + var profModules = devtools.ProfilerAgent.ProfilerModules; + if (modules & profModules.PROFILER_MODULE_HEAP_SNAPSHOT) { + if (modules & profModules.PROFILER_MODULE_HEAP_STATS) { + this.log_ += + 'heap-sample-begin,"Heap","allocated",' + + (new Date()).getTime() + '\n' + + 'heap-sample-stats,"Heap","allocated",10000,1000\n'; + this.log_ += + 'heap-sample-item,STRING_TYPE,100,1000\n' + + 'heap-sample-item,CODE_TYPE,10,200\n' + + 'heap-sample-item,MAP_TYPE,20,350\n'; + this.log_ += ProfilerStubHelper.HeapSamples[this.heapProfSample_++]; + this.heapProfSample_ %= ProfilerStubHelper.HeapSamples.length; + this.log_ += 'heap-sample-end,"Heap","allocated"\n'; + } + } else { + if (modules & profModules.PROFILER_MODULE_CPU) + this.log_ += ProfilerStubHelper.ProfilerLogBuffer; + this.activeProfilerModules_ |= modules; } - this.activeProfilerModules_ |= modules; - } }; -ProfilerStubHelper.prototype.getActiveProfilerModules = function() { - var self = this; - setTimeout(function() { - RemoteProfilerAgent.didGetActiveProfilerModules( - self.activeProfilerModules_); - }, 100); +ProfilerStubHelper.prototype.getActiveProfilerModules = function() +{ + var self = this; + setTimeout(function() { + RemoteProfilerAgent.didGetActiveProfilerModules(self.activeProfilerModules_); + }, 100); }; -ProfilerStubHelper.prototype.getLogLines = function(pos) { - var profModules = devtools.ProfilerAgent.ProfilerModules; - var logLines = this.log_.substr(pos); - setTimeout(function() { - RemoteProfilerAgent.didGetLogLines(pos + logLines.length, logLines); - }, 100); +ProfilerStubHelper.prototype.getLogLines = function(pos) +{ + var profModules = devtools.ProfilerAgent.ProfilerModules; + var logLines = this.log_.substr(pos); + setTimeout(function() { + RemoteProfilerAgent.didGetLogLines(pos + logLines.length, logLines); + }, 100); }; ProfilerStubHelper.ProfilerLogBuffer = - 'profiler,begin,1\n' + - 'profiler,resume\n' + - 'code-creation,LazyCompile,0x1000,256,"test1 http://aaa.js:1"\n' + - 'code-creation,LazyCompile,0x2000,256,"test2 http://bbb.js:2"\n' + - 'code-creation,LazyCompile,0x3000,256,"test3 http://ccc.js:3"\n' + - 'tick,0x1010,0x0,3\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x3010,0x0,3,0x2020, 0x1010\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x2030,0x0,3,0x2020, 0x1010\n' + - 'tick,0x2020,0x0,3,0x1010\n' + - 'tick,0x1010,0x0,3\n' + - 'profiler,pause\n'; + 'profiler,begin,1\n' + + 'profiler,resume\n' + + 'code-creation,LazyCompile,0x1000,256,"test1 http://aaa.js:1"\n' + + 'code-creation,LazyCompile,0x2000,256,"test2 http://bbb.js:2"\n' + + 'code-creation,LazyCompile,0x3000,256,"test3 http://ccc.js:3"\n' + + 'tick,0x1010,0x0,3\n' + + 'tick,0x2020,0x0,3,0x1010\n' + + 'tick,0x2020,0x0,3,0x1010\n' + + 'tick,0x3010,0x0,3,0x2020, 0x1010\n' + + 'tick,0x2020,0x0,3,0x1010\n' + + 'tick,0x2030,0x0,3,0x2020, 0x1010\n' + + 'tick,0x2020,0x0,3,0x1010\n' + + 'tick,0x1010,0x0,3\n' + + 'profiler,pause\n'; ProfilerStubHelper.HeapSamples = [ - 'heap-js-cons-item,foo,1,100\n' + - 'heap-js-cons-item,bar,20,2000\n' + - 'heap-js-cons-item,Object,5,100\n' + - 'heap-js-ret-item,foo,bar;3\n' + - 'heap-js-ret-item,bar,foo;5\n' + - 'heap-js-ret-item,Object:0x1234,(roots);1\n', - - 'heap-js-cons-item,foo,2000,200000\n' + - 'heap-js-cons-item,bar,10,1000\n' + - 'heap-js-cons-item,Object,6,120\n' + - 'heap-js-ret-item,foo,bar;7,Object:0x1234;10\n' + - 'heap-js-ret-item,bar,foo;10,Object:0x1234;10\n' + - 'heap-js-ret-item,Object:0x1234,(roots);1\n', - - 'heap-js-cons-item,foo,15,1500\n' + - 'heap-js-cons-item,bar,15,1500\n' + - 'heap-js-cons-item,Object,5,100\n' + - 'heap-js-cons-item,Array,3,1000\n' + - 'heap-js-ret-item,foo,bar;3,Array:0x5678;1\n' + - 'heap-js-ret-item,bar,foo;5,Object:0x1234;8,Object:0x5678;2\n' + - 'heap-js-ret-item,Object:0x1234,(roots);1,Object:0x5678;2\n' + - 'heap-js-ret-item,Object:0x5678,(global property);3,Object:0x1234;5\n' + - 'heap-js-ret-item,Array:0x5678,(global property);3,Array:0x5678;2\n', - - 'heap-js-cons-item,bar,20,2000\n' + - 'heap-js-cons-item,Object,6,120\n' + - 'heap-js-ret-item,bar,foo;5,Object:0x1234;1,Object:0x1235;3\n' + - 'heap-js-ret-item,Object:0x1234,(global property);3\n' + - 'heap-js-ret-item,Object:0x1235,(global property);5\n', - - 'heap-js-cons-item,foo,15,1500\n' + - 'heap-js-cons-item,bar,15,1500\n' + - 'heap-js-cons-item,Array,10,1000\n' + - 'heap-js-ret-item,foo,bar;1,Array:0x5678;1\n' + - 'heap-js-ret-item,bar,foo;5\n' + - 'heap-js-ret-item,Array:0x5678,(roots);3\n', - - 'heap-js-cons-item,bar,20,2000\n' + - 'heap-js-cons-item,baz,15,1500\n' + - 'heap-js-ret-item,bar,baz;3\n' + - 'heap-js-ret-item,baz,bar;3\n' + 'heap-js-cons-item,foo,1,100\n' + + 'heap-js-cons-item,bar,20,2000\n' + + 'heap-js-cons-item,Object,5,100\n' + + 'heap-js-ret-item,foo,bar;3\n' + + 'heap-js-ret-item,bar,foo;5\n' + + 'heap-js-ret-item,Object:0x1234,(roots);1\n', + + 'heap-js-cons-item,foo,2000,200000\n' + + 'heap-js-cons-item,bar,10,1000\n' + + 'heap-js-cons-item,Object,6,120\n' + + 'heap-js-ret-item,foo,bar;7,Object:0x1234;10\n' + + 'heap-js-ret-item,bar,foo;10,Object:0x1234;10\n' + + 'heap-js-ret-item,Object:0x1234,(roots);1\n', + + 'heap-js-cons-item,foo,15,1500\n' + + 'heap-js-cons-item,bar,15,1500\n' + + 'heap-js-cons-item,Object,5,100\n' + + 'heap-js-cons-item,Array,3,1000\n' + + 'heap-js-ret-item,foo,bar;3,Array:0x5678;1\n' + + 'heap-js-ret-item,bar,foo;5,Object:0x1234;8,Object:0x5678;2\n' + + 'heap-js-ret-item,Object:0x1234,(roots);1,Object:0x5678;2\n' + + 'heap-js-ret-item,Object:0x5678,(global property);3,Object:0x1234;5\n' + + 'heap-js-ret-item,Array:0x5678,(global property);3,Array:0x5678;2\n', + + 'heap-js-cons-item,bar,20,2000\n' + + 'heap-js-cons-item,Object,6,120\n' + + 'heap-js-ret-item,bar,foo;5,Object:0x1234;1,Object:0x1235;3\n' + + 'heap-js-ret-item,Object:0x1234,(global property);3\n' + + 'heap-js-ret-item,Object:0x1235,(global property);5\n', + + 'heap-js-cons-item,foo,15,1500\n' + + 'heap-js-cons-item,bar,15,1500\n' + + 'heap-js-cons-item,Array,10,1000\n' + + 'heap-js-ret-item,foo,bar;1,Array:0x5678;1\n' + + 'heap-js-ret-item,bar,foo;5\n' + + 'heap-js-ret-item,Array:0x5678,(roots);3\n', + + 'heap-js-cons-item,bar,20,2000\n' + + 'heap-js-cons-item,baz,15,1500\n' + + 'heap-js-ret-item,bar,baz;3\n' + + 'heap-js-ret-item,baz,bar;3\n' ]; /** * @constructor */ -RemoteDebuggerCommandExecutorStub = function() { +RemoteDebuggerCommandExecutorStub = function() +{ }; -RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand = function(cmd) { - if ('{"seq":2,"type":"request","command":"scripts","arguments":{"' + - 'includeSource":false}}' == cmd) { - var response1 = - '{"seq":5,"request_seq":2,"type":"response","command":"scripts","' + - 'success":true,"body":[{"handle":61,"type":"script","name":"' + - 'http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + - '"lineCount":1,"sourceStart":"function fib(n) {","sourceLength":300,' + - '"scriptType":2,"compilationType":0,"context":{"ref":60}}],"refs":[{' + - '"handle":60,"type":"context","data":"page,3"}],"running":false}'; - this.sendResponse_(response1); - } else if ('{"seq":3,"type":"request","command":"scripts","arguments":{' + - '"ids":[59],"includeSource":true}}' == cmd) { - this.sendResponse_( - '{"seq":8,"request_seq":3,"type":"response","command":"scripts",' + - '"success":true,"body":[{"handle":1,"type":"script","name":' + - '"http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + - '"lineCount":1,"source":"function fib(n) {return n+1;}",' + - '"sourceLength":244,"scriptType":2,"compilationType":0,"context":{' + - '"ref":0}}],"refs":[{"handle":0,"type":"context","data":"page,3}],"' + - '"running":false}'); - } else if (cmd.indexOf('"command":"profile"') != -1) { - var cmdObj = JSON.parse(cmd); - if (cmdObj.arguments.command == 'resume') { - ProfilerStubHelper.GetInstance().StartProfiling( - parseInt(cmdObj.arguments.modules)); - } else if (cmdObj.arguments.command == 'pause') { - ProfilerStubHelper.GetInstance().StopProfiling( - parseInt(cmdObj.arguments.modules)); - } else { - debugPrint('Unexpected profile command: ' + cmdObj.arguments.command); - } - } else { - debugPrint('Unexpected command: ' + cmd); - } +RemoteDebuggerCommandExecutorStub.prototype.DebuggerCommand = function(cmd) +{ + if ('{"seq":2,"type":"request","command":"scripts","arguments":{"includeSource":false}}' === cmd) { + var response1 = + '{"seq":5,"request_seq":2,"type":"response","command":"scripts","' + + 'success":true,"body":[{"handle":61,"type":"script","name":"' + + 'http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + + '"lineCount":1,"sourceStart":"function fib(n) {","sourceLength":300,' + + '"scriptType":2,"compilationType":0,"context":{"ref":60}}],"refs":[{' + + '"handle":60,"type":"context","data":"page,3"}],"running":false}'; + this.sendResponse_(response1); + } else if ('{"seq":3,"type":"request","command":"scripts","arguments":{"ids":[59],"includeSource":true}}' === cmd) { + this.sendResponse_( + '{"seq":8,"request_seq":3,"type":"response","command":"scripts",' + + '"success":true,"body":[{"handle":1,"type":"script","name":' + + '"http://www/~test/t.js","id":59,"lineOffset":0,"columnOffset":0,' + + '"lineCount":1,"source":"function fib(n) {return n+1;}",' + + '"sourceLength":244,"scriptType":2,"compilationType":0,"context":{' + + '"ref":0}}],"refs":[{"handle":0,"type":"context","data":"page,3}],"' + + '"running":false}'); + } else if (cmd.indexOf('"command":"profile"') !== -1) { + var cmdObj = JSON.parse(cmd); + if (cmdObj.arguments.command === "resume") + ProfilerStubHelper.GetInstance().StartProfiling(parseInt(cmdObj.arguments.modules)); + else if (cmdObj.arguments.command === "pause") + ProfilerStubHelper.GetInstance().StopProfiling(parseInt(cmdObj.arguments.modules)); + else + debugPrint("Unexpected profile command: " + cmdObj.arguments.command); + } else + debugPrint("Unexpected command: " + cmd); }; -RemoteDebuggerCommandExecutorStub.prototype.DebuggerPauseScript = function() { +RemoteDebuggerCommandExecutorStub.prototype.DebuggerPauseScript = function() +{ }; -RemoteDebuggerCommandExecutorStub.prototype.sendResponse_ = function(response) { - setTimeout(function() { - RemoteDebuggerAgent.debuggerOutput(response); - }, 0); +RemoteDebuggerCommandExecutorStub.prototype.sendResponse_ = function(response) +{ + setTimeout(function() { + RemoteDebuggerAgent.debuggerOutput(response); + }, 0); }; -DevToolsHostStub = function() { - this.isStub = true; +DevToolsHostStub = function() +{ + this.isStub = true; }; -goog.inherits(DevToolsHostStub, - WebInspector.InspectorFrontendHostStub); +DevToolsHostStub.prototype.__proto__ = WebInspector.InspectorFrontendHostStub.prototype; -DevToolsHostStub.prototype.reset = function() { +DevToolsHostStub.prototype.reset = function() +{ }; -DevToolsHostStub.prototype.setting = function() { +DevToolsHostStub.prototype.setting = function() +{ }; -DevToolsHostStub.prototype.setSetting = function() { +DevToolsHostStub.prototype.setSetting = function() +{ }; -window['RemoteDebuggerAgent'] = new RemoteDebuggerAgentStub(); -window['RemoteDebuggerCommandExecutor'] = - new RemoteDebuggerCommandExecutorStub(); -window['RemoteProfilerAgent'] = new RemoteProfilerAgentStub(); -window['RemoteToolsAgent'] = new RemoteToolsAgentStub(); +window["RemoteDebuggerAgent"] = new RemoteDebuggerAgentStub(); +window["RemoteDebuggerCommandExecutor"] = new RemoteDebuggerCommandExecutorStub(); +window["RemoteProfilerAgent"] = new RemoteProfilerAgentStub(); +window["RemoteToolsAgent"] = new RemoteToolsAgentStub(); InspectorFrontendHost = new DevToolsHostStub(); } diff --git a/webkit/glue/devtools/js/heap_profiler_panel.js b/webkit/glue/devtools/js/heap_profiler_panel.js index a1b5183..abbf580 100644 --- a/webkit/glue/devtools/js/heap_profiler_panel.js +++ b/webkit/glue/devtools/js/heap_profiler_panel.js @@ -1,6 +1,32 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** * @fileoverview Heap profiler panel implementation. @@ -364,7 +390,7 @@ WebInspector.HeapSnapshotView.prototype = { { var list = WebInspector.HeapSnapshotProfileType.snapshots; // We're assuming that snapshots can only be added. - if (this.baseSelectElement.length == list.length) + if (this.baseSelectElement.length === list.length) return; for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) { @@ -401,7 +427,7 @@ WebInspector.HeapSnapshotView.SearchHelper = { // In comparators, we assume that a value from a node is passed as the first parameter. operations: { LESS: function (a, b) { return a !== null && a < b; }, LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; }, - EQUAL: function (a, b) { return a !== null && a == b; }, + EQUAL: function (a, b) { return a !== null && a === b; }, GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; }, GREATER: function (a, b) { return a !== null && a > b; } }, @@ -416,7 +442,7 @@ WebInspector.HeapSnapshotView.SearchHelper = { var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers; for (var operation in parsers) { var match = query.match(parsers[operation]); - if (match != null) + if (match !== null) return [operations[operation], parseFloat(match[1])]; } return [operations.EQUAL, parseFloat(query)]; @@ -482,8 +508,8 @@ WebInspector.HeapSummaryCountCalculator = function() WebInspector.HeapSummaryCountCalculator.prototype = { _highFromLow: function(type) { - if (type == "CODE_TYPE" || type == "SHARED_FUNCTION_INFO_TYPE" || type == "SCRIPT_TYPE") return "code"; - if (type == "STRING_TYPE" || type == "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data"; + if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code"; + if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data"; return null; }, @@ -501,8 +527,8 @@ WebInspector.HeapSummarySizeCalculator = function() WebInspector.HeapSummarySizeCalculator.prototype = { _highFromLow: function(type) { - if (type == "CODE_TYPE" || type == "SHARED_FUNCTION_INFO_TYPE" || type == "SCRIPT_TYPE") return "code"; - if (type == "STRING_TYPE" || type == "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/)) return "data"; + if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code"; + if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/)) return "data"; return null; }, @@ -610,7 +636,7 @@ WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = { }, signForDelta: function(delta) { - if (delta == 0) + if (delta === 0) return ""; if (delta > 0) return "+"; @@ -703,7 +729,7 @@ WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = { else data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta)); - if (this.sizeDelta != null) { + if (this.sizeDelta !== null) { if (this.snapshotView.showSizeDeltaAsPercent) data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent); else @@ -798,7 +824,7 @@ WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}]; WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending) { - var propertyHash = property + '#' + property2; + var propertyHash = property + "#" + property2; var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash]; if (!comparator) { comparator = function(lhs, rhs) { diff --git a/webkit/glue/devtools/js/inject_dispatch.js b/webkit/glue/devtools/js/inject_dispatch.js index c0ea4bd..1c2cba2 100644 --- a/webkit/glue/devtools/js/inject_dispatch.js +++ b/webkit/glue/devtools/js/inject_dispatch.js @@ -1,9 +1,35 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** - * @fileoverview Injects 'injected' object into the inspectable page. + * @fileoverview Injects "injected" object into the inspectable page. */ @@ -16,9 +42,10 @@ var InspectorControllerDispatcher = {}; * @param {string} json_args JSON-serialized call parameters. * @return {string} JSON-serialized result of the dispatched call. */ -InspectorControllerDispatcher.dispatch = function(functionName, json_args) { - var params = JSON.parse(json_args); - InspectorBackend[functionName].apply(InspectorBackend, params); +InspectorControllerDispatcher.dispatch = function(functionName, json_args) +{ + var params = JSON.parse(json_args); + InspectorBackend[functionName].apply(InspectorBackend, params); }; /** @@ -32,15 +59,13 @@ var ApuAgentDispatcher = { enabled : false }; * outgoing messages that are used by APU. * @param {string} method name of the dispatch method. **/ -ApuAgentDispatcher.dispatchToApu = function(method, args) { - if (method != 'addRecordToTimeline' && - method != 'updateResource' && - method != 'addResource') { - return; - } - // TODO(knorton): Transform args so they can be used - // by APU. - DevToolsAgentHost.dispatchToApu(JSON.stringify(args)); +ApuAgentDispatcher.dispatchToApu = function(method, args) +{ + if (method !== "addRecordToTimeline" && method !== "updateResource" && method !== "addResource") + return; + // TODO(knorton): Transform args so they can be used + // by APU. + DevToolsAgentHost.dispatchToApu(JSON.stringify(args)); }; /** @@ -49,37 +74,35 @@ ApuAgentDispatcher.dispatchToApu = function(method, args) { * using dispatchOut bound method. */ function dispatch(method, var_args) { - // Handle all messages with non-primitieve arguments here. - var args = Array.prototype.slice.call(arguments); + // Handle all messages with non-primitieve arguments here. + var args = Array.prototype.slice.call(arguments); - if (method == 'inspectedWindowCleared' || - method == 'reset' || - method == 'setAttachedWindow') { - // Filter out messages we don't need here. - // We do it on the sender side since they may have non-serializable - // parameters. - return; - } + if (method === "inspectedWindowCleared" || method === "reset" || method === "setAttachedWindow") { + // Filter out messages we don't need here. + // We do it on the sender side since they may have non-serializable + // parameters. + return; + } - // Sniff some inspector controller state changes in order to support - // cross-navigation instrumentation. Keep names in sync with - // webdevtoolsagent_impl. - if (method == 'timelineProfilerWasStarted') - DevToolsAgentHost.runtimeFeatureStateChanged('timeline-profiler', true); - else if (method == 'timelineProfilerWasStopped') - DevToolsAgentHost.runtimeFeatureStateChanged('timeline-profiler', false); - else if (method == 'resourceTrackingWasEnabled') - DevToolsAgentHost.runtimeFeatureStateChanged('resource-tracking', true); - else if (method == 'resourceTrackingWasDisabled') - DevToolsAgentHost.runtimeFeatureStateChanged('resource-tracking', false); + // Sniff some inspector controller state changes in order to support + // cross-navigation instrumentation. Keep names in sync with + // webdevtoolsagent_impl. + if (method === "timelineProfilerWasStarted") + DevToolsAgentHost.runtimeFeatureStateChanged("timeline-profiler", true); + else if (method === "timelineProfilerWasStopped") + DevToolsAgentHost.runtimeFeatureStateChanged("timeline-profiler", false); + else if (method === "resourceTrackingWasEnabled") + DevToolsAgentHost.runtimeFeatureStateChanged("resource-tracking", true); + else if (method === "resourceTrackingWasDisabled") + DevToolsAgentHost.runtimeFeatureStateChanged("resource-tracking", false); - if (ApuAgentDispatcher.enabled) { - ApuAgentDispatcher.dispatchToApu(method, args); - return; - } + if (ApuAgentDispatcher.enabled) { + ApuAgentDispatcher.dispatchToApu(method, args); + return; + } - var call = JSON.stringify(args); - DevToolsAgentHost.dispatch(call); + var call = JSON.stringify(args); + DevToolsAgentHost.dispatch(call); }; /** diff --git a/webkit/glue/devtools/js/inspector_controller_impl.js b/webkit/glue/devtools/js/inspector_controller_impl.js index 1adfe8e..c92a94c 100644 --- a/webkit/glue/devtools/js/inspector_controller_impl.js +++ b/webkit/glue/devtools/js/inspector_controller_impl.js @@ -1,230 +1,257 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** * @fileoverview DevTools' implementation of the InspectorController API. */ -goog.provide('devtools.InspectorBackendImpl'); -goog.provide('devtools.InspectorFrontendHostImpl'); - -devtools.InspectorBackendImpl = function() { - WebInspector.InspectorBackendStub.call(this); - this.installInspectorControllerDelegate_('clearMessages'); - this.installInspectorControllerDelegate_('copyNode'); - this.installInspectorControllerDelegate_('deleteCookie'); - this.installInspectorControllerDelegate_('didEvaluateForTestInFrontend'); - this.installInspectorControllerDelegate_('disableResourceTracking'); - this.installInspectorControllerDelegate_('disableTimeline'); - this.installInspectorControllerDelegate_('enableResourceTracking'); - this.installInspectorControllerDelegate_('enableTimeline'); - this.installInspectorControllerDelegate_('getChildNodes'); - this.installInspectorControllerDelegate_('getCookies'); - this.installInspectorControllerDelegate_('getDatabaseTableNames'); - this.installInspectorControllerDelegate_('getDOMStorageEntries'); - this.installInspectorControllerDelegate_('getEventListenersForNode'); - this.installInspectorControllerDelegate_('getResourceContent'); - this.installInspectorControllerDelegate_('highlightDOMNode'); - this.installInspectorControllerDelegate_('hideDOMNodeHighlight'); - this.installInspectorControllerDelegate_('releaseWrapperObjectGroup'); - this.installInspectorControllerDelegate_('removeAttribute'); - this.installInspectorControllerDelegate_('removeDOMStorageItem'); - this.installInspectorControllerDelegate_('removeNode'); - this.installInspectorControllerDelegate_('saveFrontendSettings'); - this.installInspectorControllerDelegate_('setAttribute'); - this.installInspectorControllerDelegate_('setDOMStorageItem'); - this.installInspectorControllerDelegate_('setInjectedScriptSource'); - this.installInspectorControllerDelegate_('setTextNodeValue'); - this.installInspectorControllerDelegate_('startTimelineProfiler'); - this.installInspectorControllerDelegate_('stopTimelineProfiler'); - this.installInspectorControllerDelegate_('storeLastActivePanel'); +if (!this.devtools) + devtools = {}; + +devtools.InspectorBackendImpl = function() +{ + WebInspector.InspectorBackendStub.call(this); + this.installInspectorControllerDelegate_("clearMessages"); + this.installInspectorControllerDelegate_("copyNode"); + this.installInspectorControllerDelegate_("deleteCookie"); + this.installInspectorControllerDelegate_("didEvaluateForTestInFrontend"); + this.installInspectorControllerDelegate_("disableResourceTracking"); + this.installInspectorControllerDelegate_("disableTimeline"); + this.installInspectorControllerDelegate_("enableResourceTracking"); + this.installInspectorControllerDelegate_("enableTimeline"); + this.installInspectorControllerDelegate_("getChildNodes"); + this.installInspectorControllerDelegate_("getCookies"); + this.installInspectorControllerDelegate_("getDatabaseTableNames"); + this.installInspectorControllerDelegate_("getDOMStorageEntries"); + this.installInspectorControllerDelegate_("getEventListenersForNode"); + this.installInspectorControllerDelegate_("getResourceContent"); + this.installInspectorControllerDelegate_("highlightDOMNode"); + this.installInspectorControllerDelegate_("hideDOMNodeHighlight"); + this.installInspectorControllerDelegate_("releaseWrapperObjectGroup"); + this.installInspectorControllerDelegate_("removeAttribute"); + this.installInspectorControllerDelegate_("removeDOMStorageItem"); + this.installInspectorControllerDelegate_("removeNode"); + this.installInspectorControllerDelegate_("saveFrontendSettings"); + this.installInspectorControllerDelegate_("setAttribute"); + this.installInspectorControllerDelegate_("setDOMStorageItem"); + this.installInspectorControllerDelegate_("setInjectedScriptSource"); + this.installInspectorControllerDelegate_("setTextNodeValue"); + this.installInspectorControllerDelegate_("startTimelineProfiler"); + this.installInspectorControllerDelegate_("stopTimelineProfiler"); + this.installInspectorControllerDelegate_("storeLastActivePanel"); }; -goog.inherits(devtools.InspectorBackendImpl, - WebInspector.InspectorBackendStub); +devtools.InspectorBackendImpl.prototype.__proto__ = WebInspector.InspectorBackendStub.prototype; /** * {@inheritDoc}. */ -devtools.InspectorBackendImpl.prototype.toggleNodeSearch = function() { - WebInspector.InspectorBackendStub.prototype.toggleNodeSearch.call(this); - this.callInspectorController_.call(this, 'toggleNodeSearch'); - if (!this.searchingForNode()) { - // This is called from ElementsPanel treeOutline's focusNodeChanged(). - DevToolsHost.activateWindow(); - } +devtools.InspectorBackendImpl.prototype.toggleNodeSearch = function() +{ + WebInspector.InspectorBackendStub.prototype.toggleNodeSearch.call(this); + this.callInspectorController_.call(this, "toggleNodeSearch"); + if (!this.searchingForNode()) { + // This is called from ElementsPanel treeOutline's focusNodeChanged(). + DevToolsHost.activateWindow(); + } }; /** * @override */ -devtools.InspectorBackendImpl.prototype.debuggerEnabled = function() { - return true; +devtools.InspectorBackendImpl.prototype.debuggerEnabled = function() +{ + return true; }; /** * @override */ -devtools.InspectorBackendImpl.prototype.profilerEnabled = function() { - return true; +devtools.InspectorBackendImpl.prototype.profilerEnabled = function() +{ + return true; }; -devtools.InspectorBackendImpl.prototype.addBreakpoint = function( - sourceID, line, condition) { - devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line, condition); +devtools.InspectorBackendImpl.prototype.addBreakpoint = function(sourceID, line, condition) +{ + devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line, condition); }; -devtools.InspectorBackendImpl.prototype.removeBreakpoint = function( - sourceID, line) { - devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line); +devtools.InspectorBackendImpl.prototype.removeBreakpoint = function(sourceID, line) +{ + devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line); }; -devtools.InspectorBackendImpl.prototype.updateBreakpoint = function( - sourceID, line, condition) { - devtools.tools.getDebuggerAgent().updateBreakpoint( - sourceID, line, condition); +devtools.InspectorBackendImpl.prototype.updateBreakpoint = function(sourceID, line, condition) +{ + devtools.tools.getDebuggerAgent().updateBreakpoint(sourceID, line, condition); }; -devtools.InspectorBackendImpl.prototype.pauseInDebugger = function() { - devtools.tools.getDebuggerAgent().pauseExecution(); +devtools.InspectorBackendImpl.prototype.pauseInDebugger = function() +{ + devtools.tools.getDebuggerAgent().pauseExecution(); }; -devtools.InspectorBackendImpl.prototype.resumeDebugger = function() { - devtools.tools.getDebuggerAgent().resumeExecution(); +devtools.InspectorBackendImpl.prototype.resumeDebugger = function() +{ + devtools.tools.getDebuggerAgent().resumeExecution(); }; -devtools.InspectorBackendImpl.prototype.stepIntoStatementInDebugger = - function() { - devtools.tools.getDebuggerAgent().stepIntoStatement(); +devtools.InspectorBackendImpl.prototype.stepIntoStatementInDebugger = function() +{ + devtools.tools.getDebuggerAgent().stepIntoStatement(); }; -devtools.InspectorBackendImpl.prototype.stepOutOfFunctionInDebugger = - function() { - devtools.tools.getDebuggerAgent().stepOutOfFunction(); +devtools.InspectorBackendImpl.prototype.stepOutOfFunctionInDebugger = function() +{ + devtools.tools.getDebuggerAgent().stepOutOfFunction(); }; -devtools.InspectorBackendImpl.prototype.stepOverStatementInDebugger = - function() { - devtools.tools.getDebuggerAgent().stepOverStatement(); +devtools.InspectorBackendImpl.prototype.stepOverStatementInDebugger = function() +{ + devtools.tools.getDebuggerAgent().stepOverStatement(); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.setPauseOnExceptionsState = function(state) { - this._setPauseOnExceptionsState = state; - // TODO(yurys): support all three states. See http://crbug.com/32877 - var enabled = (state != - WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); - return devtools.tools.getDebuggerAgent().setPauseOnExceptions(enabled); +devtools.InspectorBackendImpl.prototype.setPauseOnExceptionsState = function(state) +{ + this._setPauseOnExceptionsState = state; + // TODO(yurys): support all three states. See http://crbug.com/32877 + var enabled = (state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); + return devtools.tools.getDebuggerAgent().setPauseOnExceptions(enabled); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.pauseOnExceptionsState = function() { - return (this._setPauseOnExceptionsState || - WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); +devtools.InspectorBackendImpl.prototype.pauseOnExceptionsState = function() +{ + return (this._setPauseOnExceptionsState || WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.pauseOnExceptions = function() { - return devtools.tools.getDebuggerAgent().pauseOnExceptions(); +devtools.InspectorBackendImpl.prototype.pauseOnExceptions = function() +{ + return devtools.tools.getDebuggerAgent().pauseOnExceptions(); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.setPauseOnExceptions = function( - value) { - return devtools.tools.getDebuggerAgent().setPauseOnExceptions(value); +devtools.InspectorBackendImpl.prototype.setPauseOnExceptions = function(value) +{ + return devtools.tools.getDebuggerAgent().setPauseOnExceptions(value); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.startProfiling = function() { - devtools.tools.getProfilerAgent().startProfiling( - devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); +devtools.InspectorBackendImpl.prototype.startProfiling = function() +{ + devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.stopProfiling = function() { - devtools.tools.getProfilerAgent().stopProfiling( - devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); +devtools.InspectorBackendImpl.prototype.stopProfiling = function() +{ + devtools.tools.getProfilerAgent().stopProfiling( devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.getProfileHeaders = function(callId) { - WebInspector.didGetProfileHeaders(callId, []); +devtools.InspectorBackendImpl.prototype.getProfileHeaders = function(callId) +{ + WebInspector.didGetProfileHeaders(callId, []); }; /** * Emulate WebKit InspectorController behavior. It stores profiles on renderer side, - * and is able to retrieve them by uid using 'getProfile'. + * and is able to retrieve them by uid using "getProfile". */ -devtools.InspectorBackendImpl.prototype.addFullProfile = function(profile) { - WebInspector.__fullProfiles = WebInspector.__fullProfiles || {}; - WebInspector.__fullProfiles[profile.uid] = profile; +devtools.InspectorBackendImpl.prototype.addFullProfile = function(profile) +{ + WebInspector.__fullProfiles = WebInspector.__fullProfiles || {}; + WebInspector.__fullProfiles[profile.uid] = profile; }; /** * @override */ -devtools.InspectorBackendImpl.prototype.getProfile = function(callId, uid) { - if (WebInspector.__fullProfiles && (uid in WebInspector.__fullProfiles)) { - WebInspector.didGetProfile(callId, WebInspector.__fullProfiles[uid]); - } +devtools.InspectorBackendImpl.prototype.getProfile = function(callId, uid) +{ + if (WebInspector.__fullProfiles && (uid in WebInspector.__fullProfiles)) + WebInspector.didGetProfile(callId, WebInspector.__fullProfiles[uid]); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.takeHeapSnapshot = function() { - devtools.tools.getProfilerAgent().startProfiling( - devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT - | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_STATS - | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_JS_CONSTRUCTORS); +devtools.InspectorBackendImpl.prototype.takeHeapSnapshot = function() +{ + devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT + | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_STATS + | devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_JS_CONSTRUCTORS); }; /** * @override */ -devtools.InspectorBackendImpl.prototype.dispatchOnInjectedScript = function( - callId, injectedScriptId, methodName, argsString, async) { - // Encode injectedScriptId into callId - if (typeof injectedScriptId != 'number') { - injectedScriptId = 0; - } - RemoteToolsAgent.dispatchOnInjectedScript( - callId, - injectedScriptId, - methodName, - argsString, - async); +devtools.InspectorBackendImpl.prototype.dispatchOnInjectedScript = function(callId, injectedScriptId, methodName, argsString, async) +{ + // Encode injectedScriptId into callId + if (typeof injectedScriptId !== "number") + injectedScriptId = 0; + RemoteToolsAgent.dispatchOnInjectedScript(callId, injectedScriptId, methodName, argsString, async); }; @@ -232,10 +259,9 @@ devtools.InspectorBackendImpl.prototype.dispatchOnInjectedScript = function( * Installs delegating handler into the inspector controller. * @param {string} methodName Method to install delegating handler for. */ -devtools.InspectorBackendImpl.prototype.installInspectorControllerDelegate_ - = function(methodName) { - this[methodName] = goog.bind(this.callInspectorController_, this, - methodName); +devtools.InspectorBackendImpl.prototype.installInspectorControllerDelegate_ = function(methodName) +{ + this[methodName] = this.callInspectorController_.bind(this, methodName); }; @@ -243,13 +269,10 @@ devtools.InspectorBackendImpl.prototype.installInspectorControllerDelegate_ * Bound function with the installInjectedScriptDelegate_ actual * implementation. */ -devtools.InspectorBackendImpl.prototype.callInspectorController_ = - function(methodName, var_arg) { - var args = Array.prototype.slice.call(arguments, 1); - RemoteToolsAgent.dispatchOnInspectorController( - WebInspector.Callback.wrap(function(){}), - methodName, - JSON.stringify(args)); +devtools.InspectorBackendImpl.prototype.callInspectorController_ = function(methodName, var_arg) +{ + var args = Array.prototype.slice.call(arguments, 1); + RemoteToolsAgent.dispatchOnInspectorController(WebInspector.Callback.wrap(function(){}), methodName, JSON.stringify(args)); }; diff --git a/webkit/glue/devtools/js/profiler_agent.js b/webkit/glue/devtools/js/profiler_agent.js index 20974fd..b7411ab 100644 --- a/webkit/glue/devtools/js/profiler_agent.js +++ b/webkit/glue/devtools/js/profiler_agent.js @@ -1,51 +1,74 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** * @fileoverview Provides communication interface to remote v8 profiler. */ -goog.provide('devtools.ProfilerAgent'); /** * @constructor */ -devtools.ProfilerAgent = function() { - RemoteProfilerAgent.didGetActiveProfilerModules = - goog.bind(this.didGetActiveProfilerModules_, this); - RemoteProfilerAgent.didGetLogLines = - goog.bind(this.didGetLogLines_, this); - - /** - * Active profiler modules flags. - * @type {number} - */ - this.activeProfilerModules_ = - devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; - - /** - * Interval for polling profiler state. - * @type {number} - */ - this.getActiveProfilerModulesInterval_ = null; - - /** - * Profiler log position. - * @type {number} - */ - this.logPosition_ = 0; - - /** - * Whether log contents retrieval must be forced next time. - * @type {boolean} - */ - this.forceGetLogLines_ = false; - - /** - * Profiler processor instance. - * @type {devtools.profiler.Processor} - */ - this.profilerProcessor_ = new devtools.profiler.Processor(); +devtools.ProfilerAgent = function() +{ + RemoteProfilerAgent.didGetActiveProfilerModules = this.didGetActiveProfilerModules_.bind(this); + RemoteProfilerAgent.didGetLogLines = this.didGetLogLines_.bind(this); + + /** + * Active profiler modules flags. + * @type {number} + */ + this.activeProfilerModules_ = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; + + /** + * Interval for polling profiler state. + * @type {number} + */ + this.getActiveProfilerModulesInterval_ = null; + + /** + * Profiler log position. + * @type {number} + */ + this.logPosition_ = 0; + + /** + * Whether log contents retrieval must be forced next time. + * @type {boolean} + */ + this.forceGetLogLines_ = false; + + /** + * Profiler processor instance. + * @type {devtools.profiler.Processor} + */ + this.profilerProcessor_ = new devtools.profiler.Processor(); }; @@ -54,60 +77,59 @@ devtools.ProfilerAgent = function() { * @enum {number} */ devtools.ProfilerAgent.ProfilerModules = { - PROFILER_MODULE_NONE: 0, - PROFILER_MODULE_CPU: 1, - PROFILER_MODULE_HEAP_STATS: 1 << 1, - PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2, - PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16 + PROFILER_MODULE_NONE: 0, + PROFILER_MODULE_CPU: 1, + PROFILER_MODULE_HEAP_STATS: 1 << 1, + PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2, + PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16 }; /** * Sets up callbacks that deal with profiles processing. */ -devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks = function() { - // A temporary icon indicating that the profile is being processed. - var processingIcon = new WebInspector.SidebarTreeElement( - 'profile-sidebar-tree-item', - WebInspector.UIString('Processing...'), - '', null, false); - var profilesSidebar = WebInspector.panels.profiles.getProfileType( - WebInspector.CPUProfileType.TypeId).treeElement; - - this.profilerProcessor_.setCallbacks( - function onProfileProcessingStarted() { - // Set visually empty string. Subtitle hiding is done via styles - // manipulation which doesn't play well with dynamic append / removal. - processingIcon.subtitle = ' '; - profilesSidebar.appendChild(processingIcon); - }, - function onProfileProcessingStatus(ticksCount) { - processingIcon.subtitle = - WebInspector.UIString('%d ticks processed', ticksCount); - }, - function onProfileProcessingFinished(profile) { - profilesSidebar.removeChild(processingIcon); - profile.typeId = WebInspector.CPUProfileType.TypeId; - InspectorBackend.addFullProfile(profile); - WebInspector.addProfileHeader(profile); - // If no profile is currently shown, show the new one. - var profilesPanel = WebInspector.panels.profiles; - if (!profilesPanel.visibleView) { - profilesPanel.showProfile(profile); +devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks = function() +{ + // A temporary icon indicating that the profile is being processed. + var processingIcon = new WebInspector.SidebarTreeElement( + "profile-sidebar-tree-item", + WebInspector.UIString("Processing..."), + '', null, false); + var profilesSidebar = WebInspector.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).treeElement; + + this.profilerProcessor_.setCallbacks( + function onProfileProcessingStarted() { + // Set visually empty string. Subtitle hiding is done via styles + // manipulation which doesn't play well with dynamic append / removal. + processingIcon.subtitle = " "; + profilesSidebar.appendChild(processingIcon); + }, + function onProfileProcessingStatus(ticksCount) { + processingIcon.subtitle = WebInspector.UIString("%d ticks processed", ticksCount); + }, + function onProfileProcessingFinished(profile) { + profilesSidebar.removeChild(processingIcon); + profile.typeId = WebInspector.CPUProfileType.TypeId; + InspectorBackend.addFullProfile(profile); + WebInspector.addProfileHeader(profile); + // If no profile is currently shown, show the new one. + var profilesPanel = WebInspector.panels.profiles; + if (!profilesPanel.visibleView) { + profilesPanel.showProfile(profile); + } } - } - ); + ); }; /** * Initializes profiling state. */ -devtools.ProfilerAgent.prototype.initializeProfiling = function() { - this.setupProfilerProcessorCallbacks(); - this.forceGetLogLines_ = true; - this.getActiveProfilerModulesInterval_ = setInterval( - function() { RemoteProfilerAgent.getActiveProfilerModules(); }, 1000); +devtools.ProfilerAgent.prototype.initializeProfiling = function() +{ + this.setupProfilerProcessorCallbacks(); + this.forceGetLogLines_ = true; + this.getActiveProfilerModulesInterval_ = setInterval(function() { RemoteProfilerAgent.getActiveProfilerModules(); }, 1000); }; @@ -115,30 +137,31 @@ devtools.ProfilerAgent.prototype.initializeProfiling = function() { * Starts profiling. * @param {number} modules List of modules to enable. */ -devtools.ProfilerAgent.prototype.startProfiling = function(modules) { - var cmd = new devtools.DebugCommand('profile', { - 'modules': modules, - 'command': 'resume'}); - devtools.DebuggerAgent.sendCommand_(cmd); - RemoteToolsAgent.executeVoidJavaScript(); - if (modules & - devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) { - var pos = this.logPosition_; - // Active modules will not change, instead, a snapshot will be logged. - setTimeout(function() { RemoteProfilerAgent.getLogLines(pos); }, 500); - } +devtools.ProfilerAgent.prototype.startProfiling = function(modules) +{ + var cmd = new devtools.DebugCommand("profile", { + "modules": modules, + "command": "resume"}); + devtools.DebuggerAgent.sendCommand_(cmd); + RemoteToolsAgent.executeVoidJavaScript(); + if (modules & devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) { + var pos = this.logPosition_; + // Active modules will not change, instead, a snapshot will be logged. + setTimeout(function() { RemoteProfilerAgent.getLogLines(pos); }, 500); + } }; /** * Stops profiling. */ -devtools.ProfilerAgent.prototype.stopProfiling = function(modules) { - var cmd = new devtools.DebugCommand('profile', { - 'modules': modules, - 'command': 'pause'}); - devtools.DebuggerAgent.sendCommand_(cmd); - RemoteToolsAgent.executeVoidJavaScript(); +devtools.ProfilerAgent.prototype.stopProfiling = function(modules) +{ + var cmd = new devtools.DebugCommand("profile", { + "modules": modules, + "command": "pause"}); + devtools.DebuggerAgent.sendCommand_(cmd); + RemoteToolsAgent.executeVoidJavaScript(); }; @@ -146,20 +169,18 @@ devtools.ProfilerAgent.prototype.stopProfiling = function(modules) { * Handles current profiler status. * @param {number} modules List of active (started) modules. */ -devtools.ProfilerAgent.prototype.didGetActiveProfilerModules_ = function( - modules) { - var profModules = devtools.ProfilerAgent.ProfilerModules; - var profModuleNone = profModules.PROFILER_MODULE_NONE; - if (this.forceGetLogLines_ || - (modules != profModuleNone && - this.activeProfilerModules_ == profModuleNone)) { - this.forceGetLogLines_ = false; - // Start to query log data. - RemoteProfilerAgent.getLogLines(this.logPosition_); - } - this.activeProfilerModules_ = modules; - // Update buttons. - WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU); +devtools.ProfilerAgent.prototype.didGetActiveProfilerModules_ = function(modules) +{ + var profModules = devtools.ProfilerAgent.ProfilerModules; + var profModuleNone = profModules.PROFILER_MODULE_NONE; + if (this.forceGetLogLines_ || (modules !== profModuleNone && this.activeProfilerModules_ === profModuleNone)) { + this.forceGetLogLines_ = false; + // Start to query log data. + RemoteProfilerAgent.getLogLines(this.logPosition_); + } + this.activeProfilerModules_ = modules; + // Update buttons. + WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU); }; @@ -168,14 +189,14 @@ devtools.ProfilerAgent.prototype.didGetActiveProfilerModules_ = function( * @param {number} pos Current position in log. * @param {string} log A portion of profiler log. */ -devtools.ProfilerAgent.prototype.didGetLogLines_ = function(pos, log) { - this.logPosition_ = pos; - if (log.length > 0) { - this.profilerProcessor_.processLogChunk(log); - } else if (this.activeProfilerModules_ == - devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE) { - // No new data and profiling is stopped---suspend log reading. - return; - } - setTimeout(function() { RemoteProfilerAgent.getLogLines(pos); }, 500); +devtools.ProfilerAgent.prototype.didGetLogLines_ = function(pos, log) +{ + this.logPosition_ = pos; + if (log.length > 0) + this.profilerProcessor_.processLogChunk(log); + else if (this.activeProfilerModules_ === devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE) { + // No new data and profiling is stopped---suspend log reading. + return; + } + setTimeout(function() { RemoteProfilerAgent.getLogLines(pos); }, 500); }; diff --git a/webkit/glue/devtools/js/profiler_processor.js b/webkit/glue/devtools/js/profiler_processor.js index d981115..b9b0beb 100644 --- a/webkit/glue/devtools/js/profiler_processor.js +++ b/webkit/glue/devtools/js/profiler_processor.js @@ -1,13 +1,38 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** * @fileoverview Profiler processor is used to process log file produced * by V8 and produce an internal profile representation which is used - * for building profile views in 'Profiles' tab. + * for building profile views in "Profiles" tab. */ -goog.provide('devtools.profiler.Processor'); /** @@ -16,20 +41,19 @@ goog.provide('devtools.profiler.Processor'); * @param {number} samplingRate Number of ms between profiler ticks. * @constructor */ -devtools.profiler.WebKitViewBuilder = function(samplingRate) { - devtools.profiler.ViewBuilder.call(this, samplingRate); +devtools.profiler.WebKitViewBuilder = function(samplingRate) +{ + devtools.profiler.ViewBuilder.call(this, samplingRate); }; -goog.inherits(devtools.profiler.WebKitViewBuilder, - devtools.profiler.ViewBuilder); +devtools.profiler.WebKitViewBuilder.prototype.__proto__ = devtools.profiler.ViewBuilder.prototype; /** * @override */ -devtools.profiler.WebKitViewBuilder.prototype.createViewNode = function( - funcName, totalTime, selfTime, head) { - return new devtools.profiler.WebKitViewNode( - funcName, totalTime, selfTime, head); +devtools.profiler.WebKitViewBuilder.prototype.createViewNode = function(funcName, totalTime, selfTime, head) +{ + return new devtools.profiler.WebKitViewNode(funcName, totalTime, selfTime, head); }; @@ -45,57 +69,52 @@ devtools.profiler.WebKitViewBuilder.prototype.createViewNode = function( * @param {devtools.profiler.ProfileView.Node} head Profile view head. * @constructor */ -devtools.profiler.WebKitViewNode = function( - internalFuncName, totalTime, selfTime, head) { - devtools.profiler.ProfileView.Node.call(this, - internalFuncName, totalTime, selfTime, head); - this.initFuncInfo_(); - this.callUID = internalFuncName; +devtools.profiler.WebKitViewNode = function(internalFuncName, totalTime, selfTime, head) +{ + devtools.profiler.ProfileView.Node.call(this, internalFuncName, totalTime, selfTime, head); + this.initFuncInfo_(); + this.callUID = internalFuncName; }; -goog.inherits(devtools.profiler.WebKitViewNode, - devtools.profiler.ProfileView.Node); +devtools.profiler.WebKitViewNode.prototype.__proto__ = devtools.profiler.ProfileView.Node.prototype; /** * RegEx for stripping V8's prefixes of compiled functions. */ -devtools.profiler.WebKitViewNode.FUNC_NAME_STRIP_RE = - /^(?:LazyCompile|Function|Callback): (.*)$/; +devtools.profiler.WebKitViewNode.FUNC_NAME_STRIP_RE = /^(?:LazyCompile|Function|Callback): (.*)$/; /** * RegEx for extracting script source URL and line number. */ -devtools.profiler.WebKitViewNode.FUNC_NAME_PARSE_RE = - /^((?:get | set )?[^ ]+) (.*):(\d+)( \{\d+\})?$/; +devtools.profiler.WebKitViewNode.FUNC_NAME_PARSE_RE = /^((?:get | set )?[^ ]+) (.*):(\d+)( \{\d+\})?$/; /** - * Inits 'functionName', 'url', and 'lineNumber' fields using 'internalFuncName' + * Inits "functionName", "url", and "lineNumber" fields using "internalFuncName" * field. * @private */ -devtools.profiler.WebKitViewNode.prototype.initFuncInfo_ = function() { - var nodeAlias = devtools.profiler.WebKitViewNode; - this.functionName = this.internalFuncName; - - var strippedName = nodeAlias.FUNC_NAME_STRIP_RE.exec(this.functionName); - if (strippedName) { - this.functionName = strippedName[1]; - } - - var parsedName = nodeAlias.FUNC_NAME_PARSE_RE.exec(this.functionName); - if (parsedName) { - this.functionName = parsedName[1]; - if (parsedName[4]) { - this.functionName += parsedName[4]; +devtools.profiler.WebKitViewNode.prototype.initFuncInfo_ = function() +{ + var nodeAlias = devtools.profiler.WebKitViewNode; + this.functionName = this.internalFuncName; + + var strippedName = nodeAlias.FUNC_NAME_STRIP_RE.exec(this.functionName); + if (strippedName) + this.functionName = strippedName[1]; + + var parsedName = nodeAlias.FUNC_NAME_PARSE_RE.exec(this.functionName); + if (parsedName) { + this.functionName = parsedName[1]; + if (parsedName[4]) + this.functionName += parsedName[4]; + this.url = parsedName[2]; + this.lineNumber = parsedName[3]; + } else { + this.url = ''; + this.lineNumber = 0; } - this.url = parsedName[2]; - this.lineNumber = parsedName[3]; - } else { - this.url = ''; - this.lineNumber = 0; - } }; @@ -103,10 +122,11 @@ devtools.profiler.WebKitViewNode.prototype.initFuncInfo_ = function() { * Ancestor of a profile object that leaves out only JS-related functions. * @constructor */ -devtools.profiler.JsProfile = function() { - devtools.profiler.Profile.call(this); +devtools.profiler.JsProfile = function() +{ + devtools.profiler.Profile.call(this); }; -goog.inherits(devtools.profiler.JsProfile, devtools.profiler.Profile); +devtools.profiler.JsProfile.prototype.__proto__ = devtools.profiler.Profile.prototype; /** @@ -114,17 +134,18 @@ goog.inherits(devtools.profiler.JsProfile, devtools.profiler.Profile); * @type {RegExp} */ devtools.profiler.JsProfile.JS_NON_NATIVE_RE = new RegExp( - '^' + - '(?:Callback:)|' + - '(?:Script: (?!native))|' + - '(?:(?:LazyCompile|Function): [^ ]*(?: (?!native )[^ ]+:\\d+)?$)'); + "^" + + "(?:Callback:)|" + + "(?:Script: (?!native))|" + + "(?:(?:LazyCompile|Function): [^ ]*(?: (?!native )[^ ]+:\\d+)?$)"); /** * @override */ -devtools.profiler.JsProfile.prototype.skipThisFunction = function(name) { - return !devtools.profiler.JsProfile.JS_NON_NATIVE_RE.test(name); +devtools.profiler.JsProfile.prototype.skipThisFunction = function(name) +{ + return !devtools.profiler.JsProfile.JS_NON_NATIVE_RE.test(name); }; @@ -135,137 +156,140 @@ devtools.profiler.JsProfile.prototype.skipThisFunction = function(name) { * that receives a new processed profile. * @constructor */ -devtools.profiler.Processor = function() { - var dispatches = { - 'code-creation': { - parsers: [null, this.createAddressParser('code'), parseInt, null], - processor: this.processCodeCreation_, backrefs: true, - needsProfile: true }, - 'code-move': { parsers: [this.createAddressParser('code'), - this.createAddressParser('code-move-to')], - processor: this.processCodeMove_, backrefs: true, - needsProfile: true }, - 'code-delete': { parsers: [this.createAddressParser('code')], - processor: this.processCodeDelete_, backrefs: true, - needsProfile: true }, - 'function-creation': { parsers: [this.createAddressParser('code'), - this.createAddressParser('function-obj')], - processor: this.processFunctionCreation_, backrefs: true }, - 'function-move': { parsers: [this.createAddressParser('code'), - this.createAddressParser('code-move-to')], - processor: this.processFunctionMove_, backrefs: true }, - 'function-delete': { parsers: [this.createAddressParser('code')], - processor: this.processFunctionDelete_, backrefs: true }, - 'tick': { parsers: [this.createAddressParser('code'), - this.createAddressParser('stack'), parseInt, 'var-args'], - processor: this.processTick_, backrefs: true, needProfile: true }, - 'profiler': { parsers: [null, 'var-args'], - processor: this.processProfiler_, needsProfile: false }, - 'heap-sample-begin': { parsers: [null, null, parseInt], - processor: this.processHeapSampleBegin_ }, - 'heap-sample-stats': { parsers: [null, null, parseInt, parseInt], - processor: this.processHeapSampleStats_ }, - 'heap-sample-item': { parsers: [null, parseInt, parseInt], - processor: this.processHeapSampleItem_ }, - 'heap-js-cons-item': { parsers: [null, parseInt, parseInt], - processor: this.processHeapJsConsItem_ }, - 'heap-js-ret-item': { parsers: [null, 'var-args'], - processor: this.processHeapJsRetItem_ }, - 'heap-sample-end': { parsers: [null, null], - processor: this.processHeapSampleEnd_ }, - // Not used in DevTools Profiler. - 'shared-library': null, - // Obsolete row types. - 'code-allocate': null, - 'begin-code-region': null, - 'end-code-region': null}; - - if (devtools.profiler.Profile.VERSION == 2) { - dispatches['tick'] = { parsers: [this.createAddressParser('code'), - this.createAddressParser('stack'), - this.createAddressParser('func'), parseInt, 'var-args'], - processor: this.processTickV2_, backrefs: true }; - } - - devtools.profiler.LogReader.call(this, dispatches); - - /** - * Callback that is called when a new profile is encountered in the log. - * @type {function()} - */ - this.startedProfileProcessing_ = null; - - /** - * Callback that is called periodically to display processing status. - * @type {function()} - */ - this.profileProcessingStatus_ = null; - - /** - * Callback that is called when a profile has been processed and is ready - * to be shown. - * @type {function(devtools.profiler.ProfileView)} - */ - this.finishedProfileProcessing_ = null; - - /** - * The current profile. - * @type {devtools.profiler.JsProfile} - */ - this.currentProfile_ = null; - - /** - * Builder of profile views. Created during "profiler,begin" event processing. - * @type {devtools.profiler.WebKitViewBuilder} - */ - this.viewBuilder_ = null; - - /** - * Next profile id. - * @type {number} - */ - this.profileId_ = 1; - - /** - * Counter for processed ticks. - * @type {number} - */ - this.ticksCount_ = 0; - - /** - * Interval id for updating processing status. - * @type {number} - */ - this.processingInterval_ = null; - - /** - * The current heap snapshot. - * @type {string} - */ - this.currentHeapSnapshot_ = null; - - /** - * Next heap snapshot id. - * @type {number} - */ - this.heapSnapshotId_ = 1; +devtools.profiler.Processor = function() +{ + var dispatches = { + "code-creation": { + parsers: [null, this.createAddressParser("code"), parseInt, null], + processor: this.processCodeCreation_, backrefs: true, + needsProfile: true }, + "code-move": { parsers: [this.createAddressParser("code"), + this.createAddressParser("code-move-to")], + processor: this.processCodeMove_, backrefs: true, + needsProfile: true }, + "code-delete": { parsers: [this.createAddressParser("code")], + processor: this.processCodeDelete_, backrefs: true, + needsProfile: true }, + "function-creation": { parsers: [this.createAddressParser("code"), + this.createAddressParser("function-obj")], + processor: this.processFunctionCreation_, backrefs: true }, + "function-move": { parsers: [this.createAddressParser("code"), + this.createAddressParser("code-move-to")], + processor: this.processFunctionMove_, backrefs: true }, + "function-delete": { parsers: [this.createAddressParser("code")], + processor: this.processFunctionDelete_, backrefs: true }, + "tick": { parsers: [this.createAddressParser("code"), + this.createAddressParser("stack"), parseInt, "var-args"], + processor: this.processTick_, backrefs: true, needProfile: true }, + "profiler": { parsers: [null, "var-args"], + processor: this.processProfiler_, needsProfile: false }, + "heap-sample-begin": { parsers: [null, null, parseInt], + processor: this.processHeapSampleBegin_ }, + "heap-sample-stats": { parsers: [null, null, parseInt, parseInt], + processor: this.processHeapSampleStats_ }, + "heap-sample-item": { parsers: [null, parseInt, parseInt], + processor: this.processHeapSampleItem_ }, + "heap-js-cons-item": { parsers: [null, parseInt, parseInt], + processor: this.processHeapJsConsItem_ }, + "heap-js-ret-item": { parsers: [null, "var-args"], + processor: this.processHeapJsRetItem_ }, + "heap-sample-end": { parsers: [null, null], + processor: this.processHeapSampleEnd_ }, + // Not used in DevTools Profiler. + "shared-library": null, + // Obsolete row types. + "code-allocate": null, + "begin-code-region": null, + "end-code-region": null}; + + if (devtools.profiler.Profile.VERSION === 2) { + dispatches["tick"] = { parsers: [this.createAddressParser("code"), + this.createAddressParser("stack"), + this.createAddressParser("func"), parseInt, "var-args"], + processor: this.processTickV2_, backrefs: true }; + } + + devtools.profiler.LogReader.call(this, dispatches); + + /** + * Callback that is called when a new profile is encountered in the log. + * @type {function()} + */ + this.startedProfileProcessing_ = null; + + /** + * Callback that is called periodically to display processing status. + * @type {function()} + */ + this.profileProcessingStatus_ = null; + + /** + * Callback that is called when a profile has been processed and is ready + * to be shown. + * @type {function(devtools.profiler.ProfileView)} + */ + this.finishedProfileProcessing_ = null; + + /** + * The current profile. + * @type {devtools.profiler.JsProfile} + */ + this.currentProfile_ = null; + + /** + * Builder of profile views. Created during "profiler,begin" event processing. + * @type {devtools.profiler.WebKitViewBuilder} + */ + this.viewBuilder_ = null; + + /** + * Next profile id. + * @type {number} + */ + this.profileId_ = 1; + + /** + * Counter for processed ticks. + * @type {number} + */ + this.ticksCount_ = 0; + + /** + * Interval id for updating processing status. + * @type {number} + */ + this.processingInterval_ = null; + + /** + * The current heap snapshot. + * @type {string} + */ + this.currentHeapSnapshot_ = null; + + /** + * Next heap snapshot id. + * @type {number} + */ + this.heapSnapshotId_ = 1; }; -goog.inherits(devtools.profiler.Processor, devtools.profiler.LogReader); +devtools.profiler.Processor.prototype.__proto__ = devtools.profiler.LogReader.prototype; /** * @override */ -devtools.profiler.Processor.prototype.printError = function(str) { - debugPrint(str); +devtools.profiler.Processor.prototype.printError = function(str) +{ + debugPrint(str); }; /** * @override */ -devtools.profiler.Processor.prototype.skipDispatch = function(dispatch) { - return dispatch.needsProfile && this.currentProfile_ == null; +devtools.profiler.Processor.prototype.skipDispatch = function(dispatch) +{ + return dispatch.needsProfile && this.currentProfile_ === null; }; @@ -276,11 +300,11 @@ devtools.profiler.Processor.prototype.skipDispatch = function(dispatch) { * @param {function(devtools.profiler.ProfileView)} finished Finished * processing callback. */ -devtools.profiler.Processor.prototype.setCallbacks = function( - started, processing, finished) { - this.startedProfileProcessing_ = started; - this.profileProcessingStatus_ = processing; - this.finishedProfileProcessing_ = finished; +devtools.profiler.Processor.prototype.setCallbacks = function(started, processing, finished) +{ + this.startedProfileProcessing_ = started; + this.profileProcessingStatus_ = processing; + this.finishedProfileProcessing_ = finished; }; @@ -298,225 +322,221 @@ devtools.profiler.Processor.PROGRAM_ENTRY = 0xffff; /** * @type {string} */ -devtools.profiler.Processor.PROGRAM_ENTRY_STR = '0xffff'; +devtools.profiler.Processor.PROGRAM_ENTRY_STR = "0xffff"; /** * Sets new profile callback. * @param {function(devtools.profiler.ProfileView)} callback Callback function. */ -devtools.profiler.Processor.prototype.setNewProfileCallback = function( - callback) { - this.newProfileCallback_ = callback; +devtools.profiler.Processor.prototype.setNewProfileCallback = function(callback) +{ + this.newProfileCallback_ = callback; }; -devtools.profiler.Processor.prototype.processProfiler_ = function( - state, params) { - switch (state) { - case 'resume': - if (this.currentProfile_ == null) { - this.currentProfile_ = new devtools.profiler.JsProfile(); - // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY - this.currentProfile_.addCode( - 'Function', '(program)', - devtools.profiler.Processor.PROGRAM_ENTRY, 1); - if (this.startedProfileProcessing_) { - this.startedProfileProcessing_(); - } - this.ticksCount_ = 0; - var self = this; - if (this.profileProcessingStatus_) { - this.processingInterval_ = window.setInterval( - function() { self.profileProcessingStatus_(self.ticksCount_); }, - 1000); - } - } - break; - case 'pause': - if (this.currentProfile_ != null) { - window.clearInterval(this.processingInterval_); - this.processingInterval_ = null; - if (this.finishedProfileProcessing_) { - this.finishedProfileProcessing_(this.createProfileForView()); - } - this.currentProfile_ = null; - } - break; - case 'begin': - var samplingRate = NaN; - if (params.length > 0) { - samplingRate = parseInt(params[0]); - } - if (isNaN(samplingRate)) { - samplingRate = 1; - } - this.viewBuilder_ = new devtools.profiler.WebKitViewBuilder(samplingRate); - break; - // These events are valid but aren't used. - case 'compression': - case 'end': break; - default: - throw new Error('unknown profiler state: ' + state); - } +devtools.profiler.Processor.prototype.processProfiler_ = function(state, params) +{ + switch (state) { + case "resume": + if (this.currentProfile_ === null) { + this.currentProfile_ = new devtools.profiler.JsProfile(); + // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY + this.currentProfile_.addCode("Function", "(program)", devtools.profiler.Processor.PROGRAM_ENTRY, 1); + if (this.startedProfileProcessing_) + this.startedProfileProcessing_(); + this.ticksCount_ = 0; + var self = this; + if (this.profileProcessingStatus_) { + this.processingInterval_ = window.setInterval( + function() { self.profileProcessingStatus_(self.ticksCount_); }, + 1000); + } + } + break; + case "pause": + if (this.currentProfile_ !== null) { + window.clearInterval(this.processingInterval_); + this.processingInterval_ = null; + if (this.finishedProfileProcessing_) + this.finishedProfileProcessing_(this.createProfileForView()); + this.currentProfile_ = null; + } + break; + case "begin": + var samplingRate = NaN; + if (params.length > 0) + samplingRate = parseInt(params[0]); + if (isNaN(samplingRate)) + samplingRate = 1; + this.viewBuilder_ = new devtools.profiler.WebKitViewBuilder(samplingRate); + break; + // These events are valid but aren't used. + case "compression": + case "end": break; + default: + throw new Error("unknown profiler state: " + state); + } }; -devtools.profiler.Processor.prototype.processCodeCreation_ = function( - type, start, size, name) { - this.currentProfile_.addCode(this.expandAlias(type), name, start, size); +devtools.profiler.Processor.prototype.processCodeCreation_ = function(type, start, size, name) +{ + this.currentProfile_.addCode(this.expandAlias(type), name, start, size); }; -devtools.profiler.Processor.prototype.processCodeMove_ = function(from, to) { - this.currentProfile_.moveCode(from, to); +devtools.profiler.Processor.prototype.processCodeMove_ = function(from, to) +{ + this.currentProfile_.moveCode(from, to); }; -devtools.profiler.Processor.prototype.processCodeDelete_ = function(start) { - this.currentProfile_.deleteCode(start); +devtools.profiler.Processor.prototype.processCodeDelete_ = function(start) +{ + this.currentProfile_.deleteCode(start); }; -devtools.profiler.Processor.prototype.processFunctionCreation_ = function( - functionAddr, codeAddr) { - this.currentProfile_.addCodeAlias(functionAddr, codeAddr); +devtools.profiler.Processor.prototype.processFunctionCreation_ = function(functionAddr, codeAddr) +{ + this.currentProfile_.addCodeAlias(functionAddr, codeAddr); }; -devtools.profiler.Processor.prototype.processFunctionMove_ = - function(from, to) { - this.currentProfile_.safeMoveDynamicCode(from, to); +devtools.profiler.Processor.prototype.processFunctionMove_ = function(from, to) +{ + this.currentProfile_.safeMoveDynamicCode(from, to); }; -devtools.profiler.Processor.prototype.processFunctionDelete_ = function(start) { - this.currentProfile_.safeDeleteDynamicCode(start); +devtools.profiler.Processor.prototype.processFunctionDelete_ = function(start) +{ + this.currentProfile_.safeDeleteDynamicCode(start); }; // TODO(mnaganov): Remove after next V8 roll. -devtools.profiler.Processor.prototype.processTick_ = function( - pc, sp, vmState, stack) { - // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY - stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR); - this.currentProfile_.recordTick(this.processStack(pc, stack)); - this.ticksCount_++; +devtools.profiler.Processor.prototype.processTick_ = function(pc, sp, vmState, stack) +{ + // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY + stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR); + this.currentProfile_.recordTick(this.processStack(pc, stack)); + this.ticksCount_++; }; -devtools.profiler.Processor.prototype.processTickV2_ = function( - pc, sp, func, vmState, stack) { - // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY - stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR); +devtools.profiler.Processor.prototype.processTickV2_ = function(pc, sp, func, vmState, stack) +{ + // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY + stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR); - if (func) { - var funcEntry = this.currentProfile_.findEntry(func); - if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) { - func = 0; - } else { - var currEntry = this.currentProfile_.findEntry(pc); - if (!currEntry || !currEntry.isJSFunction || currEntry.isJSFunction()) { - func = 0; - } + if (func) { + var funcEntry = this.currentProfile_.findEntry(func); + if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) + func = 0; + else { + var currEntry = this.currentProfile_.findEntry(pc); + if (!currEntry || !currEntry.isJSFunction || currEntry.isJSFunction()) { + func = 0; + } + } } - } - this.currentProfile_.recordTick(this.processStack(pc, func, stack)); - this.ticksCount_++; + this.currentProfile_.recordTick(this.processStack(pc, func, stack)); + this.ticksCount_++; }; -devtools.profiler.Processor.prototype.processHeapSampleBegin_ = function( - space, state, ticks) { - if (space != 'Heap') return; - this.currentHeapSnapshot_ = { - number: this.heapSnapshotId_++, - entries: {}, - clusters: {}, - lowlevels: {}, - ticks: ticks - }; +devtools.profiler.Processor.prototype.processHeapSampleBegin_ = function(space, state, ticks) +{ + if (space !== "Heap") return; + this.currentHeapSnapshot_ = { + number: this.heapSnapshotId_++, + entries: {}, + clusters: {}, + lowlevels: {}, + ticks: ticks + }; }; -devtools.profiler.Processor.prototype.processHeapSampleStats_ = function( - space, state, capacity, used) { - if (space != 'Heap') return; +devtools.profiler.Processor.prototype.processHeapSampleStats_ = function(space, state, capacity, used) +{ + if (space !== "Heap") return; }; -devtools.profiler.Processor.prototype.processHeapSampleItem_ = function( - item, number, size) { - if (!this.currentHeapSnapshot_) return; - this.currentHeapSnapshot_.lowlevels[item] = { - type: item, count: number, size: size - }; +devtools.profiler.Processor.prototype.processHeapSampleItem_ = function(item, number, size) +{ + if (!this.currentHeapSnapshot_) return; + this.currentHeapSnapshot_.lowlevels[item] = { + type: item, count: number, size: size + }; }; -devtools.profiler.Processor.prototype.processHeapJsConsItem_ = function( - item, number, size) { - if (!this.currentHeapSnapshot_) return; - this.currentHeapSnapshot_.entries[item] = { - cons: item, count: number, size: size, retainers: {} - }; +devtools.profiler.Processor.prototype.processHeapJsConsItem_ = function(item, number, size) +{ + if (!this.currentHeapSnapshot_) return; + this.currentHeapSnapshot_.entries[item] = { + cons: item, count: number, size: size, retainers: {} + }; }; -devtools.profiler.Processor.prototype.processHeapJsRetItem_ = function( - item, retainersArray) { - if (!this.currentHeapSnapshot_) return; - var rawRetainers = {}; - for (var i = 0, n = retainersArray.length; i < n; ++i) { - var entry = retainersArray[i].split(';'); - rawRetainers[entry[0]] = parseInt(entry[1], 10); - } - - function mergeRetainers(entry) { - for (var rawRetainer in rawRetainers) { - var consName = rawRetainer.indexOf(':') != -1 ? - rawRetainer.split(':')[0] : rawRetainer; - if (!(consName in entry.retainers)) - entry.retainers[consName] = { cons: consName, count: 0, clusters: {} }; - var retainer = entry.retainers[consName]; - retainer.count += rawRetainers[rawRetainer]; - if (consName != rawRetainer) - retainer.clusters[rawRetainer] = true; +devtools.profiler.Processor.prototype.processHeapJsRetItem_ = function(item, retainersArray) +{ + if (!this.currentHeapSnapshot_) return; + var rawRetainers = {}; + for (var i = 0, n = retainersArray.length; i < n; ++i) { + var entry = retainersArray[i].split(";"); + rawRetainers[entry[0]] = parseInt(entry[1], 10); } - } - - if (item.indexOf(':') != -1) { - // Array, Function, or Object instances cluster case. - if (!(item in this.currentHeapSnapshot_.clusters)) { - this.currentHeapSnapshot_.clusters[item] = { - cons: item, retainers: {} - }; + + function mergeRetainers(entry) { + for (var rawRetainer in rawRetainers) { + var consName = rawRetainer.indexOf(":") !== -1 ? rawRetainer.split(":")[0] : rawRetainer; + if (!(consName in entry.retainers)) + entry.retainers[consName] = { cons: consName, count: 0, clusters: {} }; + var retainer = entry.retainers[consName]; + retainer.count += rawRetainers[rawRetainer]; + if (consName !== rawRetainer) + retainer.clusters[rawRetainer] = true; + } + } + + if (item.indexOf(":") !== -1) { + // Array, Function, or Object instances cluster case. + if (!(item in this.currentHeapSnapshot_.clusters)) { + this.currentHeapSnapshot_.clusters[item] = { + cons: item, retainers: {} + }; + } + mergeRetainers(this.currentHeapSnapshot_.clusters[item]); + item = item.split(":")[0]; } - mergeRetainers(this.currentHeapSnapshot_.clusters[item]); - item = item.split(':')[0]; - } - mergeRetainers(this.currentHeapSnapshot_.entries[item]); + mergeRetainers(this.currentHeapSnapshot_.entries[item]); }; -devtools.profiler.Processor.prototype.processHeapSampleEnd_ = function( - space, state) { - if (space != 'Heap') return; - var snapshot = this.currentHeapSnapshot_; - this.currentHeapSnapshot_ = null; - WebInspector.panels.profiles.addSnapshot(snapshot); +devtools.profiler.Processor.prototype.processHeapSampleEnd_ = function(space, state) +{ + if (space !== "Heap") return; + var snapshot = this.currentHeapSnapshot_; + this.currentHeapSnapshot_ = null; + WebInspector.panels.profiles.addSnapshot(snapshot); }; /** * Creates a profile for further displaying in ProfileView. */ -devtools.profiler.Processor.prototype.createProfileForView = function() { - var profile = this.viewBuilder_.buildView( - this.currentProfile_.getTopDownProfile()); - profile.uid = this.profileId_++; - profile.title = UserInitiatedProfileName + '.' + profile.uid; - return profile; +devtools.profiler.Processor.prototype.createProfileForView = function() +{ + var profile = this.viewBuilder_.buildView(this.currentProfile_.getTopDownProfile()); + profile.uid = this.profileId_++; + profile.title = UserInitiatedProfileName + "." + profile.uid; + return profile; }; diff --git a/webkit/glue/devtools/js/tests.js b/webkit/glue/devtools/js/tests.js index 1b7e01b..ba832c9 100644 --- a/webkit/glue/devtools/js/tests.js +++ b/webkit/glue/devtools/js/tests.js @@ -1,6 +1,32 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /** @@ -18,9 +44,10 @@ var ___interactiveUiTestsMode = true; * Test suite for interactive UI tests. * @constructor */ -TestSuite = function() { - this.controlTaken_ = false; - this.timerId_ = -1; +TestSuite = function() +{ + this.controlTaken_ = false; + this.timerId_ = -1; }; @@ -28,29 +55,29 @@ TestSuite = function() { * Reports test failure. * @param {string} message Failure description. */ -TestSuite.prototype.fail = function(message) { - if (this.controlTaken_) { - this.reportFailure_(message); - } else { - throw message; - } +TestSuite.prototype.fail = function(message) +{ + if (this.controlTaken_) + this.reportFailure_(message); + else + throw message; }; /** - * Equals assertion tests that expected == actual. + * Equals assertion tests that expected === actual. * @param {Object} expected Expected object. * @param {Object} actual Actual object. * @param {string} opt_message User message to print if the test fails. */ -TestSuite.prototype.assertEquals = function(expected, actual, opt_message) { - if (expected != actual) { - var message = 'Expected: "' + expected + '", but was "' + actual + '"'; - if (opt_message) { - message = opt_message + '(' + message + ')'; +TestSuite.prototype.assertEquals = function(expected, actual, opt_message) +{ + if (expected !== actual) { + var message = "Expected: '" + expected + "', but was '" + actual + "'"; + if (opt_message) + message = opt_message + "(" + message + ")"; + this.fail(message); } - this.fail(message); - } }; @@ -59,8 +86,9 @@ TestSuite.prototype.assertEquals = function(expected, actual, opt_message) { * @param {Object} value Actual object. * @param {string} opt_message User message to print if the test fails. */ -TestSuite.prototype.assertTrue = function(value, opt_message) { - this.assertEquals(true, !!value, opt_message); +TestSuite.prototype.assertTrue = function(value, opt_message) +{ + this.assertEquals(true, !!value, opt_message); }; @@ -69,83 +97,87 @@ TestSuite.prototype.assertTrue = function(value, opt_message) { * @param {string} string Outer. * @param {string} substring Inner. */ -TestSuite.prototype.assertContains = function(string, substring) { - if (string.indexOf(substring) == -1) { - this.fail('Expected to: "' + string + '" to contain "' + substring + '"'); - } +TestSuite.prototype.assertContains = function(string, substring) +{ + if (string.indexOf(substring) === -1) + this.fail("Expected to: '" + string + "' to contain '" + substring + "'"); }; /** * Takes control over execution. */ -TestSuite.prototype.takeControl = function() { - this.controlTaken_ = true; - // Set up guard timer. - var self = this; - this.timerId_ = setTimeout(function() { - self.reportFailure_('Timeout exceeded: 20 sec'); - }, 20000); +TestSuite.prototype.takeControl = function() +{ + this.controlTaken_ = true; + // Set up guard timer. + var self = this; + this.timerId_ = setTimeout(function() { + self.reportFailure_("Timeout exceeded: 20 sec"); + }, 20000); }; /** * Releases control over execution. */ -TestSuite.prototype.releaseControl = function() { - if (this.timerId_ != -1) { - clearTimeout(this.timerId_); - this.timerId_ = -1; - } - this.reportOk_(); +TestSuite.prototype.releaseControl = function() +{ + if (this.timerId_ !== -1) { + clearTimeout(this.timerId_); + this.timerId_ = -1; + } + this.reportOk_(); }; /** * Async tests use this one to report that they are completed. */ -TestSuite.prototype.reportOk_ = function() { - window.domAutomationController.send('[OK]'); +TestSuite.prototype.reportOk_ = function() +{ + window.domAutomationController.send("[OK]"); }; /** * Async tests use this one to report failures. */ -TestSuite.prototype.reportFailure_ = function(error) { - if (this.timerId_ != -1) { - clearTimeout(this.timerId_); - this.timerId_ = -1; - } - window.domAutomationController.send('[FAILED] ' + error); +TestSuite.prototype.reportFailure_ = function(error) +{ + if (this.timerId_ !== -1) { + clearTimeout(this.timerId_); + this.timerId_ = -1; + } + window.domAutomationController.send("[FAILED] " + error); }; /** - * Runs all global functions starting with 'test' as unit tests. + * Runs all global functions starting with "test" as unit tests. */ -TestSuite.prototype.runTest = function(testName) { - try { - this[testName](); - if (!this.controlTaken_) { - this.reportOk_(); +TestSuite.prototype.runTest = function(testName) +{ + try { + this[testName](); + if (!this.controlTaken_) + this.reportOk_(); + } catch (e) { + this.reportFailure_(e); } - } catch (e) { - this.reportFailure_(e); - } }; /** * @param {string} panelName Name of the panel to show. */ -TestSuite.prototype.showPanel = function(panelName) { - // Open Scripts panel. - var toolbar = document.getElementById('toolbar'); - var button = toolbar.getElementsByClassName(panelName)[0]; - button.click(); - this.assertEquals(WebInspector.panels[panelName], - WebInspector.currentPanel); +TestSuite.prototype.showPanel = function(panelName) +{ + // Open Scripts panel. + var toolbar = document.getElementById("toolbar"); + var button = toolbar.getElementsByClassName(panelName)[0]; + button.click(); + this.assertEquals(WebInspector.panels[panelName], WebInspector.currentPanel); }; @@ -158,29 +190,27 @@ TestSuite.prototype.showPanel = function(panelName) { * @param {boolean} opt_sticky Whether restore original method after first run * or not. */ -TestSuite.prototype.addSniffer = function(receiver, methodName, override, - opt_sticky) { - var orig = receiver[methodName]; - if (typeof orig != 'function') { - this.fail('Cannot find method to override: ' + methodName); - } - var test = this; - receiver[methodName] = function(var_args) { - try { - var result = orig.apply(this, arguments); - } finally { - if (!opt_sticky) { - receiver[methodName] = orig; - } - } - // In case of exception the override won't be called. - try { - override.apply(this, arguments); - } catch (e) { - test.fail('Exception in overriden method "' + methodName + '": ' + e); - } - return result; - }; +TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_sticky) +{ + var orig = receiver[methodName]; + if (typeof orig !== "function") + this.fail("Cannot find method to override: " + methodName); + var test = this; + receiver[methodName] = function(var_args) { + try { + var result = orig.apply(this, arguments); + } finally { + if (!opt_sticky) + receiver[methodName] = orig; + } + // In case of exception the override won't be called. + try { + override.apply(this, arguments); + } catch (e) { + test.fail("Exception in overriden method '" + methodName + "': " + e); + } + return result; + }; }; @@ -190,19 +220,20 @@ TestSuite.prototype.addSniffer = function(receiver, methodName, override, /** * Tests that the real injected host is present in the context. */ -TestSuite.prototype.testHostIsPresent = function() { - this.assertTrue(typeof InspectorFrontendHost == 'object' && - !InspectorFrontendHost.isStub); +TestSuite.prototype.testHostIsPresent = function() +{ + this.assertTrue(typeof InspectorFrontendHost === "object" && !InspectorFrontendHost.isStub); }; /** - * Tests elements tree has an 'HTML' root. + * Tests elements tree has an "HTML" root. */ -TestSuite.prototype.testElementsTreeRoot = function() { - var doc = WebInspector.domAgent.document; - this.assertEquals('HTML', doc.documentElement.nodeName); - this.assertTrue(doc.documentElement.hasChildNodes()); +TestSuite.prototype.testElementsTreeRoot = function() +{ + var doc = WebInspector.domAgent.document; + this.assertEquals("HTML", doc.documentElement.nodeName); + this.assertTrue(doc.documentElement.hasChildNodes()); }; @@ -210,244 +241,240 @@ TestSuite.prototype.testElementsTreeRoot = function() { * Tests that main resource is present in the system and that it is * the only resource. */ -TestSuite.prototype.testMainResource = function() { - var tokens = []; - var resources = WebInspector.resources; - for (var id in resources) { - tokens.push(resources[id].lastPathComponent); - } - this.assertEquals('simple_page.html', tokens.join(',')); +TestSuite.prototype.testMainResource = function() +{ + var tokens = []; + var resources = WebInspector.resources; + for (var id in resources) + tokens.push(resources[id].lastPathComponent); + this.assertEquals("simple_page.html", tokens.join(",")); }; /** * Tests that resources tab is enabled when corresponding item is selected. */ -TestSuite.prototype.testEnableResourcesTab = function() { - this.showPanel('resources'); +TestSuite.prototype.testEnableResourcesTab = function() +{ + this.showPanel("resources"); - var test = this; - this.addSniffer(WebInspector, 'updateResource', - function(identifier, payload) { - test.assertEquals('simple_page.html', payload.lastPathComponent); - WebInspector.panels.resources.refresh(); - WebInspector.panels.resources.revealAndSelectItem( - WebInspector.resources[identifier]); + var test = this; + this.addSniffer(WebInspector, "updateResource", + function(identifier, payload) { + test.assertEquals("simple_page.html", payload.lastPathComponent); + WebInspector.panels.resources.refresh(); + WebInspector.panels.resources.revealAndSelectItem(WebInspector.resources[identifier]); - test.releaseControl(); - }); + test.releaseControl(); + }); - // Following call should lead to reload that we capture in the - // addResource override. - WebInspector.panels.resources._enableResourceTracking(); + // Following call should lead to reload that we capture in the + // addResource override. + WebInspector.panels.resources._enableResourceTracking(); - // We now have some time to report results to controller. - this.takeControl(); + // We now have some time to report results to controller. + this.takeControl(); }; /** * Tests that correct content length is reported for resources. */ -TestSuite.prototype.testResourceContentLength = function() { - this.showPanel('resources'); - var test = this; - - var png = false; - var html = false; - this.addSniffer(WebInspector, 'updateResource', - function(identifier, payload) { - if (!payload.didLengthChange) - return; - var resource = WebInspector.resources[identifier]; - if (!resource || !resource.url) - return; - if (resource.url.search('image.html$') != -1) { - var expectedLength = 87; - test.assertTrue( - resource.contentLength <= expectedLength, - 'image.html content length is greater thatn expected.'); - if (expectedLength == resource.contentLength) { - html = true; - } - } else if (resource.url.search('image.png') != -1) { - var expectedLength = 257796; - test.assertTrue( - resource.contentLength <= expectedLength, - 'image.png content length is greater than expected.'); - if (expectedLength == resource.contentLength) { - png = true; - } - } - if (html && png) { - // Wait 1 second before releasing control to check that the content - // lengths are not updated anymore. - setTimeout(function() { - test.releaseControl(); - }, 1000); - } - }, true); - - // Make sure resource tracking is on. - WebInspector.panels.resources._enableResourceTracking(); - // Reload inspected page to update all resources. - test.evaluateInConsole_( - 'window.location.reload(true);', - function(resultText) { - test.assertEquals('undefined', resultText, - 'Unexpected result of reload().'); - }); - - // We now have some time to report results to controller. - this.takeControl(); +TestSuite.prototype.testResourceContentLength = function() +{ + this.showPanel("resources"); + var test = this; + + var png = false; + var html = false; + this.addSniffer(WebInspector, "updateResource", + function(identifier, payload) { + if (!payload.didLengthChange) + return; + var resource = WebInspector.resources[identifier]; + if (!resource || !resource.url) + return; + if (resource.url.search("image.html$") !== -1) { + var expectedLength = 87; + test.assertTrue( + resource.contentLength <= expectedLength, + "image.html content length is greater thatn expected."); + if (expectedLength === resource.contentLength) + html = true; + } else if (resource.url.search("image.png") !== -1) { + var expectedLength = 257796; + test.assertTrue( + resource.contentLength <= expectedLength, + "image.png content length is greater than expected."); + if (expectedLength === resource.contentLength) + png = true; + } + if (html && png) { + // Wait 1 second before releasing control to check that the content + // lengths are not updated anymore. + setTimeout(function() { + test.releaseControl(); + }, 1000); + } + }, true); + + // Make sure resource tracking is on. + WebInspector.panels.resources._enableResourceTracking(); + // Reload inspected page to update all resources. + test.evaluateInConsole_( + "window.location.reload(true);", + function(resultText) { + test.assertEquals("undefined", resultText, "Unexpected result of reload()."); + }); + + // We now have some time to report results to controller. + this.takeControl(); }; /** * Tests resource headers. */ -TestSuite.prototype.testResourceHeaders = function() { - this.showPanel('resources'); - - var test = this; - - var responseOk = false; - var timingOk = false; - - this.addSniffer(WebInspector, 'updateResource', - function(identifier, payload) { - var resource = this.resources[identifier]; - if (!resource || resource.mainResource) { - // We are only interested in secondary resources in this test. - return; - } - - var requestHeaders = JSON.stringify(resource.requestHeaders); - test.assertContains(requestHeaders, 'Accept'); - - if (payload.didResponseChange) { - var responseHeaders = JSON.stringify(resource.responseHeaders); - test.assertContains(responseHeaders, 'Content-type'); - test.assertContains(responseHeaders, 'Content-Length'); - test.assertTrue(typeof resource.responseReceivedTime != 'undefined'); - responseOk = true; - } - - if (payload.didTimingChange) { - test.assertTrue(typeof resource.startTime != 'undefined'); - timingOk = true; - } - - if (payload.didCompletionChange) { - test.assertTrue(responseOk); - test.assertTrue(timingOk); - test.assertTrue(typeof resource.endTime != 'undefined'); - test.releaseControl(); - } - }, true); +TestSuite.prototype.testResourceHeaders = function() +{ + this.showPanel("resources"); + + var test = this; + + var responseOk = false; + var timingOk = false; + + this.addSniffer(WebInspector, "updateResource", + function(identifier, payload) { + var resource = this.resources[identifier]; + if (!resource || resource.mainResource) { + // We are only interested in secondary resources in this test. + return; + } + + var requestHeaders = JSON.stringify(resource.requestHeaders); + test.assertContains(requestHeaders, "Accept"); + + if (payload.didResponseChange) { + var responseHeaders = JSON.stringify(resource.responseHeaders); + test.assertContains(responseHeaders, "Content-type"); + test.assertContains(responseHeaders, "Content-Length"); + test.assertTrue(typeof resource.responseReceivedTime !== "undefined"); + responseOk = true; + } + + if (payload.didTimingChange) { + test.assertTrue(typeof resource.startTime !== "undefined"); + timingOk = true; + } + + if (payload.didCompletionChange) { + test.assertTrue(responseOk); + test.assertTrue(timingOk); + test.assertTrue(typeof resource.endTime !== "undefined"); + test.releaseControl(); + } + }, true); - WebInspector.panels.resources._enableResourceTracking(); - this.takeControl(); + WebInspector.panels.resources._enableResourceTracking(); + this.takeControl(); }; /** * Tests the mime type of a cached (HTTP 304) resource. */ -TestSuite.prototype.testCachedResourceMimeType = function() { - this.showPanel('resources'); - - var test = this; - var hasReloaded = false; - - this.addSniffer(WebInspector, 'updateResource', - function(identifier, payload) { - var resource = this.resources[identifier]; - if (!resource || resource.mainResource) { - // We are only interested in secondary resources in this test. - return; - } - - if (payload.didResponseChange) { - // Test server uses a default mime type for JavaScript files. - test.assertEquals('text/html', payload.mimeType); - if (!hasReloaded) { - hasReloaded = true; - // Reload inspected page to update all resources. - test.evaluateInConsole_( - 'window.location.reload(true);', - function() {}); - } else { - test.releaseControl(); - } - } +TestSuite.prototype.testCachedResourceMimeType = function() +{ + this.showPanel("resources"); + + var test = this; + var hasReloaded = false; + + this.addSniffer(WebInspector, "updateResource", + function(identifier, payload) { + var resource = this.resources[identifier]; + if (!resource || resource.mainResource) { + // We are only interested in secondary resources in this test. + return; + } + + if (payload.didResponseChange) { + // Test server uses a default mime type for JavaScript files. + test.assertEquals("text/html", payload.mimeType); + if (!hasReloaded) { + hasReloaded = true; + // Reload inspected page to update all resources. + test.evaluateInConsole_("window.location.reload(true);", function() {}); + } else + test.releaseControl(); + } - }, true); + }, true); - WebInspector.panels.resources._enableResourceTracking(); - this.takeControl(); + WebInspector.panels.resources._enableResourceTracking(); + this.takeControl(); }; /** * Tests that profiler works. */ -TestSuite.prototype.testProfilerTab = function() { - this.showPanel('profiles'); - - var test = this; - this.addSniffer(WebInspector.panels.profiles, 'addProfileHeader', - function(typeOrProfile, profile) { - if (!profile) { - profile = typeOrProfile; - } - var panel = WebInspector.panels.profiles; - panel.showProfile(profile); - var node = panel.visibleView.profileDataGridTree.children[0]; - // Iterate over displayed functions and search for a function - // that is called 'fib' or 'eternal_fib'. If found, it will mean - // that we actually have profiled page's code. - while (node) { - if (node.functionName.indexOf('fib') != -1) { - test.releaseControl(); - } - node = node.traverseNextNode(true, null, true); - } - - test.fail(); - }); - var ticksCount = 0; - var tickRecord = '\nt,'; - this.addSniffer(RemoteProfilerAgent, 'didGetLogLines', - function(posIgnored, log) { - var pos = 0; - while ((pos = log.indexOf(tickRecord, pos)) != -1) { - pos += tickRecord.length; - ticksCount++; - } - if (ticksCount > 100) { - InspectorBackend.stopProfiling(); - } - }, true); +TestSuite.prototype.testProfilerTab = function() +{ + this.showPanel("profiles"); + + var test = this; + this.addSniffer(WebInspector.panels.profiles, "addProfileHeader", + function(typeOrProfile, profile) { + if (!profile) + profile = typeOrProfile; + var panel = WebInspector.panels.profiles; + panel.showProfile(profile); + var node = panel.visibleView.profileDataGridTree.children[0]; + // Iterate over displayed functions and search for a function + // that is called "fib" or "eternal_fib". If found, it will mean + // that we actually have profiled page's code. + while (node) { + if (node.functionName.indexOf("fib") !== -1) + test.releaseControl(); + node = node.traverseNextNode(true, null, true); + } - InspectorBackend.startProfiling(); - this.takeControl(); + test.fail(); + }); + var ticksCount = 0; + var tickRecord = "\nt,"; + this.addSniffer(RemoteProfilerAgent, "didGetLogLines", + function(posIgnored, log) { + var pos = 0; + while ((pos = log.indexOf(tickRecord, pos)) !== -1) { + pos += tickRecord.length; + ticksCount++; + } + if (ticksCount > 100) + InspectorBackend.stopProfiling(); + }, true); + + InspectorBackend.startProfiling(); + this.takeControl(); }; /** * Tests that scripts tab can be open and populated with inspected scripts. */ -TestSuite.prototype.testShowScriptsTab = function() { - this.showPanel('scripts'); - var test = this; - // There should be at least main page script. - this._waitUntilScriptsAreParsed(['debugger_test_page.html$'], - function() { - test.releaseControl(); - }); - // Wait until all scripts are added to the debugger. - this.takeControl(); +TestSuite.prototype.testShowScriptsTab = function() +{ + this.showPanel("scripts"); + var test = this; + // There should be at least main page script. + this._waitUntilScriptsAreParsed(["debugger_test_page.html$"], + function() { + test.releaseControl(); + }); + // Wait until all scripts are added to the debugger. + this.takeControl(); }; @@ -456,275 +483,261 @@ TestSuite.prototype.testShowScriptsTab = function() { * hadn't been shown by the moment inspected paged refreshed. * @see http://crbug.com/26312 */ -TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = - function() { - var test = this; - this.assertEquals(WebInspector.panels.elements, - WebInspector.currentPanel, 'Elements panel should be current one.'); - - this.addSniffer(devtools.DebuggerAgent.prototype, 'reset', - waitUntilScriptIsParsed); - - // Reload inspected page. It will reset the debugger agent. - test.evaluateInConsole_( - 'window.location.reload(true);', - function(resultText) { - test.assertEquals('undefined', resultText, - 'Unexpected result of reload().'); - }); - - function waitUntilScriptIsParsed() { - var parsed = devtools.tools.getDebuggerAgent().parsedScripts_; - for (var id in parsed) { - var url = parsed[id].getUrl(); - if (url && url.search('debugger_test_page.html$') != -1) { - checkScriptsPanel(); - return; - } +TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function() +{ + var test = this; + this.assertEquals(WebInspector.panels.elements, WebInspector.currentPanel, "Elements panel should be current one."); + + this.addSniffer(devtools.DebuggerAgent.prototype, "reset", waitUntilScriptIsParsed); + + // Reload inspected page. It will reset the debugger agent. + test.evaluateInConsole_( + "window.location.reload(true);", + function(resultText) { + test.assertEquals("undefined", resultText, "Unexpected result of reload()."); + }); + + function waitUntilScriptIsParsed() { + var parsed = devtools.tools.getDebuggerAgent().parsedScripts_; + for (var id in parsed) { + var url = parsed[id].getUrl(); + if (url && url.search("debugger_test_page.html$") !== -1) { + checkScriptsPanel(); + return; + } + } + test.addSniffer(devtools.DebuggerAgent.prototype, "addScriptInfo_", waitUntilScriptIsParsed); } - test.addSniffer(devtools.DebuggerAgent.prototype, 'addScriptInfo_', - waitUntilScriptIsParsed); - } - - function checkScriptsPanel() { - test.showPanel('scripts'); - test.assertTrue(test._scriptsAreParsed(['debugger_test_page.html$']), - 'Inspected script not found in the scripts list'); - test.releaseControl(); - } - - // Wait until all scripts are added to the debugger. - this.takeControl(); + + function checkScriptsPanel() { + test.showPanel("scripts"); + test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html$"]), "Inspected script not found in the scripts list"); + test.releaseControl(); + } + + // Wait until all scripts are added to the debugger. + this.takeControl(); }; /** * Tests that scripts list contains content scripts. */ -TestSuite.prototype.testContentScriptIsPresent = function() { - this.showPanel('scripts'); - var test = this; +TestSuite.prototype.testContentScriptIsPresent = function() +{ + this.showPanel("scripts"); + var test = this; - test._waitUntilScriptsAreParsed( - ['page_with_content_script.html$', 'simple_content_script.js$'], - function() { - test.releaseControl(); - }); + test._waitUntilScriptsAreParsed( + ["page_with_content_script.html$", "simple_content_script.js$"], + function() { + test.releaseControl(); + }); - // Wait until all scripts are added to the debugger. - this.takeControl(); + // Wait until all scripts are added to the debugger. + this.takeControl(); }; /** * Tests that scripts are not duplicaed on Scripts tab switch. */ -TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() { - var test = this; +TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() +{ + var test = this; - // There should be two scripts: one for the main page and another - // one which is source of console API(see - // InjectedScript._ensureCommandLineAPIInstalled). - var expectedScriptsCount = 2; - var parsedScripts = []; + // There should be two scripts: one for the main page and another + // one which is source of console API(see + // InjectedScript._ensureCommandLineAPIInstalled). + var expectedScriptsCount = 2; + var parsedScripts = []; - this.showPanel('scripts'); + this.showPanel("scripts"); - function switchToElementsTab() { - test.showPanel('elements'); - setTimeout(switchToScriptsTab, 0); - } + function switchToElementsTab() { + test.showPanel("elements"); + setTimeout(switchToScriptsTab, 0); + } - function switchToScriptsTab() { - test.showPanel('scripts'); - setTimeout(checkScriptsPanel, 0); - } + function switchToScriptsTab() { + test.showPanel("scripts"); + setTimeout(checkScriptsPanel, 0); + } - function checkScriptsPanel() { - test.assertTrue(!!WebInspector.panels.scripts.visibleView, - 'No visible script view.'); - test.assertTrue(test._scriptsAreParsed(['debugger_test_page.html$']), - 'Some scripts are missing.'); - checkNoDuplicates(); - test.releaseControl(); - } + function checkScriptsPanel() { + test.assertTrue(!!WebInspector.panels.scripts.visibleView, "No visible script view."); + test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html$"]), "Some scripts are missing."); + checkNoDuplicates(); + test.releaseControl(); + } - function checkNoDuplicates() { - var scriptSelect = document.getElementById('scripts-files'); - var options = scriptSelect.options; - for (var i = 0; i < options.length; i++) { - var scriptName = options[i].text; - for (var j = i + 1; j < options.length; j++) { - test.assertTrue(scriptName != options[j].text, - 'Found script duplicates: ' + test.optionsToString_(options)); - } + function checkNoDuplicates() { + var scriptSelect = document.getElementById("scripts-files"); + var options = scriptSelect.options; + for (var i = 0; i < options.length; i++) { + var scriptName = options[i].text; + for (var j = i + 1; j < options.length; j++) + test.assertTrue(scriptName !== options[j].text, "Found script duplicates: " + test.optionsToString_(options)); + } } - } - test._waitUntilScriptsAreParsed( - ['debugger_test_page.html$'], - function() { - checkNoDuplicates(); - setTimeout(switchToElementsTab, 0); - }); + test._waitUntilScriptsAreParsed( + ["debugger_test_page.html$"], + function() { + checkNoDuplicates(); + setTimeout(switchToElementsTab, 0); + }); - // Wait until all scripts are added to the debugger. - this.takeControl(); + // Wait until all scripts are added to the debugger. + this.takeControl(); }; /** * Tests that a breakpoint can be set. */ -TestSuite.prototype.testSetBreakpoint = function() { - var test = this; - this.showPanel('scripts'); - - var breakpointLine = 12; - - this._waitUntilScriptsAreParsed(['debugger_test_page.html'], - function() { - test.showMainPageScriptSource_( - 'debugger_test_page.html', - function(view, url) { - view._addBreakpoint(breakpointLine); - // Force v8 execution. - RemoteToolsAgent.executeVoidJavaScript(); - test.waitForSetBreakpointResponse_(url, breakpointLine, - function() { - test.releaseControl(); - }); - }); - }); +TestSuite.prototype.testSetBreakpoint = function() +{ + var test = this; + this.showPanel("scripts"); - this.takeControl(); + var breakpointLine = 12; + + this._waitUntilScriptsAreParsed(["debugger_test_page.html"], + function() { + test.showMainPageScriptSource_( + "debugger_test_page.html", + function(view, url) { + view._addBreakpoint(breakpointLine); + // Force v8 execution. + RemoteToolsAgent.executeVoidJavaScript(); + test.waitForSetBreakpointResponse_(url, breakpointLine, + function() { + test.releaseControl(); + }); + }); + }); + + this.takeControl(); }; /** * Tests that pause on exception works. */ -TestSuite.prototype.testPauseOnException = function() { - this.showPanel('scripts'); - var test = this; - - // TODO(yurys): remove else branch once the states are supported. - if (WebInspector.ScriptsPanel.PauseOnExceptionsState) { - while (WebInspector.currentPanel.pauseOnExceptionButton.state != - WebInspector.ScriptsPanel.PauseOnExceptionsState. - PauseOnUncaughtExceptions) { - WebInspector.currentPanel.pauseOnExceptionButton.element.click(); - } - } else { - // Make sure pause on exceptions is on. - if (!WebInspector.currentPanel.pauseOnExceptionButton.toggled) { - WebInspector.currentPanel.pauseOnExceptionButton.element.click(); +TestSuite.prototype.testPauseOnException = function() +{ + this.showPanel("scripts"); + var test = this; + + // TODO(yurys): remove else branch once the states are supported. + if (WebInspector.ScriptsPanel.PauseOnExceptionsState) { + while (WebInspector.currentPanel.pauseOnExceptionButton.state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions) + WebInspector.currentPanel.pauseOnExceptionButton.element.click(); + } else { + // Make sure pause on exceptions is on. + if (!WebInspector.currentPanel.pauseOnExceptionButton.toggled) + WebInspector.currentPanel.pauseOnExceptionButton.element.click(); } - } - - this._executeCodeWhenScriptsAreParsed( - 'handleClick()', - ['pause_on_exception.html$']); - - this._waitForScriptPause( - { - functionsOnStack: ['throwAnException', 'handleClick', - '(anonymous function)'], - lineNumber: 6, - lineText: ' return unknown_var;' - }, - function() { - test.releaseControl(); - }); - this.takeControl(); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["pause_on_exception.html$"]); + + this._waitForScriptPause( + { + functionsOnStack: ["throwAnException", "handleClick", "(anonymous function)"], + lineNumber: 6, + lineText: " return unknown_var;" + }, + function() { + test.releaseControl(); + }); + + this.takeControl(); }; // Tests that debugger works correctly if pause event occurs when DevTools // frontend is being loaded. -TestSuite.prototype.testPauseWhenLoadingDevTools = function() { - this.showPanel('scripts'); - var test = this; - - var expectations = { - functionsOnStack: ['callDebugger'], - lineNumber: 8, - lineText: ' debugger;' - }; - - - // Script execution can already be paused. - if (WebInspector.currentPanel.paused) { - var callFrame = - WebInspector.currentPanel.sidebarPanes.callstack.selectedCallFrame; - this.assertEquals(expectations.functionsOnStack[0], - callFrame.functionName); - var callbackInvoked = false; - this._checkSourceFrameWhenLoaded(expectations, function() { - callbackInvoked = true; - if (test.controlTaken_) { +TestSuite.prototype.testPauseWhenLoadingDevTools = function() +{ + this.showPanel("scripts"); + var test = this; + + var expectations = { + functionsOnStack: ["callDebugger"], + lineNumber: 8, + lineText: " debugger;" + }; + + + // Script execution can already be paused. + if (WebInspector.currentPanel.paused) { + var callFrame = WebInspector.currentPanel.sidebarPanes.callstack.selectedCallFrame; + this.assertEquals(expectations.functionsOnStack[0], callFrame.functionName); + var callbackInvoked = false; + this._checkSourceFrameWhenLoaded(expectations, function() { + callbackInvoked = true; + if (test.controlTaken_) + test.releaseControl(); + }); + if (!callbackInvoked) { + test.takeControl(); + } + return; + } + + this._waitForScriptPause( + { + functionsOnStack: ["callDebugger"], + lineNumber: 8, + lineText: " debugger;" + }, + function() { test.releaseControl(); - } }); - if (!callbackInvoked) { - test.takeControl(); - } - return; - } - - this._waitForScriptPause( - { - functionsOnStack: ['callDebugger'], - lineNumber: 8, - lineText: ' debugger;' - }, - function() { - test.releaseControl(); - }); - this.takeControl(); + this.takeControl(); }; -// Tests that pressing 'Pause' will pause script execution if the script +// Tests that pressing "Pause" will pause script execution if the script // is already running. -TestSuite.prototype.testPauseWhenScriptIsRunning = function() { - this.showPanel('scripts'); - var test = this; - - test.evaluateInConsole_( - 'setTimeout("handleClick()" , 0)', - function(resultText) { - test.assertTrue(!isNaN(resultText), - 'Failed to get timer id: ' + resultText); - testScriptPauseAfterDelay(); - }); - - // Wait for some time to make sure that inspected page is running the - // infinite loop. - function testScriptPauseAfterDelay() { - setTimeout(testScriptPause, 300); - } - - function testScriptPause() { - // The script should be in infinite loop. Click 'Pause' button to - // pause it and wait for the result. - WebInspector.panels.scripts.pauseButton.click(); - - test._waitForScriptPause( - { - functionsOnStack: ['handleClick', '(anonymous function)'], - lineNumber: 5, - lineText: ' while(true) {' - }, - function() { - test.releaseControl(); +TestSuite.prototype.testPauseWhenScriptIsRunning = function() +{ + this.showPanel("scripts"); + var test = this; + + test.evaluateInConsole_( + 'setTimeout("handleClick()" , 0)', + function(resultText) { + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); + testScriptPauseAfterDelay(); }); - } - this.takeControl(); + // Wait for some time to make sure that inspected page is running the + // infinite loop. + function testScriptPauseAfterDelay() { + setTimeout(testScriptPause, 300); + } + + function testScriptPause() { + // The script should be in infinite loop. Click "Pause" button to + // pause it and wait for the result. + WebInspector.panels.scripts.pauseButton.click(); + + test._waitForScriptPause( + { + functionsOnStack: ["handleClick", "(anonymous function)"], + lineNumber: 5, + lineText: " while(true) {" + }, + function() { + test.releaseControl(); + }); + } + + this.takeControl(); }; @@ -733,12 +746,12 @@ TestSuite.prototype.testPauseWhenScriptIsRunning = function() { * @param {HTMLOptionsCollection} options * @return {string} */ -TestSuite.prototype.optionsToString_ = function(options) { - var names = []; - for (var i = 0; i < options.length; i++) { - names.push('"' + options[i].text + '"'); - } - return names.join(','); +TestSuite.prototype.optionsToString_ = function(options) +{ + var names = []; + for (var i = 0; i < options.length; i++) + names.push('"' + options[i].text + '"'); + return names.join(","); }; @@ -748,56 +761,51 @@ TestSuite.prototype.optionsToString_ = function(options) { * @param {HTMLOptionsCollection} options * @param {function(WebInspector.SourceView,string)} callback */ -TestSuite.prototype.showMainPageScriptSource_ = function(scriptName, callback) { - var test = this; - - var scriptSelect = document.getElementById('scripts-files'); - var options = scriptSelect.options; - - test.assertTrue(options.length, 'Scripts list is empty'); - - // Select page's script if it's not current option. - var scriptResource; - if (options[scriptSelect.selectedIndex].text === scriptName) { - scriptResource = options[scriptSelect.selectedIndex].representedObject; - } else { - var pageScriptIndex = -1; - for (var i = 0; i < options.length; i++) { - if (options[i].text === scriptName) { - pageScriptIndex = i; - break; - } +TestSuite.prototype.showMainPageScriptSource_ = function(scriptName, callback) +{ + var test = this; + + var scriptSelect = document.getElementById("scripts-files"); + var options = scriptSelect.options; + + test.assertTrue(options.length, "Scripts list is empty"); + + // Select page's script if it's not current option. + var scriptResource; + if (options[scriptSelect.selectedIndex].text === scriptName) + scriptResource = options[scriptSelect.selectedIndex].representedObject; + else { + var pageScriptIndex = -1; + for (var i = 0; i < options.length; i++) { + if (options[i].text === scriptName) { + pageScriptIndex = i; + break; + } + } + test.assertTrue(-1 !== pageScriptIndex, "Script with url " + scriptName + " not found among " + test.optionsToString_(options)); + scriptResource = options[pageScriptIndex].representedObject; + + // Current panel is "Scripts". + WebInspector.currentPanel._showScriptOrResource(scriptResource); + test.assertEquals(pageScriptIndex, scriptSelect.selectedIndex, "Unexpected selected option index."); } - test.assertTrue(-1 !== pageScriptIndex, - 'Script with url ' + scriptName + ' not found among ' + - test.optionsToString_(options)); - scriptResource = options[pageScriptIndex].representedObject; - - // Current panel is 'Scripts'. - WebInspector.currentPanel._showScriptOrResource(scriptResource); - test.assertEquals(pageScriptIndex, scriptSelect.selectedIndex, - 'Unexpected selected option index.'); - } - - test.assertTrue(scriptResource instanceof WebInspector.Resource, - 'Unexpected resource class.'); - test.assertTrue(!!scriptResource.url, 'Resource URL is null.'); - test.assertTrue( - scriptResource.url.search(scriptName + '$') != -1, - 'Main HTML resource should be selected.'); - - var scriptsPanel = WebInspector.panels.scripts; - - var view = scriptsPanel.visibleView; - test.assertTrue(view instanceof WebInspector.SourceView); - - if (!view.sourceFrame._loaded) { - test.addSniffer(view, '_sourceFrameSetupFinished', function(event) { - callback(view, scriptResource.url); - }); - } else { - callback(view, scriptResource.url); - } + + test.assertTrue(scriptResource instanceof WebInspector.Resource, + "Unexpected resource class."); + test.assertTrue(!!scriptResource.url, "Resource URL is null."); + test.assertTrue(scriptResource.url.search(scriptName + "$") !== -1, "Main HTML resource should be selected."); + + var scriptsPanel = WebInspector.panels.scripts; + + var view = scriptsPanel.visibleView; + test.assertTrue(view instanceof WebInspector.SourceView); + + if (!view.sourceFrame._loaded) { + test.addSniffer(view, "_sourceFrameSetupFinished", function(event) { + callback(view, scriptResource.url); + }); + } else + callback(view, scriptResource.url); }; @@ -807,168 +815,145 @@ TestSuite.prototype.showMainPageScriptSource_ = function(scriptName, callback) { * @param {string} code * @param {function(string)} callback */ -TestSuite.prototype.evaluateInConsole_ = function(code, callback) { - WebInspector.console.visible = true; - WebInspector.console.prompt.text = code; - WebInspector.console.promptElement.dispatchEvent( - TestSuite.createKeyEvent('Enter')); +TestSuite.prototype.evaluateInConsole_ = function(code, callback) +{ + WebInspector.console.visible = true; + WebInspector.console.prompt.text = code; + WebInspector.console.promptElement.dispatchEvent( TestSuite.createKeyEvent("Enter")); - this.addSniffer(WebInspector.ConsoleView.prototype, 'addMessage', - function(commandResult) { - callback(commandResult.toMessageElement().textContent); - }); + this.addSniffer(WebInspector.ConsoleView.prototype, "addMessage", + function(commandResult) { + callback(commandResult.toMessageElement().textContent); + }); }; /* - * Waits for 'setbreakpoint' response, checks that corresponding breakpoint + * Waits for "setbreakpoint" response, checks that corresponding breakpoint * was successfully set and invokes the callback if it was. * @param {string} scriptUrl * @param {number} breakpointLine * @param {function()} callback */ -TestSuite.prototype.waitForSetBreakpointResponse_ = function(scriptUrl, - breakpointLine, - callback) { - var test = this; - test.addSniffer( - devtools.DebuggerAgent.prototype, - 'handleSetBreakpointResponse_', - function(msg) { - var bps = this.urlToBreakpoints_[scriptUrl]; - test.assertTrue(!!bps, 'No breakpoints for line ' + breakpointLine); - var line = devtools.DebuggerAgent.webkitToV8LineNumber_(breakpointLine); - test.assertTrue(!!bps[line].getV8Id(), - 'Breakpoint id was not assigned.'); - callback(); - }); +TestSuite.prototype.waitForSetBreakpointResponse_ = function(scriptUrl, breakpointLine, callback) +{ + var test = this; + test.addSniffer( + devtools.DebuggerAgent.prototype, + "handleSetBreakpointResponse_", + function(msg) { + var bps = this.urlToBreakpoints_[scriptUrl]; + test.assertTrue(!!bps, "No breakpoints for line " + breakpointLine); + var line = devtools.DebuggerAgent.webkitToV8LineNumber_(breakpointLine); + test.assertTrue(!!bps[line].getV8Id(), "Breakpoint id was not assigned."); + callback(); + }); }; /** * Tests eval on call frame. */ -TestSuite.prototype.testEvalOnCallFrame = function() { - this.showPanel('scripts'); - - var breakpointLine = 16; - - var test = this; - this.addSniffer(devtools.DebuggerAgent.prototype, 'handleScriptsResponse_', - function(msg) { - test.showMainPageScriptSource_( - 'debugger_test_page.html', - function(view, url) { - view._addBreakpoint(breakpointLine); - // Force v8 execution. - RemoteToolsAgent.executeVoidJavaScript(); - test.waitForSetBreakpointResponse_(url, breakpointLine, - setBreakpointCallback); - }); - }); +TestSuite.prototype.testEvalOnCallFrame = function() +{ + this.showPanel("scripts"); - function setBreakpointCallback() { - // Since breakpoints are ignored in evals' calculate() function is - // execute after zero-timeout so that the breakpoint is hit. - test.evaluateInConsole_( - 'setTimeout("calculate(123)" , 0)', - function(resultText) { - test.assertTrue(!isNaN(resultText), - 'Failed to get timer id: ' + resultText); - waitForBreakpointHit(); - }); - } + var breakpointLine = 16; - function waitForBreakpointHit() { - test.addSniffer( - devtools.DebuggerAgent.prototype, - 'handleBacktraceResponse_', + var test = this; + this.addSniffer(devtools.DebuggerAgent.prototype, "handleScriptsResponse_", function(msg) { - test.assertEquals(2, this.callFrames_.length, - 'Unexpected stack depth on the breakpoint. ' + - JSON.stringify(msg)); - test.assertEquals('calculate', this.callFrames_[0].functionName, - 'Unexpected top frame function.'); - // Evaluate 'e+1' where 'e' is an argument of 'calculate' function. - test.evaluateInConsole_( - 'e+1', - function(resultText) { - test.assertEquals('124', resultText, 'Unexpected "e+1" value.'); - test.releaseControl(); + test.showMainPageScriptSource_( + "debugger_test_page.html", + function(view, url) { + view._addBreakpoint(breakpointLine); + // Force v8 execution. + RemoteToolsAgent.executeVoidJavaScript(); + test.waitForSetBreakpointResponse_(url, breakpointLine, setBreakpointCallback); }); }); - } - this.takeControl(); + function setBreakpointCallback() { + // Since breakpoints are ignored in evals' calculate() function is + // execute after zero-timeout so that the breakpoint is hit. + test.evaluateInConsole_( + 'setTimeout("calculate(123)" , 0)', + function(resultText) { + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); + waitForBreakpointHit(); + }); + } + + function waitForBreakpointHit() { + test.addSniffer( + devtools.DebuggerAgent.prototype, + "handleBacktraceResponse_", + function(msg) { + test.assertEquals(2, this.callFrames_.length, "Unexpected stack depth on the breakpoint. " + JSON.stringify(msg)); + test.assertEquals("calculate", this.callFrames_[0].functionName, "Unexpected top frame function."); + // Evaluate "e+1" where "e" is an argument of "calculate" function. + test.evaluateInConsole_( + "e+1", + function(resultText) { + test.assertEquals("124", resultText, 'Unexpected "e+1" value.'); + test.releaseControl(); + }); + }); + } + + this.takeControl(); }; /** * Tests that console auto completion works when script execution is paused. */ -TestSuite.prototype.testCompletionOnPause = function() { - this.showPanel('scripts'); - var test = this; - this._executeCodeWhenScriptsAreParsed( - 'handleClick()', - ['completion_on_pause.html$']); - - this._waitForScriptPause( - { - functionsOnStack: ['innerFunction', 'handleClick', - '(anonymous function)'], - lineNumber: 9, - lineText: ' debugger;' - }, - showConsole); - - function showConsole() { - test.addSniffer(WebInspector.console, 'afterShow', testLocalsCompletion); - WebInspector.showConsole(); - } - - function testLocalsCompletion() { - checkCompletions( - 'th', - ['parameter1', 'closureLocal', 'p', 'createClosureLocal'], - testThisCompletion); - } - - function testThisCompletion() { - checkCompletions( - 'this.', - ['field1', 'field2', 'm'], - testFieldCompletion); - } - - function testFieldCompletion() { - checkCompletions( - 'this.field1.', - ['id', 'name'], - function() { - test.releaseControl(); - }); - } - - function checkCompletions(expression, expectedProperties, callback) { - test.addSniffer(WebInspector.console, '_reportCompletions', - function(bestMatchOnly, completionsReadyCallback, dotNotation, - bracketNotation, prefix, result, isException) { - test.assertTrue(!isException, - 'Exception while collecting completions'); - for (var i = 0; i < expectedProperties.length; i++) { - var name = expectedProperties[i]; - test.assertTrue(result[name], 'Name ' + name + - ' not found among the completions: ' + - JSON.stringify(result)); - } - setTimeout(callback, 0); - }); - WebInspector.console.prompt.text = expression; - WebInspector.console.prompt.autoCompleteSoon(); - } +TestSuite.prototype.testCompletionOnPause = function() +{ + this.showPanel("scripts"); + var test = this; + this._executeCodeWhenScriptsAreParsed("handleClick()", ["completion_on_pause.html$"]); + + this._waitForScriptPause( + { + functionsOnStack: ["innerFunction", "handleClick", "(anonymous function)"], + lineNumber: 9, + lineText: " debugger;" + }, + showConsole); + + function showConsole() { + test.addSniffer(WebInspector.console, "afterShow", testLocalsCompletion); + WebInspector.showConsole(); + } + + function testLocalsCompletion() { + checkCompletions("th", ["parameter1", "closureLocal", "p", "createClosureLocal"], testThisCompletion); + } + + function testThisCompletion() { + checkCompletions("this.", ["field1", "field2", "m"], testFieldCompletion); + } + + function testFieldCompletion() { + checkCompletions("this.field1.", ["id", "name"], function() { test.releaseControl(); }); + } + + function checkCompletions(expression, expectedProperties, callback) { + test.addSniffer(WebInspector.console, "_reportCompletions", + function(bestMatchOnly, completionsReadyCallback, dotNotation, bracketNotation, prefix, result, isException) { + test.assertTrue(!isException, "Exception while collecting completions"); + for (var i = 0; i < expectedProperties.length; i++) { + var name = expectedProperties[i]; + test.assertTrue(result[name], "Name " + name + " not found among the completions: " + JSON.stringify(result)); + } + setTimeout(callback, 0); + }); + WebInspector.console.prompt.text = expression; + WebInspector.console.prompt.autoCompleteSoon(); + } - this.takeControl(); + this.takeControl(); }; @@ -976,61 +961,58 @@ TestSuite.prototype.testCompletionOnPause = function() { * Tests that inspected page doesn't hang on reload if it contains a syntax * error and DevTools window is open. */ -TestSuite.prototype.testAutoContinueOnSyntaxError = function() { - this.showPanel('scripts'); - var test = this; - - function checkScriptsList() { - var scriptSelect = document.getElementById('scripts-files'); - var options = scriptSelect.options; - // There should be only console API source (see - // InjectedScript._ensureCommandLineAPIInstalled) since the page script - // contains a syntax error. - for (var i = 0 ; i < options.length; i++) { - if (options[i].text.search('script_syntax_error.html$') != -1) { - test.fail('Script with syntax error should not be in the list of ' + - 'parsed scripts.'); - } +TestSuite.prototype.testAutoContinueOnSyntaxError = function() +{ + this.showPanel("scripts"); + var test = this; + + function checkScriptsList() { + var scriptSelect = document.getElementById("scripts-files"); + var options = scriptSelect.options; + // There should be only console API source (see + // InjectedScript._ensureCommandLineAPIInstalled) since the page script + // contains a syntax error. + for (var i = 0 ; i < options.length; i++) { + if (options[i].text.search("script_syntax_error.html$") !== -1) + test.fail("Script with syntax error should not be in the list of parsed scripts."); + } } - } - - this.addSniffer(devtools.DebuggerAgent.prototype, 'handleScriptsResponse_', - function(msg) { - checkScriptsList(); - // Reload inspected page. - test.evaluateInConsole_( - 'window.location.reload(true);', - function(resultText) { - test.assertEquals('undefined', resultText, - 'Unexpected result of reload().'); - waitForExceptionEvent(); - }); - }); - - function waitForExceptionEvent() { - var exceptionCount = 0; - test.addSniffer( - devtools.DebuggerAgent.prototype, - 'handleExceptionEvent_', + this.addSniffer(devtools.DebuggerAgent.prototype, "handleScriptsResponse_", function(msg) { - exceptionCount++; - test.assertEquals(1, exceptionCount, 'Too many exceptions.'); - test.assertEquals(undefined, msg.getBody().script, - 'Unexpected exception: ' + JSON.stringify(msg)); - test.releaseControl(); - }); + checkScriptsList(); - // Check that the script is not paused on parse error. - test.addSniffer( - WebInspector, - 'pausedScript', - function(callFrames) { - test.fail('Script execution should not pause on syntax error.'); + // Reload inspected page. + test.evaluateInConsole_( + "window.location.reload(true);", + function(resultText) { + test.assertEquals("undefined", resultText, "Unexpected result of reload()."); + waitForExceptionEvent(); + }); }); - } - this.takeControl(); + function waitForExceptionEvent() { + var exceptionCount = 0; + test.addSniffer( + devtools.DebuggerAgent.prototype, + "handleExceptionEvent_", + function(msg) { + exceptionCount++; + test.assertEquals(1, exceptionCount, "Too many exceptions."); + test.assertEquals(undefined, msg.getBody().script, "Unexpected exception: " + JSON.stringify(msg)); + test.releaseControl(); + }); + + // Check that the script is not paused on parse error. + test.addSniffer( + WebInspector, + "pausedScript", + function(callFrames) { + test.fail("Script execution should not pause on syntax error."); + }); + } + + this.takeControl(); }; @@ -1040,12 +1022,10 @@ TestSuite.prototype.testAutoContinueOnSyntaxError = function() { * @param {number} lineNumber Expected line number * @param {string} lineContent Expected line text */ -TestSuite.prototype._checkExecutionLine = function(sourceFrame, lineNumber, - lineContent) { - this.assertEquals(lineNumber, sourceFrame.executionLine, - 'Unexpected execution line number.'); - this.assertEquals(lineContent, sourceFrame._textModel.line(lineNumber - 1), - 'Unexpected execution line text.'); +TestSuite.prototype._checkExecutionLine = function(sourceFrame, lineNumber, lineContent) +{ + this.assertEquals(lineNumber, sourceFrame.executionLine, "Unexpected execution line number."); + this.assertEquals(lineContent, sourceFrame._textModel.line(lineNumber - 1), "Unexpected execution line text."); } @@ -1054,24 +1034,25 @@ TestSuite.prototype._checkExecutionLine = function(sourceFrame, lineNumber, * in the Scripts panel. * @param {Array.<string>} expected Regular expressions describing * expected script names. - * @return {boolean} Whether all the scripts are in 'scripts-files' select + * @return {boolean} Whether all the scripts are in "scripts-files" select * box */ -TestSuite.prototype._scriptsAreParsed = function(expected) { - var scriptSelect = document.getElementById('scripts-files'); - var options = scriptSelect.options; - - // Check that at least all the expected scripts are present. - var missing = expected.slice(0); - for (var i = 0 ; i < options.length; i++) { - for (var j = 0; j < missing.length; j++) { - if (options[i].text.search(missing[j]) != -1) { - missing.splice(j, 1); - break; - } +TestSuite.prototype._scriptsAreParsed = function(expected) +{ + var scriptSelect = document.getElementById("scripts-files"); + var options = scriptSelect.options; + + // Check that at least all the expected scripts are present. + var missing = expected.slice(0); + for (var i = 0 ; i < options.length; i++) { + for (var j = 0; j < missing.length; j++) { + if (options[i].text.search(missing[j]) !== -1) { + missing.splice(j, 1); + break; + } + } } - } - return missing.length == 0; + return missing.length === 0; }; @@ -1080,26 +1061,24 @@ TestSuite.prototype._scriptsAreParsed = function(expected) { * @param {Object} expectations Dictionary of expectations * @param {function():void} callback */ -TestSuite.prototype._waitForScriptPause = function(expectations, callback) { - var test = this; - // Wait until script is paused. - test.addSniffer( - WebInspector, - 'pausedScript', - function(callFrames) { - var functionsOnStack = []; - for (var i = 0; i < callFrames.length; i++) { - functionsOnStack.push(callFrames[i].functionName); - } +TestSuite.prototype._waitForScriptPause = function(expectations, callback) +{ + var test = this; + // Wait until script is paused. + test.addSniffer( + WebInspector, + "pausedScript", + function(callFrames) { + var functionsOnStack = []; + for (var i = 0; i < callFrames.length; i++) + functionsOnStack.push(callFrames[i].functionName); - test.assertEquals( - expectations.functionsOnStack.join(','), - functionsOnStack.join(','), 'Unexpected stack.'); + test.assertEquals(expectations.functionsOnStack.join(","), functionsOnStack.join(","), "Unexpected stack."); - // Check that execution line where the script is paused is - // expected one. - test._checkSourceFrameWhenLoaded(expectations, callback); - }); + // Check that execution line where the script is paused is + // expected one. + test._checkSourceFrameWhenLoaded(expectations, callback); + }); }; @@ -1109,23 +1088,22 @@ TestSuite.prototype._waitForScriptPause = function(expectations, callback) { * @param {Object} expectations Dictionary of expectations * @param {function():void} callback */ -TestSuite.prototype._checkSourceFrameWhenLoaded = function( - expectations, callback) { - var test = this; - - var frame = WebInspector.currentPanel.visibleView.sourceFrame; - if (frame._loaded) { - checkExecLine(); - } else { - setTimeout(function() { - test._checkSourceFrameWhenLoaded(expectations, callback); - }, 100); - } - function checkExecLine() { - test._checkExecutionLine(frame, expectations.lineNumber, - expectations.lineText); - callback(); - } +TestSuite.prototype._checkSourceFrameWhenLoaded = function(expectations, callback) +{ + var test = this; + + var frame = WebInspector.currentPanel.visibleView.sourceFrame; + if (frame._loaded) + checkExecLine(); + else { + setTimeout(function() { + test._checkSourceFrameWhenLoaded(expectations, callback); + }, 100); + } + function checkExecLine() { + test._checkExecutionLine(frame, expectations.lineNumber, expectations.lineText); + callback(); + } }; @@ -1134,18 +1112,17 @@ TestSuite.prototype._checkSourceFrameWhenLoaded = function( * @param {Array.<Object|Function>} Array [expectations1,action1,expectations2, * action2,...,actionN]. */ -TestSuite.prototype._performSteps = function(actions) { - var test = this; - var i = 0; - function doNextAction() { - if (i > 0) { - actions[i++](); - } - if (i < actions.length - 1) { - test._waitForScriptPause(actions[i++], doNextAction); +TestSuite.prototype._performSteps = function(actions) +{ + var test = this; + var i = 0; + function doNextAction() { + if (i > 0) + actions[i++](); + if (i < actions.length - 1) + test._waitForScriptPause(actions[i++], doNextAction); } - } - doNextAction(); + doNextAction(); }; @@ -1153,165 +1130,164 @@ TestSuite.prototype._performSteps = function(actions) { * Waits until all the scripts are parsed and asynchronously executes the code * in the inspected page. */ -TestSuite.prototype._executeCodeWhenScriptsAreParsed = function( - code, expectedScripts) { - var test = this; +TestSuite.prototype._executeCodeWhenScriptsAreParsed = function(code, expectedScripts) +{ + var test = this; - function executeFunctionInInspectedPage() { - // Since breakpoints are ignored in evals' calculate() function is - // execute after zero-timeout so that the breakpoint is hit. - test.evaluateInConsole_( - 'setTimeout("' + code + '" , 0)', - function(resultText) { - test.assertTrue(!isNaN(resultText), - 'Failed to get timer id: ' + resultText); - }); - } + function executeFunctionInInspectedPage() { + // Since breakpoints are ignored in evals' calculate() function is + // execute after zero-timeout so that the breakpoint is hit. + test.evaluateInConsole_( + 'setTimeout("' + code + '" , 0)', + function(resultText) { + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); + }); + } - test._waitUntilScriptsAreParsed( - expectedScripts, executeFunctionInInspectedPage); + test._waitUntilScriptsAreParsed(expectedScripts, executeFunctionInInspectedPage); }; /** * Waits until all the scripts are parsed and invokes the callback. */ -TestSuite.prototype._waitUntilScriptsAreParsed = function( - expectedScripts, callback) { - var test = this; +TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callback) +{ + var test = this; - function waitForAllScripts() { - if (test._scriptsAreParsed(expectedScripts)) { - callback(); - } else { - test.addSniffer(WebInspector, 'parsedScriptSource', waitForAllScripts); + function waitForAllScripts() { + if (test._scriptsAreParsed(expectedScripts)) + callback(); + else + test.addSniffer(WebInspector, "parsedScriptSource", waitForAllScripts); } - } - waitForAllScripts(); + waitForAllScripts(); }; /** - * Waits until all debugger scripts are parsed and executes 'a()' in the + * Waits until all debugger scripts are parsed and executes "a()" in the * inspected page. */ -TestSuite.prototype._executeFunctionForStepTest = function() { - this._executeCodeWhenScriptsAreParsed( - 'a()', - ['debugger_step.html$', 'debugger_step.js$']); +TestSuite.prototype._executeFunctionForStepTest = function() +{ + this._executeCodeWhenScriptsAreParsed("a()", ["debugger_step.html$", "debugger_step.js$"]); }; /** * Tests step over in the debugger. */ -TestSuite.prototype.testStepOver = function() { - this.showPanel('scripts'); - var test = this; - - this._executeFunctionForStepTest(); - - this._performSteps([ - { - functionsOnStack: ['d','a','(anonymous function)'], - lineNumber: 3, - lineText: ' debugger;' - }, - function() { - document.getElementById('scripts-step-over').click(); - }, - { - functionsOnStack: ['d','a','(anonymous function)'], - lineNumber: 5, - lineText: ' var y = fact(10);' - }, - function() { - document.getElementById('scripts-step-over').click(); - }, - { - functionsOnStack: ['d','a','(anonymous function)'], - lineNumber: 6, - lineText: ' return y;' - }, - function() { - test.releaseControl(); - } - ]); +TestSuite.prototype.testStepOver = function() +{ + this.showPanel("scripts"); + var test = this; + + this._executeFunctionForStepTest(); + + this._performSteps([ + { + functionsOnStack: ["d","a","(anonymous function)"], + lineNumber: 3, + lineText: " debugger;" + }, + function() { + document.getElementById("scripts-step-over").click(); + }, + { + functionsOnStack: ["d","a","(anonymous function)"], + lineNumber: 5, + lineText: " var y = fact(10);" + }, + function() { + document.getElementById("scripts-step-over").click(); + }, + { + functionsOnStack: ["d","a","(anonymous function)"], + lineNumber: 6, + lineText: " return y;" + }, + function() { + test.releaseControl(); + } + ]); - test.takeControl(); + test.takeControl(); }; /** * Tests step out in the debugger. */ -TestSuite.prototype.testStepOut = function() { - this.showPanel('scripts'); - var test = this; - - this._executeFunctionForStepTest(); - - this._performSteps([ - { - functionsOnStack: ['d','a','(anonymous function)'], - lineNumber: 3, - lineText: ' debugger;' - }, - function() { - document.getElementById('scripts-step-out').click(); - }, - { - functionsOnStack: ['a','(anonymous function)'], - lineNumber: 8, - lineText: ' printResult(result);' - }, - function() { - test.releaseControl(); - } - ]); +TestSuite.prototype.testStepOut = function() +{ + this.showPanel("scripts"); + var test = this; - test.takeControl(); + this._executeFunctionForStepTest(); + + this._performSteps([ + { + functionsOnStack: ["d","a","(anonymous function)"], + lineNumber: 3, + lineText: " debugger;" + }, + function() { + document.getElementById("scripts-step-out").click(); + }, + { + functionsOnStack: ["a","(anonymous function)"], + lineNumber: 8, + lineText: " printResult(result);" + }, + function() { + test.releaseControl(); + } + ]); + + test.takeControl(); }; /** * Tests step in in the debugger. */ -TestSuite.prototype.testStepIn = function() { - this.showPanel('scripts'); - var test = this; - - this._executeFunctionForStepTest(); - - this._performSteps([ - { - functionsOnStack: ['d','a','(anonymous function)'], - lineNumber: 3, - lineText: ' debugger;' - }, - function() { - document.getElementById('scripts-step-over').click(); - }, - { - functionsOnStack: ['d','a','(anonymous function)'], - lineNumber: 5, - lineText: ' var y = fact(10);' - }, - function() { - document.getElementById('scripts-step-into').click(); - }, - { - functionsOnStack: ['fact','d','a','(anonymous function)'], - lineNumber: 15, - lineText: ' return r;' - }, - function() { - test.releaseControl(); - } - ]); +TestSuite.prototype.testStepIn = function() +{ + this.showPanel("scripts"); + var test = this; + + this._executeFunctionForStepTest(); + + this._performSteps([ + { + functionsOnStack: ["d","a","(anonymous function)"], + lineNumber: 3, + lineText: " debugger;" + }, + function() { + document.getElementById("scripts-step-over").click(); + }, + { + functionsOnStack: ["d","a","(anonymous function)"], + lineNumber: 5, + lineText: " var y = fact(10);" + }, + function() { + document.getElementById("scripts-step-into").click(); + }, + { + functionsOnStack: ["fact","d","a","(anonymous function)"], + lineNumber: 15, + lineText: " return r;" + }, + function() { + test.releaseControl(); + } + ]); - test.takeControl(); + test.takeControl(); }; @@ -1321,19 +1297,18 @@ TestSuite.prototype.testStepIn = function() { * @param {number} resultType * @param {Node} opt_ancestor Context node. If not specified documentElement * will be used - * @return {XPathResult} Type of returned value is determined by 'resultType' parameter - */ - -TestSuite.prototype._evaluateXpath = function( - xpath, resultType, opt_ancestor) { - if (!opt_ancestor) { - opt_ancestor = document.documentElement; - } - try { - return document.evaluate(xpath, opt_ancestor, null, resultType, null); - } catch(e) { - this.fail('Error in expression: "' + xpath + '".' + e); - } + * @return {XPathResult} Type of returned value is determined by "resultType" parameter + */ + +TestSuite.prototype._evaluateXpath = function(xpath, resultType, opt_ancestor) +{ + if (!opt_ancestor) + opt_ancestor = document.documentElement; + try { + return document.evaluate(xpath, opt_ancestor, null, resultType, null); + } catch(e) { + this.fail('Error in expression: "' + xpath + '".' + e); + } }; @@ -1344,11 +1319,11 @@ TestSuite.prototype._evaluateXpath = function( * will be used * @return {?Node} */ -TestSuite.prototype._findNode = function(xpath, opt_ancestor) { - var result = this._evaluateXpath(xpath, XPathResult.FIRST_ORDERED_NODE_TYPE, - opt_ancestor).singleNodeValue; - this.assertTrue(!!result, 'Cannot find node on path: ' + xpath); - return result; +TestSuite.prototype._findNode = function(xpath, opt_ancestor) +{ + var result = this._evaluateXpath(xpath, XPathResult.FIRST_ORDERED_NODE_TYPE, opt_ancestor).singleNodeValue; + this.assertTrue(!!result, "Cannot find node on path: " + xpath); + return result; }; @@ -1359,11 +1334,11 @@ TestSuite.prototype._findNode = function(xpath, opt_ancestor) { * will be used * @return {?string} */ -TestSuite.prototype._findText = function(xpath, opt_ancestor) { - var result = this._evaluateXpath(xpath, XPathResult.STRING_TYPE, - opt_ancestor).stringValue; - this.assertTrue(!!result, 'Cannot find text on path: ' + xpath); - return result; +TestSuite.prototype._findText = function(xpath, opt_ancestor) +{ + var result = this._evaluateXpath(xpath, XPathResult.STRING_TYPE, opt_ancestor).stringValue; + this.assertTrue(!!result, "Cannot find text on path: " + xpath); + return result; }; @@ -1374,9 +1349,9 @@ TestSuite.prototype._findText = function(xpath, opt_ancestor) { * will be used * @return {XPathResult} Iterator over the nodes */ -TestSuite.prototype._nodeIterator = function(xpath, opt_ancestor) { - return this._evaluateXpath(xpath, XPathResult.ORDERED_NODE_ITERATOR_TYPE, - opt_ancestor); +TestSuite.prototype._nodeIterator = function(xpath, opt_ancestor) +{ + return this._evaluateXpath(xpath, XPathResult.ORDERED_NODE_ITERATOR_TYPE, opt_ancestor); }; @@ -1385,39 +1360,30 @@ TestSuite.prototype._nodeIterator = function(xpath, opt_ancestor) { * @param {Node} scopeSectionDiv The section div * @param {Object} expectations Expectations dictionary */ -TestSuite.prototype._checkScopeSectionDiv = function( - scopeSectionDiv, expectations) { - var scopeTitle = this._findText( - './div[@class="header"]/div[@class="title"]/text()', scopeSectionDiv); - this.assertEquals(expectations.title, scopeTitle, - 'Unexpected scope section title.'); - if (!expectations.properties) { - return; - } - this.assertTrue(scopeSectionDiv.hasStyleClass('expanded'), 'Section "' + - scopeTitle + '" is collapsed.'); - - var propertyIt = this._nodeIterator('./ol/li', - scopeSectionDiv); - var propertyLi; - var foundProps = []; - while (propertyLi = propertyIt.iterateNext()) { - var name = this._findText('./span[@class="name"]/text()', propertyLi); - var value = this._findText('./span[@class="value"]/text()', propertyLi); - this.assertTrue(!!name, 'Invalid variable name: "' + name + '"'); - this.assertTrue(name in expectations.properties, - 'Unexpected property: ' + name); - this.assertEquals(expectations.properties[name], value, - 'Unexpected "' + name + '" property value.'); - delete expectations.properties[name]; - foundProps.push(name + ' = ' + value); - } - - // Check that all expected properties were found. - for (var p in expectations.properties) { - this.fail('Property "' + p + '" was not found in scope "' + scopeTitle + - '". Found properties: "' + foundProps.join(',') + '"'); - } +TestSuite.prototype._checkScopeSectionDiv = function(scopeSectionDiv, expectations) +{ + var scopeTitle = this._findText('./div[@class="header"]/div[@class="title"]/text()', scopeSectionDiv); + this.assertEquals(expectations.title, scopeTitle, "Unexpected scope section title."); + if (!expectations.properties) + return; + this.assertTrue(scopeSectionDiv.hasStyleClass("expanded"), 'Section "' + scopeTitle + '" is collapsed.'); + + var propertyIt = this._nodeIterator("./ol/li", scopeSectionDiv); + var propertyLi; + var foundProps = []; + while (propertyLi = propertyIt.iterateNext()) { + var name = this._findText('./span[@class="name"]/text()', propertyLi); + var value = this._findText('./span[@class="value"]/text()', propertyLi); + this.assertTrue(!!name, 'Invalid variable name: "' + name + '"'); + this.assertTrue(name in expectations.properties, "Unexpected property: " + name); + this.assertEquals(expectations.properties[name], value, 'Unexpected "' + name + '" property value.'); + delete expectations.properties[name]; + foundProps.push(name + " = " + value); + } + + // Check that all expected properties were found. + for (var p in expectations.properties) + this.fail('Property "' + p + '" was not found in scope "' + scopeTitle + '". Found properties: "' + foundProps.join(",") + '"'); }; @@ -1428,110 +1394,103 @@ TestSuite.prototype._checkScopeSectionDiv = function( * filter * @param {Function} callback */ -TestSuite.prototype._expandScopeSections = function(filter, callback) { - var sections = WebInspector.currentPanel.sidebarPanes.scopechain.sections; +TestSuite.prototype._expandScopeSections = function(filter, callback) +{ + var sections = WebInspector.currentPanel.sidebarPanes.scopechain.sections; - var toBeUpdatedCount = 0; - function updateListener() { - --toBeUpdatedCount; - if (toBeUpdatedCount == 0) { - // Report when all scopes are expanded and populated. - callback(); + var toBeUpdatedCount = 0; + function updateListener() { + --toBeUpdatedCount; + if (toBeUpdatedCount === 0) { + // Report when all scopes are expanded and populated. + callback(); + } } - } - // Global scope is always the last one. - for (var i = 0; i < sections.length - 1; i++) { - var section = sections[i]; - if (!filter(sections, i)) { - continue; + // Global scope is always the last one. + for (var i = 0; i < sections.length - 1; i++) { + var section = sections[i]; + if (!filter(sections, i)) + continue; + ++toBeUpdatedCount; + var populated = section.populated; + + this._hookGetPropertiesCallback(updateListener, + function() { + section.expand(); + if (populated) { + // Make sure "updateProperties" callback will be called at least once + // after it was overridden. + section.update(); + } + }); } - ++toBeUpdatedCount; - var populated = section.populated; - - this._hookGetPropertiesCallback(updateListener, - function() { - section.expand(); - if (populated) { - // Make sure 'updateProperties' callback will be called at least once - // after it was overridden. - section.update(); - } - }); - } }; /** * Tests that scopes can be expanded and contain expected data. */ -TestSuite.prototype.testExpandScope = function() { - this.showPanel('scripts'); - var test = this; - - this._executeCodeWhenScriptsAreParsed( - 'handleClick()', - ['debugger_closure.html$']); - - this._waitForScriptPause( - { - functionsOnStack: ['innerFunction', 'handleClick', - '(anonymous function)'], - lineNumber: 8, - lineText: ' debugger;' - }, - expandAllSectionsExceptGlobal); - - // Expanding Global scope takes for too long so we skeep it. - function expandAllSectionsExceptGlobal() { - test._expandScopeSections(function(sections, i) { - return i < sections.length - 1; - }, - examineScopes /* When all scopes are expanded and populated check - them. */); - } - - // Check scope sections contents. - function examineScopes() { - var scopeVariablesSection = test._findNode('//div[@id="scripts-sidebar"]/' + - 'div[div[@class="title"]/text()="Scope Variables"]'); - var expectedScopes = [ - { - title: 'Local', - properties: { - x:2009, - innerFunctionLocalVar:2011, - 'this': 'global', - } - }, - { - title: 'Closure', - properties: { - n:'TextParam', - makeClosureLocalVar:'local.TextParam', - } - }, - { - title: 'Global', - }, - ]; - var it = test._nodeIterator('./div[@class="body"]/div', - scopeVariablesSection); - var scopeIndex = 0; - var scopeDiv; - while (scopeDiv = it.iterateNext()) { - test.assertTrue(scopeIndex < expectedScopes.length, - 'Too many scopes.'); - test._checkScopeSectionDiv(scopeDiv, expectedScopes[scopeIndex]); - ++scopeIndex; +TestSuite.prototype.testExpandScope = function() +{ + this.showPanel("scripts"); + var test = this; + + this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_closure.html$"]); + + this._waitForScriptPause( + { + functionsOnStack: ["innerFunction", "handleClick", "(anonymous function)"], + lineNumber: 8, + lineText: " debugger;" + }, + expandAllSectionsExceptGlobal); + + // Expanding Global scope takes for too long so we skeep it. + function expandAllSectionsExceptGlobal() { + test._expandScopeSections(function(sections, i) { + return i < sections.length - 1; + }, + examineScopes /* When all scopes are expanded and populated check them. */); } - test.assertEquals(expectedScopes.length, scopeIndex, - 'Unexpected number of scopes.'); - test.releaseControl(); - } + // Check scope sections contents. + function examineScopes() { + var scopeVariablesSection = test._findNode('//div[@id="scripts-sidebar"]/div[div[@class="title"]/text()="Scope Variables"]'); + var expectedScopes = [ + { + title: "Local", + properties: { + x:"2009", + innerFunctionLocalVar:"2011", + "this": "global", + } + }, + { + title: "Closure", + properties: { + n:"TextParam", + makeClosureLocalVar:"local.TextParam", + } + }, + { + title: "Global", + }, + ]; + var it = test._nodeIterator('./div[@class="body"]/div', scopeVariablesSection); + var scopeIndex = 0; + var scopeDiv; + while (scopeDiv = it.iterateNext()) { + test.assertTrue(scopeIndex < expectedScopes.length, "Too many scopes."); + test._checkScopeSectionDiv(scopeDiv, expectedScopes[scopeIndex]); + ++scopeIndex; + } + test.assertEquals(expectedScopes.length, scopeIndex, "Unexpected number of scopes."); - test.takeControl(); + test.releaseControl(); + } + + test.takeControl(); }; @@ -1543,43 +1502,42 @@ TestSuite.prototype.testExpandScope = function() { * of failure. * @return {TreeElement} */ -TestSuite.prototype._findChildProperty = function( - parent, childName, objectPath) { - var children = parent.children; - for (var i = 0; i < children.length; i++) { - var treeElement = children[i]; - var property = treeElement.property; - if (property.name == childName) { - return treeElement; +TestSuite.prototype._findChildProperty = function(parent, childName, objectPath) +{ + var children = parent.children; + for (var i = 0; i < children.length; i++) { + var treeElement = children[i]; + var property = treeElement.property; + if (property.name === childName) + return treeElement; } - } - this.fail('Cannot find property "' + childName + '" in ' + objectPath); + this.fail('Cannot find property "' + childName + '" in ' + objectPath); }; /** * Executes the 'code' with InjectedScriptAccess.getProperties overriden * so that all callbacks passed to InjectedScriptAccess.getProperties are - * extended with the 'hook'. + * extended with the "hook". * @param {Function} hook The hook function. * @param {Function} code A code snippet to be executed. */ -TestSuite.prototype._hookGetPropertiesCallback = function(hook, code) { - var accessor = InjectedScriptAccess.prototype; - var orig = accessor.getProperties; - accessor.getProperties = function(objectProxy, - ignoreHasOwnProperty, abbreviate, callback) { - orig.call(this, objectProxy, ignoreHasOwnProperty, abbreviate, - function() { - callback.apply(this, arguments); - hook(); - }); - }; - try { - code(); - } finally { - accessor.getProperties = orig; - } +TestSuite.prototype._hookGetPropertiesCallback = function(hook, code) +{ + var accessor = InjectedScriptAccess.prototype; + var orig = accessor.getProperties; + accessor.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback) { + orig.call(this, objectProxy, ignoreHasOwnProperty, abbreviate, + function() { + callback.apply(this, arguments); + hook(); + }); + }; + try { + code(); + } finally { + accessor.getProperties = orig; + } }; @@ -1587,262 +1545,250 @@ TestSuite.prototype._hookGetPropertiesCallback = function(hook, code) { * Tests that all elements in prototype chain of an object have expected * intrinic proprties(__proto__, constructor, prototype). */ -TestSuite.prototype.testDebugIntrinsicProperties = function() { - this.showPanel('scripts'); - var test = this; - - this._executeCodeWhenScriptsAreParsed( - 'handleClick()', - ['debugger_intrinsic_properties.html$']); - - this._waitForScriptPause( - { - functionsOnStack: ['callDebugger', 'handleClick', - '(anonymous function)'], - lineNumber: 29, - lineText: ' debugger;' - }, - expandLocalScope); - - var localScopeSection = null; - function expandLocalScope() { - test._expandScopeSections(function(sections, i) { - if (i == 0) { - test.assertTrue(sections[i].object.isLocal, 'Scope #0 is not Local.'); - localScopeSection = sections[i]; - return true; - } - return false; - }, - examineLocalScope); - } - - function examineLocalScope() { - var scopeExpectations = [ - 'a', 'Object', [ - 'constructor', 'function Child()', [ - 'constructor', 'function Function()', null, - 'name', 'Child', null, - 'prototype', 'Object', [ - 'childProtoField', '21', null - ] - ], +TestSuite.prototype.testDebugIntrinsicProperties = function() +{ + this.showPanel("scripts"); + var test = this; - '__proto__', 'Object', [ - '__proto__', 'Object', [ - '__proto__', 'Object', [ - '__proto__', 'null', null, - 'constructor', 'function Object()', null, - ], - 'constructor', 'function Parent()', [ - 'name', 'Parent', null, - 'prototype', 'Object', [ - 'parentProtoField', '11', null, - ] + this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_intrinsic_properties.html$"]); + + this._waitForScriptPause( + { + functionsOnStack: ["callDebugger", "handleClick", "(anonymous function)"], + lineNumber: 29, + lineText: " debugger;" + }, + expandLocalScope); + + var localScopeSection = null; + function expandLocalScope() { + test._expandScopeSections(function(sections, i) { + if (i === 0) { + test.assertTrue(sections[i].object.isLocal, "Scope #0 is not Local."); + localScopeSection = sections[i]; + return true; + } + return false; + }, + examineLocalScope); + } + + function examineLocalScope() { + var scopeExpectations = [ + "a", "Object", [ + "constructor", "function Child()", [ + "constructor", "function Function()", null, + "name", "Child", null, + "prototype", "Object", [ + "childProtoField", 21, null + ] + ], + + "__proto__", "Object", [ + "__proto__", "Object", [ + "__proto__", "Object", [ + "__proto__", "null", null, + "constructor", "function Object()", null, + ], + "constructor", "function Parent()", [ + "name", "Parent", null, + "prototype", "Object", [ + "parentProtoField", 11, null, + ] + ], + "parentProtoField", 11, null, + ], + "constructor", "function Child()", null, + "childProtoField", 21, null, ], - 'parentProtoField', '11', null, - ], - 'constructor', 'function Child()', null, - 'childProtoField', '21', null, - ], - - 'parentField', '10', null, - 'childField', '20', null, - ] - ]; - - checkProperty( - localScopeSection.propertiesTreeOutline, - '<Local Scope>', - scopeExpectations); - } - - var propQueue = []; - var index = 0; - var expectedFinalIndex = 8; - - function expandAndCheckNextProperty() { - if (index == propQueue.length) { - test.assertEquals(expectedFinalIndex, index, - 'Unexpected number of expanded objects.'); - test.releaseControl(); - return; + + "parentField", 10, null, + "childField", 20, null, + ] + ]; + + checkProperty(localScopeSection.propertiesTreeOutline, "<Local Scope>", scopeExpectations); } - // Read next property data from the queue. - var treeElement = propQueue[index].treeElement; - var path = propQueue[index].path; - var expectations = propQueue[index].expectations; - index++; + var propQueue = []; + var index = 0; + var expectedFinalIndex = 8; - // Expand the property. - test._hookGetPropertiesCallback(function() { - checkProperty(treeElement, path, expectations); - }, - function() { - treeElement.expand(); - }); - } - - function checkProperty(treeElement, path, expectations) { - for (var i = 0; i < expectations.length; i += 3) { - var name = expectations[i]; - var description = expectations[i+1]; - var value = expectations[i+2]; - - var propertyPath = path + '.' + name; - var propertyTreeElement = test._findChildProperty( - treeElement, name, path); - test.assertTrue(propertyTreeElement, - 'Property "' + propertyPath + '" not found.'); - test.assertEquals(description, - propertyTreeElement.property.value.description, - 'Unexpected "' + propertyPath + '" description.'); - if (value) { - // Schedule property content check. - propQueue.push({ - treeElement: propertyTreeElement, - path: propertyPath, - expectations: value, - }); - } + function expandAndCheckNextProperty() { + if (index === propQueue.length) { + test.assertEquals(expectedFinalIndex, index, "Unexpected number of expanded objects."); + test.releaseControl(); + return; + } + + // Read next property data from the queue. + var treeElement = propQueue[index].treeElement; + var path = propQueue[index].path; + var expectations = propQueue[index].expectations; + index++; + + // Expand the property. + test._hookGetPropertiesCallback(function() { + checkProperty(treeElement, path, expectations); + }, + function() { + treeElement.expand(); + }); + } + + function checkProperty(treeElement, path, expectations) { + for (var i = 0; i < expectations.length; i += 3) { + var name = expectations[i]; + var description = expectations[i+1]; + var value = expectations[i+2]; + + var propertyPath = path + "." + name; + var propertyTreeElement = test._findChildProperty(treeElement, name, path); + test.assertTrue(propertyTreeElement, 'Property "' + propertyPath + '" not found.'); + test.assertEquals(description, propertyTreeElement.property.value.description, 'Unexpected "' + propertyPath + '" description.'); + if (value) { + // Schedule property content check. + propQueue.push({ + treeElement: propertyTreeElement, + path: propertyPath, + expectations: value, + }); + } + } + // Check next property in the queue. + expandAndCheckNextProperty(); } - // Check next property in the queue. - expandAndCheckNextProperty(); - } - test.takeControl(); + test.takeControl(); }; /** - * Tests 'Pause' button will pause debugger when a snippet is evaluated. + * Tests "Pause" button will pause debugger when a snippet is evaluated. */ -TestSuite.prototype.testPauseInEval = function() { - this.showPanel('scripts'); +TestSuite.prototype.testPauseInEval = function() +{ + this.showPanel("scripts"); - var test = this; + var test = this; - var pauseButton = document.getElementById('scripts-pause'); - pauseButton.click(); + var pauseButton = document.getElementById("scripts-pause"); + pauseButton.click(); - devtools.tools.evaluateJavaScript('fib(10)'); + devtools.tools.evaluateJavaScript("fib(10)"); - this.addSniffer(WebInspector, 'pausedScript', - function() { - test.releaseControl(); - }); + this.addSniffer(WebInspector, "pausedScript", + function() { + test.releaseControl(); + }); - test.takeControl(); + test.takeControl(); }; /** * Key event with given key identifier. */ -TestSuite.createKeyEvent = function(keyIdentifier) { - var evt = document.createEvent('KeyboardEvent'); - evt.initKeyboardEvent('keydown', true /* can bubble */, true /* can cancel */, - null /* view */, keyIdentifier, ""); - return evt; +TestSuite.createKeyEvent = function(keyIdentifier) +{ + var evt = document.createEvent("KeyboardEvent"); + evt.initKeyboardEvent("keydown", true /* can bubble */, true /* can cancel */, null /* view */, keyIdentifier, ""); + return evt; }; /** * Tests console eval. */ -TestSuite.prototype.testConsoleEval = function() { - var test = this; - this.evaluateInConsole_('123', - function(resultText) { - test.assertEquals('123', resultText); - test.releaseControl(); - }); +TestSuite.prototype.testConsoleEval = function() +{ + var test = this; + this.evaluateInConsole_("123", + function(resultText) { + test.assertEquals("123", resultText); + test.releaseControl(); + }); - this.takeControl(); + this.takeControl(); }; /** * Tests console log. */ -TestSuite.prototype.testConsoleLog = function() { - WebInspector.console.visible = true; - var messages = WebInspector.console.messages; - var index = 0; - - var test = this; - var assertNext = function(line, message, opt_class, opt_count, opt_substr) { - var elem = messages[index++].toMessageElement(); - var clazz = elem.getAttribute('class'); - var expectation = (opt_count || '') + 'console_test_page.html:' + - line + message; - if (opt_substr) { - test.assertContains(elem.textContent, expectation); - } else { - test.assertEquals(expectation, elem.textContent); - } - if (opt_class) { - test.assertContains(clazz, 'console-' + opt_class); - } - }; - - assertNext('5', 'log', 'log-level'); - assertNext('7', 'debug', 'log-level'); - assertNext('9', 'info', 'log-level'); - assertNext('11', 'warn', 'warning-level'); - assertNext('13', 'error', 'error-level'); - assertNext('15', 'Message format number 1, 2 and 3.5'); - assertNext('17', 'Message format for string'); - assertNext('19', 'Object Object'); - assertNext('22', 'repeated', 'log-level', 5); - assertNext('26', 'count: 1'); - assertNext('26', 'count: 2'); - assertNext('29', 'group', 'group-title'); - index++; - assertNext('33', 'timer:', 'log-level', '', true); - assertNext('35', '1 2 3', 'log-level'); - assertNext('37', 'HTMLDocument', 'log-level'); - assertNext('39', '<html>', 'log-level', '', true); +TestSuite.prototype.testConsoleLog = function() +{ + WebInspector.console.visible = true; + var messages = WebInspector.console.messages; + var index = 0; + + var test = this; + var assertNext = function(line, message, opt_class, opt_count, opt_substr) { + var elem = messages[index++].toMessageElement(); + var clazz = elem.getAttribute("class"); + var expectation = (opt_count || '') + 'console_test_page.html:' + line + message; + if (opt_substr) + test.assertContains(elem.textContent, expectation); + else + test.assertEquals(expectation, elem.textContent); + if (opt_class) + test.assertContains(clazz, "console-" + opt_class); + }; + + assertNext("5", "log", "log-level"); + assertNext("7", "debug", "log-level"); + assertNext("9", "info", "log-level"); + assertNext("11", "warn", "warning-level"); + assertNext("13", "error", "error-level"); + assertNext("15", "Message format number 1, 2 and 3.5"); + assertNext("17", "Message format for string"); + assertNext("19", "Object Object"); + assertNext("22", "repeated", "log-level", 5); + assertNext("26", "count: 1"); + assertNext("26", "count: 2"); + assertNext("29", "group", "group-title"); + index++; + assertNext("33", "timer:", "log-level", "", true); + assertNext("35", "1 2 3", "log-level"); + assertNext("37", "HTMLDocument", "log-level"); + assertNext("39", "<html>", "log-level", "", true); }; /** * Tests eval of global objects. */ -TestSuite.prototype.testEvalGlobal = function() { - WebInspector.console.visible = true; - - var inputs = ['foo', 'foobar']; - var expectations = ['foo', 'fooValue', - 'foobar', 'ReferenceError: foobar is not defined']; - - // Do not change code below - simply add inputs and expectations above. - var initEval = function(input) { - WebInspector.console.prompt.text = input; - WebInspector.console.promptElement.dispatchEvent( - TestSuite.createKeyEvent('Enter')); - }; - var test = this; - var messagesCount = 0; - var inputIndex = 0; - this.addSniffer(WebInspector.ConsoleView.prototype, 'addMessage', - function(commandResult) { - messagesCount++; - if (messagesCount == expectations.length) { - var messages = WebInspector.console.messages; - for (var i = 0; i < expectations; ++i) { - var elem = messages[i++].toMessageElement(); - test.assertEquals(elem.textContent, expectations[i]); - } - test.releaseControl(); - } else if (messagesCount % 2 == 0) { - initEval(inputs[inputIndex++]); - } - }, true); +TestSuite.prototype.testEvalGlobal = function() +{ + WebInspector.console.visible = true; + + var inputs = ["foo", "foobar"]; + var expectations = ["foo", "fooValue", "foobar", "ReferenceError: foobar is not defined"]; + + // Do not change code below - simply add inputs and expectations above. + var initEval = function(input) { + WebInspector.console.prompt.text = input; + WebInspector.console.promptElement.dispatchEvent( TestSuite.createKeyEvent("Enter")); + }; + var test = this; + var messagesCount = 0; + var inputIndex = 0; + this.addSniffer(WebInspector.ConsoleView.prototype, "addMessage", + function(commandResult) { + messagesCount++; + if (messagesCount === expectations.length) { + var messages = WebInspector.console.messages; + for (var i = 0; i < expectations; ++i) { + var elem = messages[i++].toMessageElement(); + test.assertEquals(elem.textContent, expectations[i]); + } + test.releaseControl(); + } else if (messagesCount % 2 === 0) + initEval(inputs[inputIndex++]); + }, true); - initEval(inputs[inputIndex++]); - this.takeControl(); + initEval(inputs[inputIndex++]); + this.takeControl(); }; @@ -1850,36 +1796,36 @@ TestSuite.prototype.testEvalGlobal = function() { * Tests that Storage panel can be open and that local DOM storage is added * to the panel. */ -TestSuite.prototype.testShowStoragePanel = function() { - var test = this; - this.addSniffer(WebInspector.panels.storage, 'addDOMStorage', - function(storage) { - var orig = storage.getEntries; - storage.getEntries = function(callback) { - orig.call(this, function(entries) { - callback(entries); - test.releaseControl(); - }); - }; - try { - WebInspector.currentPanel.selectDOMStorage(storage.id); - storage.getEntries = orig; - } catch (e) { - test.fail('Exception in selectDOMStorage: ' + e); - } - }); - this.showPanel('storage'); - - // Access localStorage so that it's pushed to the frontend. - this.evaluateInConsole_( - 'setTimeout("localStorage.x = 10" , 0)', - function(resultText) { - test.assertTrue(!isNaN(resultText), - 'Failed to get timer id: ' + resultText); - }); - - // Wait until DOM storage is added to the panel. - this.takeControl(); +TestSuite.prototype.testShowStoragePanel = function() +{ + var test = this; + this.addSniffer(WebInspector.panels.storage, "addDOMStorage", + function(storage) { + var orig = storage.getEntries; + storage.getEntries = function(callback) { + orig.call(this, function(entries) { + callback(entries); + test.releaseControl(); + }); + }; + try { + WebInspector.currentPanel.selectDOMStorage(storage.id); + storage.getEntries = orig; + } catch (e) { + test.fail("Exception in selectDOMStorage: " + e); + } + }); + this.showPanel("storage"); + + // Access localStorage so that it's pushed to the frontend. + this.evaluateInConsole_( + 'setTimeout("localStorage.x = 10" , 0)', + function(resultText) { + test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText); + }); + + // Wait until DOM storage is added to the panel. + this.takeControl(); }; @@ -1892,14 +1838,13 @@ var uiTests = {}; /** * Run each test from the test suit on a fresh instance of the suite. */ -uiTests.runAllTests = function() { - // For debugging purposes. - for (var name in TestSuite.prototype) { - if (name.substring(0, 4) == 'test' && - typeof TestSuite.prototype[name] == 'function') { - uiTests.runTest(name); +uiTests.runAllTests = function() +{ + // For debugging purposes. + for (var name in TestSuite.prototype) { + if (name.substring(0, 4) === "test" && typeof TestSuite.prototype[name] === "function") + uiTests.runTest(name); } - } }; @@ -1907,8 +1852,9 @@ uiTests.runAllTests = function() { * Run specified test on a fresh instance of the test suite. * @param {string} name Name of a test method from TestSuite class. */ -uiTests.runTest = function(name) { - new TestSuite().runTest(name); +uiTests.runTest = function(name) +{ + new TestSuite().runTest(name); }; diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp index e8bc1da..30f46ab 100644 --- a/webkit/webkit.gyp +++ b/webkit/webkit.gyp @@ -23,7 +23,6 @@ # for copying them to resource dir, and for generating 'devtools.html' file. 'devtools_files': [ 'glue/devtools/js/devtools.css', - 'glue/devtools/js/base.js', 'glue/devtools/js/inspector_controller_impl.js', 'glue/devtools/js/debugger_agent.js', '../v8/tools/codemap.js', |