Bug 1393861: Correctly apply the display fixup for ::before and ::after pseudo-elements. r=heycam draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 05 Sep 2017 15:07:01 +0200
changeset 659986 b95e93bd4e2ad263f398150565125eac9fe32748
parent 659985 bccacfbf93423edf7e81d0c2ea163c3244c2cd09
child 730110 4f0b8a98a301a8ff2a441d5b60478386cbf09b70
push id78262
push userbmo:emilio@crisal.io
push dateWed, 06 Sep 2017 13:17:08 +0000
reviewersheycam
bugs1393861
milestone57.0a1
Bug 1393861: Correctly apply the display fixup for ::before and ::after pseudo-elements. r=heycam MozReview-Commit-ID: G0bcZmn0mP
layout/style/test/mochitest.ini
layout/style/test/test_pseudo_display_fixup.html
layout/style/test/test_reframe_pseudo_element.html
testing/web-platform/meta/cssom/getComputedStyle-pseudo.html.ini
testing/web-platform/tests/cssom/getComputedStyle-pseudo.html
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -257,16 +257,17 @@ skip-if = android_version == '18' #debug
 [test_parser_diagnostics_unprintables.html]
 [test_pixel_lengths.html]
 [test_pointer-events.html]
 [test_position_float_display.html]
 [test_position_sticky.html]
 [test_priority_preservation.html]
 [test_property_database.html]
 [test_property_syntax_errors.html]
+[test_pseudo_display_fixup.html]
 [test_pseudoelement_state.html]
 [test_pseudoelement_parsing.html]
 [test_redundant_font_download.html]
 support-files = redundant_font_download.sjs
 [test_reframe_pseudo_element.html]
 [test_rem_unit.html]
 [test_restyle_table_wrapper.html]
 [test_restyles_in_smil_animation.html]
new file mode 100644
--- /dev/null
+++ b/layout/style/test/test_pseudo_display_fixup.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test item blockification of pseudo-elements</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+  #test {
+    display: flex;
+  }
+  #test::before, #test::after {
+    content: "test";
+    display: inline-block;
+    color: green;
+    /*
+     * NOTE(emilio): The transition rule is very intentional, to avoid testing
+     * the eagerly resolved style.
+     */
+    transition: color 1s ease;
+  }
+</style>
+<div id="test"></div>
+<script>
+test(function() {
+  document.body.offsetTop;
+  let test = document.getElementById("test");
+  assert_equals(getComputedStyle(test, "::before").display, "block");
+  assert_equals(getComputedStyle(test, "::after").display, "block");
+}, "::before and ::after pseudo-elements are blockified");
+</script>
--- a/layout/style/test/test_reframe_pseudo_element.html
+++ b/layout/style/test/test_reframe_pseudo_element.html
@@ -2,32 +2,45 @@
 <meta charset="utf-8">
 <title>
   Test for bug 1376352: We don't reframe all the time a replaced element that
   matches generated content rules.
 </title>
 <link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
 <style>
+#flex::before,
 input::before {
   content: "Foo";
 }
 </style>
 <input type="text">
+<div id="flex"></div>
 <script>
 SimpleTest.waitForExplicitFinish();
 const utils = SpecialPowers.getDOMWindowUtils(window);
-document.documentElement.offsetTop;
-const input = document.querySelector('input');
 
-const previousConstructCount = utils.framesConstructed;
-const previousRestyleGeneration = utils.restyleGeneration;
+function testNoReframe(callback) {
+  document.documentElement.offsetTop;
+  const previousConstructCount = utils.framesConstructed;
+  const previousRestyleGeneration = utils.restyleGeneration;
+
+  callback();
 
-input.style.color = "blue";
+  document.documentElement.offsetTop;
+  isnot(previousRestyleGeneration, utils.restyleGeneration,
+        "We should have restyled");
+  is(previousConstructCount, utils.framesConstructed,
+     "We shouldn't have reframed");
+}
 
-document.documentElement.offsetTop;
-isnot(previousRestyleGeneration, utils.restyleGeneration,
-      "We should have restyled");
-is(previousConstructCount, utils.framesConstructed,
-   "We shouldn't have reframed");
+testNoReframe(function() {
+  const input = document.querySelector('input');
+  input.style.color = "blue";
+});
+
+testNoReframe(function() {
+  const flex = document.getElementById('flex');
+  flex.style.color = "blue";
+});
 
 SimpleTest.finish();
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/cssom/getComputedStyle-pseudo.html.ini
@@ -0,0 +1,6 @@
+[getComputedStyle-pseudo.html]
+  type: testharness
+  bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1396844
+  [Item-based blockification of nonexistent pseudo-elements]
+    expected:
+      if stylo: FAIL
--- a/testing/web-platform/tests/cssom/getComputedStyle-pseudo.html
+++ b/testing/web-platform/tests/cssom/getComputedStyle-pseudo.html
@@ -12,33 +12,43 @@
 #contents {
   display: contents;
   border: 10px solid red;
 }
 
 #test::before,
 #test::after,
 #contents::before,
-#contents::after {
+#contents::after,
+#flex::before,
+#flex::after {
   content: " ";
   width: 50%;
   height: 10px;
   display: block;
 }
 #none {
   display: none;
 }
 #none::before,
 #none::after {
   content: "Foo";
 }
+#flex {
+  display: flex;
+}
+#flex-no-pseudo {
+  display: flex;
+}
 </style>
 <div id="test">
   <div id="contents"></div>
   <div id="none"></div>
+  <div id="flex"></div>
+  <div id="flex-no-pseudo"></div>
 </div>
 <script>
 test(function() {
   var div = document.getElementById('test');
   [":before", ":after"].forEach(function(pseudo) {
     assert_equals(getComputedStyle(div, pseudo).width, "50px");
   });
 }, "Resolution of width is correct for ::before and ::after pseudo-elements");
@@ -59,9 +69,23 @@ test(function() {
 }, "Resolution of nonexistent pseudo-element styles");
 test(function() {
   var none = document.getElementById('none');
   [":before", ":after"].forEach(function(pseudo) {
     assert_equals(getComputedStyle(none, pseudo).content, "\"Foo\"",
                   "Pseudo-styles of display: none elements should be correct");
   });
 }, "Resolution of pseudo-element styles in display: none elements");
+test(function() {
+  var flex = document.getElementById('flex');
+  [":before", ":after"].forEach(function(pseudo) {
+    assert_equals(getComputedStyle(flex, pseudo).display, "block",
+                  "Pseudo-styles of display: flex elements should get blockified");
+  });
+}, "Item-based blockification of pseudo-elements");
+test(function() {
+  var flexNoPseudo = document.getElementById('flex-no-pseudo');
+  [":before", ":after"].forEach(function(pseudo) {
+    assert_equals(getComputedStyle(flexNoPseudo, pseudo).display, "block",
+                  "Pseudo-styles of display: flex elements should get blockified");
+  });
+}, "Item-based blockification of nonexistent pseudo-elements");
 </script>