Backed out changeset fda9bea59c6f (
bug 1345529) for timeouts in browser_markup_mutation_01.js
--- a/devtools/client/inspector/markup/test/browser.ini
+++ b/devtools/client/inspector/markup/test/browser.ini
@@ -143,17 +143,16 @@ skip-if = (os == 'linux' && bits == 32 &
[browser_markup_node_names_namespaced.js]
[browser_markup_node_not_displayed_01.js]
[browser_markup_node_not_displayed_02.js]
[browser_markup_pagesize_01.js]
[browser_markup_pagesize_02.js]
[browser_markup_remove_xul_attributes.js]
skip-if = e10s # Bug 1036409 - The last selected node isn't reselected
[browser_markup_search_01.js]
-[browser_markup_tag_delete_whitespace_node.js]
[browser_markup_tag_edit_01.js]
[browser_markup_tag_edit_02.js]
[browser_markup_tag_edit_03.js]
[browser_markup_tag_edit_04-backspace.js]
[browser_markup_tag_edit_04-delete.js]
[browser_markup_tag_edit_05.js]
[browser_markup_tag_edit_06.js]
[browser_markup_tag_edit_07.js]
deleted file mode 100644
--- a/devtools/client/inspector/markup/test/browser_markup_tag_delete_whitespace_node.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 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";
-
-// After deleting a node, whitespace siblings that had an impact on the layout might no
-// longer have any impact. This tests that the markup view is correctly rendered after
-// deleting a node that triggers such a change.
-
-const HTML =
- `<div>
- <p id="container">
- <span>1</span> <span id="after-whitespace">2</span>
- </p>
- </div>`;
-
-const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
-
-add_task(function* () {
- let {inspector} = yield openInspectorForURL(TEST_URL);
-
- info("Test deleting a node that will modify the whitespace nodes rendered in the " +
- "markup view.");
-
- info("Select node #after-whitespace and make sure it is focused");
- yield selectNode("#after-whitespace", inspector);
- yield clickContainer("#after-whitespace", inspector);
-
- info("Delete the node with the delete key");
- let mutated = inspector.once("markupmutation");
- EventUtils.sendKey("delete", inspector.panelWin);
- yield Promise.all([mutated, inspector.once("inspector-updated")]);
-
- // TODO: There is still an issue with selection here. When the span is deleted, the
- // selection goes to text-node. But since the text-node gets removed from the markup
- // view after losing its impact on the layout, the selection remains on a node which
- // is no longer part of the markup view (but still a valid node in the content DOM).
- let parentNodeFront = yield inspector.selection.nodeFront.parentNode();
- let nodeFront = yield getNodeFront("#container", inspector);
- is(parentNodeFront, nodeFront, "Selection is as expected after deletion");
-
- info("Check that the node was really removed");
- let node = yield getNodeFront("#after-whitespace", inspector);
- ok(!node, "The node can't be found in the page anymore");
-
- info("Undo the deletion to restore the original markup");
- yield undoChange(inspector);
- node = yield getNodeFront("#after-whitespace", inspector);
- ok(node, "The node is back");
-});
--- a/devtools/server/actors/inspector.js
+++ b/devtools/server/actors/inspector.js
@@ -85,21 +85,16 @@ const FONT_FAMILY_PREVIEW_TEXT = "The qu
const FONT_FAMILY_PREVIEW_TEXT_SIZE = 20;
const PSEUDO_CLASSES = [":hover", ":active", ":focus"];
const HIDDEN_CLASS = "__fx-devtools-hide-shortcut__";
const SVG_NS = "http://www.w3.org/2000/svg";
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const IMAGE_FETCHING_TIMEOUT = 500;
-// SKIP_TO_* arguments are used with the DocumentWalker, driving the strategy to use if
-// the starting node is incompatible with the filter function of the walker.
-const SKIP_TO_PARENT = "SKIP_TO_PARENT";
-const SKIP_TO_SIBLING = "SKIP_TO_SIBLING";
-
// The possible completions to a ':' with added score to give certain values
// some preference.
const PSEUDO_SELECTORS = [
[":active", 1],
[":hover", 1],
[":focus", 1],
[":visited", 0],
[":link", 0],
@@ -934,22 +929,22 @@ var WalkerActor = protocol.ActorClassWit
}
};
},
toString: function () {
return "[WalkerActor " + this.actorID + "]";
},
- getDocumentWalker: function (node, whatToShow, skipTo) {
+ getDocumentWalker: function (node, whatToShow) {
// Allow native anon content (like <video> controls) if preffed on
let nodeFilter = this.showAllAnonymousContent
- ? allAnonymousContentTreeWalkerFilter
- : standardTreeWalkerFilter;
- return new DocumentWalker(node, this.rootWin, whatToShow, nodeFilter, skipTo);
+ ? allAnonymousContentTreeWalkerFilter
+ : standardTreeWalkerFilter;
+ return new DocumentWalker(node, this.rootWin, whatToShow, nodeFilter);
},
destroy: function () {
if (this._destroyed) {
return;
}
this._destroyed = true;
protocol.Actor.prototype.destroy.call(this);
@@ -1370,20 +1365,17 @@ var WalkerActor = protocol.ActorClassWit
let maxNodes = options.maxNodes || -1;
if (maxNodes == -1) {
maxNodes = Number.MAX_VALUE;
}
// We're going to create a few document walkers with the same filter,
// make it easier.
let getFilteredWalker = documentWalkerNode => {
- let { whatToShow } = options;
- // Use SKIP_TO_SIBLING to force the walker to use a sibling of the provided node
- // in case this one is incompatible with the walker's filter function.
- return this.getDocumentWalker(documentWalkerNode, whatToShow, SKIP_TO_SIBLING);
+ return this.getDocumentWalker(documentWalkerNode, options.whatToShow);
};
// Need to know the first and last child.
let rawNode = node.rawNode;
let firstChild = getFilteredWalker(rawNode).firstChild();
let lastChild = getFilteredWalker(rawNode).lastChild();
if (!firstChild) {
@@ -1399,17 +1391,17 @@ var WalkerActor = protocol.ActorClassWit
} else {
start = firstChild;
}
let nodes = [];
// Start by reading backward from the starting point if we're centering...
let backwardWalker = getFilteredWalker(start);
- if (backwardWalker.currentNode != firstChild && options.center) {
+ if (start != firstChild && options.center) {
backwardWalker.previousSibling();
let backwardCount = Math.floor(maxNodes / 2);
let backwardNodes = this._readBackward(backwardWalker, backwardCount);
nodes = backwardNodes;
}
// Then read forward by any slack left in the max children...
let forwardWalker = getFilteredWalker(start);
@@ -1521,43 +1513,33 @@ var WalkerActor = protocol.ActorClassWit
},
/**
* Helper function for the `children` method: Read forward in the sibling
* list into an array with `count` items, including the current node.
*/
_readForward: function (walker, count) {
let ret = [];
-
let node = walker.currentNode;
do {
- if (!walker.isSkippedNode(node)) {
- // The walker can be on a node that would be filtered out if it didn't find any
- // other node to fallback to.
- ret.push(this._ref(node));
- }
+ ret.push(this._ref(node));
node = walker.nextSibling();
} while (node && --count);
return ret;
},
/**
* Helper function for the `children` method: Read backward in the sibling
* list into an array with `count` items, including the current node.
*/
_readBackward: function (walker, count) {
let ret = [];
-
let node = walker.currentNode;
do {
- if (!walker.isSkippedNode(node)) {
- // The walker can be on a node that would be filtered out if it didn't find any
- // other node to fallback to.
- ret.push(this._ref(node));
- }
+ ret.push(this._ref(node));
node = walker.previousSibling();
} while (node && --count);
ret.reverse();
return ret;
},
/**
* Return the first node in the document that matches the given selector.
@@ -2981,56 +2963,50 @@ function isNodeDead(node) {
}
/**
* Wrapper for inDeepTreeWalker. Adds filtering to the traversal methods.
* See inDeepTreeWalker for more information about the methods.
*
* @param {DOMNode} node
* @param {Window} rootWin
- * @param {Number} whatToShow
- * See nodeFilterConstants / inIDeepTreeWalker for options.
- * @param {Function} filter
- * A custom filter function Taking in a DOMNode and returning an Int. See
- * WalkerActor.nodeFilter for an example.
- * @param {String} skipTo
- * Either SKIP_TO_PARENT or SKIP_TO_SIBLING. If the provided node is not compatible
- * with the filter function for this walker, try to find a compatible one either
- * in the parents or in the siblings of the node.
+ * @param {Int} whatToShow See nodeFilterConstants / inIDeepTreeWalker for
+ * options.
+ * @param {Function} filter A custom filter function Taking in a DOMNode
+ * and returning an Int. See WalkerActor.nodeFilter for an example.
*/
function DocumentWalker(node, rootWin,
whatToShow = nodeFilterConstants.SHOW_ALL,
- filter = standardTreeWalkerFilter,
- skipTo = SKIP_TO_PARENT) {
+ filter = standardTreeWalkerFilter) {
if (!rootWin.location) {
throw new Error("Got an invalid root window in DocumentWalker");
}
this.walker = Cc["@mozilla.org/inspector/deep-tree-walker;1"]
.createInstance(Ci.inIDeepTreeWalker);
this.walker.showAnonymousContent = true;
this.walker.showSubDocuments = true;
this.walker.showDocumentsAsNodes = true;
this.walker.init(rootWin.document, whatToShow);
this.filter = filter;
- if (skipTo === SKIP_TO_PARENT) {
- while (node && this.isSkippedNode(node)) {
- node = node.parentNode;
- }
- } else if (skipTo === SKIP_TO_SIBLING) {
- node = this.getClosestAcceptedSibling(node);
+ // Make sure that the walker knows about the initial node (which could
+ // be skipped due to a filter). Note that simply calling parentNode()
+ // causes currentNode to be updated.
+ this.walker.currentNode = node;
+ while (node &&
+ this.filter(node) === nodeFilterConstants.FILTER_SKIP) {
+ node = this.walker.parentNode();
}
-
- // Make sure that the walker knows about the initial node (which could
- // be skipped due to a filter).
- this.walker.currentNode = node;
}
DocumentWalker.prototype = {
+ get node() {
+ return this.walker.node;
+ },
get whatToShow() {
return this.walker.whatToShow;
},
get currentNode() {
return this.walker.currentNode;
},
set currentNode(val) {
this.walker.currentNode = val;
@@ -3042,101 +3018,69 @@ DocumentWalker.prototype = {
nextNode: function () {
let node = this.walker.currentNode;
if (!node) {
return null;
}
let nextNode = this.walker.nextNode();
- while (nextNode && this.isSkippedNode(nextNode)) {
+ while (nextNode &&
+ this.filter(nextNode) === nodeFilterConstants.FILTER_SKIP) {
nextNode = this.walker.nextNode();
}
return nextNode;
},
firstChild: function () {
let node = this.walker.currentNode;
if (!node) {
return null;
}
let firstChild = this.walker.firstChild();
- while (firstChild && this.isSkippedNode(firstChild)) {
+ while (firstChild &&
+ this.filter(firstChild) === nodeFilterConstants.FILTER_SKIP) {
firstChild = this.walker.nextSibling();
}
return firstChild;
},
lastChild: function () {
let node = this.walker.currentNode;
if (!node) {
return null;
}
let lastChild = this.walker.lastChild();
- while (lastChild && this.isSkippedNode(lastChild)) {
+ while (lastChild &&
+ this.filter(lastChild) === nodeFilterConstants.FILTER_SKIP) {
lastChild = this.walker.previousSibling();
}
return lastChild;
},
previousSibling: function () {
let node = this.walker.previousSibling();
- while (node && this.isSkippedNode(node)) {
+ while (node && this.filter(node) === nodeFilterConstants.FILTER_SKIP) {
node = this.walker.previousSibling();
}
return node;
},
nextSibling: function () {
let node = this.walker.nextSibling();
- while (node && this.isSkippedNode(node)) {
+ while (node && this.filter(node) === nodeFilterConstants.FILTER_SKIP) {
node = this.walker.nextSibling();
}
return node;
- },
-
- /**
- * Loop on all of the provided node siblings until finding one that is compliant with
- * the filter function.
- */
- getClosestAcceptedSibling: function (startingNode) {
- if (this.filter(startingNode) === nodeFilterConstants.FILTER_ACCEPT) {
- // startingNode is already valid, return immediately.
- return startingNode;
- }
-
- // Loop on starting node siblings.
- let previous = startingNode;
- let next = startingNode;
- while (previous || next) {
- previous = previous && previous.previousSibling;
- next = next && next.nextSibling;
-
- if (this.filter(previous) === nodeFilterConstants.FILTER_ACCEPT) {
- // A valid node was found in the previous siblings of the startingNode.
- return previous;
- }
-
- if (this.filter(next) === nodeFilterConstants.FILTER_ACCEPT) {
- // A valid node was found in the next siblings of the startingNode.
- return next;
- }
- }
-
- return null;
- },
-
- isSkippedNode: function (node) {
- return this.filter(node) === nodeFilterConstants.FILTER_SKIP;
- },
+ }
};
function isInXULDocument(el) {
let doc = nodeDocument(el);
return doc &&
doc.documentElement &&
doc.documentElement.namespaceURI === XUL_NS;
}