Bug 1421105 - Part4:Update the styling of anon boxes created by column-span splitting for Servo. draft
authorNeerja Pancholi <npancholi@mozilla.com>
Mon, 27 Nov 2017 17:50:30 -0800
changeset 708741 cda90257e264ed55df169332ce365204f5ba0844
parent 708740 b6988f872c9ba61e3c90f9ba8f6dfc0576ca5437
child 708742 b87bf9901409e7723c86b210986d38d8113d9d02
push id92427
push userbmo:npancholi@mozilla.com
push dateThu, 07 Dec 2017 01:40:41 +0000
bugs1421105
milestone59.0a1
Bug 1421105 - Part4:Update the styling of anon boxes created by column-span splitting for Servo. MozReview-Commit-ID: JtoGXkDELsS
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsColumnSetWrapperFrame.cpp
layout/generic/nsColumnSetWrapperFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsInlineFrame.cpp
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -952,16 +952,52 @@ nsBlockFrame::GetPrefWidthTightBounds(gf
       }
     }
   }
   data.ForceBreak();
 
   return NS_OK;
 }
 
+void
+nsBlockFrame::UpdateStyleOfOwnedAnonBoxesForColumnSpanSplit(
+  mozilla::ServoRestyleState& aRestyleState) {
+  MOZ_ASSERT(StyleContext()->StyleColumn()->mColumnSpan ==
+    NS_STYLE_COLUMN_SPAN_ALL, "Why call this if we are not the column span?");
+
+  nsIFrame* blockFrame = GetProperty(nsIFrame::IBSplitPrevSibling());
+  if (!blockFrame) {
+    // If this column-span is not an IB-split sibling then no need to restyle it?
+    return;
+  }
+
+  // The later blocks need to get original parent's style.
+  ServoStyleContext* originalStyle = blockFrame->StyleContext()->AsServo();
+
+  // The anonymous block's style inherits from the original parent
+  RefPtr<ServoStyleContext> newContext =
+  aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle(
+    nsCSSAnonBoxes::mozColumnSpanWrapper, originalStyle);
+
+  MOZ_ASSERT(!GetPrevContinuation(), "Must be first continuation");
+  MOZ_ASSERT(StyleContext()->GetPseudo() == nsCSSAnonBoxes::mozColumnSpanWrapper,
+              "Unexpected kind of style context");
+
+  for (nsIFrame* cont = this; cont; cont = cont->GetNextContinuation()) {
+    cont->SetStyleContext(newContext);
+  }
+
+  nsIFrame* nextSibling = GetProperty(nsIFrame::IBSplitSibling());
+  if (nextSibling) {
+    for (nsIFrame* cont = nextSibling; cont; cont = cont->GetNextContinuation()) {
+      cont->SetStyleContext(originalStyle);
+    }
+  }
+}
+
 /**
  * Return whether aNewAvailableSpace is smaller *on either side*
  * (inline-start or inline-end) than aOldAvailableSpace, so that we know
  * if we need to redo layout on an line, replaced block, or block
  * formatting context, because its height (which we used to compute
  * aNewAvailableSpace) caused it to intersect additional floats.
  */
 static bool
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -289,16 +289,21 @@ public:
   nscoord GetPrefISize(gfxContext *aRenderingContext) override;
 
   nsRect ComputeTightBounds(DrawTarget* aDrawTarget) const override;
 
   nsresult GetPrefWidthTightBounds(gfxContext* aContext,
                                    nscoord* aX,
                                    nscoord* aXMost) override;
 
