Bug 1483663 - Show native anonymous nodes under UA widgets;r=ladybenko

Differential Revision: https://phabricator.services.mozilla.com/D14700

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Julian Descottes 2018-12-19 20:09:47 +00:00
parent 149cb23b37
commit 2c7c95fa56
4 changed files with 90 additions and 4 deletions

View File

@ -196,6 +196,7 @@ subsuite = clipboard
[browser_markup_shadowdom_slotted_keyboard_focus.js]
[browser_markup_shadowdom_slotupdate.js]
[browser_markup_shadowdom_ua_widgets.js]
[browser_markup_shadowdom_ua_widgets_with_nac.js]
[browser_markup_tag_delete_whitespace_node.js]
[browser_markup_tag_edit_01.js]
[browser_markup_tag_edit_02.js]

View File

@ -0,0 +1,51 @@
/* 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";
const TEST_URL = `data:text/html;charset=utf-8,` + encodeURIComponent(`
<video id="video-with-subtitles" style="border: 4px solid red" controls>
<track label="en" kind="subtitles" srclang="en" src="data:text/vtt,WEBVTT" default>
</video>`);
const TEST_ID = "#video-with-subtitles";
// Test that Inspector can show Native Anonymous Content (nac) in user agent widgets, as
// siblings of the ua widget closed shadow-root.
add_task(async function testWithoutShowAllAnonymousContent() {
info("Test a <video> element with subtitles, without showAllAnonymousContent");
const { inspector } = await setup({ showAllAnonymousContent: false });
// We should only see the shadow root and the authored <track> element.
const tree = `
video
#shadow-root!ignore-children
track`;
await assertMarkupViewAsTree(tree, TEST_ID, inspector);
});
add_task(async function testWithShowAllAnonymousContent() {
info("Test a <video> element with subtitles, expect to see native anonymous content");
const { inspector } = await setup({ showAllAnonymousContent: true });
// We should only see the shadow root, the <track> and two NAC elements <img> and <div>.
const tree = `
video
#shadow-root!ignore-children
track
img
class="caption-box"`;
await assertMarkupViewAsTree(tree, TEST_ID, inspector);
});
async function setup({ showAllAnonymousContent }) {
await pushPref("dom.ua_widget.enabled", true);
await pushPref("devtools.inspector.showUserAgentShadowRoots", true);
await pushPref("devtools.inspector.showAllAnonymousContent", showAllAnonymousContent);
const { inspector } = await openInspectorForURL(TEST_URL);
const { markup } = inspector;
return { inspector, markup };
}

View File

@ -589,7 +589,12 @@ function assertContainerHasText(container, expectedText) {
* subchild2
* child2
* subchild3!slotted`
* child3!ignore-children
* Each sub level should be indented by 2 spaces.
* Each line contains text expected to match with the text of the corresponding
* node in the markup view. Some suffixes are supported:
* - !slotted -> indicates that the line corresponds to the slotted version
* - !ignore-children -> the node might have children but do not assert them
* @param {String} selector
* A CSS selector that will uniquely match the "root" element from the tree
* @param {Inspector} inspector
@ -612,13 +617,21 @@ async function _checkMarkupViewNode(treeNode, container, inspector) {
info("Checking [" + path + "]");
info("Checking node: " + node);
const ignoreChildren = node.includes("!ignore-children");
const slotted = node.includes("!slotted");
// Remove optional suffixes.
const nodeText = node.replace("!slotted", "")
.replace("!ignore-children", "");
assertContainerHasText(container, nodeText);
if (slotted) {
const nodeName = node.replace("!slotted", "");
assertContainerHasText(container, nodeName);
assertContainerSlotted(container);
} else {
assertContainerHasText(container, node);
}
if (ignoreChildren) {
return;
}
if (!children.length) {

View File

@ -17,6 +17,7 @@ loader.lazyRequireGetter(this, "isAfterPseudoElement", "devtools/shared/layout/u
loader.lazyRequireGetter(this, "isAnonymous", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "isBeforePseudoElement", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "isDirectShadowHostChild", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "isNativeAnonymous", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "isShadowHost", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "isShadowRoot", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "isTemplateElement", "devtools/shared/layout/utils", true);
@ -735,6 +736,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
// developers.
const isUAWidget = shadowHost && node.rawNode.openOrClosedShadowRoot.isUAWidget();
const hideShadowRoot = isUAWidget && !this.showUserAgentShadowRoots;
const showNativeAnonymousChildren = isUAWidget && this.showUserAgentShadowRoots;
const templateElement = isTemplateElement(node.rawNode);
if (templateElement) {
@ -865,6 +867,9 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
...(hasBefore ? [first] : []),
// shadow host direct children
...nodes,
// native anonymous content for UA widgets
...(showNativeAnonymousChildren ?
this.getNativeAnonymousChildren(node.rawNode) : []),
// ::after
...(hasAfter ? [last] : []),
];
@ -873,6 +878,22 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
return { hasFirst, hasLast, nodes };
},
getNativeAnonymousChildren: function(rawNode) {
// Get an anonymous walker and start on the first child.
const walker = this.getDocumentWalker(rawNode);
let node = walker.firstChild();
const nodes = [];
while (node) {
// We only want native anonymous content here.
if (isNativeAnonymous(node)) {
nodes.push(node);
}
node = walker.nextSibling();
}
return nodes;
},
/**
* Get the next sibling of a given node. Getting nodes one at a time
* might be inefficient, be careful.