From 315ccebd6d81df06f6d13934f46e3501193af3b6 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Thu, 12 Mar 2015 16:21:01 +1300 Subject: [PATCH] Bug 1125767. Centralize code into nsStylePosition::IsFixedPosContainingBlock. r=mats Also renames IsPositioned to IsAbsPosContainingBlock. --- dom/html/nsGenericHTMLElement.cpp | 4 +-- layout/base/RestyleManager.cpp | 2 +- layout/base/nsCSSFrameConstructor.cpp | 36 ++++++++++++--------------- layout/base/nsDisplayList.cpp | 2 +- layout/base/nsLayoutUtils.cpp | 2 +- layout/base/nsPresShell.cpp | 2 +- layout/generic/nsContainerFrame.cpp | 10 +++----- layout/generic/nsFrame.cpp | 4 +-- layout/generic/nsGfxScrollFrame.cpp | 2 +- layout/generic/nsIFrame.h | 2 +- layout/generic/nsIFrameInlines.h | 4 +-- layout/style/nsStyleStruct.h | 4 ++- layout/style/nsStyleStructInlines.h | 29 ++++++++++----------- 13 files changed, 49 insertions(+), 54 deletions(-) diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index 49cedffcb4c..3728f1bb2ca 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -351,7 +351,7 @@ nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect) parent = frame; } else { - const bool isPositioned = frame->IsPositioned(); + const bool isPositioned = frame->IsAbsPosContaininingBlock(); const bool isAbsolutelyPositioned = frame->IsAbsolutelyPositioned(); origin += frame->GetPositionIgnoringScrolling(); @@ -359,7 +359,7 @@ nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect) content = parent->GetContent(); // Stop at the first ancestor that is positioned. - if (parent->IsPositioned()) { + if (parent->IsAbsPosContaininingBlock()) { offsetParent = content; break; } diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index d8ad30472c4..d4575486f5e 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -742,7 +742,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) // It's because we need to set this state on each affected frame // that we can't coalesce nsChangeHint_AddOrRemoveTransform hints up // to ancestors (i.e. it can't be an inherited change hint). - if (cont->IsPositioned()) { + if (cont->IsAbsPosContaininingBlock()) { // If a transform has been added, we'll be taking this path, // but we may be taking this path even if a transform has been // removed. It's OK to add the bit even if it's not needed. diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 41707956936..25a25da7b8a 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -748,8 +748,8 @@ public: // using this state. nsFrameState mAdditionalStateBits; - // When working with the -moz-transform property, we want to hook - // the abs-pos and fixed-pos lists together, since transformed + // When working with the transform and filter properties, we want to hook + // the abs-pos and fixed-pos lists together, since such // elements are fixed-pos containing blocks. This flag determines // whether or not we want to wire the fixed-pos and abs-pos lists // together. @@ -938,7 +938,7 @@ nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShe mAdditionalStateBits(nsFrameState(0)), // If the fixed-pos containing block is equal to the abs-pos containing // block, use the abs-pos containing block's abs-pos list for fixed-pos - // frames. + // frames. mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock), mHavePendingPopupgroup(false), mCreatingExtraFrames(false), @@ -972,7 +972,7 @@ nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShell, mAdditionalStateBits(nsFrameState(0)), // If the fixed-pos containing block is equal to the abs-pos containing // block, use the abs-pos containing block's abs-pos list for fixed-pos - // frames. + // frames. mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock), mHavePendingPopupgroup(false), mCreatingExtraFrames(false), @@ -1059,8 +1059,7 @@ nsFrameConstructorState::PushAbsoluteContainingBlock(nsContainerFrame* aNewAbsol * we're a transformed element. */ mFixedPosIsAbsPos = aPositionedFrame && - (aPositionedFrame->StylePosition()->HasTransform(aPositionedFrame) || - aPositionedFrame->StylePosition()->HasPerspectiveStyle()); + aPositionedFrame->StylePosition()->IsFixedPosContainingBlock(aPositionedFrame); if (aNewAbsoluteContainingBlock) { aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock(); @@ -2033,7 +2032,7 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState, // Mark the table frame as an absolute container if needed newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); - if (display->IsPositioned(newFrame)) { + if (display->IsAbsPosContainingBlock(newFrame)) { aState.PushAbsoluteContainingBlock(newFrame, newFrame, absoluteSaveState); } NS_ASSERTION(aItem.mAnonChildren.IsEmpty(), @@ -2076,7 +2075,7 @@ MakeTablePartAbsoluteContainingBlockIfNeeded(nsFrameConstructorState& aState // However, in this case flag serves the additional purpose of indicating that // the frame was registered with its table frame. This allows us to avoid the // overhead of unregistering the frame in most cases. - if (aDisplay->IsPositioned(aFrame)) { + if (aDisplay->IsAbsPosContainingBlock(aFrame)) { aFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); aState.PushAbsoluteContainingBlock(aFrame, aFrame, aAbsSaveState); nsTableFrame::RegisterPositionedTablePart(aFrame); @@ -2608,7 +2607,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle mDocElementContainingBlock), mDocElementContainingBlock, styleContext, &contentFrame, frameItems, - display->IsPositioned(contentFrame) ? contentFrame : nullptr, + display->IsAbsPosContainingBlock(contentFrame) ? contentFrame : nullptr, nullptr); newFrame = frameItems.FirstChild(); NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames"); @@ -3093,7 +3092,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState, // Notify combobox that it should use the listbox as it's popup comboBox->SetDropDown(listFrame); - NS_ASSERTION(!listFrame->IsPositioned(), + NS_ASSERTION(!listFrame->IsAbsPosContaininingBlock(), "Ended up with positioned dropdown list somehow."); NS_ASSERTION(!listFrame->IsFloating(), "Ended up with floating dropdown list somehow."); @@ -3249,7 +3248,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState, nsFrameItems childItems; blockFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); - if (fieldsetFrame->IsPositioned()) { + if (fieldsetFrame->IsAbsPosContaininingBlock()) { aState.PushAbsoluteContainingBlock(blockFrame, fieldsetFrame, absoluteSaveState); } @@ -3811,7 +3810,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt // absolute container. It should be the latter if it's // positioned, otherwise the former. const nsStyleDisplay* blockDisplay = blockContext->StyleDisplay(); - if (blockDisplay->IsPositioned(blockFrame)) { + if (blockDisplay->IsAbsPosContainingBlock(blockFrame)) { maybeAbsoluteContainingBlockDisplay = blockDisplay; maybeAbsoluteContainingBlockPosition = blockContext->StylePosition(); maybeAbsoluteContainingBlock = blockFrame; @@ -3854,9 +3853,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt // make the inner the containing block. if ((maybeAbsoluteContainingBlockDisplay->IsAbsolutelyPositionedStyle() || maybeAbsoluteContainingBlockDisplay->IsRelativelyPositionedStyle() || - (maybeAbsoluteContainingBlockPosition->HasTransformStyle() && - cb->IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) || - maybeAbsoluteContainingBlockPosition->HasPerspectiveStyle()) && + maybeAbsoluteContainingBlockPosition->IsFixedPosContainingBlock(cb)) && !cb->IsSVGText()) { nsContainerFrame* cf = static_cast(cb); aState.PushAbsoluteContainingBlock(cf, cf, absoluteSaveState); @@ -4697,7 +4694,7 @@ nsCSSFrameConstructor::ConstructScrollableBlock(nsFrameConstructorState& aState, ConstructBlock(aState, scrolledContentStyle->StyleDisplay(), content, newFrame, newFrame, scrolledContentStyle, &scrolledFrame, blockItem, - aDisplay->IsPositioned(newFrame) ? newFrame : nullptr, + aDisplay->IsAbsPosContainingBlock(newFrame) ? newFrame : nullptr, aItem.mPendingBinding); NS_ASSERTION(blockItem.FirstChild() == scrolledFrame, @@ -4740,7 +4737,7 @@ nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState& aSta aState.GetGeometricParent(aDisplay, aParentFrame), aParentFrame, styleContext, &newFrame, aFrameItems, - aDisplay->IsPositioned(newFrame) ? newFrame : nullptr, + aDisplay->IsAbsPosContainingBlock(newFrame) ? newFrame : nullptr, aItem.mPendingBinding); return newFrame; } @@ -5981,10 +5978,9 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame, // the correct containing block (the scrolledframe) in that case. // If we're looking for a fixed-pos containing block and the frame is // not transformed, skip it. - if (!frame->IsPositioned() || + if (!frame->IsAbsPosContaininingBlock() || (aType == FIXED_POS && - !frame->StylePosition()->HasTransform(frame) && - !frame->StylePosition()->HasPerspectiveStyle())) { + !frame->StylePosition()->IsFixedPosContainingBlock(frame))) { continue; } nsIFrame* absPosCBCandidate = frame; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 0998e00ac8b..a4ac4703c68 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2084,7 +2084,7 @@ nsDisplayItem::MaxActiveLayers() int32_t nsDisplayItem::ZIndex() const { - if (!mFrame->IsPositioned() && !mFrame->IsFlexOrGridItem()) + if (!mFrame->IsAbsPosContaininingBlock() && !mFrame->IsFlexOrGridItem()) return 0; const nsStylePosition* position = mFrame->StylePosition(); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 7102a37362b..ea5fa57b086 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5597,7 +5597,7 @@ nsLayoutUtils::GetClosestLayer(nsIFrame* aFrame) { nsIFrame* layer; for (layer = aFrame; layer; layer = layer->GetParent()) { - if (layer->IsPositioned() || + if (layer->IsAbsPosContaininingBlock() || (layer->GetParent() && layer->GetParent()->GetType() == nsGkAtoms::scrollFrame)) break; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 2bc6e69d5b5..7187e1c3ece 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -3372,7 +3372,7 @@ AccumulateFrameBounds(nsIFrame* aContainerFrame, nsIFrame *f = aFrame; while (f && f->IsFrameOfType(nsIFrame::eLineParticipant) && - !f->IsTransformed() && !f->IsPositioned()) { + !f->IsTransformed() && !f->IsAbsPosContaininingBlock()) { prevFrame = f; f = prevFrame->GetParent(); } diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 8341d6a17bb..63c47386abe 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -752,16 +752,10 @@ nsContainerFrame::SyncFrameViewProperties(nsPresContext* aPresContext, ? nsViewVisibility_kShow : nsViewVisibility_kHide); } - // See if the frame is being relatively positioned or absolutely - // positioned - bool isPositioned = aFrame->IsPositioned(); - int32_t zIndex = 0; bool autoZIndex = false; - if (!isPositioned) { - autoZIndex = true; - } else { + if (aFrame->IsAbsPosContaininingBlock()) { // Make sure z-index is correct const nsStylePosition* position = aStyleContext->StylePosition(); @@ -770,6 +764,8 @@ nsContainerFrame::SyncFrameViewProperties(nsPresContext* aPresContext, } else if (position->mZIndex.GetUnit() == eStyleUnit_Auto) { autoZIndex = true; } + } else { + autoZIndex = true; } vm->SetViewZIndex(aView, autoZIndex, zIndex); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index ed3b63dffc3..30173f4d5c7 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2357,7 +2357,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, || nsSVGIntegrationUtils::UsingEffectsForFrame(child) || (child->GetStateBits() & NS_FRAME_HAS_VR_CONTENT); - bool isPositioned = disp->IsPositioned(child); + bool isPositioned = disp->IsAbsPosContainingBlock(child); bool isStackingContext = (isPositioned && (disp->mPosition == NS_STYLE_POSITION_STICKY || pos->mZIndex.GetUnit() == eStyleUnit_Integer)) || @@ -8802,7 +8802,7 @@ nsIFrame::IsPseudoStackingContextFromStyle() { // If you change this, also change the computation of pseudoStackingContext // in BuildDisplayListForChild() return disp->mOpacity != 1.0f || - disp->IsPositioned(this) || + disp->IsAbsPosContainingBlock(this) || disp->IsFloating(this) || (StylePosition()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index e816b12f83a..c76068da9af 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -2633,7 +2633,7 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, nsAutoTArray scrollParts; for (nsIFrame* kid = mOuter->GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) { if (kid == mScrolledFrame || - (kid->IsPositioned() || overlayScrollbars) != aPositioned) + (kid->IsAbsPosContaininingBlock() || overlayScrollbars) != aPositioned) continue; scrollParts.AppendElement(kid); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index c6c37aaba94..f9b748a0948 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2902,7 +2902,7 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty())) inline bool IsInlineOutside() const; inline uint8_t GetDisplay() const; inline bool IsFloating() const; - inline bool IsPositioned() const; + inline bool IsAbsPosContaininingBlock() const; inline bool IsRelativelyPositioned() const; inline bool IsAbsolutelyPositioned() const; diff --git a/layout/generic/nsIFrameInlines.h b/layout/generic/nsIFrameInlines.h index 19501e34399..e2872b2a384 100644 --- a/layout/generic/nsIFrameInlines.h +++ b/layout/generic/nsIFrameInlines.h @@ -45,9 +45,9 @@ nsIFrame::IsFloating() const } bool -nsIFrame::IsPositioned() const +nsIFrame::IsAbsPosContaininingBlock() const { - return StyleDisplay()->IsPositioned(this); + return StyleDisplay()->IsAbsPosContainingBlock(this); } bool diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 2b6c8a3a68e..fc5d5fcda69 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1474,6 +1474,8 @@ struct nsStylePosition { * or a related property, and supports CSS transforms. */ inline bool HasTransform(const nsIFrame* aContextFrame) const; + inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const; + private: static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord); static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord) @@ -2227,7 +2229,7 @@ struct nsStyleDisplay { inline bool IsOriginalDisplayInlineOutside(const nsIFrame* aContextFrame) const; inline uint8_t GetDisplay(const nsIFrame* aContextFrame) const; inline bool IsFloating(const nsIFrame* aContextFrame) const; - inline bool IsPositioned(const nsIFrame* aContextFrame) const; + inline bool IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const; inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const; inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const; }; diff --git a/layout/style/nsStyleStructInlines.h b/layout/style/nsStyleStructInlines.h index 1360c0baae8..99a727feb1f 100644 --- a/layout/style/nsStyleStructInlines.h +++ b/layout/style/nsStyleStructInlines.h @@ -37,6 +37,13 @@ nsStylePosition::HasTransform(const nsIFrame* aContextFrame) const return HasTransformStyle() && aContextFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms); } +bool +nsStylePosition::IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const +{ + return (HasTransform(aContextFrame) || HasPerspectiveStyle()) && + !aContextFrame->IsSVGText(); +} + bool nsStyleText::HasTextShadow() const { @@ -123,24 +130,18 @@ nsStyleDisplay::IsFloating(const nsIFrame* aContextFrame) const return IsFloatingStyle() && !aContextFrame->IsSVGText(); } +// If you change this function, also change the corresponding block in +// nsCSSFrameConstructor::ConstructFrameFromItemInternal that references +// this function in comments. bool -nsStyleDisplay::IsPositioned(const nsIFrame* aContextFrame) const +nsStyleDisplay::IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const { NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame"); - if (aContextFrame->IsSVGText()) { - return false; - } - if (IsAbsolutelyPositionedStyle() || - IsRelativelyPositionedStyle()) { - return true; - } - const nsStylePosition* position = aContextFrame->StylePosition(); - if (position->HasTransform(aContextFrame) || - position->HasPerspectiveStyle()) { - return true; - } - return false; + return ((IsAbsolutelyPositionedStyle() || IsRelativelyPositionedStyle()) && + !aContextFrame->IsSVGText()) || + aContextFrame->StylePosition()-> + IsFixedPosContainingBlock(aContextFrame); } bool