Bug 1476908 - Show keyframes for elements in shadow dom;r=bgrins
MozReview-Commit-ID: 6YJUnReL3PS
--- a/devtools/client/inspector/markup/test/head.js
+++ b/devtools/client/inspector/markup/test/head.js
@@ -553,24 +553,16 @@ async function checkDeleteAndSelection(i
info("Undo the deletion to restore the original markup");
await undoChange(inspector);
node = await getNodeFront(selector, inspector);
ok(node, "The node is back");
}
/**
- * Temporarily flip all the preferences needed to enable web components.
- */
-async function enableWebComponents() {
- await pushPref("dom.webcomponents.shadowdom.enabled", true);
- await pushPref("dom.webcomponents.customelements.enabled", true);
-}
-
-/**
* Assert whether the provided container is slotted.
*/
function assertContainerSlotted(container) {
ok(container.isSlotted(), "Container is a slotted container");
ok(container.elt.querySelector(".reveal-link"),
"Slotted container has a reveal link element");
}
--- a/devtools/client/inspector/rules/test/browser.ini
+++ b/devtools/client/inspector/rules/test/browser.ini
@@ -189,16 +189,17 @@ skip-if = (os == "win" && debug) # bug 9
[browser_rules_inherited-properties_02.js]
[browser_rules_inherited-properties_03.js]
[browser_rules_inherited-properties_04.js]
[browser_rules_inline-source-map.js]
[browser_rules_inline-style-order.js]
[browser_rules_invalid.js]
[browser_rules_invalid-source-map.js]
[browser_rules_keybindings.js]
+[browser_rules_keyframes-rule-shadowdom.js]
[browser_rules_keyframes-rule_01.js]
[browser_rules_keyframes-rule_02.js]
[browser_rules_keyframeLineNumbers.js]
[browser_rules_lineNumbers.js]
[browser_rules_livepreview.js]
[browser_rules_mark_overridden_01.js]
[browser_rules_mark_overridden_02.js]
[browser_rules_mark_overridden_03.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/test/browser_rules_keyframes-rule-shadowdom.js
@@ -0,0 +1,77 @@
+/* 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 that keyframes are displayed for elements nested under a shadow-root.
+
+const TEST_URI = `data:text/html;charset=utf-8,
+ <div></div>
+ <script>
+ document.querySelector('div').attachShadow({mode: 'open'}).innerHTML = \`
+ <span>text</span>
+ <style>
+ @keyframes blink {
+ 0% {
+ border: rgba(255,0,0,1) 2px dashed;
+ }
+ 100% {
+ border: rgba(255,0,0,0) 2px dashed;
+ }
+ }
+ span {
+ animation: blink .5s 0s infinite;
+ }
+ </style>\`;
+ </script>`;
+
+add_task(async function() {
+ await enableWebComponents();
+
+ await addTab(TEST_URI);
+
+ const {inspector, view} = await openRuleView();
+
+ info("Expand the shadow-root parent");
+ const divFront = await getNodeFront("div", inspector);
+ await inspector.markup.expandNode(divFront);
+ await waitForMultipleChildrenUpdates(inspector);
+
+ const {markup} = inspector;
+ const divContainer = markup.getContainer(divFront);
+
+ info("Expand the shadow-root");
+ const shadowRootContainer = divContainer.getChildContainers()[0];
+ await expandContainer(inspector, shadowRootContainer);
+
+ info("Retrieve the rules displayed for the span under the shadow root");
+ const spanContainer = shadowRootContainer.getChildContainers()[0];
+ const rules = await getKeyframeRules(spanContainer.node, inspector, view);
+
+ is(convertTextPropsToString(rules.keyframeRules[0].textProps),
+ "border: rgba(255,0,0,1) 2px dashed",
+ "Keyframe blink (0%) property is correct"
+ );
+
+ is(convertTextPropsToString(rules.keyframeRules[1].textProps),
+ "border: rgba(255,0,0,0) 2px dashed",
+ "Keyframe blink (100%) property is correct"
+ );
+});
+
+function convertTextPropsToString(textProps) {
+ return textProps.map(t => t.name + ": " + t.value).join("; ");
+}
+
+async function getKeyframeRules(selector, inspector, view) {
+ await selectNode(selector, inspector);
+ const elementStyle = view._elementStyle;
+
+ const rules = {
+ elementRules: elementStyle.rules.filter(rule => !rule.keyframes),
+ keyframeRules: elementStyle.rules.filter(rule => rule.keyframes)
+ };
+
+ return rules;
+}
--- a/devtools/client/shared/test/shared-head.js
+++ b/devtools/client/shared/test/shared-head.js
@@ -717,8 +717,16 @@ async function injectEventUtilsInContent
EventUtils.synthesizeMouseAtCenter(element,
{ type: "mouseup", isSynthesized: false }, content);
});
Services.scriptloader.loadSubScript(
"chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
});
}
+
+/**
+ * Temporarily flip all the preferences needed to enable web components.
+ */
+async function enableWebComponents() {
+ await pushPref("dom.webcomponents.shadowdom.enabled", true);
+ await pushPref("dom.webcomponents.customelements.enabled", true);
+}
--- a/devtools/server/actors/inspector/css-logic.js
+++ b/devtools/server/actors/inspector/css-logic.js
@@ -221,18 +221,18 @@ CssLogic.prototype = {
* Cache all the stylesheets in the inspected document
* @private
*/
_cacheSheets: function() {
this._passId++;
this.reset();
// styleSheets isn't an array, but forEach can work on it anyway
- Array.prototype.forEach.call(this.viewedDocument.styleSheets,
- this._cacheSheet, this);
+ const styleSheets = InspectorUtils.getAllStyleSheets(this.viewedDocument, true);
+ Array.prototype.forEach.call(styleSheets, this._cacheSheet, this);
this._sheetsCached = true;
},
/**
* Cache a stylesheet if it falls within the requirements: if it's enabled,
* and if the @media is allowed. This method also walks through the stylesheet
* cssRules to find @imported rules, to cache the stylesheets of those rules
--- a/devtools/server/actors/stylesheets.js
+++ b/devtools/server/actors/stylesheets.js
@@ -316,18 +316,19 @@ var StyleSheetActor = protocol.ActorClas
/**
* Retrieve the index (order) of stylesheet in the document.
*
* @return number
*/
get styleSheetIndex() {
if (this._styleSheetIndex == -1) {
- for (let i = 0; i < this.document.styleSheets.length; i++) {
- if (this.document.styleSheets[i] == this.rawSheet) {
+ const styleSheets = InspectorUtils.getAllStyleSheets(this.document, true);
+ for (let i = 0; i < styleSheets.length; i++) {
+ if (styleSheets[i] == this.rawSheet) {
this._styleSheetIndex = i;
break;
}
}
}
return this._styleSheetIndex;
},