+  // Restyles the block wrappers around our column spans.
+  // This will only be called when such wrappers exist.
+  void UpdateStyleOfOwnedAnonBoxesForColumnSpanSplit(
+    mozilla::ServoRestyleState& aRestyleState);
+
   /**
    * Compute the final block size of this frame.
    *
    * @param aReflowInput Data structure passed from parent during reflow.
    * @param aReflowStatus A pointer to the reflow status for when we're finished
    *        doing reflow. this will get set appropriately if the block-size
    *        causes us to exceed the current available (page) block-size.
    * @param aContentBSize The block-size of content, precomputed outside of this
--- a/layout/generic/nsColumnSetWrapperFrame.cpp
+++ b/layout/generic/nsColumnSetWrapperFrame.cpp
@@ -66,16 +66,24 @@ nsColumnSetWrapperFrame::BuildDisplayLis
 
   // Our children won't have backgrounds so it doesn't matter where we put them.
   for (nsIFrame* childFrame : mFrames) {
     BuildDisplayListForChild(aBuilder, childFrame, aLists);
   }
 }
 
 void
+nsColumnSetWrapperFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
+{
+  if (mFrames.NotEmpty()) {
+    aResult.AppendElement(OwnedAnonBox(mFrames.FirstChild()));
+  }
+}
+
+void
 nsColumnSetWrapperFrame::Reflow(nsPresContext*     aPresContext,
                                 ReflowOutput&      aDesiredSize,
                                 const ReflowInput& aReflowInput,
                                 nsReflowStatus&    aStatus)
 {
   MarkInReflow();
   DO_GLOBAL_REFLOW_COUNT("nsColumnSetWrapperFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
--- a/layout/generic/nsColumnSetWrapperFrame.h
+++ b/layout/generic/nsColumnSetWrapperFrame.h
@@ -25,16 +25,18 @@ public:
   NS_DECL_FRAMEARENA_HELPERS(nsColumnSetWrapperFrame)
 
   friend nsContainerFrame* NS_NewColumnSetWrapperFrame(nsIPresShell* aPresShell,
                                                        nsStyleContext* aContext,
                                                        nsFrameState aStateFlags);
   void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                         const nsDisplayListSet& aLists) override;
 
+  void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
+
   virtual nsContainerFrame* GetContentInsertionFrame() override {
     nsIFrame* frame = PrincipalChildList().FirstChild();
 
     if (!frame)
       return nullptr;
 
     return frame->GetContentInsertionFrame();
   }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -11132,17 +11132,24 @@ nsIFrame::DoUpdateStyleOfOwnedAnonBoxes(
   }
 
   AutoTArray<OwnedAnonBox,4> frames;
   AppendDirectlyOwnedAnonBoxes(frames);
   for (OwnedAnonBox& box : frames) {
     if (box.mUpdateStyleFn) {
       box.mUpdateStyleFn(this, box.mAnonBoxFrame, aRestyleState);
     } else {
-      UpdateStyleOfChildAnonBox(box.mAnonBoxFrame, aRestyleState);
+      if (box.mAnonBoxFrame->StyleContext()->StyleColumn()->mColumnSpan ==
+            NS_STYLE_COLUMN_SPAN_ALL) {
+        nsBlockFrame* blockFrame = static_cast<nsBlockFrame*>(box.mAnonBoxFrame);
+        MOZ_ASSERT(blockFrame, "This must be a valid block frame!");
+        blockFrame->UpdateStyleOfOwnedAnonBoxesForColumnSpanSplit(aRestyleState);
+      } else {
+        UpdateStyleOfChildAnonBox(box.mAnonBoxFrame, aRestyleState);
+      }
     }
   }
 }
 
 /* virtual */ void
 nsIFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
 {
   MOZ_ASSERT(!(GetStateBits() & NS_FRAME_OWNS_ANON_BOXES));
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -970,17 +970,19 @@ nsInlineFrame::UpdateStyleOfOwnedAnonBox
   // changehint being in aChangeList is good enough.  So we don't need to touch
   // aChangeList at all here.
 
   while (blockFrame) {
     MOZ_ASSERT(!blockFrame->GetPrevContinuation(),
                "Must be first continuation");
 
     MOZ_ASSERT(blockFrame->StyleContext()->GetPseudo() ==
-               nsCSSAnonBoxes::mozBlockInsideInlineWrapper,
+               nsCSSAnonBoxes::mozBlockInsideInlineWrapper ||
+               blockFrame->StyleContext()->GetPseudo() ==
+               nsCSSAnonBoxes::mozColumnSpanWrapper,
                "Unexpected kind of style context");
 
     // We don't want to just walk through using GetNextContinuationWithSameStyle
     // here, because we want to set updated style contexts on both our
     // ib-sibling blocks and inlines.
     for (nsIFrame* cont = blockFrame; cont; cont = cont->GetNextContinuation()) {
       cont->SetStyleContext(newContext);
     }