Bug 1421105 - Part5:Update the styling of anon boxes created by column-span splitting for Servo.
MozReview-Commit-ID: JtoGXkDELsS
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -941,16 +941,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
@@ -288,16 +288,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
@@ -22,16 +22,24 @@ NS_NewColumnSetWrapperFrame(nsIPresShell
NS_IMPL_FRAMEARENA_HELPERS(nsColumnSetWrapperFrame)
nsColumnSetWrapperFrame::nsColumnSetWrapperFrame(nsStyleContext* aContext)
: nsBlockFrame(aContext, kClassID)
{
}
+void
+nsColumnSetWrapperFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
+{
+ if (mFrames.NotEmpty()) {
+ aResult.AppendElement(OwnedAnonBox(mFrames.FirstChild()));
+ }
+}
+
/*
* Any append, insert or remove operation is disallowed on ColumnSetWrapperFrame
* because in that case we must recreate the entire frame hierarchy under this
* wrapper to account for the added/removed element changing the breaking of
* frames across column-spans. This is handled in nsCSSFrameConstructor's
* ContentAppended/ContentRemoved/ContentInserted path.
* See nsCSSFrameConstructor::WipeContainingBlock.
*/
--- a/layout/generic/nsColumnSetWrapperFrame.h
+++ b/layout/generic/nsColumnSetWrapperFrame.h
@@ -22,16 +22,18 @@ class nsColumnSetWrapperFrame final : pu
{
public:
NS_DECL_FRAMEARENA_HELPERS(nsColumnSetWrapperFrame)
friend nsBlockFrame* NS_NewColumnSetWrapperFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext,
nsFrameState aStateFlags);
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
+
virtual nsContainerFrame* GetContentInsertionFrame() override {
MOZ_ASSERT_UNREACHABLE("Should not be called because we don't know whether"
" we're inserting a column-span or not.");
}
#ifdef DEBUG_FRAME_DUMP
nsresult GetFrameName(nsAString& aResult) const override {
return MakeFrameName(NS_LITERAL_STRING("ColumnSetWrapper"), aResult);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -11210,17 +11210,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);
}