--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1184,25 +1184,20 @@ nsComboboxControlFrame::SetFormProperty(
}
nsContainerFrame*
nsComboboxControlFrame::GetContentInsertionFrame() {
return mInRedisplayText ? mDisplayFrame : mDropdownFrame->GetContentInsertionFrame();
}
void
-nsComboboxControlFrame::DoUpdateStyleOfOwnedAnonBoxes(
- ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsComboboxControlFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
- UpdateStyleOfChildAnonBox(mDropdownFrame, aStyleSet, aChangeList,
- aHintForThisFrame);
- UpdateStyleOfChildAnonBox(mDisplayFrame, aStyleSet, aChangeList,
- aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(mDropdownFrame));
+ aResult.AppendElement(OwnedAnonBox(mDisplayFrame));
}
nsresult
nsComboboxControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
// The frames used to display the combo box and the button used to popup the dropdown list
// are created through anonymous content. The dropdown list is not created through anonymous
// content because its frame is initialized specifically for the drop-down case and it is placed
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -112,20 +112,18 @@ public:
virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
virtual void SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) override;
virtual const nsFrameList& GetChildList(ChildListID aListID) const override;
virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
virtual nsContainerFrame* GetContentInsertionFrame() override;
- // Update the style on the block wrappers around our kids.
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return the dropdown and display frame.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
// nsIFormControlFrame
virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) override;
/**
* Inform the control that it got (or lost) focus.
* If it lost focus, the dropdown menu will be rolled up if needed,
* and FireOnChange() will be called.
* @param aOn true if got focus, false if lost focus.
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -659,18 +659,15 @@ nsFieldSetFrame::GetNaturalBaselineBOffs
*aBaseline += innerBStart;
} else {
*aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM));
}
return true;
}
void
-nsFieldSetFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsFieldSetFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
- nsIFrame* kid = GetInner();
- if (kid) {
- UpdateStyleOfChildAnonBox(kid, aStyleSet, aChangeList, aHintForThisFrame);
+ if (nsIFrame* kid = GetInner()) {
+ aResult.AppendElement(OwnedAnonBox(kid));
}
}
--- a/layout/forms/nsFieldSetFrame.h
+++ b/layout/forms/nsFieldSetFrame.h
@@ -68,21 +68,18 @@ public:
return nsContainerFrame::IsFrameOfType(aFlags &
~nsIFrame::eCanContainOverflowContainers);
}
virtual nsIScrollableFrame* GetScrollTargetFrame() override
{
return do_QueryFrame(GetInner());
}
- // Update the style on the block wrappers around our kids.
- virtual void DoUpdateStyleOfOwnedAnonBoxes(
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return the block wrapper around our kids.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
#ifdef ACCESSIBILITY
virtual mozilla::a11y::AccType AccessibleType() override;
#endif
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override {
return MakeFrameName(NS_LITERAL_STRING("FieldSet"), aResult);
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -391,26 +391,22 @@ nsHTMLButtonControlFrame::GetAdditionalS
void
nsHTMLButtonControlFrame::SetAdditionalStyleContext(int32_t aIndex,
nsStyleContext* aStyleContext)
{
mRenderer.SetStyleContext(aIndex, aStyleContext);
}
void
-nsHTMLButtonControlFrame::DoUpdateStyleOfOwnedAnonBoxes(
- ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsHTMLButtonControlFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
MOZ_ASSERT(mFrames.FirstChild(), "Must have our button-content anon box");
MOZ_ASSERT(!mFrames.FirstChild()->GetNextSibling(),
"Must only have our button-content anon box");
- UpdateStyleOfChildAnonBox(mFrames.FirstChild(),
- aStyleSet, aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(mFrames.FirstChild()));
}
#ifdef DEBUG
void
nsHTMLButtonControlFrame::AppendFrames(ChildListID aListID,
nsFrameList& aFrameList)
{
MOZ_CRASH("unsupported operation");
--- a/layout/forms/nsHTMLButtonControlFrame.h
+++ b/layout/forms/nsHTMLButtonControlFrame.h
@@ -93,22 +93,19 @@ public:
}
virtual bool IsFrameOfType(uint32_t aFlags) const override
{
return nsContainerFrame::IsFrameOfType(aFlags &
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
}
- /**
- * Update the style of our ::-moz-button-content anonymous box.
- */
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return the ::-moz-button-content anonymous box.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
+
protected:
nsHTMLButtonControlFrame(nsStyleContext* aContext, nsIFrame::ClassID aID);
virtual bool IsInput() { return false; }
// Indicates whether we should clip our children's painting to our
// border-box (either because of "overflow" or because of legacy reasons
// about how <input>-flavored buttons work).
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -1255,33 +1255,30 @@ nsColumnSetFrame::BuildDisplayList(nsDis
// Our children won't have backgrounds so it doesn't matter where we put them.
for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
BuildDisplayListForChild(aBuilder, e.get(), aDirtyRect, aLists);
}
}
void
-nsColumnSetFrame::DoUpdateStyleOfOwnedAnonBoxes(
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsColumnSetFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
// Everything in mFrames is continuations of the first thing in mFrames.
nsIFrame* column = mFrames.FirstChild();
// We might not have any columns, apparently?
if (!column) {
return;
}
MOZ_ASSERT(column->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::columnContent,
"What sort of child is this?");
- UpdateStyleOfChildAnonBox(column, aStyleSet, aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(column));
}
#ifdef DEBUG
void
nsColumnSetFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
{
MOZ_ASSERT(aListID != kPrincipalList || aChildList.OnlyChild(),
--- a/layout/generic/nsColumnSetFrame.h
+++ b/layout/generic/nsColumnSetFrame.h
@@ -72,22 +72,18 @@ public:
/**
* Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
* handled by our prev-in-flow, and any columns sitting on our own
* overflow list, and put them in our primary child list for reflowing.
*/
void DrainOverflowColumns();
- /**
- * Update the style on our column-content frames.
- */
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return the column-content frame.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override {
return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult);
}
#endif
nsRect CalculateBounds(const nsPoint& aOffset);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -40,17 +40,17 @@
#include "mozilla/Logging.h"
#include "mozilla/Sprintf.h"
#include "nsFrameManager.h"
#include "nsLayoutUtils.h"
#include "LayoutLogging.h"
#include "mozilla/GeckoRestyleManager.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/RestyleManagerInlines.h"
-
+#include "nsInlineFrame.h"
#include "nsIDOMNode.h"
#include "nsISelection.h"
#include "nsISelectionPrivate.h"
#include "nsFrameSelection.h"
#include "nsGkAtoms.h"
#include "nsCSSAnonBoxes.h"
#include "nsFrameTraversal.h"
@@ -10195,20 +10195,20 @@ nsBoxLayoutMetrics*
nsFrame::BoxMetrics() const
{
nsBoxLayoutMetrics* metrics = GetProperty(BoxMetricsProperty());
NS_ASSERTION(metrics, "A box layout method was called but InitBoxMetrics was never called");
return metrics;
}
void
-nsFrame::UpdateStyleOfChildAnonBox(nsIFrame* aChildFrame,
- ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsIFrame::UpdateStyleOfChildAnonBox(nsIFrame* aChildFrame,
+ ServoStyleSet& aStyleSet,
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame)
{
MOZ_ASSERT(aChildFrame->GetParent() == this,
"This should only be used for children!");
MOZ_ASSERT(aChildFrame->GetContent() == GetContent(),
"What content node is it a frame for?");
MOZ_ASSERT(!aChildFrame->GetPrevContinuation(),
"Only first continuations should end up here");
@@ -10473,26 +10473,83 @@ IsFrameScrolledOutOfView(nsIFrame *aFram
}
bool
nsIFrame::IsScrolledOutOfView()
{
return IsFrameScrolledOutOfView(this);
}
-/* virtual */
void
nsIFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame)
+{
+ // As a special case, we check for {ib}-split block frames here, rather
+ // than have an nsInlineFrame::AppendDirectlyOwnedAnonBoxes implementation
+ // that returns them.
+ //
+ // (If we did handle them in AppendDirectlyOwnedAnonBoxes, we would have to
+ // return *all* of the in-flow {ib}-split block frames, not just the first
+ // one. For restyling, we really just need the first in flow, and the other
+ // user of the AppendOwnedAnonBoxes API, AllChildIterator, doesn't need to
+ // know about them at all, since these block frames never create NAC. So we
+ // avoid any unncessary hashtable lookups for the {ib}-split frames by calling
+ // UpdateStyleOfOwnedAnonBoxesForIBSplit directly here.)
+ if (IsInlineFrame()) {
+ if ((GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
+ static_cast<nsInlineFrame*>(this)->
+ UpdateStyleOfOwnedAnonBoxesForIBSplit(aStyleSet, aChangeList,
+ aHintForThisFrame);
+ }
+ return;
+ }
+
+ AutoTArray<OwnedAnonBox,4> frames;
+ AppendDirectlyOwnedAnonBoxes(frames);
+ for (OwnedAnonBox& box : frames) {
+ if (box.mUpdateStyleFn) {
+ box.mUpdateStyleFn(this, box.mAnonBoxFrame,
+ aStyleSet, aChangeList, aHintForThisFrame);
+ } else {
+ UpdateStyleOfChildAnonBox(box.mAnonBoxFrame,
+ aStyleSet, aChangeList, aHintForThisFrame);
+ }
+ }
+}
+
+/* virtual */ void
+nsIFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
MOZ_ASSERT(!(GetStateBits() & NS_FRAME_OWNS_ANON_BOXES));
MOZ_ASSERT(false, "Why did this get called?");
}
+void
+nsIFrame::DoAppendOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
+{
+ size_t i = aResult.Length();
+ AppendDirectlyOwnedAnonBoxes(aResult);
+
+ // After appending the directly owned anonymous boxes of this frame to
+ // aResult above, we need to check each of them to see if they own
+ // any anonymous boxes themselves. Note that we keep progressing
+ // through aResult, looking for additional entries in aResult from these
+ // subsequent AppendDirectlyOwnedAnonBoxes calls. (Thus we can't
+ // use a ranged for loop here.)
+
+ while (i < aResult.Length()) {
+ nsIFrame* f = aResult[i].mAnonBoxFrame;
+ if (f->GetStateBits() & NS_FRAME_OWNS_ANON_BOXES) {
+ f->AppendDirectlyOwnedAnonBoxes(aResult);
+ }
+ ++i;
+ }
+}
+
nsIFrame::CaretPosition::CaretPosition()
: mContentOffset(0)
{
}
nsIFrame::CaretPosition::~CaretPosition()
{
}
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -696,23 +696,16 @@ protected:
void GetBoxName(nsAutoString& aName) override;
#endif
nsBoxLayoutMetrics* BoxMetrics() const;
// Fire DOM event. If no aContent argument use frame's mContent.
void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr);
- // A helper for implementing UpdateStyleOfOwnedAnonBoxes for the specific case
- // of the owned anon box being a child of this frame.
- void UpdateStyleOfChildAnonBox(nsIFrame* aChildFrame,
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame);
-
private:
void BoxReflow(nsBoxLayoutState& aState,
nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
gfxContext* aRenderingContext,
nscoord aX,
nscoord aY,
nscoord aWidth,
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -1037,22 +1037,19 @@ public:
virtual void AsyncScrollbarDragRejected() override {
return mHelper.AsyncScrollbarDragRejected();
}
virtual bool IsRootScrollFrameOfDocument() const override {
return mHelper.IsRootScrollFrameOfDocument();
}
- // Update the style on our scrolled frame.
- virtual void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override {
- UpdateStyleOfChildAnonBox(mHelper.GetScrolledFrame(), aStyleSet,
- aChangeList, aHintForThisFrame);
+ // Return the scrolled frame.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override {
+ aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame()));
}
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
#ifdef ACCESSIBILITY
virtual mozilla::a11y::AccType AccessibleType() override;
@@ -1482,21 +1479,19 @@ public:
virtual void AsyncScrollbarDragRejected() override {
return mHelper.AsyncScrollbarDragRejected();
}
virtual bool IsRootScrollFrameOfDocument() const override {
return mHelper.IsRootScrollFrameOfDocument();
}
- virtual void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override {
- UpdateStyleOfChildAnonBox(mHelper.GetScrolledFrame(), aStyleSet,
- aChangeList, aHintForThisFrame);
+ // Return the scrolled frame.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override {
+ aResult.AppendElement(OwnedAnonBox(mHelper.GetScrolledFrame()));
}
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
protected:
nsXULScrollFrame(nsStyleContext* aContext, bool aIsRoot,
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -409,25 +409,22 @@ nsHTMLCanvasFrame::GetContinuationOffset
}
offset -= mBorderPadding.GetPhysicalMargin(GetWritingMode()).top;
offset = std::max(0, offset);
}
return offset;
}
void
-nsHTMLCanvasFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsHTMLCanvasFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
MOZ_ASSERT(mFrames.FirstChild(), "Must have our canvas content anon box");
MOZ_ASSERT(!mFrames.FirstChild()->GetNextSibling(),
"Must only have our canvas content anon box");
- UpdateStyleOfChildAnonBox(mFrames.FirstChild(),
- aStyleSet, aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(mFrames.FirstChild()));
}
#ifdef ACCESSIBILITY
a11y::AccType
nsHTMLCanvasFrame::AccessibleType()
{
return a11y::eHTMLCanvasType;
}
--- a/layout/generic/nsHTMLCanvasFrame.h
+++ b/layout/generic/nsHTMLCanvasFrame.h
@@ -92,22 +92,19 @@ public:
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
// Inserted child content gets its frames parented by our child block
virtual nsContainerFrame* GetContentInsertionFrame() override {
return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
}
- /**
- * Update the style of our ::-moz-html-canvas-content anonymous box.
- */
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return the ::-moz-html-canvas-content anonymous box.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
+
protected:
virtual ~nsHTMLCanvasFrame();
nscoord GetContinuationOffset(nscoord* aWidth = 0) const;
mozilla::LogicalMargin mBorderPadding;
};
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -3304,35 +3304,91 @@ public:
void UpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
nsStyleChangeList& aChangeList,
nsChangeHint aHintForThisFrame) {
if (GetStateBits() & NS_FRAME_OWNS_ANON_BOXES) {
DoUpdateStyleOfOwnedAnonBoxes(aStyleSet, aChangeList, aHintForThisFrame);
}
}
+protected:
+ // This does the actual work of UpdateStyleOfOwnedAnonBoxes. It calls
+ // AppendDirectlyOwnedAnonBoxes to find all of the anonymous boxes
+ // owned by this frame, and then updates styles on each of them.
+ void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame);
+
+ // A helper for DoUpdateStyleOfOwnedAnonBoxes for the specific case
+ // of the owned anon box being a child of this frame.
+ void UpdateStyleOfChildAnonBox(nsIFrame* aChildFrame,
+ mozilla::ServoStyleSet& aStyleSet,
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame);
+
+public:
// A helper both for UpdateStyleOfChildAnonBox, and to update frame-backed
// pseudo-elements in ServoRestyleManager.
//
// This gets a style context that will be the new style context for
// `aChildFrame`, and takes care of updating it, calling CalcStyleDifference,
// and adding to the change list as appropriate.
//
// Returns the generated change hint for the frame.
- nsChangeHint UpdateStyleOfOwnedChildFrame(nsIFrame* aChildFrame,
- nsStyleContext* aNewStyleContext,
- nsStyleChangeList& aChangeList);
-
- /**
- * Hook subclasses can override to actually implement updating of style of
- * owned anon boxes.
- */
- virtual void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame);
+ nsChangeHint UpdateStyleOfOwnedChildFrame(
+ nsIFrame* aChildFrame,
+ nsStyleContext* aNewStyleContext,
+ nsStyleChangeList& aChangeList);
+
+ struct OwnedAnonBox
+ {
+ typedef void (*UpdateStyleFn)(nsIFrame* aOwningFrame, nsIFrame* aAnonBox,
+ mozilla::ServoStyleSet&,
+ nsStyleChangeList&, nsChangeHint);
+
+ explicit OwnedAnonBox(nsIFrame* aAnonBoxFrame,
+ UpdateStyleFn aUpdateStyleFn = nullptr)
+ : mAnonBoxFrame(aAnonBoxFrame)
+ , mUpdateStyleFn(aUpdateStyleFn)
+ {}
+
+ nsIFrame* mAnonBoxFrame;
+ UpdateStyleFn mUpdateStyleFn;
+ };
+
+ /**
+ * Appends information about all of the anonymous boxes owned by this frame,
+ * including other anonymous boxes owned by those which this frame owns
+ * directly.
+ */
+ void AppendOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) {
+ if (GetStateBits() & NS_FRAME_OWNS_ANON_BOXES) {
+ if (IsInlineFrame()) {
+ // See comment in nsIFrame::DoUpdateStyleOfOwnedAnonBoxes for why
+ // we skip nsInlineFrames.
+ return;
+ }
+ DoAppendOwnedAnonBoxes(aResult);
+ }
+ }
+
+protected:
+ // This does the actual work of AppendOwnedAnonBoxes.
+ void DoAppendOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult);
+
+public:
+ /**
+ * Hook subclasses can override to return their owned anonymous boxes.
+ *
+ * This function only appends anonymous boxes that are directly owned by
+ * this frame, i.e. direct children or (for certain frames) a wrapper
+ * parent, unlike AppendOwnedAnonBoxes, which will append all anonymous
+ * boxes transitively owned by this frame.
+ */
+ virtual void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult);
/**
* Determines whether a frame is visible for painting;
* taking into account whether it is painting a selection or printing.
*/
bool IsVisibleForPainting(nsDisplayListBuilder* aBuilder);
/**
* Determines whether a frame is visible for painting or collapsed;
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -1009,19 +1009,20 @@ nsInlineFrame::AccessibleType()
if (mContent->IsHTMLElement(nsGkAtoms::img)) // Create accessible for broken <img>
return a11y::eHyperTextType;
return a11y::eNoType;
}
#endif
void
-nsInlineFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsInlineFrame::UpdateStyleOfOwnedAnonBoxesForIBSplit(
+ ServoStyleSet& aStyleSet,
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame)
{
MOZ_ASSERT(GetStateBits() & NS_FRAME_OWNS_ANON_BOXES,
"Why did we get called?");
MOZ_ASSERT(GetStateBits() & NS_FRAME_PART_OF_IBSPLIT,
"Why did we have the NS_FRAME_OWNS_ANON_BOXES bit set?");
// Note: this assert _looks_ expensive, but it's cheap in all the cases when
// it passes!
MOZ_ASSERT(nsLayoutUtils::FirstContinuationOrIBSplitSibling(this) == this,
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -109,22 +109,22 @@ public:
bool IsLast() const {
// If the frame's bidi visual state is set, return is-last state
// else return true if it's the last continuation.
return (GetStateBits() & NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET)
? !!(GetStateBits() & NS_INLINE_FRAME_BIDI_VISUAL_IS_LAST)
: (!GetNextInFlow());
}
- // Update the style on the block wrappers around our non-inline-outside kids.
+ // Restyles the block wrappers around our non-inline-outside kids.
// This will only be called when such wrappers in fact exist.
- virtual void DoUpdateStyleOfOwnedAnonBoxes(
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ void UpdateStyleOfOwnedAnonBoxesForIBSplit(
+ mozilla::ServoStyleSet& aStyleSet,
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame);
protected:
// Additional reflow state used during our reflow methods
struct InlineReflowInput {
nsIFrame* mPrevFrame;
nsInlineFrame* mNextInFlow;
nsIFrame* mLineContainer;
nsLineLayout* mLineLayout;
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -5577,16 +5577,13 @@ SVGTextFrame::TransformFrameRectFromText
float factor = presContext->AppUnitsPerCSSPixel();
gfxPoint framePosition(NSAppUnitsToFloatPixels(mRect.x, factor),
NSAppUnitsToFloatPixels(mRect.y, factor));
return result - framePosition;
}
void
-SVGTextFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+SVGTextFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
MOZ_ASSERT(PrincipalChildList().FirstChild(), "Must have our anon box");
- UpdateStyleOfChildAnonBox(PrincipalChildList().FirstChild(),
- aStyleSet, aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(PrincipalChildList().FirstChild()));
}
--- a/layout/svg/SVGTextFrame.h
+++ b/layout/svg/SVGTextFrame.h
@@ -348,22 +348,18 @@ public:
* Takes an app unit rectangle in the coordinate space of a given descendant
* frame of this frame, and returns a rectangle in the <text> element's user
* space that covers all parts of rendered runs that intersect with the
* rectangle.
*/
gfxRect TransformFrameRectFromTextChild(const nsRect& aRect,
nsIFrame* aChildFrame);
- /**
- * Update the style of our ::-moz-svg-text anonymous box.
- */
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return our ::-moz-svg-text anonymous box.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
private:
/**
* Mutation observer used to watch for text positioning attribute changes
* on descendent text content elements (like <tspan>s).
*/
class MutationObserver final : public nsStubMutationObserver {
public:
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -567,17 +567,13 @@ nsSVGForeignObjectFrame::GetInvalidRegio
nsRect rect = nsSVGUtils::ToCanvasBounds(r, GetCanvasTM(), PresContext());
rect = nsSVGUtils::GetPostFilterVisualOverflowRect(this, rect);
return rect;
}
return nsRect();
}
void
-nsSVGForeignObjectFrame::DoUpdateStyleOfOwnedAnonBoxes(
- ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsSVGForeignObjectFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
MOZ_ASSERT(PrincipalChildList().FirstChild(), "Must have our anon box");
- UpdateStyleOfChildAnonBox(PrincipalChildList().FirstChild(),
- aStyleSet, aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(PrincipalChildList().FirstChild()));
}
--- a/layout/svg/nsSVGForeignObjectFrame.h
+++ b/layout/svg/nsSVGForeignObjectFrame.h
@@ -77,22 +77,18 @@ public:
virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
uint32_t aFlags) override;
virtual bool IsDisplayContainer() override { return true; }
gfxMatrix GetCanvasTM();
nsRect GetInvalidRegion();
- /**
- * Update the style of our ::-moz-svg-foreign-content anonymous box.
- */
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return our ::-moz-svg-foreign-content anonymous box.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
protected:
// implementation helpers:
void DoReflow();
void RequestReflow(nsIPresShell::IntrinsicDirty aType);
// If width or height is less than or equal to zero we must disable rendering
bool IsDisabled() const { return mRect.width <= 0 || mRect.height <= 0; }
--- a/layout/svg/nsSVGMarkerFrame.cpp
+++ b/layout/svg/nsSVGMarkerFrame.cpp
@@ -196,23 +196,19 @@ nsSVGMarkerFrame::GetMarkBBoxContributio
void
nsSVGMarkerFrame::SetParentCoordCtxProvider(SVGSVGElement *aContext)
{
SVGMarkerElement *marker = static_cast<SVGMarkerElement*>(mContent);
marker->SetParentCoordCtxProvider(aContext);
}
void
-nsSVGMarkerFrame::DoUpdateStyleOfOwnedAnonBoxes(
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsSVGMarkerFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
- UpdateStyleOfChildAnonBox(GetAnonymousChildFrame(this), aStyleSet,
- aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(GetAnonymousChildFrame(this)));
}
//----------------------------------------------------------------------
// helper class
nsSVGMarkerFrame::AutoMarkerReferencer::AutoMarkerReferencer(
nsSVGMarkerFrame *aFrame,
SVGGeometryFrame *aMarkedFrame
--- a/layout/svg/nsSVGMarkerFrame.h
+++ b/layout/svg/nsSVGMarkerFrame.h
@@ -85,20 +85,18 @@ public:
imgDrawingParams& aImgParams);
SVGBBox GetMarkBBoxContribution(const Matrix& aToBBoxUserspace,
uint32_t aFlags,
mozilla::SVGGeometryFrame* aMarkedFrame,
const nsSVGMark& aMark,
float aStrokeWidth);
- // Update the style on our anonymous box child.
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return our anonymous box child.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
private:
// stuff needed for callback
mozilla::SVGGeometryFrame *mMarkedFrame;
Matrix mMarkerTM;
// nsSVGContainerFrame methods:
virtual gfxMatrix GetCanvasTM() override;
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -966,24 +966,21 @@ bool
nsSVGOuterSVGFrame::VerticalScrollbarNotNeeded() const
{
nsSVGLength2 &height = static_cast<SVGSVGElement*>(mContent)->
mLengthAttributes[SVGSVGElement::ATTR_HEIGHT];
return height.IsPercentage() && height.GetBaseValInSpecifiedUnits() <= 100;
}
void
-nsSVGOuterSVGFrame::DoUpdateStyleOfOwnedAnonBoxes(
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsSVGOuterSVGFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
nsIFrame* anonKid = PrincipalChildList().FirstChild();
MOZ_ASSERT(anonKid->IsSVGOuterSVGAnonChildFrame());
- UpdateStyleOfChildAnonBox(anonKid, aStyleSet, aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(anonKid));
}
//----------------------------------------------------------------------
// Implementation of nsSVGOuterSVGAnonChildFrame
nsContainerFrame*
NS_NewSVGOuterSVGAnonChildFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext)
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -94,20 +94,18 @@ public:
PrincipalChildList().FirstChild()->IsSVGOuterSVGAnonChildFrame(),
"Where is our anonymous child?");
return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
}
bool IsSVGTransformed(Matrix* aOwnTransform,
Matrix* aFromParentTransform) const override;
- // Update the style on our anonymous box child.
- void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return our anonymous box child.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
// nsISVGSVGFrame interface:
virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) override;
// nsSVGDisplayableFrame methods:
virtual void PaintSVG(gfxContext& aContext,
const gfxMatrix& aTransform,
imgDrawingParams& aImgParams,
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -1060,24 +1060,22 @@ NS_IMPL_FRAMEARENA_HELPERS(nsBCTableCell
LogicalMargin
nsTableCellFrame::GetBorderWidth(WritingMode aWM) const
{
return LogicalMargin(aWM, StyleBorder()->GetComputedBorder());
}
void
-nsTableCellFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsTableCellFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
nsIFrame* kid = mFrames.FirstChild();
MOZ_ASSERT(kid && !kid->GetNextSibling(),
"Table cells should have just one child");
- UpdateStyleOfChildAnonBox(kid, aStyleSet, aChangeList, aHintForThisFrame);
+ aResult.AppendElement(OwnedAnonBox(kid));
}
#ifdef DEBUG_FRAME_DUMP
nsresult
nsTableCellFrame::GetFrameName(nsAString& aResult) const
{
return MakeFrameName(NS_LITERAL_STRING("TableCell"), aResult);
}
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -153,21 +153,18 @@ public:
* content model or in the style info, and is always >= 1.
* to get the effective row span (the actual value that applies), use GetEffectiveRowSpan()
* @see nsTableFrame::GetEffectiveRowSpan()
*/
virtual int32_t GetRowSpan();
// there is no set row index because row index depends on the cell's parent row only
- // Update the style on the block wrappers around our kids.
- virtual void DoUpdateStyleOfOwnedAnonBoxes(
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return our cell content frame.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
/*---------------- nsITableCellLayout methods ------------------------*/
/**
* return the cell's starting row index (starting at 0 for the first row).
* for continued cell frames the row index is that of the cell's first-in-flow
* and the column index (starting at 0 for the first column
*/
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -7996,43 +7996,56 @@ nsTableFrame::InvalidateTableFrame(nsIFr
aFrame->InvalidateFrameWithRect(aOrigVisualOverflow);
aFrame->InvalidateFrame();
parent->InvalidateFrameWithRect(aOrigRect);
parent->InvalidateFrame();
}
}
void
-nsTableFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame)
+nsTableFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult)
{
nsIFrame* wrapper = GetParent();
-
MOZ_ASSERT(wrapper->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::tableWrapper,
"What happened to our parent?");
+ aResult.AppendElement(
+ OwnedAnonBox(wrapper, &UpdateStyleOfOwnedAnonBoxesForTableWrapper));
+}
+
+/* static */ void
+nsTableFrame::UpdateStyleOfOwnedAnonBoxesForTableWrapper(
+ nsIFrame* aOwningFrame,
+ nsIFrame* aWrapperFrame,
+ ServoStyleSet& aStyleSet,
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame)
+{
+ MOZ_ASSERT(aWrapperFrame->StyleContext()->GetPseudo() ==
+ nsCSSAnonBoxes::tableWrapper,
+ "What happened to our parent?");
RefPtr<nsStyleContext> newContext =
aStyleSet.ResolveInheritingAnonymousBoxStyle(nsCSSAnonBoxes::tableWrapper,
- StyleContext());
+ aOwningFrame->StyleContext());
// Figure out whether we have an actual change. It's important that we do
// this, even though all the wrapper's changes are due to properties it
// inherits from us, because it's possible that no one ever asked us for those
// style structs and hence changes to them aren't reflected in
// aHintForThisFrame at all.
uint32_t equalStructs, samePointerStructs; // Not used, actually.
- nsChangeHint wrapperHint = wrapper->StyleContext()->CalcStyleDifference(
+ nsChangeHint wrapperHint = aWrapperFrame->StyleContext()->CalcStyleDifference(
newContext,
&equalStructs,
&samePointerStructs);
if (wrapperHint) {
- aChangeList.AppendChange(wrapper, wrapper->GetContent(), wrapperHint);
- }
-
- for (nsIFrame* cur = wrapper; cur; cur = cur->GetNextContinuation()) {
+ aChangeList.AppendChange(aWrapperFrame, aWrapperFrame->GetContent(),
+ wrapperHint);
+ }
+
+ for (nsIFrame* cur = aWrapperFrame; cur; cur = cur->GetNextContinuation()) {
cur->SetStyleContext(newContext);
}
- MOZ_ASSERT(!(wrapper->GetStateBits() & NS_FRAME_OWNS_ANON_BOXES),
+ MOZ_ASSERT(!(aWrapperFrame->GetStateBits() & NS_FRAME_OWNS_ANON_BOXES),
"Wrapper frame doesn't have any anon boxes of its own!");
}
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -588,22 +588,26 @@ public:
*/
static void InvalidateTableFrame(nsIFrame* aFrame,
const nsRect& aOrigRect,
const nsRect& aOrigVisualOverflow,
bool aIsFirstReflow);
virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
- // Update the style of our table wrapper frame.
- virtual void DoUpdateStyleOfOwnedAnonBoxes(
- mozilla::ServoStyleSet& aStyleSet,
- nsStyleChangeList& aChangeList,
- nsChangeHint aHintForThisFrame) override;
+ // Return our wrapper frame.
+ void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
+
protected:
+ static void UpdateStyleOfOwnedAnonBoxesForTableWrapper(
+ nsIFrame* aOwningFrame,
+ nsIFrame* aWrapperFrame,
+ mozilla::ServoStyleSet& aStyleSet,
+ nsStyleChangeList& aChangeList,
+ nsChangeHint aHintForThisFrame);
/** protected constructor.
* @see NewFrame
*/
explicit nsTableFrame(nsStyleContext* aContext, ClassID aID = kClassID);
/** destructor, responsible for mColumnLayoutData */
virtual ~nsTableFrame();