Bug 1375315. Make sure to update block pseudo-element styles on various anonymous blocks. r=emilio
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 22 Jun 2017 11:24:11 -0400
changeset 365593 64a65ce29ca3c2f5d25463aeda3427cabd4a9f9c
parent 365592 72a8245e2525ce5130d4e6dce391c1e7147c733e
child 365594 2b190948b81bb6a571630bf16719ecde88f8e3b3
push id32080
push usercbook@mozilla.com
push dateFri, 23 Jun 2017 09:16:43 +0000
treeherdermozilla-central@3b468193c933 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1375315
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1375315. Make sure to update block pseudo-element styles on various anonymous blocks. r=emilio MozReview-Commit-ID: HBabvfWYgdP
layout/base/ServoRestyleManager.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsFrame.cpp
layout/reftests/bugs/1375315-1-ref.html
layout/reftests/bugs/1375315-1.html
layout/reftests/bugs/1375315-10-ref.html
layout/reftests/bugs/1375315-10.html
layout/reftests/bugs/1375315-11-ref.html
layout/reftests/bugs/1375315-11.html
layout/reftests/bugs/1375315-12-ref.html
layout/reftests/bugs/1375315-12.html
layout/reftests/bugs/1375315-2-ref.html
layout/reftests/bugs/1375315-2.html
layout/reftests/bugs/1375315-3-ref.html
layout/reftests/bugs/1375315-3.html
layout/reftests/bugs/1375315-4-ref.html
layout/reftests/bugs/1375315-4.html
layout/reftests/bugs/1375315-5-ref.html
layout/reftests/bugs/1375315-5.html
layout/reftests/bugs/1375315-6-ref.html
layout/reftests/bugs/1375315-6.html
layout/reftests/bugs/1375315-7-ref.html
layout/reftests/bugs/1375315-7.html
layout/reftests/bugs/1375315-8-ref.html
layout/reftests/bugs/1375315-8.html
layout/reftests/bugs/1375315-9-ref.html
layout/reftests/bugs/1375315-9.html
layout/reftests/bugs/reftest.list
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -246,32 +246,16 @@ private:
   ServoRestyleState& mParentRestyleState;
   RefPtr<nsStyleContext> mStyle;
   bool mShouldPostHints;
   bool mShouldComputeHints;
   nsChangeHint mComputedHint;
 };
 
 static void
