Diff
Modified: trunk/LayoutTests/ChangeLog (139428 => 139429)
--- trunk/LayoutTests/ChangeLog 2013-01-11 12:26:37 UTC (rev 139428)
+++ trunk/LayoutTests/ChangeLog 2013-01-11 12:28:24 UTC (rev 139429)
@@ -1,3 +1,19 @@
+2013-01-11 Antoine Quint <[email protected]>
+
+ Web Inspector: Option+Click on Node Expander Doesn't Work the First Time
+ https://bugs.webkit.org/show_bug.cgi?id=66868
+
+ Adding a new protocol test that covers the new `depth` parameter for the
+ requestChildNodes method and a new front-end method that tests correct
+ behavior of the expandRecursively() method.
+
+ Reviewed by Pavel Feldman.
+
+ * inspector-protocol/dom-request-child-nodes-depth-expected.txt: Added.
+ * inspector-protocol/dom-request-child-nodes-depth.html: Added.
+ * inspector/elements/expand-recursively-expected.txt: Added.
+ * inspector/elements/expand-recursively.html: Added.
+
2013-01-11 Noel Gordon <[email protected]>
[chromium] Add ImageOnlyFailure for fast/css/font-face-unicode-range.html on win
Added: trunk/LayoutTests/inspector/elements/expand-recursively-expected.txt (0 => 139429)
--- trunk/LayoutTests/inspector/elements/expand-recursively-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/elements/expand-recursively-expected.txt 2013-01-11 12:28:24 UTC (rev 139429)
@@ -0,0 +1,28 @@
+Tests that expanding elements recursively works.
+
+===== Initial state of tree outline =====
+
++ <div id="depth-1">…</div>
+
+===== State of tree outline after calling .expandRecursively() =====
+
+- <div id="depth-1">
+ - <div id="depth-2">
+ - <div id="depth-3">
+ - <div id="depth-4">
+ - <div id="depth-5">
+ - <div id="depth-6">
+ - <div id="depth-7">
+ - <div id="depth-8">
+ - <div id="depth-9">
+ <div id="depth-10"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
Added: trunk/LayoutTests/inspector/elements/expand-recursively.html (0 => 139429)
--- trunk/LayoutTests/inspector/elements/expand-recursively.html (rev 0)
+++ trunk/LayoutTests/inspector/elements/expand-recursively.html 2013-01-11 12:28:24 UTC (rev 139429)
@@ -0,0 +1,67 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+
+function test()
+{
+ WebInspector.showPanel("elements");
+ var treeOutline = WebInspector.panels.elements.treeOutline;
+ InspectorTest.findNode(function() { return false; }, firstStep);
+
+ function firstStep()
+ {
+ InspectorTest.addResult("===== Initial state of tree outline =====\n");
+ dump();
+
+ var topNode = treeOutline.children[0].children[1].children[1];
+ topNode.expandRecursively();
+ InspectorTest.runAfterPendingDispatches(secondStep);
+ };
+
+ function secondStep()
+ {
+ InspectorTest.addResult("\n===== State of tree outline after calling .expandRecursively() =====\n");
+ dump();
+
+ InspectorTest.completeTest();
+ };
+
+ function dump()
+ {
+ var node = InspectorTest.expandedNodeWithId("depth-1");
+ InspectorTest.dumpElementsTree(node);
+ };
+}
+
+</script>
+</head>
+
+<body _onload_="runTest()">
+<p>
+Tests that expanding elements recursively works.
+</p>
+
+<div id="depth-1">
+ <div id="depth-2">
+ <div id="depth-3">
+ <div id="depth-4">
+ <div id="depth-5">
+ <div id="depth-6">
+ <div id="depth-7">
+ <div id="depth-8">
+ <div id="depth-9">
+ <div id="depth-10"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+</body>
+</html>
Added: trunk/LayoutTests/inspector-protocol/dom-request-child-nodes-depth-expected.txt (0 => 139429)
--- trunk/LayoutTests/inspector-protocol/dom-request-child-nodes-depth-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector-protocol/dom-request-child-nodes-depth-expected.txt 2013-01-11 12:28:24 UTC (rev 139429)
@@ -0,0 +1,21 @@
+
+=== Get the Document ===
+
+
+=== Get immediate children of the body ===
+
+PASS: First child is a div
+PASS: First child is div#depth-1
+PASS: First child has one child
+PASS: First child has no .children property
+
+=== Get all children of div#depth-1 ===
+
+PASS: div#depth-1 has nodes 9 levels deep
+
+=== Pass an invalid depth ===
+
+Backend error: Please provide a positive integer as a depth or -1 for entire subtree (-32000)
+
+PASS: Expected number of setChildNodes events
+
Added: trunk/LayoutTests/inspector-protocol/dom-request-child-nodes-depth.html (0 => 139429)
--- trunk/LayoutTests/inspector-protocol/dom-request-child-nodes-depth.html (rev 0)
+++ trunk/LayoutTests/inspector-protocol/dom-request-child-nodes-depth.html 2013-01-11 12:28:24 UTC (rev 139429)
@@ -0,0 +1,140 @@
+<html>
+<head>
+<script type="text/_javascript_" src=""
+<script type="text/_javascript_">
+
+function test()
+{
+
+ var eventsCount = 0;
+
+ getDocument();
+
+ InspectorTest.eventHandler["DOM.setChildNodes"] = function setChildNodes(messageObject)
+ {
+ eventsCount++;
+
+ if (eventsCount === 1)
+ gotImmediateChildren(messageObject);
+ else if (eventsCount === 2)
+ gotAllChildren(messageObject);
+ };
+
+ function getDocument()
+ {
+ // We must first get the document so that later on we may get sensible nodeIds.
+ step({
+ name: "Get the Document",
+ command: "DOM.getDocument",
+ parameters: {},
+ callback: getImmediateChildren
+ });
+ };
+
+ function getImmediateChildren(result)
+ {
+ var bodyId = result.root.children[0].children[1].nodeId;
+ step({
+ name: "Get immediate children of the body",
+ command: "DOM.requestChildNodes",
+ parameters: {"nodeId": bodyId}
+ });
+ };
+
+ function gotImmediateChildren(messageObject)
+ {
+ var firstChild = messageObject.params.nodes[0];
+ assert("First child is a div", firstChild.localName, "div");
+ assert("First child is div#depth-1", firstChild.attributes[1], "depth-1");
+ assert("First child has one child", firstChild.childNodeCount, 1);
+ assert("First child has no .children property", firstChild.children, undefined);
+
+ step({
+ name: "Get all children of div#depth-1",
+ command: "DOM.requestChildNodes",
+ parameters: {"nodeId": firstChild.nodeId, "depth": -1}
+ });
+ };
+
+ function gotAllChildren(messageObject)
+ {
+ var depth = 1;
+ var firstChild = messageObject.params.nodes[0];
+ var node = firstChild;
+ while (node && node.children) {
+ depth++;
+ node = node.children[0];
+ }
+
+ assert("div#depth-1 has nodes 9 levels deep", depth, 9);
+
+ step({
+ name: "Pass an invalid depth",
+ command: "DOM.requestChildNodes",
+ parameters: {"nodeId": firstChild.nodeId, "depth": 0},
+ callback: finishTest
+ });
+ };
+
+ function finishTest()
+ {
+ assert("Expected number of setChildNodes events", eventsCount, 2);
+
+ InspectorTest.completeTest();
+ };
+
+ function step(test)
+ {
+ InspectorTest.log("\n=== " + test.name + " ===\n");
+ InspectorTest.sendCommand(test.command, test.parameters, function(messageObject) {
+ if (messageObject.hasOwnProperty("error"))
+ InspectorTest.log("Backend error: " + messageObject.error.message + " (" + messageObject.error.code + ")\n");
+
+ if (test.callback)
+ test.callback(messageObject.result);
+ });
+ };
+
+ function assert(message, actual, expected)
+ {
+ if (actual === expected)
+ InspectorTest.log("PASS: " + message);
+ else {
+ InspectorTest.log("FAIL: " + message + ", expected \"" + expected + "\" but got \"" + actual + "\"");
+ InspectorTest.completeTest();
+ }
+ };
+
+};
+
+window.addEventListener("DOMContentLoaded", function () {
+ runTest();
+}, false);
+
+</script>
+</head>
+<body>
+
+<div id="depth-1">
+ <div id="depth-2">
+ <div id="depth-3">
+ <div id="depth-4">
+ <div id="depth-5">
+ <div id="depth-6">
+ <div id="depth-7">
+ <div id="depth-8">
+ <div id="depth-9">
+ <div id="depth-10">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (139428 => 139429)
--- trunk/Source/WebCore/ChangeLog 2013-01-11 12:26:37 UTC (rev 139428)
+++ trunk/Source/WebCore/ChangeLog 2013-01-11 12:28:24 UTC (rev 139429)
@@ -1,3 +1,44 @@
+2013-01-11 Antoine Quint <[email protected]>
+
+ Web Inspector: Option+Click on Node Expander Doesn't Work the First Time
+ https://bugs.webkit.org/show_bug.cgi?id=66868
+
+ Up to now, the TreeElement.prototype.expandRecursively() method would correctly
+ expand children recursively based on the provided depth, but would not wait to
+ perform this task until all child nodes had been populated, which means that this
+ would only work incrementally with one additional level of child nodes being shown
+ expanded in the DOM tree upon alt+clicking a given node with a deep hierarchy.
+
+ In order to fix this, this patch adds a new optional argument to the DOMAgent's
+ requestChildNodes() methods to provide the depth at which we want to retrieve children
+ of a given node. The DOMAgent provides a new .getSubtree() method that calls
+ requestChildNodes() with the provided depth.
+
+ Then in ElementsTreeOutline, we subclass .expandRecursively() to first call DOMAgent's
+ new .getSubtree() method and then call the default implementation when all nodes
+ have been retrieved from the backend.
+
+ Reviewed by Pavel Feldman.
+
+ Tests: inspector-protocol/dom-request-child-nodes-depth.html
+ inspector/elements/expand-recursively.html
+
+ * inspector/Inspector.json: Add the new `depth` parameter to DOM.requestChildNodes().
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::pushChildNodesToFrontend): Add a new optional `depth` parameter
+ which defaults to 1.
+ (WebCore::InspectorDOMAgent::requestChildNodes): Add a new optional `depth` parameter
+ which defaults to 1 and allows -1 as an unbound value.
+ * inspector/InspectorDOMAgent.h:
+ (InspectorDOMAgent):
+ * inspector/front-end/DOMAgent.js:
+ (WebInspector.DOMNode.prototype.):
+ (WebInspector.DOMNode.prototype.getSubtree): New method allowing to specify at what depth
+ we want to retrieve children of a given node from the backend.
+ * inspector/front-end/ElementsTreeOutline.js:
+ (WebInspector.ElementsTreeElement.prototype.expandRecursively): Override default implementation
+ to first obtain the deepest subtree for the current node so that deep expansion happens as expected.
+
2013-01-11 Alexander Pavlov <[email protected]>
Web Inspector: [Elements] Search in the DOM tree does not scroll horizontally
Modified: trunk/Source/WebCore/inspector/Inspector.json (139428 => 139429)
--- trunk/Source/WebCore/inspector/Inspector.json 2013-01-11 12:26:37 UTC (rev 139428)
+++ trunk/Source/WebCore/inspector/Inspector.json 2013-01-11 12:28:24 UTC (rev 139429)
@@ -1707,9 +1707,10 @@
{
"name": "requestChildNodes",
"parameters": [
- { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get children for." }
+ { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get children for." },
+ { "name": "depth", "type": "integer", "optional": true, "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0." }
],
- "description": "Requests that children of the node with given id are returned to the caller in form of <code>setChildNodes</code> events."
+ "description": "Requests that children of the node with given id are returned to the caller in form of <code>setChildNodes</code> events where not only immediate children are retrieved, but all children down to the specified depth."
},
{
"name": "querySelector",
Modified: trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp (139428 => 139429)
--- trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp 2013-01-11 12:26:37 UTC (rev 139428)
+++ trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp 2013-01-11 12:28:24 UTC (rev 139429)
@@ -433,7 +433,7 @@
root = buildObjectForNode(m_document.get(), 2, &m_documentNodeToIdMap);
}
-void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId)
+void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth)
{
Node* node = nodeForId(nodeId);
if (!node || (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE && node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE))
@@ -442,7 +442,7 @@
return;
NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId);
- RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, 1, nodeMap);
+ RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, depth, nodeMap);
m_frontend->setChildNodes(nodeId, children.release());
}
@@ -478,9 +478,22 @@
return 0;
}
-void InspectorDOMAgent::requestChildNodes(ErrorString*, int nodeId)
+void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, int nodeId, const int* depth)
{
- pushChildNodesToFrontend(nodeId);
+ int sanitizedDepth;
+
+ if (!depth)
+ sanitizedDepth = 1;
+ else if (*depth == -1)
+ sanitizedDepth = INT_MAX;
+ else if (*depth > 0)
+ sanitizedDepth = *depth;
+ else {
+ *errorString = "Please provide a positive integer as a depth or -1 for entire subtree";
+ return;
+ }
+
+ pushChildNodesToFrontend(nodeId, sanitizedDepth);
}
void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, const String& selectors, int* elementId)
Modified: trunk/Source/WebCore/inspector/InspectorDOMAgent.h (139428 => 139429)
--- trunk/Source/WebCore/inspector/InspectorDOMAgent.h 2013-01-11 12:26:37 UTC (rev 139428)
+++ trunk/Source/WebCore/inspector/InspectorDOMAgent.h 2013-01-11 12:28:24 UTC (rev 139429)
@@ -122,7 +122,7 @@
virtual void querySelector(ErrorString*, int nodeId, const String& selectors, int* elementId);
virtual void querySelectorAll(ErrorString*, int nodeId, const String& selectors, RefPtr<TypeBuilder::Array<int> >& result);
virtual void getDocument(ErrorString*, RefPtr<TypeBuilder::DOM::Node>& root);
- virtual void requestChildNodes(ErrorString*, int nodeId);
+ virtual void requestChildNodes(ErrorString*, int nodeId, const int* depth);
virtual void setAttributeValue(ErrorString*, int elementId, const String& name, const String& value);
virtual void setAttributesAsText(ErrorString*, int elementId, const String& text, const String* name);
virtual void removeAttribute(ErrorString*, int elementId, const String& name);
@@ -218,7 +218,7 @@
Element* assertEditableElement(ErrorString*, int nodeId);
int pushNodePathToFrontend(Node*);
- void pushChildNodesToFrontend(int nodeId);
+ void pushChildNodesToFrontend(int nodeId, int depth = 1);
bool hasBreakpoint(Node*, int type);
void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
Modified: trunk/Source/WebCore/inspector/front-end/DOMAgent.js (139428 => 139429)
--- trunk/Source/WebCore/inspector/front-end/DOMAgent.js 2013-01-11 12:26:37 UTC (rev 139428)
+++ trunk/Source/WebCore/inspector/front-end/DOMAgent.js 2013-01-11 12:28:24 UTC (rev 139429)
@@ -301,6 +301,25 @@
},
/**
+ * @param {number} depth
+ * @param {function(Array.<WebInspector.DOMNode>)=} callback
+ */
+ getSubtree: function(depth, callback)
+ {
+ /**
+ * @this {WebInspector.DOMNode}
+ * @param {?Protocol.Error} error
+ */
+ function mycallback(error)
+ {
+ if (callback)
+ callback(error ? null : this.children);
+ }
+
+ DOMAgent.requestChildNodes(this.id, depth, mycallback.bind(this));
+ },
+
+ /**
* @param {function(?Protocol.Error)=} callback
*/
getOuterHTML: function(callback)
Modified: trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js (139428 => 139429)
--- trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js 2013-01-11 12:26:37 UTC (rev 139428)
+++ trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js 2013-01-11 12:28:24 UTC (rev 139429)
@@ -1048,6 +1048,16 @@
this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit);
},
+ expandRecursively: function()
+ {
+ function callback()
+ {
+ TreeElement.prototype.expandRecursively.call(this, Number.MAX_VALUE);
+ }
+
+ this.representedObject.getSubtree(-1, callback.bind(this));
+ },
+
onexpand: function()
{
if (this._elementCloseTag)