summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-22 06:42:12 +0000
committerpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-22 06:42:12 +0000
commit5b39762b9d74cd1db0b899b6c2348f84f7cf6069 (patch)
tree23d2fdb6e692cf29faf0c7748e7c1754450b78e7
parentccd0b2138f8a024e439bdcc31f1a1a8a42915a34 (diff)
downloadchromium_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.cc4
-rw-r--r--webkit/glue/devtools/devtools_copy.rules18
-rw-r--r--webkit/glue/devtools/js/base.js1083
-rw-r--r--webkit/glue/devtools/js/devtools.html115
-rw-r--r--webkit/glue/devtools/js/devtools.js55
-rw-r--r--webkit/glue/devtools/js/devtools_host_stub.js104
-rw-r--r--webkit/glue/devtools/js/dom.js333
-rw-r--r--webkit/glue/devtools/js/inspector_controller.js388
-rw-r--r--webkit/glue/devtools/js/inspector_controller_impl.js78
-rw-r--r--webkit/glue/devtools/js/json.js318
-rw-r--r--webkit/glue/devtools/js/net.js79
-rw-r--r--webkit/glue/glue.vcproj46
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>