Bug 997622 - Expand all descendant nodes on alt-click in markup-view; r=jwalker

This commit is contained in:
Patrick Brosset 2014-04-17 23:39:29 +02:00
parent cc65e6f9d0
commit 55c48e9e74
8 changed files with 205 additions and 12 deletions

View File

@ -822,11 +822,17 @@ MarkupView.prototype = {
/**
* Mark the given node expanded.
* @param aNode The NodeFront to mark as expanded.
* @param {NodeFront} aNode The NodeFront to mark as expanded.
* @param {Boolean} aExpanded Whether the expand or collapse.
* @param {Boolean} aExpandDescendants Whether to expand all descendants too
*/
setNodeExpanded: function(aNode, aExpanded) {
setNodeExpanded: function(aNode, aExpanded, aExpandDescendants) {
if (aExpanded) {
this.expandNode(aNode);
if (aExpandDescendants) {
this.expandAll(aNode);
} else {
this.expandNode(aNode);
}
} else {
this.collapseNode(aNode);
}
@ -1413,7 +1419,7 @@ MarkupContainer.prototype = {
_onToggle: function(event) {
this.markup.navigate(this);
if(this.hasChildren) {
this.markup.setNodeExpanded(this.node, !this.expanded);
this.markup.setNodeExpanded(this.node, !this.expanded, event.altKey);
}
event.stopPropagation();
},

View File

@ -9,6 +9,7 @@ support-files =
doc_markup_pagesize_01.html
doc_markup_pagesize_02.html
doc_markup_search.html
doc_markup_toggle.html
doc_markup_tooltip.png
head.js
helper_attributes_test_runner.js
@ -37,3 +38,6 @@ support-files =
[browser_markupview_tag_edit_07.js]
[browser_markupview_tag_edit_08.js]
[browser_markupview_textcontent_edit_01.js]
[browser_markupview_toggle_01.js]
[browser_markupview_toggle_02.js]
[browser_markupview_toggle_03.js]

View File

@ -113,14 +113,6 @@ function pressKey(key) {
}
}
function waitForChildrenUpdated(inspector) {
let def = promise.defer();
inspector.markup._waitForChildren().then(() => {
executeSoon(def.resolve);
});
return def.promise;
}
function checkSelectedNode(key, className, inspector) {
let node = inspector.selection.node;

View File

@ -0,0 +1,45 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test toggling (expand/collapse) elements by clicking on twisties
const TEST_URL = TEST_URL_ROOT + "doc_markup_toggle.html";
let test = asyncTest(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
info("Getting the container for the UL parent element");
let container = getContainerForRawNode("ul", inspector);
info("Clicking on the UL parent expander, and waiting for children");
let onChildren = waitForChildrenUpdated(inspector);
let onUpdated = inspector.once("inspector-updated");
EventUtils.synthesizeMouseAtCenter(container.expander, {},
inspector.markup.doc.defaultView);
yield onChildren;
yield onUpdated;
info("Checking that child LI elements have been created");
for (let li of content.document.querySelectorAll("li")) {
ok(getContainerForRawNode(li, inspector),
"A container for the child LI element was created");
}
ok(container.expanded, "Parent UL container is expanded");
info("Clicking again on the UL expander");
// No need to wait, this is a local, synchronous operation where nodes are
// only hidden from the view, not destroyed
EventUtils.synthesizeMouseAtCenter(container.expander, {},
inspector.markup.doc.defaultView);
info("Checking that child LI elements have been hidden");
for (let li of content.document.querySelectorAll("li")) {
let liContainer = getContainerForRawNode(li, inspector);
is(liContainer.elt.getClientRects().length, 0,
"The container for the child LI element was hidden");
}
ok(!container.expanded, "Parent UL container is collapsed");
});

View File

@ -0,0 +1,45 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test toggling (expand/collapse) elements by dbl-clicking on tag lines
const TEST_URL = TEST_URL_ROOT + "doc_markup_toggle.html";
let test = asyncTest(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
info("Getting the container for the UL parent element");
let container = getContainerForRawNode("ul", inspector);
info("Dbl-clicking on the UL parent expander, and waiting for children");
let onChildren = waitForChildrenUpdated(inspector);
let onUpdated = inspector.once("inspector-updated");
EventUtils.synthesizeMouseAtCenter(container.tagLine, {clickCount: 2},
inspector.markup.doc.defaultView);
yield onChildren;
yield onUpdated;
info("Checking that child LI elements have been created");
for (let li of content.document.querySelectorAll("li")) {
ok(getContainerForRawNode(li, inspector),
"A container for the child LI element was created");
}
ok(container.expanded, "Parent UL container is expanded");
info("Dbl-clicking again on the UL expander");
// No need to wait, this is a local, synchronous operation where nodes are
// only hidden from the view, not destroyed
EventUtils.synthesizeMouseAtCenter(container.tagLine, {clickCount: 2},
inspector.markup.doc.defaultView);
info("Checking that child LI elements have been hidden");
for (let li of content.document.querySelectorAll("li")) {
let liContainer = getContainerForRawNode(li, inspector);
is(liContainer.elt.getClientRects().length, 0,
"The container for the child LI element was hidden");
}
ok(!container.expanded, "Parent UL container is collapsed");
});

View File

@ -0,0 +1,44 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test toggling (expand/collapse) elements by alt-clicking on twisties, which
// should expand all the descendants
const TEST_URL = TEST_URL_ROOT + "doc_markup_toggle.html";
let test = asyncTest(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
info("Getting the container for the UL parent element");
let container = getContainerForRawNode("ul", inspector);
info("Alt-clicking on the UL parent expander, and waiting for children");
let onUpdated = inspector.once("inspector-updated");
EventUtils.synthesizeMouseAtCenter(container.expander, {altKey: true},
inspector.markup.doc.defaultView);
yield onUpdated;
yield waitForMultipleChildrenUpdates(inspector);
info("Checking that all nodes exist and are expanded");
for (let node of content.document.querySelectorAll("ul, li, span, em")) {
let nodeContainer = getContainerForRawNode(node, inspector);
ok(nodeContainer, "Container for node " + node.tagName + " exists");
ok(nodeContainer.expanded,
"Container for node " + node.tagName + " is expanded");
}
});
// The expand all operation of the markup-view calls itself recursively and
// there's not one event we can wait for to know when it's done
function* waitForMultipleChildrenUpdates(inspector) {
// As long as child updates are queued up while we wait for an update already
// wait again
if (inspector.markup._queuedChildUpdates &&
inspector.markup._queuedChildUpdates.size) {
yield waitForChildrenUpdated(inspector);
return yield waitForMultipleChildrenUpdates(inspector);
}
}

View File

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Expanding and collapsing markup-view containers</title>
</head>
<body>
<ul>
<li>
<span>list <em>item</em></span>
</li>
<li>
<span>list <em>item</em></span>
</li>
<li>
<span>list <em>item</em></span>
</li>
<li>
<span>list <em>item</em></span>
</li>
<li>
<span>list <em>item</em></span>
</li>
<li>
<span>list <em>item</em></span>
</li>
</ul>
</body>
</html>

View File

@ -166,6 +166,23 @@ function getContainerForRawNode(nodeOrSelector, {markup}) {
return container;
}
/**
* Using the markupview's _waitForChildren function, wait for all queued
* children updates to be handled.
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return a promise that resolves when all queued children updates have been
* handled
*/
function waitForChildrenUpdated({markup}) {
info("Waiting for queued children updates to be handled");
let def = promise.defer();
markup._waitForChildren().then(() => {
executeSoon(def.resolve);
});
return def.promise;
}
/**
* Simulate a mouse-over on the markup-container (a line in the markup-view)
* that corresponds to the node or selector passed.
@ -352,3 +369,15 @@ function searchUsingSelectorSearch(selector, inspector) {
field.value = selector;
EventUtils.sendKey("return", inspector.panelWin);
}
/**
* This shouldn't be used in the tests, but is useful when writing new tests or
* debugging existing tests in order to introduce delays in the test steps
* @param {Number} ms The time to wait
* @return A promise that resolves when the time is passed
*/
function wait(ms) {
let def = promise.defer();
content.setTimeout(def.resolve, ms);
return def.promise;
}