/* vim: set ft=javascript 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 for Bug 777674
add_task(async function() {
const { walker } =
await initInspectorFront(MAIN_DOMAIN + "inspector-traversal-data.html");
await testXBLAnonymousInHTMLDocument(walker);
await testNativeAnonymous(walker);
await testNativeAnonymousStartingNode(walker);
await testPseudoElements(walker);
await testEmptyWithPseudo(walker);
await testShadowAnonymous(walker);
});
async function testXBLAnonymousInHTMLDocument(walker) {
info("Testing XBL anonymous in an HTML document.");
await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const rawToolbarbutton = content.document.createElementNS(XUL_NS, "toolbarbutton");
content.document.documentElement.appendChild(rawToolbarbutton);
});
const toolbarbutton = await walker.querySelector(walker.rootNode, "toolbarbutton");
const children = await walker.children(toolbarbutton);
is(toolbarbutton.numChildren, 0, "XBL content is not visible in HTML doc");
is(children.nodes.length, 0, "XBL content is not returned in HTML doc");
}
async function testNativeAnonymous(walker) {
info("Testing native anonymous content with walker.");
const select = await walker.querySelector(walker.rootNode, "select");
const children = await walker.children(select);
is(select.numChildren, 2, "No native anon content for form control");
is(children.nodes.length, 2, "No native anon content for form control");
}
async function testNativeAnonymousStartingNode(walker) {
info("Tests attaching an element that a walker can't see.");
await ContentTask.spawn(gBrowser.selectedBrowser, [walker.actorID],
async function(actorID) {
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
const { DebuggerServer } = require("devtools/server/main");
const {DocumentWalker} =
require("devtools/server/actors/inspector/document-walker");
const nodeFilterConstants =
require("devtools/shared/dom-node-filter-constants");
const docwalker = new DocumentWalker(
content.document.querySelector("select"),
content,
{
whatToShow: nodeFilterConstants.SHOW_ALL,
filter: () => {
return nodeFilterConstants.FILTER_ACCEPT;
},
}
);
const scrollbar = docwalker.lastChild();
is(scrollbar.tagName, "scrollbar", "An anonymous child has been fetched");
// Convert actorID to current compartment string otherwise
// searchAllConnectionsForActor is confused and won't find the actor.
actorID = String(actorID);
const serverWalker = DebuggerServer.searchAllConnectionsForActor(actorID);
const node = await serverWalker.attachElement(scrollbar);
ok(node, "A response has arrived");
ok(node.node, "A node is in the response");
is(node.node.rawNode.tagName, "SELECT",
"The node has changed to a parent that the walker recognizes");
});
}
async function testPseudoElements(walker) {
info("Testing pseudo elements with walker.");
// Markup looks like:
<::before /><::after />
const pseudo = await walker.querySelector(walker.rootNode, "#pseudo");
const children = await walker.children(pseudo);
is(pseudo.numChildren, 1, "::before/::after are not counted if there is a child");
is(children.nodes.length, 3, "Correct number of children");
const before = children.nodes[0];
ok(before.isAnonymous, "Child is anonymous");
ok(!before._form.isXBLAnonymous, "Child is not XBL anonymous");
ok(!before._form.isShadowAnonymous, "Child is not shadow anonymous");
ok(before._form.isNativeAnonymous, "Child is native anonymous");
const span = children.nodes[1];
ok(!span.isAnonymous, "Child is not anonymous");
const after = children.nodes[2];
ok(after.isAnonymous, "Child is anonymous");
ok(!after._form.isXBLAnonymous, "Child is not XBL anonymous");
ok(!after._form.isShadowAnonymous, "Child is not shadow anonymous");
ok(after._form.isNativeAnonymous, "Child is native anonymous");
}
async function testEmptyWithPseudo(walker) {
info("Testing elements with no childrent, except for pseudos.");
info("Checking an element whose only child is a pseudo element");
const pseudo = await walker.querySelector(walker.rootNode, "#pseudo-empty");
const children = await walker.children(pseudo);
is(pseudo.numChildren, 1,
"::before/::after are is counted if there are no other children");
is(children.nodes.length, 1, "Correct number of children");
const before = children.nodes[0];
ok(before.isAnonymous, "Child is anonymous");
ok(!before._form.isXBLAnonymous, "Child is not XBL anonymous");
ok(!before._form.isShadowAnonymous, "Child is not shadow anonymous");
ok(before._form.isNativeAnonymous, "Child is native anonymous");
}
async function testShadowAnonymous(walker) {
if (true) {
// FIXME(bug 1465114)
return;
}
info("Testing shadow DOM content.");
const shadow = await walker.querySelector(walker.rootNode, "#shadow");
const children = await walker.children(shadow);
is(shadow.numChildren, 3, "Children of the shadow root are counted");
is(children.nodes.length, 3, "Children returned from walker");
const before = children.nodes[0];
ok(before.isAnonymous, "Child is anonymous");
ok(!before._form.isXBLAnonymous, "Child is not XBL anonymous");
ok(!before._form.isShadowAnonymous, "Child is not shadow anonymous");
ok(before._form.isNativeAnonymous, "Child is native anonymous");
//
Shadow DOM
const shadowChild1 = children.nodes[1];
ok(shadowChild1.isAnonymous, "Child is anonymous");
ok(!shadowChild1._form.isXBLAnonymous, "Child is not XBL anonymous");
ok(shadowChild1._form.isShadowAnonymous, "Child is shadow anonymous");
ok(!shadowChild1._form.isNativeAnonymous, "Child is not native anonymous");
const shadowSubChildren = await walker.children(children.nodes[1]);
is(shadowChild1.numChildren, 2, "Subchildren of the shadow root are counted");
is(shadowSubChildren.nodes.length, 2, "Subchildren are returned from walker");
// DOM
const shadowSubChild = children.nodes[1];
ok(shadowSubChild.isAnonymous, "Child is anonymous");
ok(!shadowSubChild._form.isXBLAnonymous, "Child is not XBL anonymous");
ok(shadowSubChild._form.isShadowAnonymous, "Child is shadow anonymous");
ok(!shadowSubChild._form.isNativeAnonymous, "Child is not native anonymous");
//
const shadowChild2 = children.nodes[2];
ok(shadowChild2.isAnonymous, "Child is anonymous");
ok(!shadowChild2._form.isXBLAnonymous, "Child is not XBL anonymous");
ok(shadowChild2._form.isShadowAnonymous, "Child is shadow anonymous");
ok(!shadowChild2._form.isNativeAnonymous, "Child is not native anonymous");
}