summaryrefslogtreecommitdiff
path: root/Source/WebInspectorUI/UserInterface/RemoteObject.js
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/WebInspectorUI/UserInterface/RemoteObject.js
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/RemoteObject.js')
-rw-r--r--Source/WebInspectorUI/UserInterface/RemoteObject.js492
1 files changed, 492 insertions, 0 deletions
diff --git a/Source/WebInspectorUI/UserInterface/RemoteObject.js b/Source/WebInspectorUI/UserInterface/RemoteObject.js
new file mode 100644
index 000000000..9a9a1d304
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/RemoteObject.js
@@ -0,0 +1,492 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @param {string|undefined} objectId
+ * @param {string} type
+ * @param {string|undefined} subtype
+ * @param {*} value
+ * @param {string=} description
+ */
+WebInspector.RemoteObject = function(objectId, type, subtype, value, description)
+{
+ this._type = type;
+ this._subtype = subtype;
+ if (objectId) {
+ // handle
+ this._objectId = objectId;
+ this._description = description;
+ this._hasChildren = true;
+ } else {
+ // Primitive or null object.
+ console.assert(type !== "object" || value === null);
+ this._description = description || (value + "");
+ this._hasChildren = false;
+ this.value = value;
+ }
+}
+
+/**
+ * @param {number|string|boolean} value
+ * @return {WebInspector.RemoteObject}
+ */
+WebInspector.RemoteObject.fromPrimitiveValue = function(value)
+{
+ return new WebInspector.RemoteObject(undefined, typeof value, undefined, value);
+}
+
+/**
+ * @param {Object} value
+ * @return {WebInspector.RemoteObject}
+ */
+WebInspector.RemoteObject.fromLocalObject = function(value)
+{
+ return new WebInspector.LocalJSONObject(value);
+}
+
+/**
+ * @param {WebInspector.DOMNode} node
+ * @param {string} objectGroup
+ * @param {function(?WebInspector.RemoteObject)} callback
+ */
+WebInspector.RemoteObject.resolveNode = function(node, objectGroup, callback)
+{
+ /**
+ * @param {?Protocol.Error} error
+ * @param {RuntimeAgent.RemoteObject} object
+ */
+ function mycallback(error, object)
+ {
+ if (!callback)
+ return;
+
+ if (error || !object)
+ callback(null);
+ else
+ callback(WebInspector.RemoteObject.fromPayload(object));
+ }
+ DOMAgent.resolveNode(node.id, objectGroup, mycallback);
+}
+
+/**
+ * @param {RuntimeAgent.RemoteObject} payload
+ * @return {WebInspector.RemoteObject}
+ */
+WebInspector.RemoteObject.fromPayload = function(payload)
+{
+ console.assert(typeof payload === "object", "Remote object payload should only be an object");
+
+ return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description);
+}
+
+/**
+ * @param {WebInspector.RemoteObject} remoteObject
+ * @return {string}
+ */
+WebInspector.RemoteObject.type = function(remoteObject)
+{
+ if (remoteObject === null)
+ return "null";
+
+ var type = typeof remoteObject;
+ if (type !== "object" && type !== "function")
+ return type;
+
+ return remoteObject.type;
+}
+
+WebInspector.RemoteObject.prototype = {
+ /** @return {RuntimeAgent.RemoteObjectId} */
+ get objectId()
+ {
+ return this._objectId;
+ },
+
+ /** @return {string} */
+ get type()
+ {
+ return this._type;
+ },
+
+ /** @return {string|undefined} */
+ get subtype()
+ {
+ return this._subtype;
+ },
+
+ /** @return {string|undefined} */
+ get description()
+ {
+ return this._description;
+ },
+
+ /** @return {boolean} */
+ get hasChildren()
+ {
+ return this._hasChildren;
+ },
+
+ /**
+ * @param {function(Array.<WebInspector.RemoteObjectProperty>)} callback
+ */
+ getOwnProperties: function(callback)
+ {
+ this._getProperties(true, callback);
+ },
+
+ /**
+ * @param {function(Array.<WebInspector.RemoteObjectProperty>)} callback
+ */
+ getAllProperties: function(callback)
+ {
+ this._getProperties(false, callback);
+ },
+
+ /**
+ * @param {boolean} ownProperties
+ * @param {function(Array.<RuntimeAgent.RemoteObject>)} callback
+ */
+ _getProperties: function(ownProperties, callback)
+ {
+ if (!this._objectId) {
+ callback([]);
+ return;
+ }
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {Array.<WebInspector.RemoteObjectProperty>} properties
+ */
+ function remoteObjectBinder(error, properties)
+ {
+ if (error) {
+ callback(null);
+ return;
+ }
+ var result = [];
+ for (var i = 0; properties && i < properties.length; ++i) {
+ var property = properties[i];
+ if (property.get || property.set) {
+ if (property.get)
+ result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property));
+ if (property.set)
+ result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property));
+ } else
+ result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property));
+ }
+ callback(result);
+ }
+ RuntimeAgent.getProperties(this._objectId, ownProperties, remoteObjectBinder);
+ },
+
+ /**
+ * @param {string} name
+ * @param {string} value
+ * @param {function(string=)} callback
+ */
+ setPropertyValue: function(name, value, callback)
+ {
+ if (!this._objectId) {
+ callback("Can't set a property of non-object.");
+ return;
+ }
+
+ RuntimeAgent.evaluate.invoke({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {RuntimeAgent.RemoteObject} result
+ * @param {boolean=} wasThrown
+ */
+ function evaluatedCallback(error, result, wasThrown)
+ {
+ if (error || wasThrown) {
+ callback(error || result.description);
+ return;
+ }
+
+ function setPropertyValue(propertyName, propertyValue)
+ {
+ this[propertyName] = propertyValue;
+ }
+
+ delete result.description; // Optimize on traffic.
+ RuntimeAgent.callFunctionOn(this._objectId, setPropertyValue.toString(), [{ value:name }, result], true, undefined, propertySetCallback.bind(this));
+ if (result._objectId)
+ RuntimeAgent.releaseObject(result._objectId);
+ }
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {RuntimeAgent.RemoteObject} result
+ * @param {boolean=} wasThrown
+ */
+ function propertySetCallback(error, result, wasThrown)
+ {
+ if (error || wasThrown) {
+ callback(error || result.description);
+ return;
+ }
+ callback();
+ }
+ },
+
+ /**
+ * @param {function(DOMAgent.NodeId)} callback
+ */
+ pushNodeToFrontend: function(callback)
+ {
+ if (this._objectId)
+ WebInspector.domTreeManager.pushNodeToFrontend(this._objectId, callback);
+ else
+ callback(0);
+ },
+
+ /**
+ * @param {string} functionDeclaration
+ * @param {function(?WebInspector.RemoteObject)} callback
+ */
+ callFunction: function(functionDeclaration, args, callback)
+ {
+ function mycallback(error, result, wasThrown)
+ {
+ callback((error || wasThrown) ? null : WebInspector.RemoteObject.fromPayload(result));
+ }
+
+ RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, mycallback);
+ },
+
+ /**
+ * @param {string} functionDeclaration
+ * @param {function(*)} callback
+ */
+ callFunctionJSON: function(functionDeclaration, args, callback)
+ {
+ function mycallback(error, result, wasThrown)
+ {
+ callback((error || wasThrown) ? null : result.value);
+ }
+
+ RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, mycallback);
+ },
+
+ release: function()
+ {
+ RuntimeAgent.releaseObject(this._objectId);
+ },
+
+ /**
+ * @return {number}
+ */
+ arrayLength: function()
+ {
+ if (this.subtype !== "array")
+ return 0;
+
+ var matches = this._description.match(/\[([0-9]+)\]/);
+ if (!matches)
+ return 0;
+ return parseInt(matches[1], 10);
+ }
+}
+
+/**
+ * @constructor
+ * @param {string} name
+ * @param {WebInspector.RemoteObject} value
+ * @param {Object=} descriptor
+ */
+WebInspector.RemoteObjectProperty = function(name, value, descriptor)
+{
+ this.name = name;
+ this.value = value;
+ this.enumerable = descriptor ? !!descriptor.enumerable : true;
+ this.writable = descriptor ? !!descriptor.writable : true;
+ if (descriptor && descriptor.wasThrown)
+ this.wasThrown = true;
+}
+
+/**
+ * @param {string} name
+ * @param {string} value
+ * @return {WebInspector.RemoteObjectProperty}
+ */
+WebInspector.RemoteObjectProperty.fromPrimitiveValue = function(name, value)
+{
+ return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value));
+}
+
+// The below is a wrapper around a local object that provides an interface comaptible
+// with RemoteObject, to be used by the UI code (primarily ObjectPropertiesSection).
+// Note that only JSON-compliant objects are currently supported, as there's no provision
+// for traversing prototypes, extracting class names via constuctor, handling properties
+// or functions.
+
+/**
+ * @constructor
+ * @extends {WebInspector.RemoteObject}
+ * @param {Object} value
+ */
+WebInspector.LocalJSONObject = function(value)
+{
+ this._value = value;
+}
+
+WebInspector.LocalJSONObject.prototype = {
+ /**
+ * @return {string}
+ */
+ get description()
+ {
+ if (this._cachedDescription)
+ return this._cachedDescription;
+
+ if (this.type === "object") {
+ switch (this.subtype) {
+ case "array":
+ function formatArrayItem(property)
+ {
+ return property.value.description;
+ }
+ this._cachedDescription = this._concatenate("[", "]", formatArrayItem);
+ break;
+ case "null":
+ this._cachedDescription = "null";
+ break;
+ default:
+ function formatObjectItem(property)
+ {
+ return property.name + ":" + property.value.description;
+ }
+ this._cachedDescription = this._concatenate("{", "}", formatObjectItem);
+ }
+ } else
+ this._cachedDescription = String(this._value);
+
+ return this._cachedDescription;
+ },
+
+ /**
+ * @param {string} prefix
+ * @param {string} suffix
+ * @return {string}
+ */
+ _concatenate: function(prefix, suffix, formatProperty)
+ {
+ const previewChars = 100;
+
+ var buffer = prefix;
+ var children = this._children();
+ for (var i = 0; i < children.length; ++i) {
+ var itemDescription = formatProperty(children[i]);
+ if (buffer.length + itemDescription.length > previewChars) {
+ buffer += ",\u2026";
+ break;
+ }
+ if (i)
+ buffer += ", ";
+ buffer += itemDescription;
+ }
+ buffer += suffix;
+ return buffer;
+ },
+
+ /**
+ * @return {string}
+ */
+ get type()
+ {
+ return typeof this._value;
+ },
+
+ /**
+ * @return {string|undefined}
+ */
+ get subtype()
+ {
+ if (this._value === null)
+ return "null";
+
+ if (this._value instanceof Array)
+ return "array";
+
+ return undefined;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ get hasChildren()
+ {
+ return typeof this._value === "object" && this._value !== null && !isEmptyObject(this._value);
+ },
+
+ /**
+ * @param {function(Array.<WebInspector.RemoteObjectProperty>)} callback
+ */
+ getOwnProperties: function(callback)
+ {
+ callback(this._children());
+ },
+
+ /**
+ * @param {function(Array.<WebInspector.RemoteObjectProperty>)} callback
+ */
+ getAllProperties: function(callback)
+ {
+ callback(this._children());
+ },
+
+ /**
+ * @return {Array.<WebInspector.RemoteObjectProperty>}
+ */
+ _children: function()
+ {
+ if (!this.hasChildren)
+ return [];
+
+ function buildProperty(propName)
+ {
+ return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName]));
+ }
+ if (!this._cachedChildren)
+ this._cachedChildren = Object.keys(this._value || {}).map(buildProperty.bind(this));
+ return this._cachedChildren;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isError: function()
+ {
+ return false;
+ }
+}