diff options
author | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-22 06:42:12 +0000 |
---|---|---|
committer | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-22 06:42:12 +0000 |
commit | 5b39762b9d74cd1db0b899b6c2348f84f7cf6069 (patch) | |
tree | 23d2fdb6e692cf29faf0c7748e7c1754450b78e7 | |
parent | ccd0b2138f8a024e439bdcc31f1a1a8a42915a34 (diff) | |
download | chromium_src-5b39762b9d74cd1db0b899b6c2348f84f7cf6069.zip chromium_src-5b39762b9d74cd1db0b899b6c2348f84f7cf6069.tar.gz chromium_src-5b39762b9d74cd1db0b899b6c2348f84f7cf6069.tar.bz2 |
Initial revision of the DevTools frontend.
Review URL: http://codereview.chromium.org/45012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12265 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/debugger/devtools_view.cc | 4 | ||||
-rw-r--r-- | webkit/glue/devtools/devtools_copy.rules | 18 | ||||
-rw-r--r-- | webkit/glue/devtools/js/base.js | 1083 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools.html | 115 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools.js | 55 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools_host_stub.js | 104 | ||||
-rw-r--r-- | webkit/glue/devtools/js/dom.js | 333 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inspector_controller.js | 388 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inspector_controller_impl.js | 78 | ||||
-rw-r--r-- | webkit/glue/devtools/js/json.js | 318 | ||||
-rw-r--r-- | webkit/glue/devtools/js/net.js | 79 | ||||
-rw-r--r-- | webkit/glue/glue.vcproj | 46 |
12 files changed, 2619 insertions, 2 deletions
diff --git a/chrome/browser/debugger/devtools_view.cc b/chrome/browser/debugger/devtools_view.cc index 5c92ad9..ca43a94 100644 --- a/chrome/browser/debugger/devtools_view.cc +++ b/chrome/browser/debugger/devtools_view.cc @@ -60,8 +60,8 @@ void DevToolsView::Init() { web_contents_->render_view_host()->AllowDOMUIBindings(); descriptor_->SetDevToolsHost(web_contents_->render_view_host()); - // chrome-ui://devtools/tools.html - GURL contents(std::string(chrome::kChromeUIDevToolsURL) + "tools.html"); + // chrome-ui://devtools/devtools.html + GURL contents(std::string(chrome::kChromeUIDevToolsURL) + "devtools.html"); // this will call CreateRenderView to create renderer process web_contents_->controller()->LoadURL(contents, GURL(), diff --git a/webkit/glue/devtools/devtools_copy.rules b/webkit/glue/devtools/devtools_copy.rules new file mode 100644 index 0000000..c705b4e --- /dev/null +++ b/webkit/glue/devtools/devtools_copy.rules @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<VisualStudioToolFile + Name="devtools file copy" + Version="8.00" + > + <Rules> + <CustomBuildRule + Name="devtools file copy" + CommandLine="xcopy /Y /D $(InputPath) $(OutDir)\Resources\Inspector\" + Outputs="$(OutDir)\Resources\Inspector\$(InputFileName)" + FileExtensions="*.html;*.js" + ExecutionDescription="Copying resource file..." + > + <Properties> + </Properties> + </CustomBuildRule> + </Rules> +</VisualStudioToolFile> diff --git a/webkit/glue/devtools/js/base.js b/webkit/glue/devtools/js/base.js new file mode 100644 index 0000000..d0e35e3 --- /dev/null +++ b/webkit/glue/devtools/js/base.js @@ -0,0 +1,1083 @@ +// Copyright 2006 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. +// +// 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 Bootstrap for the Google JS Library + */ + +/** + * @define {boolean} Overridden to true by the compiler when + * --mark_as_compiled is specified. + */ +var COMPILED = false; + + +/** + * Base namespace for the Google JS library. Checks to see goog is + * already defined in the current scope before assigning to prevent + * clobbering if base.js is loaded more than once. + */ +var goog = {}; // Check to see if already defined in current scope + + +/** + * Reference to the global context. In most cases this will be 'window'. + */ +goog.global = this; + + +/** + * Indicates whether or not we can call 'eval' directly to eval code in the + * global scope. Set to a Boolean by the first call to goog.globalEval (which + * empirically tests whether eval works for globals). @see goog.globalEval + * @type {boolean?} + * @private + */ +goog.evalWorksForGlobals_ = null; + + +/** + * Creates object stubs for a namespace. When present in a file, goog.provide + * also indicates that the file defines the indicated object. + * @param {string} name name of the object that this file defines. + */ +goog.provide = function(name) { + if (!COMPILED) { + // Ensure that the same namespace isn't provided twice. This is intended + // to teach new developers that 'goog.provide' is effectively a variable + // declaration. And when JSCompiler transforms goog.provide into a real + // variable declaration, the compiled JS should work the same as the raw + // JS--even when the raw JS uses goog.provide incorrectly. + if (goog.getObjectByName(name) && !goog.implicitNamespaces_[name]) { + throw 'Namespace "' + name + '" already declared.'; + } + + var namespace = name; + while ((namespace = namespace.substr(0, namespace.lastIndexOf('.')))) { + goog.implicitNamespaces_[namespace] = true; + } + } + + goog.exportPath_(name); +}; + + +if (!COMPILED) { + /** + * Namespaces implicitly defined by goog.provide. For example, + * goog.provide('goog.events.Event') implicitly declares + * that 'goog' and 'goog.events' must be namespaces. + * + * @type {Object} + * @private + */ + goog.implicitNamespaces_ = {}; +} + + +/** + * Builds an object structure for the provided namespace path, + * ensuring that names that already exist are not overwritten. For + * example: + * "a.b.c" -> a = {};a.b={};a.b.c={}; + * Used by goog.provide and goog.exportSymbol. + * @param {string} name name of the object that this file defines. + * @param {Object} opt_object the object to expose at the end of the path. + * @private + */ +goog.exportPath_ = function(name, opt_object) { + var parts = name.split('.'); + var cur = goog.global; + var part; + + // Internet Explorer exhibits strange behavior when throwing errors from + // methods externed in this manner. See the testExportSymbolExceptions in + // base_test.html for an example. + if (!(parts[0] in cur) && cur.execScript) { + cur.execScript('var ' + parts[0]); + } + + // Parentheses added to eliminate strict JS warning in Firefox. + while ((part = parts.shift())) { + if (!parts.length && goog.isDef(opt_object)) { + // last part and we have an object; use it + cur[part] = opt_object; + } else if (cur[part]) { + cur = cur[part]; + } else { + cur = cur[part] = {}; + } + } +}; + + +/** + * Returns an object based on its fully qualified name + * @param {string} name The fully qualified name. + * @return {Object?} The object or, if not found, null. + */ +goog.getObjectByName = function(name) { + var parts = name.split('.'); + var cur = goog.global; + for (var part; part = parts.shift(); ) { + if (cur[part]) { + cur = cur[part]; + } else { + return null; + } + } + return cur; +}; + + +/** + * Globalizes a whole namespace, such as goog or goog.lang. + * + * @param {Object} obj The namespace to globalize. + * @param {Object} opt_global The object to add the properties to. + * @deprecated Properties may be explicitly exported to the global scope, but + * this should no longer be done in bulk. + */ +goog.globalize = function(obj, opt_global) { + var global = opt_global || goog.global; + for (var x in obj) { + global[x] = obj[x]; + } +}; + + +/** + * Adds a dependency from a file to the files it requires. + * @param {string} relPath The path to the js file. + * @param {Array} provides An array of strings with the names of the objects + * this file provides. + * @param {Array} requires An array of strings with the names of the objects + * this file requires. + */ +goog.addDependency = function(relPath, provides, requires) { + if (!COMPILED) { + var provide, require; + var path = relPath.replace(/\\/g, '/'); + var deps = goog.dependencies_; + for (var i = 0; provide = provides[i]; i++) { + deps.nameToPath[provide] = path; + if (!(path in deps.pathToNames)) { + deps.pathToNames[path] = {}; + } + deps.pathToNames[path][provide] = true; + } + for (var j = 0; require = requires[j]; j++) { + if (!(path in deps.requires)) { + deps.requires[path] = {}; + } + deps.requires[path][require] = true; + } + } +}; + + +/** + * Implements a system for the dynamic resolution of dependencies + * that works in parallel with the BUILD system. + * @param {string} rule Rule to include, in the form goog.package.part. + */ +goog.require = function(rule) { + + // if the object already exists we do not need do do anything + if (!COMPILED) { + if (goog.getObjectByName(rule)) { + return; + } + var path = goog.getPathFromDeps_(rule); + if (path) { + goog.included_[path] = true; + goog.writeScripts_(); + } else { + // NOTE(nicksantos): We could throw an error, but this would break + // legacy users that depended on this failing silently. Instead, the + // compiler should warn us when there are invalid goog.require calls. + } + } +}; + + +/** + * Path for included scripts + * @type {string} + */ +goog.basePath = ''; + + +/** + * Null function used for default values of callbacks, etc. + * @type {Function} + */ +goog.nullFunction = function() {}; + + +/** + * When defining a class Foo with an abstract method bar(), you can do: + * + * Foo.prototype.bar = goog.abstractMethod + * + * Now if a subclass of Foo fails to override bar(), an error + * will be thrown when bar() is invoked. + * + * Note: This does not take the name of the function to override as + * an argument because that would make it more difficult to obfuscate + * our JavaScript code. + * + * @throws {Error} when invoked to indicate the method should be + * overridden. + */ +goog.abstractMethod = function() { + throw Error('unimplemented abstract method'); +}; + + +if (!COMPILED) { + /** + * Object used to keep track of urls that have already been added. This + * record allows the prevention of circular dependencies. + * @type {Object} + * @private + */ + goog.included_ = {}; + + + /** + * This object is used to keep track of dependencies and other data that is + * used for loading scripts + * @private + * @type {Object} + */ + goog.dependencies_ = { + pathToNames: {}, // 1 to many + nameToPath: {}, // 1 to 1 + requires: {}, // 1 to many + visited: {}, // used when resolving dependencies to prevent us from + // visiting the file twice + written: {} // used to keep track of script files we have written + }; + + + /** + * Tries to detect the base path of the base.js script that bootstraps + * Google JS Library + * @private + */ + goog.findBasePath_ = function() { + var doc = goog.global.document; + if (typeof doc == 'undefined') { + return; + } + if (goog.global.GOOG_BASE_PATH) { + goog.basePath = goog.global.GOOG_BASE_PATH; + return; + } else { + goog.global.GOOG_BASE_PATH = null; + } + var scripts = doc.getElementsByTagName('script'); + for (var script, i = 0; script = scripts[i]; i++) { + var src = script.src; + var l = src.length; + if (src.substr(l - 7) == 'base.js') { + goog.basePath = src.substr(0, l - 7); + return; + } + } + }; + + + /** + * Writes a script tag if, and only if, that script hasn't already been added + * to the document. (Must be called at execution time) + * @param {string} src Script source. + * @private + */ + goog.writeScriptTag_ = function(src) { + var doc = goog.global.document; + if (typeof doc != 'undefined' && + !goog.dependencies_.written[src]) { + goog.dependencies_.written[src] = true; + doc.write('<script type="text/javascript" src="' + + src + '"></' + 'script>'); + } + }; + + + /** + * Resolves dependencies based on the dependencies added using addDependency + * and calls writeScriptTag_ in the correct order. + * @private + */ + goog.writeScripts_ = function() { + // the scripts we need to write this time + var scripts = []; + var seenScript = {}; + var deps = goog.dependencies_; + + function visitNode(path) { + if (path in deps.written) { + return; + } + + // we have already visited this one. We can get here if we have cyclic + // dependencies + if (path in deps.visited) { + if (!(path in seenScript)) { + seenScript[path] = true; + scripts.push(path); + } + return; + } + + deps.visited[path] = true; + + if (path in deps.requires) { + for (var requireName in deps.requires[path]) { + visitNode(deps.nameToPath[requireName]); + } + } + + if (!(path in seenScript)) { + seenScript[path] = true; + scripts.push(path); + } + } + + for (var path in goog.included_) { + if (!deps.written[path]) { + visitNode(path); + } + } + + for (var i = 0; i < scripts.length; i++) { + if (scripts[i]) { + goog.writeScriptTag_(goog.basePath + scripts[i]); + } else { + throw Error('Undefined script input'); + } + } + }; + + + /** + * Looks at the dependency rules and tries to determine the script file that + * fulfills a particular rule. + * @param {string} rule In the form goog.namespace.Class or project.script. + * @return {string?} Url corresponding to the rule, or null. + * @private + */ + goog.getPathFromDeps_ = function(rule) { + if (rule in goog.dependencies_.nameToPath) { + return goog.dependencies_.nameToPath[rule]; + } else { + return null; + } + }; + + goog.findBasePath_(); + goog.writeScriptTag_(goog.basePath + 'deps.js'); +} + + + +//============================================================================== +// Language Enhancements +//============================================================================== + + +/** + * This is a "fixed" version of the typeof operator. It differs from the typeof + * operator in such a way that null returns 'null' and arrays return 'array'. + * @param {*} value The value to get the type of. + * @return {string} The name of the type. + */ +goog.typeOf = function(value) { + var s = typeof value; + if (s == 'object') { + if (value) { + // We cannot use constructor == Array or instanceof Array because + // different frames have different Array objects. In IE6, if the iframe + // where the array was created is destroyed, the array loses its + // prototype. Then dereferencing val.splice here throws an exception, so + // we can't use goog.isFunction. Calling typeof directly returns 'unknown' + // so that will work. In this case, this function will return false and + // most array functions will still work because the array is still + // array-like (supports length and []) even though it has lost its + // prototype. Custom object cannot have non enumerable length and + // NodeLists don't have a slice method. + if (typeof value.length == 'number' && + typeof value.splice != 'undefined' && + !goog.propertyIsEnumerable_(value, 'length')) { + return 'array'; + } + + // IE in cross-window calls does not correctly marshal the function type + // (it appears just as an object) so we cannot use just typeof val == + // 'function'. However, if the object has a call property, it is a + // function. + if (typeof value.call != 'undefined') { + return 'function'; + } + } else { + return 'null'; + } + + // In Safari typeof nodeList returns function. We would like to return + // object for those and we can detect an invalid function by making sure that + // the function object has a call method + } else if (s == 'function' && typeof value.call == 'undefined') { + return 'object'; + } + return s; +}; + +if (Object.prototype.propertyIsEnumerable) { + /** + * Safe way to test whether a property is enumarable. It allows testing + * for enumarable on objects where 'propertyIsEnumerable' is overridden or + * does not exist (like DOM nodes in IE). + * @param {Object} object The object to test if the property is enumerable. + * @param {string} propName The property name to check for. + * @return {boolean} True if the property is enumarable. + * @private + */ + goog.propertyIsEnumerable_ = function(object, propName) { + return Object.prototype.propertyIsEnumerable.call(object, propName); + }; +} else { + /** + * Safe way to test whether a property is enumarable. It allows testing + * for enumarable on objects where 'propertyIsEnumerable' is overridden or + * does not exist (like DOM nodes in IE). + * @param {Object} object The object to test if the property is enumerable. + * @param {string} propName The property name to check for. + * @return {boolean} True if the property is enumarable. + * @private + */ + goog.propertyIsEnumerable_ = function(object, propName) { + // KJS in Safari 2 is not ECMAScript compatible and lacks crucial methods + // such as propertyIsEnumerable. We therefore use a workaround. + // Does anyone know a more efficient work around? + if (propName in object) { + for (var key in object) { + if (key == propName) { + return true; + } + } + } + return false; + }; +} + +/** + * Returns true if the specified value is not |undefined|. + * WARNING: Do not use this to test if an object has a property. Use the in + * operator instead. + * @param {*} val Variable to test. + * @return {boolean} Whether variable is defined. + */ +goog.isDef = function(val) { + return typeof val != 'undefined'; +}; + + +/** + * Returns true if the specified value is |null| + * @param {*} val Variable to test. + * @return {boolean} Whether variable is null. + */ +goog.isNull = function(val) { + return val === null; +}; + + +/** + * Returns true if the specified value is defined and not null + * @param {*} val Variable to test. + * @return {boolean} Whether variable is defined and not null. + */ +goog.isDefAndNotNull = function(val) { + return goog.isDef(val) && !goog.isNull(val); +}; + + +/** + * Returns true if the specified value is an array + * @param {*} val Variable to test. + * @return {boolean} Whether variable is an array. + */ +goog.isArray = function(val) { + return goog.typeOf(val) == 'array'; +}; + + +/** + * Returns true if the object looks like an array. To qualify as array like + * the value needs to be either a NodeList or an object with a Number length + * property. + * @param {*} val Variable to test. + * @return {boolean} Whether variable is an array. + */ +goog.isArrayLike = function(val) { + var type = goog.typeOf(val); + return type == 'array' || type == 'object' && typeof val.length == 'number'; +}; + + +/** + * Returns true if the object looks like a Date. To qualify as Date-like + * the value needs to be an object and have a getFullYear() function. + * @param {*} val Variable to test. + * @return {boolean} Whether variable is a like a Date. + */ +goog.isDateLike = function(val) { + return goog.isObject(val) && typeof val.getFullYear == 'function'; +}; + + +/** + * Returns true if the specified value is a string + * @param {*} val Variable to test. + * @return {boolean} Whether variable is a string. + */ +goog.isString = function(val) { + return typeof val == 'string'; +}; + + +/** + * Returns true if the specified value is a boolean + * @param {*} val Variable to test. + * @return {boolean} Whether variable is boolean. + */ +goog.isBoolean = function(val) { + return typeof val == 'boolean'; +}; + + +/** + * Returns true if the specified value is a number + * @param {*} val Variable to test. + * @return {boolean} Whether variable is a number. + */ +goog.isNumber = function(val) { + return typeof val == 'number'; +}; + + +/** + * Returns true if the specified value is a function + * @param {*} val Variable to test. + * @return {boolean} Whether variable is a function. + */ +goog.isFunction = function(val) { + return goog.typeOf(val) == 'function'; +}; + + +/** + * Returns true if the specified value is an object. This includes arrays + * and functions. + * @param {*} val Variable to test. + * @return {boolean} Whether variable is an object. + */ +goog.isObject = function(val) { + var type = goog.typeOf(val); + return type == 'object' || type == 'array' || type == 'function'; +}; + + +/** + * Adds a hash code field to an object. The hash code is unique for the + * given object. + * @param {Object} obj The object to get the hash code for. + * @return {number} The hash code for the object. + */ +goog.getHashCode = function(obj) { + // In IE, DOM nodes do not extend Object so they do not have this method. + // we need to check hasOwnProperty because the proto might have this set. + + if (obj.hasOwnProperty && obj.hasOwnProperty(goog.HASH_CODE_PROPERTY_)) { + return obj[goog.HASH_CODE_PROPERTY_]; + } + if (!obj[goog.HASH_CODE_PROPERTY_]) { + obj[goog.HASH_CODE_PROPERTY_] = ++goog.hashCodeCounter_; + } + return obj[goog.HASH_CODE_PROPERTY_]; +}; + + +/** + * Removes the hash code field from an object. + * @param {Object} obj The object to remove the field from. + */ +goog.removeHashCode = function(obj) { + // DOM nodes in IE are not instance of Object and throws exception + // for delete. Instead we try to use removeAttribute + if ('removeAttribute' in obj) { + obj.removeAttribute(goog.HASH_CODE_PROPERTY_); + } + /** @preserveTry */ + try { + delete obj[goog.HASH_CODE_PROPERTY_]; + } catch (ex) { + } +}; + + +/** + * {String} Name for hash code property + * @private + */ +goog.HASH_CODE_PROPERTY_ = 'goog_hashCode_'; + + +/** + * @type {number} Counter for hash codes. + * @private + */ +goog.hashCodeCounter_ = 0; + + +/** + * Clone an object/array (recursively) + * @param {Object} proto Object to clone. + * @return {Object} Clone of x;. + */ +goog.cloneObject = function(proto) { + var type = goog.typeOf(proto); + if (type == 'object' || type == 'array') { + if (proto.clone) { + return proto.clone(); + } + var clone = type == 'array' ? [] : {}; + for (var key in proto) { + clone[key] = goog.cloneObject(proto[key]); + } + return clone; + } + + return proto; +}; + + +/** + * Partially applies this function to a particular 'this object' and zero or + * more arguments. The result is a new function with some arguments of the first + * function pre-filled and the value of |this| 'pre-specified'.<br><br> + * + * Remaining arguments specified at call-time are appended to the pre- + * specified ones.<br><br> + * + * Also see: {@link #partial}.<br><br> + * + * Note that bind and partial are optimized such that repeated calls to it do + * not create more than one function object, so there is no additional cost for + * something like:<br> + * + * <pre>var g = bind(f, obj); + * var h = partial(g, 1, 2, 3); + * var k = partial(h, a, b, c);</pre> + * + * Usage: + * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2'); + * barMethBound('arg3', 'arg4');</pre> + * + * @param {Function} fn A function to partially apply. + * @param {Object} self Specifies the object which |this| should point to + * when the function is run. If the value is null or undefined, it will + * default to the global object. + * @param {Object} var_args Additional arguments that are partially + * applied to the function. + * + * @return {Function} A partially-applied form of the function bind() was + * invoked as a method of. + */ +goog.bind = function(fn, self, var_args) { + var boundArgs = fn.boundArgs_; + + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + if (boundArgs) { + args.unshift.apply(args, boundArgs); + } + boundArgs = args; + } + + self = fn.boundSelf_ || self; + fn = fn.boundFn_ || fn; + + var newfn; + var context = self || goog.global; + + if (boundArgs) { + newfn = function() { + // Combine the static args and the new args into one big array + var args = Array.prototype.slice.call(arguments); + args.unshift.apply(args, boundArgs); + return fn.apply(context, args); + } + } else { + newfn = function() { + return fn.apply(context, arguments); + } + } + + newfn.boundArgs_ = boundArgs; + newfn.boundSelf_ = self; + newfn.boundFn_ = fn; + + return newfn; +}; + + +/** + * Like bind(), except that a 'this object' is not required. Useful when the + * target function is already bound. + * + * Usage: + * var g = partial(f, arg1, arg2); + * g(arg3, arg4); + * + * @param {Function} fn A function to partially apply. + * @param {Object} var_args Additional arguments that are partially + * applied to fn. + * @return {Function} A partially-applied form of the function bind() was + * invoked as a method of. + */ +goog.partial = function(fn, var_args) { + var args = Array.prototype.slice.call(arguments, 1); + args.unshift(fn, null); + return goog.bind.apply(null, args); +}; + + +/** + * Copies all the members of a source object to a target object. + * This is deprecated. Use goog.object.extend instead. + * @param {Object} target Target. + * @param {Object} source Source. + * @deprecated + */ +goog.mixin = function(target, source) { + for (var x in source) { + target[x] = source[x]; + } + + // For IE the for-in-loop does not contain any properties that are not + // enumerable on the prototype object (for example, isPrototypeOf from + // Object.prototype) but also it will not include 'replace' on objects that + // extend String and change 'replace' (not that it is common for anyone to + // extend anything except Object). +}; + + +/** + * A simple wrapper for new Date().getTime(). + * + * @return {number} An integer value representing the number of milliseconds + * between midnight, January 1, 1970 and the current time. + */ +goog.now = Date.now || (function() { + return new Date().getTime(); +}); + + +/** + * Evals javascript in the global scope. In IE this uses execScript, other + * browsers use goog.global.eval. If goog.global.eval does not evaluate in the + * global scope (for example, in Safari), appends a script tag instead. + * Throws an exception if neither execScript or eval is defined. + * @param {string} script JavaScript string. + */ +goog.globalEval = function(script) { + if (goog.global.execScript) { + goog.global.execScript(script, 'JavaScript'); + } else if (goog.global.eval) { + // Test to see if eval works + if (goog.evalWorksForGlobals_ == null) { + goog.global.eval('var _et_ = 1;'); + if (typeof goog.global['_et_'] != 'undefined') { + delete goog.global['_et_']; + goog.evalWorksForGlobals_ = true; + } else { + goog.evalWorksForGlobals_ = false; + } + } + + if (goog.evalWorksForGlobals_) { + goog.global.eval(script); + } else { + var doc = goog.global.document; + var scriptElt = doc.createElement('script'); + scriptElt.type = 'text/javascript'; + scriptElt.defer = false; + // Note(pupius): can't use .innerHTML since "t('<test>')" will fail and + // .text doesn't work in Safari 2. Therefore we append a text node. + scriptElt.appendChild(doc.createTextNode(script)); + doc.body.appendChild(scriptElt); + doc.body.removeChild(scriptElt); + } + } else { + throw Error('goog.globalEval not available'); + } +}; + + +/** + * Abstract implementation of goog.getMsg for use with localized messages + * @param {string} str Translatable string, places holders in the form.{$foo} + * @param {Object} opt_values Map of place holder name to value. + */ +goog.getMsg = function(str, opt_values) { + var values = opt_values || {}; + for (var key in values) { + str = str.replace(new RegExp('\\{\\$' + key + '\\}', 'gi'), values[key]); + } + return str; +}; + + +/** + * Exposes an unobfuscated global namespace path for the given object. + * Note that fields of the exported object *will* be obfuscated, + * unless they are exported in turn via this function or + * goog.exportProperty + * + * <p>Also handy for making public items that are defined in anonymous + * closures. + * + * ex. goog.exportSymbol('Foo', Foo); + * + * ex. goog.exportSymbol('public.path.Foo.staticFunction', + * Foo.staticFunction); + * public.path.Foo.staticFunction(); + * + * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod', + * Foo.prototype.myMethod); + * new public.path.Foo().myMethod(); + * + * @param {string} publicPath Unobfuscated name to export. + * @param {Object} object Object the name should point to. + */ +goog.exportSymbol = function(publicPath, object) { + goog.exportPath_(publicPath, object); +}; + + +/** + * Exports a property unobfuscated into the object's namespace. + * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction); + * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod); + * @param {Object} object Object whose static property is being exported. + * @param {string} publicName Unobfuscated name to export. + * @param {Object} symbol Object the name should point to. + */ +goog.exportProperty = function(object, publicName, symbol) { + object[publicName] = symbol; +}; + + + +//============================================================================== +// Extending Function +//============================================================================== + + +/** + * Some old browsers don't have Function.apply. So sad. We emulate it for them. + * @param {Object} oScope The Object within the scope of which the Function is + * applied. In other words, |this| will be bound to oScope within the body + * of the Function called with apply. + * @param {Array} args Arguments for the function. + * @return {Object} Value returned from the function. + */ +if (!Function.prototype.apply) { + Function.prototype.apply = function(oScope, args) { + var sarg = []; + var rtrn, call; + + if (!oScope) oScope = goog.global; + if (!args) args = []; + + for (var i = 0; i < args.length; i++) { + sarg[i] = 'args[' + i + ']'; + } + + call = 'oScope.__applyTemp__.peek().(' + sarg.join(',') + ');'; + + if (!oScope['__applyTemp__']) { + oScope['__applyTemp__'] = []; + } + + oScope['__applyTemp__'].push(this); + rtrn = eval(call); + oScope['__applyTemp__'].pop(); + + return rtrn; + }; +} + + +/** + * An alias to the {@link goog.bind()} global function. + * + * Usage: + * var g = f.bind(obj, arg1, arg2); + * g(arg3, arg4); + * + * @param {Object} self Specifies the object to which |this| should point + * when the function is run. If the value is null or undefined, it will + * default to the global object. + * @param {Object} var_args Additional arguments that are partially + * applied to fn. + * @return {Function} A partially-applied form of the Function on which bind() + * was invoked as a method. + * @deprecated + */ +Function.prototype.bind = function(self, var_args) { + if (arguments.length > 1) { + var args = Array.prototype.slice.call(arguments, 1); + args.unshift(this, self); + return goog.bind.apply(null, args); + } else { + return goog.bind(this, self); + } +}; + + +/** + * An alias to the {@link goog.partial()} global function. + * + * Usage: + * var g = f.partial(arg1, arg2); + * g(arg3, arg4); + * + * @param {Object} var_args Additional arguments that are partially + * applied to fn. + * @return {Function} A partially-applied form of the function partial() was + * invoked as a method of. + * @deprecated + */ +Function.prototype.partial = function(var_args) { + var args = Array.prototype.slice.call(arguments); + args.unshift(this, null); + return goog.bind.apply(null, args); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * Usage: + * <pre> + * function ParentClass(a, b) { } + * ParentClass.prototype.foo = function(a) { } + * + * function ChildClass(a, b, c) { + * ParentClass.call(this, a, b); + * } + * + * ChildClass.inherits(ParentClass); + * + * var child = new ChildClass('a', 'b', 'see'); + * child.foo(); // works + * </pre> + * + * In addition, a superclass' implementation of a method can be invoked + * as follows: + * + * <pre> + * ChildClass.prototype.foo = function(a) { + * ChildClass.superClass_.foo.call(this, a); + * // other code + * }; + * </pre> + * + * @param {Function} parentCtor Parent class. + */ +Function.prototype.inherits = function(parentCtor) { + goog.inherits(this, parentCtor); +}; + + +/** + * Static variant of Function.prototype.inherits. + * @param {Function} childCtor Child class. + * @param {Function} parentCtor Parent class. + */ +goog.inherits = function(childCtor, parentCtor) { + /** @constructor */ + function tempCtor() {}; + tempCtor.prototype = parentCtor.prototype; + childCtor.superClass_ = parentCtor.prototype; + childCtor.prototype = new tempCtor(); + childCtor.prototype.constructor = childCtor; +}; + + +/** + * Mixes in an object's properties and methods into the callee's prototype. + * Basically mixin based inheritance, thus providing an alternative method for + * adding properties and methods to a class' prototype. + * + * <pre> + * function X() {} + * X.mixin({ + * one: 1, + * two: 2, + * three: 3, + * doit: function() { return this.one + this.two + this.three; } + * }); + * + * function Y() { } + * Y.mixin(X.prototype); + * Y.prototype.four = 15; + * Y.prototype.doit2 = function() { return this.doit() + this.four; } + * }); + * + * // or + * + * function Y() { } + * Y.inherits(X); + * Y.mixin({ + * one: 10, + * four: 15, + * doit2: function() { return this.doit() + this.four; } + * }); + * </pre> + * + * @param {Object} source from which to copy properties. + * @see goog.mixin + * @deprecated + */ +Function.prototype.mixin = function(source) { + goog.mixin(this.prototype, source); +}; diff --git a/webkit/glue/devtools/js/devtools.html b/webkit/glue/devtools/js/devtools.html new file mode 100644 index 0000000..af21bd5 --- /dev/null +++ b/webkit/glue/devtools/js/devtools.html @@ -0,0 +1,115 @@ +<!-- +Copyright (c) 2009 The Chromium Authors. All rights reserved. + +This is the Chromium version of the WebInspector. This html file serves +as a deployment descriptor and specifies which js libraries to include into the +app. Once the "main" frontend method that is building WebInspector +from the js building blocks is extracted, we will be able have different +implementations of it for Chromium and WebKit. That would allow us for +example not to create WebKit Database tab and remove corresponding js files +from here. Longer term we would like to employ closure + basic js compilation. +That way js libraries would know their dependencies and js compiler would be +able to compile them into a single file. After that this HTML file will +include single <sctipt src='fe-compiled.js'> and will become upstreamable. + +Copyright (C) 2006, 2007, 2008 Apple 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: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. 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. +3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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. +--> +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <link rel="stylesheet" type="text/css" href="inspector.css"> + <script type="text/javascript" src="base.js"></script> + <script type="text/javascript" src="json.js"></script> + <script type="text/javascript" src="utilities.js"></script> + <script type="text/javascript" src="treeoutline.js"></script> + <script type="text/javascript" src="dom.js"></script> + <script type="text/javascript" src="net.js"></script> + <script type="text/javascript" src="inspector_controller.js"></script> + <script type="text/javascript" src="inspector_controller_impl.js"></script> + <script type="text/javascript" src="inspector.js"></script> + <script type="text/javascript" src="Object.js"></script> + <script type="text/javascript" src="TextPrompt.js"></script> + <script type="text/javascript" src="Placard.js"></script> + <script type="text/javascript" src="View.js"></script> + <script type="text/javascript" src="Console.js"></script> + <script type="text/javascript" src="Resource.js"></script> + <script type="text/javascript" src="ResourceCategory.js"></script> + <script type="text/javascript" src="Database.js"></script> + <script type="text/javascript" src="DOMStorage.js"></script> + <script type="text/javascript" src="DOMStorageItemsView.js"></script> + <script type="text/javascript" src="DataGrid.js"></script> + <script type="text/javascript" src="DOMStorageDataGrid.js"></script> + <script type="text/javascript" src="Script.js"></script> + <script type="text/javascript" src="Breakpoint.js"></script> + <script type="text/javascript" src="SidebarPane.js"></script> + <script type="text/javascript" src="ElementsTreeOutline.js"></script> + <script type="text/javascript" src="SidebarTreeElement.js"></script> + <script type="text/javascript" src="PropertiesSection.js"></script> + <script type="text/javascript" src="ObjectPropertiesSection.js"></script> + <script type="text/javascript" src="BreakpointsSidebarPane.js"></script> + <script type="text/javascript" src="CallStackSidebarPane.js"></script> + <script type="text/javascript" src="ScopeChainSidebarPane.js"></script> + <script type="text/javascript" src="MetricsSidebarPane.js"></script> + <script type="text/javascript" src="PropertiesSidebarPane.js"></script> + <script type="text/javascript" src="StylesSidebarPane.js"></script> + <script type="text/javascript" src="Panel.js"></script> + <script type="text/javascript" src="PanelEnablerView.js"></script> + <script type="text/javascript" src="ElementsPanel.js"></script> + <script type="text/javascript" src="ResourcesPanel.js"></script> + <script type="text/javascript" src="ScriptsPanel.js"></script> + <script type="text/javascript" src="DatabasesPanel.js"></script> + <script type="text/javascript" src="ProfilesPanel.js"></script> + <script type="text/javascript" src="ResourceView.js"></script> + <script type="text/javascript" src="SourceFrame.js"></script> + <script type="text/javascript" src="SourceView.js"></script> + <script type="text/javascript" src="FontView.js"></script> + <script type="text/javascript" src="ImageView.js"></script> + <script type="text/javascript" src="DatabaseTableView.js"></script> + <script type="text/javascript" src="DatabaseQueryView.js"></script> + <script type="text/javascript" src="ScriptView.js"></script> + <script type="text/javascript" src="ProfileView.js"></script> + <script type="text/javascript" src="devtools.js"></script> + <script type="text/javascript" src="devtools_host_stub.js"></script> +</head> +<body class="detached"> + <div id="toolbar"> + <div class="toolbar-item close"><button id="close-button"></button></div> + <div class="toolbar-item flexable-space"></div> + <div class="toolbar-item hidden" id="search-results-matches"></div> + <div class="toolbar-item"><input id="search" type="search" incremental results="0"><div id="search-toolbar-label" class="toolbar-label"></div></div> + </div> + <div id="main"> + <div id="main-panels" tabindex="0"></div> + <div id="main-status-bar" class="status-bar"><div id="anchored-status-bar-items"><button id="dock-status-bar-item" class="status-bar-item toggled"></button><button id="console-status-bar-item" class="status-bar-item"></button><div id="error-warning-count" class="hidden"></div></div></div> + </div> + <div id="console"> + <div id="console-messages"><div id="console-prompt"><br></div></div> + <div id="console-status-bar" class="status-bar"><div id="other-console-status-bar-items"><button id="clear-console-status-bar-item" class="status-bar-item"></button></div></div> + </div> +</body> +</html> diff --git a/webkit/glue/devtools/js/devtools.js b/webkit/glue/devtools/js/devtools.js new file mode 100644 index 0000000..32c5e71 --- /dev/null +++ b/webkit/glue/devtools/js/devtools.js @@ -0,0 +1,55 @@ +// 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. + +/** + * @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.Dom'); +goog.require('devtools.Net'); + +devtools.Tools = function() { +}; + + +// ToolsAgent implementation. +devtools.Tools.prototype.updateFocusedNode = function(node_id) { + var node = dom.getNodeForId(node_id); + WebInspector.updateFocusedNode(node); +}; + +// Frontend global objects. +var dom = new devtools.DomDocument(); +var net = new devtools.Net(); +var tools = new devtools.Tools(); +var context = {}; // Used by WebCore's inspector routines. + +// Overrides for existing WebInspector methods. +// TODO(pfeldman): Patch WebCore and upstream changes. + +var oldLoaded = WebInspector.loaded; +WebInspector.loaded = function() { + oldLoaded.call(this); + Preferences.ignoreWhitespace = false; + DevToolsHost.getDocumentElement(function(root) { + dom.setDocumentElement(eval(root)); + }); +}; + + +WebInspector.ElementsTreeElement.prototype.onpopulate = function() { + if (this.children.length || this.whitespaceIgnored !== + Preferences.ignoreWhitespace) + return; + this.whitespaceIgnored = Preferences.ignoreWhitespace; + var self = this; + var id = this.representedObject.id; + DevToolsHost.getChildNodes(id, function(children) { + dom.setChildren(id, eval(children)); + self.updateChildren(); + }); +}; diff --git a/webkit/glue/devtools/js/devtools_host_stub.js b/webkit/glue/devtools/js/devtools_host_stub.js new file mode 100644 index 0000000..7bee0d7 --- /dev/null +++ b/webkit/glue/devtools/js/devtools_host_stub.js @@ -0,0 +1,104 @@ +// 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. + +/** + * @fileoverview DevToolsHost Stub emulates backend functionality and allows + * DevTools frontend to function as a standalone web app. + */ +goog.provide('devtools.DevToolsHostStub'); + +/** + * @constructor + */ +devtools.DevToolsHostStub = function() { +}; + + +devtools.DevToolsHostStub.prototype.getDocumentElement = function(callback) { + setTimeout(function() { + callback(goog.json.serialize([ + 1, // id + 1, // type = Node.ELEMENT_NODE, + "HTML", // nodeName + "", // nodeValue + ["foo","bar"], // attributes + 2, // childNodeCount + ])) + }, 0); +}; + + +devtools.DevToolsHostStub.prototype.getChildNodes = function(id, callback) { + if (id == 1) { + setTimeout(function() { + callback(goog.json.serialize( + [ + [ + 2, // id + 1, // type = Node.ELEMENT_NODE, + "DIV", // nodeName + "", // nodeValue + ["foo","bar"], // attributes + 1, // childNodeCount + ], + [ + 3, // id + 3, // type = Node.TEXT_NODE, + "", // nodeName + "Text", // nodeValue + ] + ])); + }, 0); + } else if (id == 2) { + setTimeout(function() { + callback(goog.json.serialize( + [ + [ + 4, // id + 1, // type = Node.ELEMENT_NODE, + "span", // nodeName + "", // nodeValue + ["foo","bar"], // attributes + 0, // childNodeCount + ] + ])); + }, 0); + } +}; + + +devtools.DevToolsHostStub.prototype.attach = function() { +}; + + +devtools.DevToolsHostStub.prototype.evaluate = function(str) { +}; + + +devtools.DevToolsHostStub.prototype.setAttribute = function() { +}; + + +devtools.DevToolsHostStub.prototype.removeAttribute = function() { +}; + + +devtools.DevToolsHostStub.prototype.setTextNodeValue = function() { +}; + + +devtools.DevToolsHostStub.prototype.hideDOMNodeHighlight = function() { +}; + + +devtools.DevToolsHostStub.prototype.highlighDOMNode = function() { +}; + + +devtools.DevToolsHostStub.prototype.debuggerSendMessage = function() { +}; + +if (!window['DevToolsHost']) { + window['DevToolsHost'] = new devtools.DevToolsHostStub(); +}
\ No newline at end of file diff --git a/webkit/glue/devtools/js/dom.js b/webkit/glue/devtools/js/dom.js new file mode 100644 index 0000000..c745333 --- /dev/null +++ b/webkit/glue/devtools/js/dom.js @@ -0,0 +1,333 @@ +// 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. + +/** + * @fileoverview Dom and DomNode are used to represent remote DOM in the + * web inspector. + */ +goog.provide('devtools.DomDocument'); +goog.provide('devtools.DomNode'); + + +/** + * Defines indexes for the node payload properties. + */ +devtools.PayloadIndex = { + ID : 0, + TYPE : 1, + NAME : 2, + VALUE : 3, + ATTRS : 4, + HAS_CHILDREN : 5, + CHILD_NODES : 6 +}; + + +/** + * Creates document node in a given document based on a given payload data. + * @param {devtools.Doc} doc Document to create node in. + * @param {Array.<Object>} payload Data to build node based upon. + * @constructor + */ +devtools.DomNode = function(doc, payload) { + this.ownerDocument = doc; + + this.id = payload[devtools.PayloadIndex.ID]; + this.nodeType = payload[devtools.PayloadIndex.TYPE]; + this.nodeName = payload[devtools.PayloadIndex.NAME]; + this.nodeValue = payload[devtools.PayloadIndex.VALUE]; + this.textContent = this.nodeValue; + + this.attributes = []; + this.attributesMap_ = {}; + if (payload.length > devtools.PayloadIndex.ATTRS) { + this.setAttributesPayload_(payload[devtools.PayloadIndex.ATTRS]); + } + + this.childNodesCount_ = payload[devtools.PayloadIndex.HAS_CHILDREN]; + this.children = null; + + this.nextSibling = null; + this.prevSibling = null; + this.firstChild = null; + this.parentNode = null; + + if (payload.length > devtools.PayloadIndex.CHILD_NODES) { + // Has children payloads + this.setChildrenPayload_( + payload[devtools.PayloadIndex.CHILD_NODES]); + } +}; + + +/** + * Sets attributes for a given node based on a given attrs payload. + * @param {Array.<string>} attrs Attribute key-value pairs to set. + * @private + */ +devtools.DomNode.prototype.setAttributesPayload_ = function(attrs) { + for (var i = 0; i < attrs.length; i += 2) { + this.attributes.push({"name" : attrs[i], "value" : attrs[i+1]}); + this.attributesMap_[attrs[i]] = attrs[i+1]; + } +}; + + +/** + * @return True iff node has attributes. + */ +devtools.DomNode.prototype.hasAttributes = function() { + return this.attributes.length > 0; +}; + + +/** + * @return True iff node has child nodes. + */ +devtools.DomNode.prototype.hasChildNodes = function() { + return this.childNodesCount_ > 0; +}; + + +/** + * Inserts child node into this node after a given anchor. + * @param {devtools.DomNode} prev Node to insert child after. + * @param {Array.<Object>} payload Child node data. + * @private + */ +devtools.DomNode.prototype.insertChild_ = function(prev, payload) { + var node = new devtools.DomNode(this.ownerDocument, payload); + if (!prev) { + // First node + this.children = [ node ]; + } else { + this.children.splice(this.children.indexOf(prev) + 1, 0, node); + } + this.renumber_(); + return node; +}; + + +/** + * Removes child node from this node. + * @param {devtools.DomNode} node Node to remove. + * @private + */ +devtools.DomNode.prototype.removeChild_ = function(node) { + this.children.splice(this.children.indexOf(node), 1); + node.parentNode = null; + this.renumber_(); +}; + + +/** + * Sets children for this node based on the given payload. + * @param {Array.<Object>} payload Data for children. + * @private + */ +devtools.DomNode.prototype.setChildrenPayload_ = function(payloads) { + this.children = []; + for (var i = 0; i < payloads.length; ++i) { + var payload = payloads[i]; + var node = new devtools.DomNode(this.ownerDocument, payload); + this.children.push(node); + } + this.renumber_(); +}; + + +/** + * Normalizes prev/next/parent/firstChild links for this node's children. + * @private + */ +devtools.DomNode.prototype.renumber_ = function() { + this.childNodesCount_ = this.children.length; + if (this.childNodesCount_ == 0) { + this.firstChild = null; + return; + } + this.firstChild = this.children[0]; + for (var i = 0; i < this.childNodesCount_; ++i) { + var child = this.children[i]; + child.nextSibling = i + 1 < this.childNodesCount_ ? + this.children[i + 1] : null; + child.prevSibling = i - 1 >= 0 ? this.children[i - 1] : null; + child.parentNode = this; + } +}; + + +/** + * Returns attribute value. + * @param {string} name Attribute name to get value for. + @ @return {string} Attribute value. + */ +devtools.DomNode.prototype.getAttribute = function(name) { + return this.attributesMap_[name]; +}; + + +/** + * Remote Dom document abstraction. + * @constructor. + */ +devtools.DomDocument = function() { + devtools.DomNode.call(this, null, + [ + 0, // id + 9, // type = Node.DOCUMENT_NODE, + "", // nodeName + "", // nodeValue + [], // attributes + 0, // childNodeCount + ]); + this.id_to_dom_node_ = { 0 : this }; + this.listeners_ = {}; + this.defaultView = { + getComputedStyle : function() {}, + getMatchedCSSRules : function() {} + }; +}; +goog.inherits(devtools.DomDocument, devtools.DomNode); + + +/** + * Adds event listener to the Dom. + * @param {string} name Event name. + * @param {function(Event):undefined} callback Listener callback. + * @param {bool} useCapture Listener's useCapture settings. + */ +devtools.DomDocument.prototype.addEventListener = + function(name, callback, useCapture) { + var listeners = this.listeners_[name]; + if (!listeners) { + listeners = []; + this.listeners_[name] = listeners; + } + listeners.push(callback); +}; + + +/** + * Removes event listener from the Dom. + * @param {string} name Event name. + * @param {function(Event):undefined} callback Listener callback. + * @param {bool} useCapture Listener's useCapture settings. + */ +devtools.DomDocument.prototype.removeEventListener = + function(name, callback, useCapture) { + var listeners = this.listeners_[name]; + if (!listeners) { + return; + } + var index = listeners.indexOf(callback); + if (index != -1) { + listeners.splice(index, 1); + } +}; + + +/** + * Fires Dom event to the listeners for given event type. + * @param {string} name Event type. + * @param {Event} event Event to fire. + * @private + */ +devtools.DomDocument.prototype.fireDomEvent_ = function(name, event) { + var listeners = this.listeners_[name]; + if (!listeners) { + return; + } + for (var i = 0; i < listeners.length; ++i) { + listeners[i](event); + } +}; + + +/** + * Sets root document element. + * @param {Array.<Object>} payload Document element data. + */ +devtools.DomDocument.prototype.setDocumentElement = function(payload) { + this.setChildren(0, [payload]); + this.documentElement = this.firstChild; + this.fireDomEvent_("DOMContentLoaded"); +}; + + +/** + * Sets element's children. + * @param {string} id Parent id. + * @param {Array.<Object>} payloads Array with elements' data. + */ +devtools.DomDocument.prototype.setChildren = function(id, payloads) { + var parent = this.id_to_dom_node_[id]; + parent.setChildrenPayload_(payloads); + var children = parent.children; + for (var i = 0; i < children.length; ++i) { + this.id_to_dom_node_[children[i].id] = children[i]; + } +}; + + +/** + * Inserts node into the given parent after the given anchor. + * @param {string} parentId Parent id. + * @param {string} prevId Node to insert given node after. + * @param {Array.<Object>} payload Node data. + */ +devtools.DomDocument.prototype.nodeInserted = function( + parentId, prevId, payload) { + var parent = this.id_to_dom_node_[parentId]; + var prev = this.id_to_dom_node_[prevId]; + var node = parent.insertChild_(prev, payload); + this.id_to_dom_node_[node.id] = node; + var event = { target : node, relatedNode : parent }; + this.fireDomEvent_("DOMNodeInserted", event); +}; + + +/** + * Removes node from the given parent. + * @param {string} parentId Parent id. + * @param {string} nodeId Id of the node to remove. + */ +devtools.DomDocument.prototype.nodeRemoved = function( + parentId, nodeId) { + var parent = this.id_to_dom_node_[parentId]; + var node = this.id_to_dom_node_[nodeId]; + parent.removeChild_(node); + var event = { target : node, relatedNode : parent }; + this.fireDomEvent_("DOMNodeRemoved", event); + delete this.id_to_dom_node_[nodeId]; +}; + + +/** + * Sets attributes to an element with given id. + * @param {string} nodeId Id of the element to set attributes for. + * @param {Array.<Object>} attrsArray Flat attributes data. + */ +devtools.DomDocument.prototype.setAttributes = function( + nodeId, attrsArray) { + var node = this.id_to_dom_node_[nodeId]; + node.setAttributesPayload_(attrsArray); +}; + + +function firstChildSkippingWhitespace() { + return this.firstChild; +} + + +function onlyTextChild() { + if (!this.children) { + return null; + } else if (this.children.length == 1 && + this.children[0].nodeType == Node.TEXT_NODE) { + return this.children[0]; + } else { + return null; + } +} diff --git a/webkit/glue/devtools/js/inspector_controller.js b/webkit/glue/devtools/js/inspector_controller.js new file mode 100644 index 0000000..6a7871a --- /dev/null +++ b/webkit/glue/devtools/js/inspector_controller.js @@ -0,0 +1,388 @@ +// 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. + +/** + * @fileoverview Stub implementation of the InspectorController API. + * This stub class is supposed to make front-end a standalone WebApp + * that can be implemented/refactored in isolation from the Web browser + * backend. Clients need to subclass it in order to wire calls to the + * non-stub backends. + */ +goog.provide('devtools.InspectorController'); + + +/** + * Creates inspector controller stub instance. + * @constructor. + */ +devtools.InspectorController = function() { + /** + * @type {boolean} + */ + this.searchingForNode_ = false; + + /** + * @type {boolean} + */ + this.windowVisible_ = true; + + /** + * @type {number} + */ + this.attachedWindowHeight_ = 0; + + /** + * @type {boolean} + */ + this.debuggerEnabled_ = true; + + /** + * @type {boolean} + */ + this.profilerEnabled_ = true; +}; + + +/** + * Wraps javascript callback. + * @param {function():undefined} func The callback to wrap. + * @return {function():undefined} Callback wrapper. + */ +devtools.InspectorController.prototype.wrapCallback = function f(func) { + // Just return as is. + return func; +}; + + +/** + * @return {boolean} True iff inspector window is currently visible. + */ +devtools.InspectorController.prototype.isWindowVisible = function() { + return this.windowVisible_; +}; + + +/** + * @return {string} Platform identifier. + */ +devtools.InspectorController.prototype.platform = function() { + return "windows"; +}; + + +/** + * Closes inspector window. + */ +devtools.InspectorController.prototype.closeWindow = function() { + this.windowVisible_ = false; +}; + + +/** + * Attaches frontend to the backend. + */ +devtools.InspectorController.prototype.attach = function() { +}; + + +/** + * Detaches frontend from the backend. + */ +devtools.InspectorController.prototype.detach = function() { +}; + + +/** + * Clears console message log in the backend. + */ +devtools.InspectorController.prototype.clearMessages = function() { +}; + + +/** + * Returns true iff browser is currently in the search for node mode. + * @return {boolean} True is currently searching for a node. + */ +devtools.InspectorController.prototype.searchingForNode = function() { + return this.searchingForNode_; +}; + + +/** + * Initiates search for a given query starting on a given row. + * @param {number} sourceRow Row to start searching from. + * @param {string} query Query string for search for. + */ +devtools.InspectorController.prototype.search = function(sourceRow, query) { +}; + + +/** + * Toggles node search mode on/off. + */ +devtools.InspectorController.prototype.toggleNodeSearch = function() { + this.searchingForNode_ = !this.searchingForNode_; +}; + + +/** + * Sets the inspector window height while in the attached mode. + * @param {number} height Window height being set. + */ +devtools.InspectorController.prototype.setAttachedWindowHeight = + function(height) { + this.attachedWindowHeight_ = height; +}; + + +/** + * Moves window by the given offset. + * @param {number} x X offset. + * @param {number} y Y offset. + */ +devtools.InspectorController.prototype.moveByUnrestricted = function(x, y) { +}; + + +/** + * Adds resource with given identifier into the given iframe element. + * @param {number} identifier Identifier of the resource to add into the frame. + * @param {Element} element Element to add resource content to. + */ +devtools.InspectorController.prototype.addResourceSourceToFrame = + function(identifier, element) { +}; + + +/** + * Adds given source of a given mimeType into the given iframe element. + * @param {string} mimeType MIME type of the content to be added. + * @param {string} source String content to be added. + * @param {Element} element Element to add resource content to. + */ +devtools.InspectorController.prototype.addSourceToFrame = + function(mimeType, source, element) { + return true; +}; + + +/** + * Returns document node corresponding to the resource with given id. + * @return {Node} Node containing the resource. + */ +devtools.InspectorController.prototype.getResourceDocumentNode = + function(identifier) { + return undefined; +}; + + +/** + * Highlights the given node on the page. + * @param {Node} node Node to highlight. + */ +devtools.InspectorController.prototype.highlightDOMNode = function(node) { + // Does nothing in stub. +}; + + +/** + * Clears current highlight. + */ +devtools.InspectorController.prototype.hideDOMNodeHighlight = function() { + // Does nothing in stub. +}; + + +/** + * @return {window} Inspectable window instance. + */ +devtools.InspectorController.prototype.inspectedWindow = function() { + return window; +}; + + +/** + * Notifies backend that the frontend has been successfully loaded. + */ +devtools.InspectorController.prototype.loaded = function() { + // Does nothing in stub. +}; + + +/** + * @return {string} Url of the i18n-ed strings map. + */ +devtools.InspectorController.prototype.localizedStringsURL = function() { + return undefined; +}; + + +/** + * @return {boolean} True iff window is currently unloading. + */ +devtools.InspectorController.prototype.windowUnloading = function() { + return false; +}; + + +/** + * @return {string} Identifiers of the panels that should be hidden. + */ +devtools.InspectorController.prototype.hiddenPanels = function() { + return ""; +}; + + +/** + * @return {boolean} True iff debugger is enabled. + */ +devtools.InspectorController.prototype.debuggerEnabled = function() { + return this.debuggerEnabled_; +}; + + +/** + * Enables debugger. + */ +devtools.InspectorController.prototype.enableDebugger = function() { + this.debuggerEnabled_ = true; +}; + + +/** + * Disables debugger. + */ +devtools.InspectorController.prototype.disableDebugger = function() { + this.debuggerEnabled_ = false; +}; + + +/** + * Adds breakpoint to the given line of the source with given ID. + * @param {string} sourceID Source Id to add breakpoint to. + * @param {number} line Line number to add breakpoint to. + */ +devtools.InspectorController.prototype.addBreakpoint = + function(sourceID, line) { +}; + + +/** + * Removes breakpoint from the given line of the source with given ID. + * @param {string} sourceID Source Id to remove breakpoint from. + * @param {number} line Line number to remove breakpoint from. + */ +devtools.InspectorController.prototype.removeBreakpoint = + function(sourceID, line) { +}; + + +/** + * Tells backend to pause in the debugger. + */ +devtools.InspectorController.prototype.pauseInDebugger = function() { + // Does nothing in stub. +}; + + +/** + * Tells backend to pause in the debugger on the exceptions. + */ +devtools.InspectorController.prototype.pauseOnExceptions = function() { + // Does nothing in stub. +}; + + +/** + * Tells backend to resume execution. + */ +devtools.InspectorController.prototype.resumeDebugger = function() { +}; + + +/** + * @return {boolean} True iff profiler is enabled. + */ +devtools.InspectorController.prototype.profilerEnabled = function() { + return true; +}; + + +/** + * Enables profiler. + */ +devtools.InspectorController.prototype.enableProfiler = function() { + this.profilerEnabled_ = true; +}; + + +/** + * Disables profiler. + */ +devtools.InspectorController.prototype.disableProfiler = function() { + this.profilerEnabled_ = false; +}; + + +/** + * Returns given callframe while on a debugger break. + * @return {Object} Current call frame. + */ +devtools.InspectorController.prototype.currentCallFrame = function() { + return undefined; +}; + + +/** + * Tells backend to start collecting profiler data. + */ +devtools.InspectorController.prototype.startProfiling = function() { +}; + + +/** + * Tells backend to stop collecting profiler data. + */ +devtools.InspectorController.prototype.stopProfiling = function() { +}; + + +/** + * @return {Array.<Object>} Profile snapshots array. + */ +devtools.InspectorController.prototype.profiles = function() { + return []; +}; + + +/** + * @return {Array.<string>} Database table names available offline. + */ +devtools.InspectorController.prototype.databaseTableNames = + function(database) { + return []; +}; + + +/** + * Tells backend to step into the function in debugger. + */ +devtools.InspectorController.prototype.stepIntoStatementInDebugger = + function() { +}; + + +/** + * Tells backend to step out of the function in debugger. + */ +devtools.InspectorController.prototype.stepOutOfFunctionInDebugger = + function() {}; + + +/** + * Tells backend to step over the statement in debugger. + */ +devtools.InspectorController.prototype.stepOverStatementInDebugger = + function() { +}; diff --git a/webkit/glue/devtools/js/inspector_controller_impl.js b/webkit/glue/devtools/js/inspector_controller_impl.js new file mode 100644 index 0000000..91199fc --- /dev/null +++ b/webkit/glue/devtools/js/inspector_controller_impl.js @@ -0,0 +1,78 @@ +// 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. + +/** + * @fileoverview DevTools' implementation of the InspectorController API. + */ +goog.require('devtools.InspectorController'); + +goog.provide('devtools.InspectorControllerImpl'); + +devtools.InspectorControllerImpl = function() { + devtools.InspectorController.call(this); + this.frame_element_id_ = 1; + + this.window_ = { + get document() { + return dom; + }, + get Node() { + return devtools.DomNode; + }, + get Element() { + return devtools.DomNode; + } + }; +}; +goog.inherits(devtools.InspectorControllerImpl, + devtools.InspectorController); + + +/** + * {@inheritDoc}. + */ +devtools.InspectorControllerImpl.prototype.hiddenPanels = function() { + return "scripts,profiles,databases"; +}; + + +/** + * {@inheritDoc}. + */ +devtools.InspectorControllerImpl.prototype.addSourceToFrame = + function(mimeType, source, element) { + if (!element.id) { + element.id = "f" + this.frame_element_id_++; + } + DevToolsHost.addSourceToFrame(mimeType, source, element.id); + return true; +}; + + +/** + * {@inheritDoc}. + */ +devtools.InspectorControllerImpl.prototype.hideDOMNodeHighlight = function() { + DevToolsHost.hideDOMNodeHighlight(); +}; + + +/** + * {@inheritDoc}. + */ +devtools.InspectorControllerImpl.prototype.highlightDOMNode = + function(hoveredNode) { + DevToolsHost.highlightDOMNode(hoveredNode.id); +}; + + +/** + * {@inheritDoc}. + */ +devtools.InspectorControllerImpl.prototype.inspectedWindow = function() { + return this.window_; +}; + + +var InspectorController = new devtools.InspectorControllerImpl(); diff --git a/webkit/glue/devtools/js/json.js b/webkit/glue/devtools/js/json.js new file mode 100644 index 0000000..227d7d1 --- /dev/null +++ b/webkit/glue/devtools/js/json.js @@ -0,0 +1,318 @@ +// Copyright 2006 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. +// +// 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 JSON utility functions + */ + + + +goog.provide('goog.json'); +goog.provide('goog.json.Serializer'); + + +/** + * Tests if a string is an invalid JSON string. This only ensures that we are + * not using any invalid characters + * @param {string} s The string to test. + * @return {boolean} True if the input is a valid JSON string. + * @private + */ +goog.json.isValid_ = function(s) { + // All empty whitespace is not valid. + if (/^\s*$/.test(s)) { + return false; + } + + // This is taken from http://www.json.org/json2.js which is released to the + // public domain. + // Changes: We dissallow \u2028 Line separator and \u2029 Paragraph separator + // inside strings. We also treat \u2028 and \u2029 as whitespace which they + // are in the RFC but IE and Safari does not match \s to these so we need to + // include them in the reg exps in all places where whitespace is allowed. + + // Parsing happens in three stages. In the first stage, we run the text + // against regular expressions that look for non-JSON patterns. We are + // especially concerned with '()' and 'new' because they can cause invocation, + // and '=' because it can cause mutation. But just to be safe, we want to + // reject all unexpected forms. + + // We split the first stage into 4 regexp operations in order to work around + // crippling inefficiencies in IE's and Safari's regexp engines. First we + // replace all backslash pairs with '@' (a non-JSON character). Second, we + // replace all simple value tokens with ']' characters. Third, we delete all + // open brackets that follow a colon or comma or that begin the text. Finally, + // we look to see that the remaining characters are only whitespace or ']' or + // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + // Don't make these static since they have the global flag. + var backslashesRe = /\\["\\\/bfnrtu]/g; + var simpleValuesRe = + /"[^"\\\n\r\u2028\u2029\x00-\x1f\x7f-\x9f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; + var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g; + var remainderRe = /^[\],:{}\s\u2028\u2029]*$/; + + return remainderRe.test(s.replace(backslashesRe, '@'). + replace(simpleValuesRe, ']'). + replace(openBracketsRe, '')); +}; + + +/** + * Parses a JSON string and returns the result. This throws an exception if + * the string is an invalid JSON string. + * + * If the user agent has built in support for parsing JSON (using + * <code>String.prototype.parseJSON</code>) that will be used. + * + * Note that this is very slow on large strings. If you trust the source of + * the string then you should use unsafeParse instead. + * + * @param {string} s The JSON string to parse. + * @return {Object} The object generated from the JSON string. + */ +goog.json.parse = function(s) { + s = String(s); + if (typeof s.parseJSON == 'function') { + return s.parseJSON(); + } + if (goog.json.isValid_(s)) { + /** @preserveTry */ + try { + return eval('(' + s + ')'); + } catch (ex) { + } + } + throw Error('Invalid JSON string: ' + s); +}; + + +/** + * Parses a JSON string and returns the result. This uses eval so it is open + * to security issues and it should only be used if you trust the source. + * + * @param {string} s The JSON string to parse. + * @return {Object} The object generated from the JSON string. + */ +goog.json.unsafeParse = function(s) { + return eval('(' + s + ')'); +}; + + +/** + * Instance of the serializer object. + * @type {goog.json.Serializer} + * @private + */ +goog.json.serializer_ = null; + + +/** + * Serializes an object or a value to a JSON string. + * + * If the user agent has built in support for serializing JSON (using + * <code>Object.prototype.toJSONString</code>) that will be used. + * + * @param {Object} object The object to serialize. + * @throws Error if there are loops in the object graph. + * @return {string} A JSON string representation of the input. + */ +goog.json.serialize = function(object) { + if (!goog.json.serializer_) { + goog.json.serializer_ = new goog.json.Serializer; + } + return goog.json.serializer_.serialize(object); +}; + + + +/** + * Class that is used to serialize JSON objects to a string. + * @constructor + */ +goog.json.Serializer = function() { +}; + + +/** + * Serializes an object or a value to a JSON string. + * + * If the user agent has built in support for serializing JSON (using + * <code>Object.prototype.toJSONString</code>) that will be used. + * + * @param {Object?} object The object to serialize. + * @throws Error if there are loops in the object graph. + * @return {string} A JSON string representation of the input. + */ +goog.json.Serializer.prototype.serialize = function(object) { + // null and undefined cannot have properties. (null == undefined) + if (object != null && typeof object.toJSONString == 'function') { + return object.toJSONString(); + } + var sb = []; + this.serialize_(object, sb); + return sb.join(''); +}; + + +/** + * Serializes a generic value to a JSON string + * @private + * @param {Object?} object The object to serialize. + * @param {Array} sb Array used as a string builder. + * @throws Error if there are loops in the object graph. + */ +goog.json.Serializer.prototype.serialize_ = function(object, sb) { + switch (typeof object) { + case 'string': + this.serializeString_(object, sb); + break; + case 'number': + this.serializeNumber_(object, sb); + break; + case 'boolean': + sb.push(object); + break; + case 'undefined': + sb.push('null'); + break; + case 'object': + if (object == null) { + sb.push('null'); + break; + } + if (goog.isArray(object)) { + this.serializeArray_(object, sb); + break; + } + // should we allow new String, new Number and new Boolean to be treated + // as string, number and boolean? Most implementations do not and the + // need is not very big + this.serializeObject_(object, sb); + break; + default: + throw Error('Unknown type: ' + typeof object); + } +}; + + +/** + * Character mappings used internally for goog.string.quote + * @private + * @type {Object} + */ +goog.json.Serializer.charToJsonCharCache_ = { + '\"': '\\"', + '\\': '\\\\', + '/': '\\/', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + + '\x0B': '\\u000b' // '\v' is not supported in JScript +}; + + +/** + * Serializes a string to a JSON string + * @private + * @param {string} s The string to serialize. + * @param {Array} sb Array used as a string builder. + */ +goog.json.Serializer.prototype.serializeString_ = function(s, sb) { + // The official JSON implementation does not work with international + // characters. + sb.push('"', s.replace(/[\\\"\x00-\x1f\x80-\uffff]/g, function(c) { + // caching the result improves performance by a factor 2-3 + if (c in goog.json.Serializer.charToJsonCharCache_) { + return goog.json.Serializer.charToJsonCharCache_[c]; + } + + var cc = c.charCodeAt(0); + var rv = '\\u'; + if (cc < 16) { + rv += '000'; + } else if (cc < 256) { + rv += '00'; + } else if (cc < 4096) { // \u1000 + rv += '0'; + } + return goog.json.Serializer.charToJsonCharCache_[c] = rv + cc.toString(16); + }), '"'); +}; + + +/** + * Serializes a number to a JSON string + * @private + * @param {number} n The number to serialize. + * @param {Array} sb Array used as a string builder. + */ +goog.json.Serializer.prototype.serializeNumber_ = function(n, sb) { + sb.push(isFinite(n) && !isNaN(n) ? n : 'null'); +}; + + +/** + * Serializes an array to a JSON string + * @private + * @param {Array} arr The array to serialize. + * @param {Array} sb Array used as a string builder. + */ +goog.json.Serializer.prototype.serializeArray_ = function(arr, sb) { + var l = arr.length; + sb.push('['); + var sep = ''; + for (var i = 0; i < l; i++) { + sb.push(sep) + this.serialize_(arr[i], sb); + sep = ','; + } + sb.push(']'); +}; + + +/** + * Serializes an object to a JSON string + * @private + * @param {Object} obj The object to serialize. + * @param {Array} sb Array used as a string builder. + */ +goog.json.Serializer.prototype.serializeObject_ = function(obj, sb) { + sb.push('{'); + var sep = ''; + for (var key in obj) { + sb.push(sep); + this.serializeString_(key, sb); + sb.push(':'); + this.serialize_(obj[key], sb); + sep = ','; + } + sb.push('}'); +}; diff --git a/webkit/glue/devtools/js/net.js b/webkit/glue/devtools/js/net.js new file mode 100644 index 0000000..92933b2 --- /dev/null +++ b/webkit/glue/devtools/js/net.js @@ -0,0 +1,79 @@ +// 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. + +/** + * @fileoverview 'Net' manages resources along with the corresponding + * HTTP requests and responses. + * web inspector. + */ +goog.provide('devtools.Net'); + +devtools.Net = function() { + this.resources_ = {}; + this.id_for_url_ = {}; +}; + + +devtools.Net.prototype.willSendRequest = function(identifier, request) { + var mainResource = false; + var cached = false; + var resource = new WebInspector.Resource(request.requestHeaders, + request.url, request.domain, request.path, request.lastPathComponent, + identifier, mainResource, cached); + resource.startTime = request.startTime; + WebInspector.addResource(resource); + this.resources_[identifier] = resource; + this.id_for_url_[request.url] = identifier; +}; + + +devtools.Net.prototype.didReceiveResponse = function(identifier, response) { + var resource = this.resources_[identifier]; + if (!resource) { + return; + } + resource.expectedContentLength = response.expectedContentLength; + resource.responseStatusCode = response.responseStatusCode; + resource.mimeType = response.mimeType; + resource.suggestedFilename = response.suggestedFilename; + var mimeType = response.mimeType; + if (mimeType.indexOf("image/") == 0) { + resource.type = WebInspector.Resource.Type.Image; + } else if (mimeType.indexOf("text/html") == 0) { + resource.type = WebInspector.Resource.Type.Document; + } else if (mimeType.indexOf("script") != -1 || + response.url.indexOf(".js") != -1) { + resource.type = WebInspector.Resource.Type.Script; + } else { + resource.type = WebInspector.Resource.Type.Other; + } + resource.responseReceivedTime = response.responseReceivedTime; +}; + + +devtools.Net.prototype.didFinishLoading = function(identifier, value) { + var resource = this.resources_[identifier]; + if (!resource) { + return; + } + resource.endTime = value.endTime; + resource.finished = true; + resource.failed = false; +}; + + +devtools.Net.prototype.didFailLoading = function(identifier, value) { + var resource = this.resources_[identifier]; + if (!resource) { + return; + } + resource.endTime = value.endTime; + resource.finished = false; + resource.failed = true; +}; + + +devtools.Net.prototype.setResourceContent = function(identifier, + content) { +}; diff --git a/webkit/glue/glue.vcproj b/webkit/glue/glue.vcproj index 17cfc38..7cab829 100644 --- a/webkit/glue/glue.vcproj +++ b/webkit/glue/glue.vcproj @@ -13,6 +13,9 @@ />
</Platforms>
<ToolFiles>
+ <ToolFile
+ RelativePath=".\devtools\devtools_copy.rules"
+ />
</ToolFiles>
<Configurations>
<Configuration
@@ -24,6 +27,9 @@ Name="VCPreBuildEventTool"
/>
<Tool
+ Name="devtools file copy"
+ />
+ <Tool
Name="VCCustomBuildTool"
/>
<Tool
@@ -912,6 +918,46 @@ RelativePath=".\devtools\tools_agent.h"
>
</File>
+ <Filter
+ Name="js"
+ >
+ <File
+ RelativePath=".\devtools\js\base.js"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\devtools.html"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\devtools.js"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\devtools_host_stub.js"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\dom.js"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\inspector_controller.js"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\inspector_controller_impl.js"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\json.js"
+ >
+ </File>
+ <File
+ RelativePath=".\devtools\js\net.js"
+ >
+ </File>
+ </Filter>
</Filter>
</Files>
<Globals>
|