-UpdateBlockFramePseudoElements(nsBlockFrame* aFrame,
-                               ServoRestyleState& aRestyleState)
-{
-  if (nsBulletFrame* bullet = aFrame->GetBullet()) {
-    RefPtr<nsStyleContext> newContext =
-      aRestyleState.StyleSet().ResolvePseudoElementStyle(
-        aFrame->GetContent()->AsElement(),
-        bullet->StyleContext()->GetPseudoType(),
-        aFrame->StyleContext(),
-        /* aPseudoElement = */ nullptr);
-
-    aFrame->UpdateStyleOfOwnedChildFrame(bullet, newContext, aRestyleState);
-  }
-}
-
-static void
 UpdateBackdropIfNeeded(nsIFrame* aFrame, ServoRestyleState& aRestyleState)
 {
   const nsStyleDisplay* display = aFrame->StyleContext()->StyleDisplay();
   if (display->mTopLayer != NS_STYLE_TOP_LAYER_TOP) {
     return;
   }
 
   // Elements in the top layer are guaranteed to have absolute or fixed
@@ -302,18 +286,17 @@ UpdateBackdropIfNeeded(nsIFrame* aFrame,
     backdropFrame, newContext, aRestyleState);
 }
 
 static void
 UpdateFramePseudoElementStyles(nsIFrame* aFrame,
                                ServoRestyleState& aRestyleState)
 {
   if (aFrame->IsFrameOfType(nsIFrame::eBlockFrame)) {
-    UpdateBlockFramePseudoElements(static_cast<nsBlockFrame*>(aFrame),
-                                   aRestyleState);
+    static_cast<nsBlockFrame*>(aFrame)->UpdatePseudoElementStyles(aRestyleState);
   }
 
   UpdateBackdropIfNeeded(aFrame, aRestyleState);
 }
 
 bool
 ServoRestyleManager::ProcessPostTraversal(Element* aElement,
                                           nsStyleContext* aParentContext,
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -50,16 +50,18 @@
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSFrameConstructor.h"
 #include "TextOverflow.h"
 #include "nsIFrameInlines.h"
 #include "CounterStyleManager.h"
 #include "nsISelection.h"
 #include "mozilla/dom/HTMLDetailsElement.h"
 #include "mozilla/dom/HTMLSummaryElement.h"
+#include "mozilla/ServoRestyleManager.h"
+#include "mozilla/ServoStyleSet.h"
 #include "mozilla/StyleSetHandle.h"
 #include "mozilla/StyleSetHandleInlines.h"
 #include "mozilla/Telemetry.h"
 
 #include "nsBidiPresUtils.h"
 
 #include <inttypes.h>
 
@@ -7074,24 +7076,18 @@ nsBlockFrame::CreateBulletFrameForListIt
                                            bool aListStylePositionInside)
 {
   nsIPresShell* shell = PresContext()->PresShell();
 
   CSSPseudoElementType pseudoType = aCreateBulletList ?
     CSSPseudoElementType::mozListBullet :
     CSSPseudoElementType::mozListNumber;
 
-  nsStyleContext* parentStyle =
-    CorrectStyleParentFrame(this,
-                            nsCSSPseudoElements::GetPseudoAtom(pseudoType))->
-    StyleContext();
-
-  RefPtr<nsStyleContext> kidSC = shell->StyleSet()->
-    ResolvePseudoElementStyle(mContent->AsElement(), pseudoType,
-                              parentStyle, nullptr);
+  RefPtr<nsStyleContext> kidSC = ResolveBulletStyle(pseudoType,
+                                                    shell->StyleSet());
 
   // Create bullet frame
   nsBulletFrame* bullet = new (shell) nsBulletFrame(kidSC);
   bullet->Init(mContent, this, nullptr);
 
   // If the list bullet frame should be positioned inside then add
   // it to the flow now.
   if (aListStylePositionInside) {
@@ -7514,16 +7510,40 @@ nsBlockFrame::ResolveBidi()
   nsPresContext* presContext = PresContext();
   if (!presContext->BidiEnabled()) {
     return NS_OK;
   }
 
   return nsBidiPresUtils::Resolve(this);
 }
 
+void
+nsBlockFrame::UpdatePseudoElementStyles(ServoRestyleState& aRestyleState)
+{
+  if (nsBulletFrame* bullet = GetBullet()) {
+    CSSPseudoElementType type = bullet->StyleContext()->GetPseudoType();
+    RefPtr<nsStyleContext> newBulletStyle =
+      ResolveBulletStyle(type, &aRestyleState.StyleSet());
+    UpdateStyleOfOwnedChildFrame(bullet, newBulletStyle, aRestyleState);
+  }
+}
+
+already_AddRefed<nsStyleContext>
+nsBlockFrame::ResolveBulletStyle(CSSPseudoElementType aType,
+                                 StyleSetHandle aStyleSet)
+{
+  nsStyleContext* parentStyle =
+    CorrectStyleParentFrame(this,
+                            nsCSSPseudoElements::GetPseudoAtom(aType))->
+    StyleContext();
+
+  return aStyleSet->ResolvePseudoElementStyle(mContent->AsElement(), aType,
+                                              parentStyle, nullptr);
+}
+
 #ifdef DEBUG
 void
 nsBlockFrame::VerifyLines(bool aFinalCheckOK)
 {
   if (!gVerifyLines) {
     return;
   }
   if (mLines.empty()) {
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -39,16 +39,18 @@ enum class LineReflowStatus {
   // the next page or column if it's not the first line on the current page/column.
   Truncated
 };
 
 class nsBlockInFlowLineIterator;
 class nsBulletFrame;
 namespace mozilla {
 class BlockReflowInput;
+class ServoRestyleState;
+class StyleSetHandle;
 } // namespace mozilla
 
 /**
  * Some invariants:
  * -- The overflow out-of-flows list contains the out-of-
  * flow frames whose placeholders are in the overflow list.
  * -- A given piece of content has at most one placeholder
  * frame in a block's normal child list.
@@ -390,16 +392,22 @@ public:
    */
   static nsBlockFrame* GetNearestAncestorBlock(nsIFrame* aCandidate);
 
   struct FrameLines {
     nsLineList mLines;
     nsFrameList mFrames;
   };
 
+  /**
+   * Update the styles of our various pseudo-elements (bullets, first-letter,
+   * first-line, etc).
+   */
+  void UpdatePseudoElementStyles(mozilla::ServoRestyleState& aRestyleState);
+
 protected:
   explicit nsBlockFrame(nsStyleContext* aContext, ClassID aID = kClassID)
     : nsContainerFrame(aContext, aID)
     , mMinWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
     , mPrefWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
   {
 #ifdef DEBUG
   InitDebugFlags();
@@ -898,16 +906,23 @@ protected:
   // this block until our next continuation takes them.
   nsFrameList* GetPushedFloats() const;
   // Get the pushed floats list, or if there is not currently one,
   // make a new empty one.
   nsFrameList* EnsurePushedFloats();
   // Remove and return the pushed floats list.
   nsFrameList* RemovePushedFloats();
 
+  // Resolve a style context for our bullet frame.  aType should be
+  // mozListBullet or mozListNumber.  Passing in the style set is an
+  // optimization, because all callsites have it.
+  already_AddRefed<nsStyleContext> ResolveBulletStyle(
+    mozilla::CSSPseudoElementType aType,
+    mozilla::StyleSetHandle aStyleSet);
+
 #ifdef DEBUG
   void VerifyLines(bool aFinalCheckOK);
   void VerifyOverflowSituation();
   int32_t GetDepth() const;
 #endif
 
   nscoord mMinWidth, mPrefWidth;
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -10226,16 +10226,27 @@ nsIFrame::UpdateStyleOfChildAnonBox(nsIF
 
   nsChangeHint childHint =
     UpdateStyleOfOwnedChildFrame(aChildFrame, newContext, aRestyleState);
 
   // Now that we've updated the style on aChildFrame, check whether it itself
   // has anon boxes to deal with.
   ServoRestyleState childrenState(aRestyleState, childHint);
   aChildFrame->UpdateStyleOfOwnedAnonBoxes(childrenState);
+
+  // Assuming anon boxes don't have ::backdrop associated with them... if that
+  // ever changes, we'd need to handle that here, like we do in
+  // ServoRestyleManager::ProcessPostTraversal
+
+  // We do need to handle block pseudo-elements here, though.  Especially list
+  // bullets.
+  if (aChildFrame->IsFrameOfType(nsIFrame::eBlockFrame)) {
+    auto block = static_cast<nsBlockFrame*>(aChildFrame);
+    block->UpdatePseudoElementStyles(childrenState);
+  }
 }
 
 nsChangeHint
 nsIFrame::UpdateStyleOfOwnedChildFrame(nsIFrame* aChildFrame,
                                        nsStyleContext* aNewStyleContext,
                                        ServoRestyleState& aRestyleState)
 {
   // Figure out whether we have an actual change.  It's important that we do
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<ul>
+  <li style="overflow: hidden; list-style-position: inside; color: green">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-1.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("li").style.color = "green";
+  }
+</script>
+<ul>
+  <li style="overflow: hidden; list-style-position: inside; color: red">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-10-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<button style="display: list-item; color: green">
+  Bullet should be green.
+</button>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-10.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("button").style.color = "green";
+  }
+</script>
+<button style="display: list-item; color: red">
+  Bullet should be green.
+</button>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-11-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<select style="display: list-item; list-style-position: inside; color: green">
+  <option>Bullets should be green</option>
+</select>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-11.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("select").style.color = "green";
+  }
+</script>
+<select style="display: list-item; list-style-position: inside; color: red">
+  <option>Bullets should be green</option>
+</select>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-12-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<select multiple
+        style="display: list-item; list-style-position: inside; color: green">
+  <option>Bullet should be green</option>
+</select>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-12.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("select").style.color = "green";
+  }
+</script>
+<select multiple
+        style="display: list-item; list-style-position: inside; color: red">
+  <option>Bullet should be green</option>
+</select>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-2-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<ul>
+  <li style="column-count: 2; width: 50px; list-style-position: inside; color: green">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-2.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("li").style.color = "green";
+  }
+</script>
+<ul>
+  <li style="column-count: 2; width: 50px; list-style-position: inside; color: red">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-3-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<ul>
+  <li style="column-count: 2; width: 50px; color: green">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-3.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("li").style.color = "green";
+  }
+</script>
+<ul>
+  <li style="column-count: 2; width: 50px; color: red">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-4-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<ul>
+  <li style="column-count: 2; width: 50px; color: green">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-4.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("li").style.color = "green";
+  }
+</script>
+<ul>
+  <li style="column-count: 2; width: 50px; color: red">
+    Bullet should be green.
+  </li>
+</ul>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-5-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<details open
+         style="display: list-item; padding: 40px; margin: 40px; color: green">
+    Bullet should be green.
+</details>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-5.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("details").style.color = "green";
+  }
+</script>
+<details open
+         style="display: list-item; padding: 40px; margin: 40px; color: red">
+    Bullet should be green.
+</details>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-6-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<details open
+         style="display: list-item; list-style-position: inside; color: green">
+    Bullet should be green.
+</details>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-6.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("details").style.color = "green";
+  }
+</script>
+<details open
+         style="display: list-item; list-style-position: inside; color: red">
+    Bullet should be green.
+</details>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-7-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<fieldset>
+  <legend style="display: list-item; color: green">Bullet should be green</legend>
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-7.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("legend").style.color = "green";
+  }
+</script>
+<fieldset>
+  <legend style="display: list-item; color: red">Bullet should be green</legend>
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-8-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<fieldset style="display: list-item; margin: 40px; color: green">
+  Bullet should be green
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-8.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("fieldset").style.color = "green";
+  }
+</script>
+<fieldset style="display: list-item; margin: 40px; color: red">
+  Bullet should be green
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-9-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<fieldset style="display: list-item; column-count: 2; width: 100px; color: green">
+  Bullet should be green
+</fieldset>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1375315-9.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script>
+  onload = function() {
+    var height = document.body.offsetHeight; // Flush layout
+    document.querySelector("fieldset").style.color = "green";
+  }
+</script>
+<fieldset style="display: list-item; column-count: 2; width: 100px; color: red">
+  Bullet should be green
+</fieldset>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -2010,9 +2010,21 @@ fails-if(!stylo||styloVsGecko) == 136516
 == 1366144.html 1366144-ref.html
 == 1367592-1.html 1367592-1-ref.html
 == 1368113-1.html 1368113-1-ref.html
 == 1369584-1a.html 1369584-1-ref.html
 == 1369584-1b.html 1369584-1-ref.html
 == 1369954-1.xhtml 1369954-1-ref.xhtml
 == 1369985-1.html 1369985-1-ref.html
 == 1371130.xhtml 1371130-ref.xhtml
+== 1375315-1.html 1375315-1-ref.html
+== 1375315-2.html 1375315-2-ref.html
+== 1375315-3.html 1375315-3-ref.html
+== 1375315-4.html 1375315-4-ref.html
+== 1375315-5.html 1375315-5-ref.html
+== 1375315-6.html 1375315-6-ref.html
+== 1375315-7.html 1375315-7-ref.html
+== 1375315-8.html 1375315-8-ref.html
+== 1375315-9.html 1375315-9-ref.html
+== 1375315-10.html 1375315-10-ref.html
+== 1375315-11.html 1375315-11-ref.html
+== 1375315-12.html 1375315-12-ref.html
 == 1374062.html 1374062-ref.html