--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1163,66 +1163,16 @@ GetPrevContinuationWithSameStyle(nsIFram
NS_ASSERTION(prevStyle->GetPseudo() != selfStyle->GetPseudo() ||
prevStyle->GetParent() != selfStyle->GetParent(),
"continuations should have the same style context");
prevContinuation = nullptr;
}
return prevContinuation;
}
-/**
- * Get the next continuation or similar ib-split sibling (assuming
- * block/inline alternation), conditionally on it having the same style.
- *
- * Since this is used when deciding to copy the new style context, it
- * takes as an argument the old style context to check if the style is
- * the same. When it is used in other contexts (i.e., where the next
- * continuation would already have the new style context), the current
- * style context should be passed.
- */
-static nsIFrame*
-GetNextContinuationWithSameStyle(nsIFrame* aFrame,
- nsStyleContext* aOldStyleContext,
- bool* aHaveMoreContinuations = nullptr)
-{
- // See GetPrevContinuationWithSameStyle about {ib} splits.
-
- nsIFrame *nextContinuation = aFrame->GetNextContinuation();
- if (!nextContinuation &&
- (aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
- // We're the last continuation, so we have to hop back to the first
- // before getting the frame property
- nextContinuation = aFrame->FirstContinuation()->
- Properties().Get(nsIFrame::IBSplitSibling());
- if (nextContinuation) {
- nextContinuation =
- nextContinuation->Properties().Get(nsIFrame::IBSplitSibling());
- }
- }
-
- if (!nextContinuation) {
- return nullptr;
- }
-
- NS_ASSERTION(nextContinuation->GetContent() == aFrame->GetContent(),
- "unexpected content mismatch");
-
- nsStyleContext* nextStyle = nextContinuation->StyleContext();
- if (nextStyle != aOldStyleContext) {
- NS_ASSERTION(aOldStyleContext->GetPseudo() != nextStyle->GetPseudo() ||
- aOldStyleContext->GetParent() != nextStyle->GetParent(),
- "continuations should have the same style context");
- nextContinuation = nullptr;
- if (aHaveMoreContinuations) {
- *aHaveMoreContinuations = true;
- }
- }
- return nextContinuation;
-}
-
nsresult
RestyleManager::ReparentStyleContext(nsIFrame* aFrame)
{
nsIAtom* frameType = aFrame->GetType();
if (frameType == nsGkAtoms::placeholderFrame) {
// Also reparent the out-of-flow and all its continuations.
nsIFrame* outOfFlow =
nsPlaceholderFrame::GetRealFrameForPlaceholder(aFrame);
@@ -1778,17 +1728,17 @@ ElementRestyler::ConditionallyRestyleCon
MOZ_ASSERT(aFrame->GetContent()->IsElement());
MOZ_ASSERT(!aFrame->GetContent()->IsStyledByServo());
if (aFrame->GetContent()->HasFlag(mRestyleTracker.RootBit())) {
aRestyleRoot = aFrame->GetContent()->AsElement();
}
for (nsIFrame* f = aFrame; f;
- f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+ f = RestyleManager::GetNextContinuationWithSameStyle(f, f->StyleContext())) {
nsIFrame::ChildListIterator lists(f);
for (; !lists.IsDone(); lists.Next()) {
for (nsIFrame* child : lists.CurrentList()) {
// Out-of-flows are reached through their placeholders. Continuations
// and block-in-inline splits are reached through those chains.
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
!GetPrevContinuationWithSameStyle(child)) {
// only do frames that are in flow
@@ -2059,17 +2009,17 @@ ElementRestyler::MoveStyleContextsForChi
nsTArray<nsStyleContext*> contextsToMove;
MOZ_ASSERT(!MustReframeForBeforePseudo(),
"shouldn't need to reframe ::before as we would have had "
"eRestyle_Subtree and wouldn't get in here");
DebugOnly<nsIFrame*> lastContinuation;
for (nsIFrame* f = mFrame; f;
- f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+ f = RestyleManager::GetNextContinuationWithSameStyle(f, f->StyleContext())) {
lastContinuation = f;
if (!MoveStyleContextsForContentChildren(f, aOldContext, contextsToMove)) {
return false;
}
}
MOZ_ASSERT(!MustReframeForAfterPseudo(lastContinuation),
"shouldn't need to reframe ::after as we would have had "
@@ -2214,17 +2164,19 @@ ElementRestyler::Restyle(nsRestyleHint a
if (thisResult > result) {
// We take the highest RestyleResult value when working out what to do
// with this frame and its descendants. Higher RestyleResult values
// represent a superset of the work done by lower values.
result = thisResult;
}
- f = GetNextContinuationWithSameStyle(f, oldContext, &haveMoreContinuations);
+ f = RestyleManager::GetNextContinuationWithSameStyle(f,
+ oldContext,
+ &haveMoreContinuations);
}
// Some changes to animations don't affect the computed style and yet still
// require the layer to be updated. For example, pausing an animation via
// the Web Animations API won't affect an element's style but still
// requires us to pull the animation off the layer.
//
// Although we only expect this code path to be called when computed style
@@ -3295,17 +3247,17 @@ ElementRestyler::RestyleChildren(nsResty
// kids would use mFrame->StyleContext(), which is out of date if
// mHintsHandled has a ReconstructFrame hint; doing this could trigger
// assertions about mismatched rule trees.
nsIFrame* lastContinuation;
if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
InitializeAccessibilityNotifications(mFrame->StyleContext());
for (nsIFrame* f = mFrame; f;
- f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+ f = RestyleManager::GetNextContinuationWithSameStyle(f, f->StyleContext())) {
lastContinuation = f;
RestyleContentChildren(f, aChildRestyleHint);
}
SendAccessibilityNotifications();
}
// Check whether we might need to create a new ::after frame.
--- a/layout/base/RestyleManagerBase.cpp
+++ b/layout/base/RestyleManagerBase.cpp
@@ -52,43 +52,44 @@ RestyleManagerBase::ContentStateChangedI
aStateMask.HasAtLeastOneOfStates(NS_EVENT_STATE_BROKEN |
NS_EVENT_STATE_USERDISABLED |
NS_EVENT_STATE_SUPPRESSED |
NS_EVENT_STATE_LOADING)) {
*aOutChangeHint = nsChangeHint_ReconstructFrame;
} else {
uint8_t app = primaryFrame->StyleDisplay()->mAppearance;
if (app) {
- nsITheme *theme = PresContext()->GetTheme();
- if (theme && theme->ThemeSupportsWidget(PresContext(),
- primaryFrame, app)) {
+ nsITheme* theme = PresContext()->GetTheme();
+ if (theme &&
+ theme->ThemeSupportsWidget(PresContext(), primaryFrame, app)) {
bool repaint = false;
- theme->WidgetStateChanged(primaryFrame, app, nullptr, &repaint, nullptr);
+ theme->WidgetStateChanged(primaryFrame, app, nullptr, &repaint,
+ nullptr);
if (repaint) {
*aOutChangeHint |= nsChangeHint_RepaintFrame;
}
}
}
}
pseudoType = primaryFrame->StyleContext()->GetPseudoType();
primaryFrame->ContentStatesChanged(aStateMask);
}
if (pseudoType >= CSSPseudoElementType::Count) {
*aOutRestyleHint = styleSet->HasStateDependentStyle(aElement, aStateMask);
} else if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(
- pseudoType)) {
+ pseudoType)) {
// If aElement is a pseudo-element, we want to check to see whether there
// are any state-dependent rules applying to that pseudo.
- Element* ancestor = ElementForStyleContext(nullptr, primaryFrame,
- pseudoType);
- *aOutRestyleHint = styleSet->HasStateDependentStyle(ancestor, pseudoType, aElement,
- aStateMask);
+ Element* ancestor =
+ ElementForStyleContext(nullptr, primaryFrame, pseudoType);
+ *aOutRestyleHint = styleSet->HasStateDependentStyle(ancestor, pseudoType,
+ aElement, aStateMask);
} else {
*aOutRestyleHint = nsRestyleHint(0);
}
if (aStateMask.HasState(NS_EVENT_STATE_HOVER) && *aOutRestyleHint != 0) {
IncrementHoverGeneration();
}
@@ -142,27 +143,27 @@ static bool gInApplyRenderingChangeToTre
#endif
#ifdef DEBUG
static void
DumpContext(nsIFrame* aFrame, nsStyleContext* aContext)
{
if (aFrame) {
fputs("frame: ", stdout);
- nsAutoString name;
+ nsAutoString name;
aFrame->GetFrameName(name);
fputs(NS_LossyConvertUTF16toASCII(name).get(), stdout);
fprintf(stdout, " (%p)", static_cast<void*>(aFrame));
}
if (aContext) {
fprintf(stdout, " style: %p ", static_cast<void*>(aContext));
nsIAtom* pseudoTag = aContext->GetPseudo();
if (pseudoTag) {
- nsAutoString buffer;
+ nsAutoString buffer;
pseudoTag->ToString(buffer);
fputs(NS_LossyConvertUTF16toASCII(buffer).get(), stdout);
fputs(" ", stdout);
}
fputs("{}\n", stdout);
}
}
@@ -206,30 +207,28 @@ VerifyContextParent(nsIFrame* aFrame, ns
NS_ASSERTION(aContext, "Failure to get required contexts");
nsStyleContext* actualParentContext = aContext->GetParent();
if (aParentContext) {
if (aParentContext != actualParentContext) {
DumpContext(aFrame, aContext);
if (aContext == aParentContext) {
NS_ERROR("Using parent's style context");
- }
- else {
+ } else {
NS_ERROR("Wrong parent style context");
fputs("Wrong parent style context: ", stdout);
DumpContext(nullptr, actualParentContext);
fputs("should be using: ", stdout);
DumpContext(nullptr, aParentContext);
VerifySameTree(actualParentContext, aParentContext);
fputs("\n", stdout);
}
}
- }
- else {
+ } else {
if (actualParentContext) {
NS_ERROR("Have parent context and shouldn't");
DumpContext(aFrame, aContext);
fputs("Has parent context: ", stdout);
DumpContext(nullptr, actualParentContext);
fputs("Should be null\n\n", stdout);
}
}
@@ -247,17 +246,17 @@ VerifyContextParent(nsIFrame* aFrame, ns
DumpContext(aFrame, aContext);
fputs("\n", stdout);
}
}
static void
VerifyStyleTree(nsIFrame* aFrame)
{
- nsStyleContext* context = aFrame->StyleContext();
+ nsStyleContext* context = aFrame->StyleContext();
VerifyContextParent(aFrame, context, nullptr);
nsIFrame::ChildListIterator lists(aFrame);
for (; !lists.IsDone(); lists.Next()) {
for (nsIFrame* child : lists.CurrentList()) {
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that are in flow
if (nsGkAtoms::placeholderFrame == child->GetType()) {
@@ -295,33 +294,31 @@ RestyleManagerBase::DebugVerifyStyleTree
{
if (aFrame) {
VerifyStyleTree(aFrame);
}
}
#endif // DEBUG
-
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ChangeListProperty, bool)
/**
* Sync views on aFrame and all of aFrame's descendants (following placeholders),
* if aChange has nsChangeHint_SyncFrameView.
* Calls DoApplyRenderingChangeToTree on all aFrame's out-of-flow descendants
* (following placeholders), if aChange has nsChangeHint_RepaintFrame.
* aFrame should be some combination of nsChangeHint_SyncFrameView,
* nsChangeHint_RepaintFrame, nsChangeHint_UpdateOpacityLayer and
* nsChangeHint_SchedulePaint, nothing else.
*/
-static void
-SyncViewsAndInvalidateDescendants(nsIFrame* aFrame, nsChangeHint aChange);
+static void SyncViewsAndInvalidateDescendants(nsIFrame* aFrame,
+ nsChangeHint aChange);
-static void
-StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint);
+static void StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint);
/**
* To handle nsChangeHint_ChildrenOnlyTransform we must iterate over the child
* frames of the SVG frame concerned. This helper function is used to find that
* SVG frame when we encounter nsChangeHint_ChildrenOnlyTransform to ensure
* that we iterate over the intended children, since sometimes we end up
* handling that hint while processing hints for one of the SVG frame's
* ancestor frames.
@@ -348,23 +345,21 @@ GetFrameForChildrenOnlyTransformHint(nsI
// For an nsHTMLScrollFrame, this will get the SVG frame that has the
// children-only transforms:
aFrame = aFrame->GetContent()->GetPrimaryFrame();
if (aFrame->GetType() == nsGkAtoms::svgOuterSVGFrame) {
aFrame = aFrame->PrincipalChildList().FirstChild();
MOZ_ASSERT(aFrame->GetType() == nsGkAtoms::svgOuterSVGAnonChildFrame,
"Where is the nsSVGOuterSVGFrame's anon child??");
}
- MOZ_ASSERT(aFrame->IsFrameOfType(nsIFrame::eSVG |
- nsIFrame::eSVGContainer),
+ MOZ_ASSERT(aFrame->IsFrameOfType(nsIFrame::eSVG | nsIFrame::eSVGContainer),
"Children-only transforms only expected on SVG frames");
return aFrame;
}
-
// Returns true if this function managed to successfully move a frame, and
// false if it could not process the position change, and a reflow should
// be performed instead.
bool
RecomputePosition(nsIFrame* aFrame)
{
// Don't process position changes on table frames, since we already handle
// the dynamic position change on the table wrapper frame, and the
@@ -410,17 +405,18 @@ RecomputePosition(nsIFrame* aFrame)
// continuation or ib-split sibling, but it can happen when styles differ
// across continuations such as ::first-line or ::first-letter, and in
// those cases we will generally (but maybe not always) do the work twice.
nsIFrame* firstContinuation =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
StickyScrollContainer::ComputeStickyOffsets(firstContinuation);
StickyScrollContainer* ssc =
- StickyScrollContainer::GetStickyScrollContainerForFrame(firstContinuation);
+ StickyScrollContainer::GetStickyScrollContainerForFrame(
+ firstContinuation);
if (ssc) {
ssc->PositionContinuations(firstContinuation);
}
} else {
MOZ_ASSERT(NS_STYLE_POSITION_RELATIVE == display->mPosition,
"Unexpected type of positioning");
for (nsIFrame* cont = aFrame; cont;
cont = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(cont)) {
@@ -455,18 +451,18 @@ RecomputePosition(nsIFrame* aFrame)
// Construct a bogus parent reflow state so that there's a usable
// containing block reflow state.
nsIFrame* parentFrame = aFrame->GetParent();
WritingMode parentWM = parentFrame->GetWritingMode();
WritingMode frameWM = aFrame->GetWritingMode();
LogicalSize parentSize = parentFrame->GetLogicalSize();
nsFrameState savedState = parentFrame->GetStateBits();
- ReflowInput parentReflowInput(aFrame->PresContext(), parentFrame,
- &rc, parentSize);
+ ReflowInput parentReflowInput(aFrame->PresContext(), parentFrame, &rc,
+ parentSize);
parentFrame->RemoveStateBits(~nsFrameState(0));
parentFrame->AddStateBits(savedState);
// The bogus parent state here was created with no parent state of its own,
// and therefore it won't have an mCBReflowInput set up.
// But we may need one (for InitCBReflowInput in a child state), so let's
// try to create one here for the cases where it will be needed.
Maybe<ReflowInput> cbReflowInput;
@@ -498,22 +494,24 @@ RecomputePosition(nsIFrame* aFrame)
ViewportFrame* viewport = do_QueryFrame(parentFrame);
nsSize cbSize = viewport ?
viewport->AdjustReflowInputAsContainingBlock(&parentReflowInput).Size()
: aFrame->GetContainingBlock()->GetSize();
const nsMargin& parentBorder =
parentReflowInput.mStyleBorder->GetComputedBorder();
cbSize -= nsSize(parentBorder.LeftRight(), parentBorder.TopBottom());
LogicalSize lcbSize(frameWM, cbSize);
- ReflowInput reflowInput(aFrame->PresContext(), parentReflowInput,
- aFrame, availSize, &lcbSize);
- nsSize computedSize(reflowInput.ComputedWidth(), reflowInput.ComputedHeight());
+ ReflowInput reflowInput(aFrame->PresContext(), parentReflowInput, aFrame,
+ availSize, &lcbSize);
+ nsSize computedSize(reflowInput.ComputedWidth(),
+ reflowInput.ComputedHeight());
computedSize.width += reflowInput.ComputedPhysicalBorderPadding().LeftRight();
if (computedSize.height != NS_INTRINSICSIZE) {
- computedSize.height += reflowInput.ComputedPhysicalBorderPadding().TopBottom();
+ computedSize.height +=
+ reflowInput.ComputedPhysicalBorderPadding().TopBottom();
}
nsSize size = aFrame->GetSize();
// The RecomputePosition hint is not used if any offset changed between auto
// and non-auto. If computedSize.height == NS_INTRINSICSIZE then the new
// element height will be its intrinsic height, and since 'top' and 'bottom''s
// auto-ness hasn't changed, the old height must also be its intrinsic
// height, which we can assume hasn't changed (or reflow would have
// been triggered).
@@ -563,25 +561,27 @@ HasBoxAncestor(nsIFrame* aFrame)
return false;
}
/**
* Return true if aFrame's subtree has placeholders for out-of-flow content
* whose 'position' style's bit in aPositionMask is set.
*/
static bool
-FrameHasPositionedPlaceholderDescendants(nsIFrame* aFrame, uint32_t aPositionMask)
+FrameHasPositionedPlaceholderDescendants(nsIFrame* aFrame,
+ uint32_t aPositionMask)
{
const nsIFrame::ChildListIDs skip(nsIFrame::kAbsoluteList |
nsIFrame::kFixedList);
for (nsIFrame::ChildListIterator lists(aFrame); !lists.IsDone(); lists.Next()) {
if (!skip.Contains(lists.CurrentID())) {
for (nsIFrame* f : lists.CurrentList()) {
if (f->GetType() == nsGkAtoms::placeholderFrame) {
- nsIFrame* outOfFlow = nsPlaceholderFrame::GetRealFrameForPlaceholder(f);
+ nsIFrame* outOfFlow =
+ nsPlaceholderFrame::GetRealFrameForPlaceholder(f);
// If SVG text frames could appear here, they could confuse us since
// they ignore their position style ... but they can't.
NS_ASSERTION(!outOfFlow->IsSVGText(),
"SVG text frames can't be out of flow");
if (aPositionMask & (1 << outOfFlow->StyleDisplay()->mPosition)) {
return true;
}
}
@@ -600,28 +600,27 @@ NeedToReframeForAddingOrRemovingTransfor
static_assert(0 <= NS_STYLE_POSITION_ABSOLUTE &&
NS_STYLE_POSITION_ABSOLUTE < 32, "Style constant out of range");
static_assert(0 <= NS_STYLE_POSITION_FIXED &&
NS_STYLE_POSITION_FIXED < 32, "Style constant out of range");
uint32_t positionMask;
// Don't call aFrame->IsPositioned here, since that returns true if
// the frame already has a transform, and we want to ignore that here
- if (aFrame->IsAbsolutelyPositioned() ||
- aFrame->IsRelativelyPositioned()) {
+ if (aFrame->IsAbsolutelyPositioned() || aFrame->IsRelativelyPositioned()) {
// This frame is a container for abs-pos descendants whether or not it
// has a transform.
// So abs-pos descendants are no problem; we only need to reframe if
// we have fixed-pos descendants.
positionMask = 1 << NS_STYLE_POSITION_FIXED;
} else {
// This frame may not be a container for abs-pos descendants already.
// So reframe if we have abs-pos or fixed-pos descendants.
- positionMask = (1 << NS_STYLE_POSITION_FIXED) |
- (1 << NS_STYLE_POSITION_ABSOLUTE);
+ positionMask =
+ (1 << NS_STYLE_POSITION_FIXED) | (1 << NS_STYLE_POSITION_ABSOLUTE);
}
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(f)) {
if (FrameHasPositionedPlaceholderDescendants(f, positionMask)) {
return true;
}
}
return false;
@@ -635,17 +634,18 @@ RestyleManagerBase::GetNearestAncestorFr
ancestor && !ancestorFrame;
ancestor = ancestor->GetParent()) {
ancestorFrame = ancestor->GetPrimaryFrame();
}
return ancestorFrame;
}
/* static */ nsIFrame*
-RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable, nsIFrame* aFrame)
+RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable,
+ nsIFrame* aFrame)
{
NS_ASSERTION(!aFrame->GetPrevContinuation(),
"must start with the first continuation");
// Might we have ib-split siblings?
if (!(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
// nothing more to do here
return nullptr;
}
@@ -693,19 +693,18 @@ DoApplyRenderingChangeToTree(nsIFrame* a
nsSVGUtils::ScheduleReflowSVG(aFrame);
}
}
if (aChange & nsChangeHint_UpdateTextPath) {
if (aFrame->IsSVGText()) {
// Invalidate and reflow the entire SVGTextFrame:
NS_ASSERTION(aFrame->GetContent()->IsSVGElement(nsGkAtoms::textPath),
"expected frame for a <textPath> element");
- nsIFrame* text = nsLayoutUtils::GetClosestFrameOfType(
- aFrame,
- nsGkAtoms::svgTextFrame);
+ nsIFrame* text =
+ nsLayoutUtils::GetClosestFrameOfType(aFrame, nsGkAtoms::svgTextFrame);
NS_ASSERTION(text, "expected to find an ancestor SVGTextFrame");
static_cast<SVGTextFrame*>(text)->NotifyGlyphMetricsChange();
} else {
MOZ_ASSERT(false, "unexpected frame got nsChangeHint_UpdateTextPath");
}
}
if (aChange & nsChangeHint_UpdateOpacityLayer) {
// FIXME/bug 796697: we can get away with empty transactions for
@@ -729,70 +728,71 @@ DoApplyRenderingChangeToTree(nsIFrame* a
if (!needInvalidatingPaint) {
Layer* layer;
needInvalidatingPaint |= !aFrame->TryUpdateTransformOnly(&layer);
if (!needInvalidatingPaint) {
// Since we're not going to paint, we need to resend animation
// data to the layer.
MOZ_ASSERT(layer, "this can't happen if there's no layer");
- nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(layer,
- nullptr, nullptr, aFrame, eCSSProperty_transform);
+ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(
+ layer, nullptr, nullptr, aFrame, eCSSProperty_transform);
}
}
}
if (aChange & nsChangeHint_ChildrenOnlyTransform) {
needInvalidatingPaint = true;
nsIFrame* childFrame =
GetFrameForChildrenOnlyTransformHint(aFrame)->PrincipalChildList().FirstChild();
for ( ; childFrame; childFrame = childFrame->GetNextSibling()) {
ActiveLayerTracker::NotifyRestyle(childFrame, eCSSProperty_transform);
}
}
if (aChange & nsChangeHint_SchedulePaint) {
needInvalidatingPaint = true;
}
- aFrame->SchedulePaint(needInvalidatingPaint ?
- nsIFrame::PAINT_DEFAULT :
- nsIFrame::PAINT_COMPOSITE_ONLY);
+ aFrame->SchedulePaint(needInvalidatingPaint
+ ? nsIFrame::PAINT_DEFAULT
+ : nsIFrame::PAINT_COMPOSITE_ONLY);
}
}
/* static */ void
-SyncViewsAndInvalidateDescendants(nsIFrame* aFrame,
- nsChangeHint aChange)
+SyncViewsAndInvalidateDescendants(nsIFrame* aFrame, nsChangeHint aChange)
{
+ NS_PRECONDITION(gInApplyRenderingChangeToTree,
+ "should only be called within ApplyRenderingChangeToTree");
NS_ASSERTION(nsChangeHint_size_t(aChange) ==
(aChange & (nsChangeHint_RepaintFrame |
nsChangeHint_SyncFrameView |
nsChangeHint_UpdateOpacityLayer |
nsChangeHint_SchedulePaint)),
"Invalid change flag");
nsView* view = aFrame->GetView();
if (view) {
if (aChange & nsChangeHint_SyncFrameView) {
- nsContainerFrame::SyncFrameViewProperties(aFrame->PresContext(),
- aFrame, nullptr, view);
+ nsContainerFrame::SyncFrameViewProperties(aFrame->PresContext(), aFrame,
+ nullptr, view);
}
}
nsIFrame::ChildListIterator lists(aFrame);
for (; !lists.IsDone(); lists.Next()) {
for (nsIFrame* child : lists.CurrentList()) {
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that don't have placeholders
if (nsGkAtoms::placeholderFrame == child->GetType()) {
// do the out-of-flow frame and its continuations
nsIFrame* outOfFlowFrame =
nsPlaceholderFrame::GetRealFrameForPlaceholder(child);
DoApplyRenderingChangeToTree(outOfFlowFrame, aChange);
} else if (lists.CurrentID() == nsIFrame::kPopupList) {
DoApplyRenderingChangeToTree(child, aChange);
- } else { // regular frame
+ } else { // regular frame
SyncViewsAndInvalidateDescendants(child, aChange);
}
}
}
}
}
void
@@ -811,18 +811,18 @@ ApplyRenderingChangeToTree(nsIPresShell*
if (aPresShell->IsPaintingSuppressed()) {
// Don't allow synchronous rendering changes when painting is turned off.
aChange &= ~nsChangeHint_RepaintFrame;
if (!aChange) {
return;
}
}
- // Trigger rendering updates by damaging this frame and any
- // continuations of this frame.
+// Trigger rendering updates by damaging this frame and any
+// continuations of this frame.
#ifdef DEBUG
gInApplyRenderingChangeToTree = true;
#endif
if (aChange & nsChangeHint_RepaintFrame) {
// If the frame's background is propagated to an ancestor, walk up to
// that ancestor and apply the RepaintFrame change hint to it.
nsStyleContext* bgSC;
nsIFrame* propagatedFrame = aFrame;
@@ -867,17 +867,18 @@ StyleChangeReflow(nsIFrame* aFrame, nsCh
nsIPresShell::IntrinsicDirty dirtyType;
if (aHint & nsChangeHint_ClearDescendantIntrinsics) {
NS_ASSERTION(aHint & nsChangeHint_ClearAncestorIntrinsics,
"Please read the comments in nsChangeHint.h");
NS_ASSERTION(aHint & nsChangeHint_NeedDirtyReflow,
"ClearDescendantIntrinsics requires NeedDirtyReflow");
dirtyType = nsIPresShell::eStyleChange;
} else if ((aHint & nsChangeHint_UpdateComputedBSize) &&
- aFrame->HasAnyStateBits(NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE)) {
+ aFrame->HasAnyStateBits(
+ NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE)) {
dirtyType = nsIPresShell::eStyleChange;
} else if (aHint & nsChangeHint_ClearAncestorIntrinsics) {
dirtyType = nsIPresShell::eTreeChange;
} else if ((aHint & nsChangeHint_UpdateComputedBSize) &&
HasBoxAncestor(aFrame)) {
// The frame's computed BSize is changing, and we have a box ancestor
// whose cached intrinsic height may need to be updated.
dirtyType = nsIPresShell::eTreeChange;
@@ -903,35 +904,75 @@ StyleChangeReflow(nsIFrame* aFrame, nsCh
nsIPresShell::ReflowRootHandling rootHandling;
if (aHint & nsChangeHint_ReflowChangesSizeOrPosition) {
rootHandling = nsIPresShell::ePositionOrSizeChange;
} else {
rootHandling = nsIPresShell::eNoPositionOrSizeChange;
}
do {
- aFrame->PresContext()->PresShell()->FrameNeedsReflow(aFrame, dirtyType, dirtyBits,
- rootHandling);
+ aFrame->PresContext()->PresShell()->FrameNeedsReflow(
+ aFrame, dirtyType, dirtyBits, rootHandling);
aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
} while (aFrame);
}
+/* static */ nsIFrame*
+RestyleManagerBase::GetNextContinuationWithSameStyle(
+ nsIFrame* aFrame, nsStyleContext* aOldStyleContext,
+ bool* aHaveMoreContinuations)
+{
+ // See GetPrevContinuationWithSameStyle about {ib} splits.
+
+ nsIFrame* nextContinuation = aFrame->GetNextContinuation();
+ if (!nextContinuation &&
+ (aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
+ // We're the last continuation, so we have to hop back to the first
+ // before getting the frame property
+ nextContinuation =
+ aFrame->FirstContinuation()->Properties().Get(nsIFrame::IBSplitSibling());
+ if (nextContinuation) {
+ nextContinuation =
+ nextContinuation->Properties().Get(nsIFrame::IBSplitSibling());
+ }
+ }
+
+ if (!nextContinuation) {
+ return nullptr;
+ }
+
+ NS_ASSERTION(nextContinuation->GetContent() == aFrame->GetContent(),
+ "unexpected content mismatch");
+
+ nsStyleContext* nextStyle = nextContinuation->StyleContext();
+ if (nextStyle != aOldStyleContext) {
+ NS_ASSERTION(aOldStyleContext->GetPseudo() != nextStyle->GetPseudo() ||
+ aOldStyleContext->GetParent() != nextStyle->GetParent(),
+ "continuations should have the same style context");
+ nextContinuation = nullptr;
+ if (aHaveMoreContinuations) {
+ *aHaveMoreContinuations = true;
+ }
+ }
+ return nextContinuation;
+}
+
/* static */ nsresult
-RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
- nsPresContext& aPresContext,
- OverflowChangedTracker& aOverflowChangedTracker)
+RestyleManagerBase::ProcessRestyledFrames(
+ nsStyleChangeList& aChangeList, nsPresContext& aPresContext,
+ OverflowChangedTracker& aOverflowChangedTracker)
{
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker");
int32_t count = aChangeList.Count();
if (!count)
return NS_OK;
PROFILER_LABEL("RestyleManager", "ProcessRestyledFrames",
- js::ProfileEntry::Category::CSS);
+ js::ProfileEntry::Category::CSS);
FramePropertyTable* propTable = aPresContext.PropertyTable();
nsCSSFrameConstructor* frameConstructor = aPresContext.FrameConstructor();
// Make sure to not rebuild quote or counter lists while we're
// processing restyles
frameConstructor->BeginUpdate();