https://bugs.webkit.org/show_bug.cgi?id=142254
Patch by Joseph Pecoraro <pecoraro@apple.com> on 2015-03-04
Reviewed by Timothy Hatcher.
Source/JavaScriptCore:
* runtime/WeakMapData.h:
(JSC::WeakMapData::size):
* inspector/JSInjectedScriptHost.cpp:
(Inspector::JSInjectedScriptHost::weakMapSize):
* inspector/JSInjectedScriptHost.h:
* inspector/JSInjectedScriptHostPrototype.cpp:
(Inspector::JSInjectedScriptHostPrototype::finishCreation):
(Inspector::jsInjectedScriptHostPrototypeFunctionWeakMapSize):
Add a way to get a WeakMap's size.
* inspector/protocol/Runtime.json:
Include size in RemoteObject and ObjectPreview.
* inspector/InjectedScriptSource.js:
Set the size of RemoteObjects and previews if they
are array/collection types.
Source/WebInspectorUI:
* UserInterface/Models/ObjectPreview.js:
(WebInspector.ObjectPreview):
(WebInspector.ObjectPreview.fromPayload):
(WebInspector.ObjectPreview.prototype.get size):
(WebInspector.ObjectPreview.prototype.hasSize):
* UserInterface/Protocol/RemoteObject.js:
(WebInspector.RemoteObject):
(WebInspector.RemoteObject.fromPrimitiveValue):
(WebInspector.RemoteObject.fromPayload):
(WebInspector.RemoteObject.prototype.get size):
(WebInspector.RemoteObject.prototype.hasSize):
Check if this type has a size and get the size.
Gracefully handle construction for legacy protocols.
* UserInterface/Views/ObjectPreviewView.css:
(.object-preview > .size):
* UserInterface/Views/FormattedValue.css:
(:matches(.formatted-array, .formatted-map, .formatted-set, .formatted-weakmap) > .size):
Style the array/collection size.
* UserInterface/Views/ObjectPreviewView.js:
(WebInspector.ObjectPreviewView):
* UserInterface/Views/FormattedValue.js:
(WebInspector.FormattedValue.createElementForTypesAndValue):
(WebInspector.FormattedValue.createElementForRemoteObject):
(WebInspector.FormattedValue.createElementForObjectPreview):
(WebInspector.FormattedValue.createElementForPropertyPreview):
Add an element showing the array/collection size.
* UserInterface/Views/ObjectTreePropertyTreeElement.js:
(WebInspector.ObjectTreePropertyTreeElement.prototype):
Remove special handling for Array sizes now that this is handled earlier.
* UserInterface/Controllers/StorageManager.js:
(WebInspector.StorageManager.prototype.processData):
(WebInspector.StorageManager.prototype.requestIndexedDatabaseData):
Fix what looks like broken RemoteObject construction.
LayoutTests:
* inspector-protocol/runtime/getProperties-expected.txt:
* inspector/model/remote-object-expected.txt:
* inspector/model/remote-object.html:
Update tests now that RemoteObjects and Previews may have an explicit size.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@181061
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2015-03-04 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: Array/Collection Sizes should be visible and distinct
+ https://bugs.webkit.org/show_bug.cgi?id=142254
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector-protocol/runtime/getProperties-expected.txt:
+ * inspector/model/remote-object-expected.txt:
+ * inspector/model/remote-object.html:
+ Update tests now that RemoteObjects and Previews may have an explicit size.
+
2015-03-04 Timothy Horton <timothy_horton@apple.com>
<attachment> should show the file size as detail text below the icon
__proto__ object Number
foo string cat
Properties of array
- __proto__ object Array[0]
+ __proto__ object Array
0 string red
1 string green
2 string blue
length number 0
name string Number
Internal properties
- boundArgs object Array[1]
+ boundArgs object Array
boundThis object Object
targetFunction function function Number() {
[native code]
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[0]",
+ "_description": "Array",
+ "_size": 0,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[0]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 0,
"_properties": [],
"_entries": null
}
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[2]",
+ "_description": "Array",
+ "_size": 2,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[2]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 2,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[3]",
+ "_description": "Array",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[3]",
+ "_description": "Array",
"_lossless": false,
"_overflow": false,
+ "_size": 3,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
- "_value": "Array[1]"
+ "_value": "Array"
},
{
"_name": "1",
"_type": "object",
"_subtype": "array",
- "_value": "Array[1]"
+ "_value": "Array"
},
{
"_name": "2",
"_type": "object",
"_subtype": "array",
- "_value": "Array[1]"
+ "_value": "Array"
}
],
"_entries": null
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[5]",
+ "_description": "Array",
+ "_size": 5,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[5]",
+ "_description": "Array",
"_lossless": false,
"_overflow": false,
+ "_size": 5,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[3]",
+ "_description": "Array",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[3]",
+ "_description": "Array",
"_lossless": false,
"_overflow": false,
+ "_size": 3,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[1]",
+ "_description": "Array",
+ "_size": 1,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[1]",
+ "_description": "Array",
"_lossless": false,
"_overflow": false,
+ "_size": 1,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
- "_value": "Array[3]"
+ "_value": "Array"
}
],
"_entries": null
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[100]",
+ "_description": "Array",
+ "_size": 100,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[100]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 100,
"_properties": [],
"_entries": null
}
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[100]",
+ "_description": "Array",
+ "_size": 100,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[100]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 100,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Array[100]",
+ "_description": "Array",
+ "_size": 100,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[100]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 100,
"_properties": [
{
"_name": "10",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Arguments[3]",
+ "_description": "Arguments",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Arguments[3]",
+ "_description": "Arguments",
"_lossless": false,
"_overflow": false,
+ "_size": 3,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Int32Array[4]",
+ "_description": "Int32Array",
+ "_size": 4,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Int32Array[4]",
+ "_description": "Int32Array",
"_lossless": false,
"_overflow": false,
+ "_size": 4,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "Int32Array[4]",
+ "_description": "Int32Array",
+ "_size": 4,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "Int32Array[4]",
+ "_description": "Int32Array",
"_lossless": false,
"_overflow": false,
+ "_size": 4,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "HTMLCollection[3]",
+ "_description": "HTMLCollection",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "HTMLCollection[3]",
+ "_description": "HTMLCollection",
"_lossless": false,
"_overflow": false,
+ "_size": 3,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "NodeList[3]",
+ "_description": "NodeList",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "NodeList[3]",
+ "_description": "NodeList",
"_lossless": false,
"_overflow": false,
+ "_size": 3,
"_properties": [
{
"_name": "0",
"_type": "object",
"_subtype": "array",
"_objectId": "<filtered>",
- "_description": "NodeList[3]",
+ "_description": "NodeList",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "array",
- "_description": "NodeList[3]",
+ "_description": "NodeList",
"_lossless": false,
"_overflow": false,
+ "_size": 3,
"_properties": [
{
"_name": "0",
}
-----------------------------------------------------
-EXPRESSION: Object.seal({})
-{
- "_type": "object",
- "_objectId": "<filtered>",
- "_description": "Object",
- "_preview": {
- "_type": "object",
- "_description": "Object",
- "_lossless": true,
- "_overflow": false,
- "_properties": [],
- "_entries": null
- }
-}
-
------------------------------------------------------
-EXPRESSION: Object.freeze({})
-{
- "_type": "object",
- "_objectId": "<filtered>",
- "_description": "Object",
- "_preview": {
- "_type": "object",
- "_description": "Object",
- "_lossless": true,
- "_overflow": false,
- "_properties": [],
- "_entries": null
- }
-}
-
------------------------------------------------------
EXPRESSION: new Map
{
"_type": "object",
"_subtype": "map",
"_objectId": "<filtered>",
"_description": "Map",
+ "_size": 0,
"_preview": {
"_type": "object",
"_subtype": "map",
"_description": "Map",
"_lossless": true,
"_overflow": false,
+ "_size": 0,
"_properties": [],
"_entries": []
}
"_subtype": "map",
"_objectId": "<filtered>",
"_description": "Map",
+ "_size": 2,
"_preview": {
"_type": "object",
"_subtype": "map",
"_description": "Map",
"_lossless": true,
"_overflow": false,
+ "_size": 2,
"_properties": [],
"_entries": [
{
"_subtype": "map",
"_objectId": "<filtered>",
"_description": "Map",
+ "_size": 2,
"_preview": {
"_type": "object",
"_subtype": "map",
"_description": "Map",
"_lossless": true,
"_overflow": false,
+ "_size": 2,
"_properties": [],
"_entries": [
{
"_value": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[2]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 2,
"_properties": [
{
"_name": "0",
"_subtype": "map",
"_objectId": "<filtered>",
"_description": "Map",
+ "_size": 101,
"_preview": {
"_type": "object",
"_subtype": "map",
"_description": "Map",
"_lossless": false,
"_overflow": true,
+ "_size": 101,
"_properties": [],
"_entries": [
{
"_subtype": "weakmap",
"_objectId": "<filtered>",
"_description": "WeakMap",
+ "_size": 1,
"_preview": {
"_type": "object",
"_subtype": "weakmap",
"_description": "WeakMap",
"_lossless": true,
"_overflow": false,
+ "_size": 1,
"_properties": [],
"_entries": [
{
"_value": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[2]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 2,
"_properties": [
{
"_name": "0",
"_subtype": "set",
"_objectId": "<filtered>",
"_description": "Set",
+ "_size": 0,
"_preview": {
"_type": "object",
"_subtype": "set",
"_description": "Set",
"_lossless": true,
"_overflow": false,
+ "_size": 0,
"_properties": [],
"_entries": []
}
"_subtype": "set",
"_objectId": "<filtered>",
"_description": "Set",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "set",
"_description": "Set",
"_lossless": true,
"_overflow": false,
+ "_size": 3,
"_properties": [],
"_entries": [
{
"_subtype": "set",
"_objectId": "<filtered>",
"_description": "Set",
+ "_size": 3,
"_preview": {
"_type": "object",
"_subtype": "set",
"_description": "Set",
"_lossless": true,
"_overflow": false,
+ "_size": 3,
"_properties": [],
"_entries": [
{
"_value": {
"_type": "object",
"_subtype": "array",
- "_description": "Array[2]",
+ "_description": "Array",
"_lossless": true,
"_overflow": false,
+ "_size": 2,
"_properties": [
{
"_name": "0",
"_subtype": "set",
"_objectId": "<filtered>",
"_description": "Set",
+ "_size": 101,
"_preview": {
"_type": "object",
"_subtype": "set",
"_description": "Set",
"_lossless": false,
"_overflow": true,
+ "_size": 101,
"_properties": [],
"_entries": [
{
}
}
+-----------------------------------------------------
+EXPRESSION: Object.seal({})
+{
+ "_type": "object",
+ "_objectId": "<filtered>",
+ "_description": "Object",
+ "_preview": {
+ "_type": "object",
+ "_description": "Object",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [],
+ "_entries": null
+ }
+}
+
+-----------------------------------------------------
+EXPRESSION: Object.freeze({})
+{
+ "_type": "object",
+ "_objectId": "<filtered>",
+ "_description": "Object",
+ "_preview": {
+ "_type": "object",
+ "_description": "Object",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [],
+ "_entries": null
+ }
+}
+
{expression: "error = null; try { eval('if()'); } catch (e) { error = e; }; error"},
{expression: "error = null; try { document.createTextNode('').splitText(100); } catch (e) { error = e; }; error"},
- // Improveable:
-
- // Sealed / Frozen objects.
- {expression: "Object.seal({})"},
- {expression: "Object.freeze({})"},
-
// Map / WeakMap
{expression: "new Map"},
{expression: "map = new Map; map.set(1, 2); map.set('key', 'value'); map"},
{expression: "Promise.resolve()"},
{expression: "Promise.resolve({result:1})"},
+ // Improveable:
+
+ // Sealed / Frozen objects.
+ {expression: "Object.seal({})"},
+ {expression: "Object.freeze({})"},
];
if (!window.WebInspector) {
+2015-03-04 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: Array/Collection Sizes should be visible and distinct
+ https://bugs.webkit.org/show_bug.cgi?id=142254
+
+ Reviewed by Timothy Hatcher.
+
+ * runtime/WeakMapData.h:
+ (JSC::WeakMapData::size):
+ * inspector/JSInjectedScriptHost.cpp:
+ (Inspector::JSInjectedScriptHost::weakMapSize):
+ * inspector/JSInjectedScriptHost.h:
+ * inspector/JSInjectedScriptHostPrototype.cpp:
+ (Inspector::JSInjectedScriptHostPrototype::finishCreation):
+ (Inspector::jsInjectedScriptHostPrototypeFunctionWeakMapSize):
+ Add a way to get a WeakMap's size.
+
+ * inspector/protocol/Runtime.json:
+ Include size in RemoteObject and ObjectPreview.
+
+ * inspector/InjectedScriptSource.js:
+ Set the size of RemoteObjects and previews if they
+ are array/collection types.
+
2015-03-04 Andreas Kling <akling@apple.com>
GC should compute stack bounds and dump registers at the earliest opportunity.
}
var className = InjectedScriptHost.internalConstructorName(obj);
- if (subtype === "array") {
- if (typeof obj.length === "number")
- className += "[" + obj.length + "]";
+ if (subtype === "array")
return className;
- }
// NodeList in JSC is a function, check for array prior to this.
if (typeof obj === "function")
this.className = InjectedScriptHost.internalConstructorName(object);
this.description = injectedScript._describe(object);
+ if (subtype === "array")
+ this.size = typeof object.length === "number" ? object.length : 0;
+ else if (subtype === "set" || subtype === "map")
+ this.size = object.size;
+ else if (subtype === "weakmap")
+ this.size = InjectedScriptHost.weakMapSize(object);
+
if (generatePreview && this.type === "object")
this.preview = this._generatePreview(object, undefined, columnNames);
}
}
}
+ if ("size" in this)
+ preview.size = this.size;
+
return preview;
},
return jsUndefined();
}
+JSValue JSInjectedScriptHost::weakMapSize(ExecState* exec)
+{
+ if (exec->argumentCount() < 1)
+ return jsUndefined();
+
+ JSValue value = exec->uncheckedArgument(0);
+ JSWeakMap* weakMap = jsDynamicCast<JSWeakMap*>(value);
+ if (!weakMap)
+ return jsUndefined();
+
+ return jsNumber(weakMap->weakMapData()->size());
+}
+
JSValue JSInjectedScriptHost::weakMapEntries(ExecState* exec)
{
if (exec->argumentCount() < 1)
JSC::JSValue subtype(JSC::ExecState*);
JSC::JSValue functionDetails(JSC::ExecState*);
JSC::JSValue getInternalProperties(JSC::ExecState*);
+ JSC::JSValue weakMapSize(JSC::ExecState*);
JSC::JSValue weakMapEntries(JSC::ExecState*);
protected:
static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionGetInternalProperties(ExecState*);
static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionInternalConstructorName(ExecState*);
static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection(ExecState*);
+static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapSize(ExecState*);
static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapEntries(ExecState*);
static EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeAttributeEvaluate(ExecState*);
JSC_NATIVE_FUNCTION("getInternalProperties", jsInjectedScriptHostPrototypeFunctionGetInternalProperties, DontEnum, 1);
JSC_NATIVE_FUNCTION("internalConstructorName", jsInjectedScriptHostPrototypeFunctionInternalConstructorName, DontEnum, 1);
JSC_NATIVE_FUNCTION("isHTMLAllCollection", jsInjectedScriptHostPrototypeFunctionIsHTMLAllCollection, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("weakMapSize", jsInjectedScriptHostPrototypeFunctionWeakMapSize, DontEnum, 1);
JSC_NATIVE_FUNCTION("weakMapEntries", jsInjectedScriptHostPrototypeFunctionWeakMapEntries, DontEnum, 1);
Identifier evaluateIdentifier(&vm, "evaluate");
return JSValue::encode(castedThis->isHTMLAllCollection(exec));
}
+EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapSize(ExecState* exec)
+{
+ JSValue thisValue = exec->thisValue();
+ JSInjectedScriptHost* castedThis = jsDynamicCast<JSInjectedScriptHost*>(thisValue);
+ if (!castedThis)
+ return throwVMTypeError(exec);
+
+ ASSERT_GC_OBJECT_INHERITS(castedThis, JSInjectedScriptHost::info());
+ return JSValue::encode(castedThis->weakMapSize(exec));
+}
+
EncodedJSValue JSC_HOST_CALL jsInjectedScriptHostPrototypeFunctionWeakMapEntries(ExecState* exec)
{
JSValue thisValue = exec->thisValue();
{ "name": "value", "type": "any", "optional": true, "description": "Remote object value (in case of primitive values or JSON values if it was requested)." },
{ "name": "description", "type": "string", "optional": true, "description": "String representation of the object." },
{ "name": "objectId", "$ref": "RemoteObjectId", "optional": true, "description": "Unique object identifier (for non-primitive values)." },
+ { "name": "size", "type": "integer", "optional": true, "description": "Size of the array/collection. Specified for array/map/set/weakmap object type values only." },
{ "name": "preview", "$ref": "ObjectPreview", "optional": true, "description": "Preview containing abbreviated property values. Specified for <code>object</code> type values only." }
]
},
{ "name": "lossless", "type": "boolean", "description": "Determines whether preview is lossless (contains all information of the original object)." },
{ "name": "overflow", "type": "boolean", "optional": true, "description": "True iff some of the properties of the original did not fit." },
{ "name": "properties", "type": "array", "items": { "$ref": "PropertyPreview" }, "optional": true, "description": "List of the properties." },
- { "name": "entries", "type": "array", "items": { "$ref": "EntryPreview" }, "optional": true, "description": "List of the entries. Specified for <code>map</code> and <code>set</code> subtype values only." }
+ { "name": "entries", "type": "array", "items": { "$ref": "EntryPreview" }, "optional": true, "description": "List of the entries. Specified for <code>map</code> and <code>set</code> subtype values only." },
+ { "name": "size", "type": "integer", "optional": true, "description": "Size of the array/collection. Specified for array/map/set/weakmap object type values only." }
]
},
{
MapType::const_iterator begin() const { return m_map.begin(); }
MapType::const_iterator end() const { return m_map.end(); }
+ int size() const { return m_map.size(); }
+
private:
WeakMapData(VM&);
static void destroy(JSCell*);
+2015-03-04 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: Array/Collection Sizes should be visible and distinct
+ https://bugs.webkit.org/show_bug.cgi?id=142254
+
+ Reviewed by Timothy Hatcher.
+
+ * UserInterface/Models/ObjectPreview.js:
+ (WebInspector.ObjectPreview):
+ (WebInspector.ObjectPreview.fromPayload):
+ (WebInspector.ObjectPreview.prototype.get size):
+ (WebInspector.ObjectPreview.prototype.hasSize):
+ * UserInterface/Protocol/RemoteObject.js:
+ (WebInspector.RemoteObject):
+ (WebInspector.RemoteObject.fromPrimitiveValue):
+ (WebInspector.RemoteObject.fromPayload):
+ (WebInspector.RemoteObject.prototype.get size):
+ (WebInspector.RemoteObject.prototype.hasSize):
+ Check if this type has a size and get the size.
+ Gracefully handle construction for legacy protocols.
+
+ * UserInterface/Views/ObjectPreviewView.css:
+ (.object-preview > .size):
+ * UserInterface/Views/FormattedValue.css:
+ (:matches(.formatted-array, .formatted-map, .formatted-set, .formatted-weakmap) > .size):
+ Style the array/collection size.
+
+ * UserInterface/Views/ObjectPreviewView.js:
+ (WebInspector.ObjectPreviewView):
+ * UserInterface/Views/FormattedValue.js:
+ (WebInspector.FormattedValue.createElementForTypesAndValue):
+ (WebInspector.FormattedValue.createElementForRemoteObject):
+ (WebInspector.FormattedValue.createElementForObjectPreview):
+ (WebInspector.FormattedValue.createElementForPropertyPreview):
+ Add an element showing the array/collection size.
+
+ * UserInterface/Views/ObjectTreePropertyTreeElement.js:
+ (WebInspector.ObjectTreePropertyTreeElement.prototype):
+ Remove special handling for Array sizes now that this is handled earlier.
+
+ * UserInterface/Controllers/StorageManager.js:
+ (WebInspector.StorageManager.prototype.processData):
+ (WebInspector.StorageManager.prototype.requestIndexedDatabaseData):
+ Fix what looks like broken RemoteObject construction.
+
2015-03-04 Brian J. Burg <burg@cs.washington.edu>
Web Inspector: TimelineViews should be displayed in a ContentViewContainer
for (var entryPayload of entryPayloads) {
var entry = {};
- entry.primaryKey = new WebInspector.RemoteObject.fromPayload(entryPayload.primaryKey);
- entry.key = new WebInspector.RemoteObject.fromPayload(entryPayload.key);
- entry.value = new WebInspector.RemoteObject.fromPayload(entryPayload.value);
+ entry.primaryKey = WebInspector.RemoteObject.fromPayload(entryPayload.primaryKey);
+ entry.key = WebInspector.RemoteObject.fromPayload(entryPayload.key);
+ entry.value = WebInspector.RemoteObject.fromPayload(entryPayload.value);
entries.push(entry);
}
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.ObjectPreview = function(type, subtype, description, lossless, overflow, properties, entries)
+WebInspector.ObjectPreview = function(type, subtype, description, lossless, overflow, properties, entries, size)
{
WebInspector.Object.call(this);
this._description = description || "";
this._lossless = lossless;
this._overflow = overflow || false;
+ this._size = size;
this._properties = properties || null;
this._entries = entries || null;
if (payload.entries)
payload.entries = payload.entries.map(function(entry) { return WebInspector.CollectionEntryPreview.fromPayload(entry); });
- return new WebInspector.ObjectPreview(payload.type, payload.subtype, payload.description, payload.lossless, payload.overflow, payload.properties, payload.entries);
+ if (payload.subtype === "array") {
+ // COMPATIBILITY (iOS 8): Runtime.ObjectPreview did not have size property,
+ // instead it was tacked onto the end of the description, like "Array[#]".
+ var match = payload.description.match(/\[(\d+)\]$/);
+ if (match) {
+ payload.size = parseInt(match[1]);
+ payload.description = payload.description.replace(/\[\d+\]$/, "");
+ }
+ }
+
+ return new WebInspector.ObjectPreview(payload.type, payload.subtype, payload.description, payload.lossless, payload.overflow, payload.properties, payload.entries, payload.size);
};
WebInspector.ObjectPreview.prototype = {
get collectionEntryPreviews()
{
return this._entries;
+ },
+
+ get size()
+ {
+ return this._size;
+ },
+
+ hasSize: function()
+ {
+ return this._size !== undefined && (this._subtype === "array" || this._subtype === "set" || this._subtype === "map" || this._subtype === "weakmap");
}
};
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.RemoteObject = function(objectId, type, subtype, value, description, preview)
+WebInspector.RemoteObject = function(objectId, type, subtype, value, description, size, preview)
{
// No superclass.
this._objectId = objectId;
this._description = description;
this._hasChildren = type !== "symbol";
+ this._size = size;
this._preview = preview;
} else {
// Primitive or null.
WebInspector.RemoteObject.fromPrimitiveValue = function(value)
{
- return new WebInspector.RemoteObject(undefined, typeof value, undefined, value);
+ return new WebInspector.RemoteObject(undefined, typeof value, undefined, undefined, value);
};
WebInspector.RemoteObject.fromPayload = function(payload)
{
console.assert(typeof payload === "object", "Remote object payload should only be an object");
+ if (payload.subtype === "array") {
+ // COMPATIBILITY (iOS 8): Runtime.RemoteObject did not have size property,
+ // instead it was tacked onto the end of the description, like "Array[#]".
+ var match = payload.description.match(/\[(\d+)\]$/);
+ if (match) {
+ payload.size = parseInt(match[1]);
+ payload.description = payload.description.replace(/\[\d+\]$/, "");
+ }
+ }
+
if (payload.preview) {
// COMPATIBILITY (iOS 8): iOS 7 and 8 did not have type/subtype/description on
// Runtime.ObjectPreview. Copy them over from the RemoteObject.
payload.preview.type = payload.type;
payload.preview.subtype = payload.subtype;
payload.preview.description = payload.description;
+ payload.preview.size = payload.size;
}
payload.preview = WebInspector.ObjectPreview.fromPayload(payload.preview);
}
- return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
+ return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.size, payload.preview);
};
WebInspector.RemoteObject.createCallArgument = function(valueOrObject)
return this._value;
},
+ get size()
+ {
+ return this._size || 0;
+ },
+
get preview()
{
return this._preview;
},
+ hasSize: function()
+ {
+ return this.isArray() || this.isCollectionType();
+ },
+
hasValue: function()
{
return "_value" in this;
color: black;
}
+:matches(.formatted-array, .formatted-map, .formatted-set, .formatted-weakmap) > .size {
+ font-style: normal;
+ color: hsl(0, 0%, 67%);
+}
+
.formatted-node > ol {
display: block !important;
}
return span;
};
-WebInspector.FormattedValue.createElementForTypesAndValue = function(type, subtype, displayString, isPreview, hadException)
+WebInspector.FormattedValue.createElementForTypesAndValue = function(type, subtype, displayString, size, isPreview, hadException)
{
var span = document.createElement("span");
span.classList.add(WebInspector.FormattedValue.classNameForTypes(type, subtype));
// Everything else, the description/value string.
span.textContent = displayString;
+
+ // If there is a size, include it.
+ if (size !== undefined && (subtype === "array" || subtype === "set" || subtype === "map" || subtype === "weakmap")) {
+ var sizeElement = span.appendChild(document.createElement("span"));
+ sizeElement.className = "size";
+ sizeElement.textContent = " (" + size + ")";
+ }
+
return span;
};
WebInspector.FormattedValue.createElementForRemoteObject = function(object, hadException)
{
- return WebInspector.FormattedValue.createElementForTypesAndValue(object.type, object.subtype, object.description, false, hadException);
+ return WebInspector.FormattedValue.createElementForTypesAndValue(object.type, object.subtype, object.description, object.size, false, hadException);
};
WebInspector.FormattedValue.createElementForObjectPreview = function(objectPreview)
{
- return WebInspector.FormattedValue.createElementForTypesAndValue(objectPreview.type, objectPreview.subtype, objectPreview.description, true, false);
+ return WebInspector.FormattedValue.createElementForTypesAndValue(objectPreview.type, objectPreview.subtype, objectPreview.description, objectPreview.size, true, false);
};
WebInspector.FormattedValue.createElementForPropertyPreview = function(propertyPreview)
{
- return WebInspector.FormattedValue.createElementForTypesAndValue(propertyPreview.type, propertyPreview.subtype, propertyPreview.value, true, false);
+ return WebInspector.FormattedValue.createElementForTypesAndValue(propertyPreview.type, propertyPreview.subtype, propertyPreview.value, undefined, true, false);
};
WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject = function(object, propertyPath)
.object-preview .name {
color: rgb(136, 19, 145);
}
+
+.object-preview > .size {
+ font-style: normal;
+ color: hsl(0, 0%, 67%);
+}
this._titleElement.hidden = true;
this._initTitleElement();
+ if (this._preview.hasSize()) {
+ var sizeElement = this._element.appendChild(document.createElement("span"));
+ sizeElement.className = "size";
+ sizeElement.textContent = " (" + this._preview.size + ")";
+ }
+
if (this._lossless)
this._element.classList.add("lossless");
};
if (value.subtype === "regexp")
return "RegExp";
- return value.description.replace(/\[\d+\]$/, "").replace(/Prototype$/, "");
+ return value.description.replace(/Prototype$/, "");
},
_propertyPathString: function(propertyPath)