зеркало из https://github.com/mozilla/gecko-dev.git
Bug 806056 - Add a frame bit that says if a frame is allowed to have abs/fixed pos. children when the style so indicates (position/transform usually). Copy the bit to next-in-flows. Don't call MarkAsAbsoluteContainingBlock for style changes on an existing frame unless that bit is set (style changes that recreates the frame resets it of course). Assert in MarkAs[Not]AbsoluteContainingBlock() that the bit is set. r=bz
This commit is contained in:
Родитель
7eb78c7eb5
Коммит
1a123c0b7d
|
@ -1942,6 +1942,7 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState,
|
|||
const nsStyleDisplay* display = outerStyleContext->GetStyleDisplay();
|
||||
|
||||
// Mark the table frame as an absolute container if needed
|
||||
newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (display->IsPositioned(aParentFrame)) {
|
||||
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
|
||||
}
|
||||
|
@ -2387,6 +2388,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
|
|||
if (mHasRootAbsPosContainingBlock) {
|
||||
// Push the absolute containing block now so we can absolutely position
|
||||
// the root element
|
||||
mDocElementContainingBlock->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
state.PushAbsoluteContainingBlock(mDocElementContainingBlock,
|
||||
absoluteSaveState);
|
||||
}
|
||||
|
@ -2575,6 +2577,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIFrame** aNewFrame)
|
|||
// The viewport is the containing block for 'fixed' elements
|
||||
mFixedContainingBlock = viewportFrame;
|
||||
// Make it an absolute container for fixed-pos elements
|
||||
mFixedContainingBlock->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
mFixedContainingBlock->MarkAsAbsoluteContainingBlock();
|
||||
|
||||
*aNewFrame = viewportFrame;
|
||||
|
@ -2844,6 +2847,7 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
|
|||
SetInitialSingleChild(aPageFrame, pageContentFrame);
|
||||
mFixedContainingBlock = pageContentFrame;
|
||||
// Make it an absolute container for fixed-pos elements
|
||||
mFixedContainingBlock->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
mFixedContainingBlock->MarkAsAbsoluteContainingBlock();
|
||||
|
||||
nsRefPtr<nsStyleContext> canvasPseudoStyle;
|
||||
|
@ -3150,6 +3154,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
|
|||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
nsFrameItems childItems;
|
||||
|
||||
newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (newFrame->IsPositioned()) {
|
||||
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
|
||||
}
|
||||
|
@ -3726,11 +3731,12 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
|
|||
|
||||
if (bits & FCDATA_FORCE_NULL_ABSPOS_CONTAINER) {
|
||||
aState.PushAbsoluteContainingBlock(nullptr, absoluteSaveState);
|
||||
} else if (!(bits & FCDATA_SKIP_ABSPOS_PUSH) &&
|
||||
maybeAbsoluteContainingBlockDisplay->IsPositioned
|
||||
(maybeAbsoluteContainingBlock)) {
|
||||
aState.PushAbsoluteContainingBlock(maybeAbsoluteContainingBlock,
|
||||
absoluteSaveState);
|
||||
} else if (!(bits & FCDATA_SKIP_ABSPOS_PUSH)) {
|
||||
nsIFrame* cb = maybeAbsoluteContainingBlock;
|
||||
cb->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (maybeAbsoluteContainingBlockDisplay->IsPositioned(cb)) {
|
||||
aState.PushAbsoluteContainingBlock(cb, absoluteSaveState);
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & FCDATA_USE_CHILD_ITEMS) {
|
||||
|
@ -8160,7 +8166,8 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
|||
// 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.
|
||||
frame->AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
|
||||
if (!frame->IsAbsoluteContainer()) {
|
||||
if (!frame->IsAbsoluteContainer() &&
|
||||
(frame->GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN)) {
|
||||
frame->MarkAsAbsoluteContainingBlock();
|
||||
}
|
||||
} else {
|
||||
|
@ -11122,6 +11129,7 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
|
|||
// children. So use the block and try to compensate with hacks
|
||||
// in nsBlockFrame::CalculateContainingBlockSizeForAbsolutes.
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
(*aNewFrame)->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (aAbsPosContainer) {
|
||||
// NS_ASSERTION(aRelPos, "should have made area frame for this");
|
||||
aState.PushAbsoluteContainingBlock(*aNewFrame, absoluteSaveState);
|
||||
|
@ -11226,6 +11234,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
|
|||
// because the object's destructor is significant
|
||||
// this is part of the fix for bug 42372
|
||||
|
||||
newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (positioned) {
|
||||
// Relatively positioned frames becomes a container for child
|
||||
// frames that are positioned
|
||||
|
@ -11339,8 +11348,8 @@ nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState,
|
|||
InitAndRestoreFrame(aState, content, parentFrame, nullptr, inlineFrame,
|
||||
false);
|
||||
|
||||
inlineFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
|
||||
|
||||
inlineFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT |
|
||||
NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
if (aIsPositioned) {
|
||||
inlineFrame->MarkAsAbsoluteContainingBlock();
|
||||
}
|
||||
|
|
|
@ -251,6 +251,7 @@ nsIFrame::GetAbsoluteContainingBlock() const {
|
|||
void
|
||||
nsIFrame::MarkAsAbsoluteContainingBlock()
|
||||
{
|
||||
MOZ_ASSERT(GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
NS_ASSERTION(!Properties().Get(AbsoluteContainingBlockProperty()),
|
||||
"Already has an abs-pos containing block property?");
|
||||
NS_ASSERTION(!HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
|
||||
|
@ -267,6 +268,7 @@ nsIFrame::MarkAsNotAbsoluteContainingBlock()
|
|||
"Should have an abs-pos containing block property");
|
||||
NS_ASSERTION(HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
|
||||
"Should have NS_FRAME_HAS_ABSPOS_CHILDREN state bit");
|
||||
MOZ_ASSERT(HasAnyStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN));
|
||||
RemoveStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
|
||||
Properties().Delete(AbsoluteContainingBlockProperty());
|
||||
}
|
||||
|
@ -512,7 +514,8 @@ nsFrame::Init(nsIContent* aContent,
|
|||
mState |= state & (NS_FRAME_INDEPENDENT_SELECTION |
|
||||
NS_FRAME_IS_SPECIAL |
|
||||
NS_FRAME_MAY_BE_TRANSFORMED |
|
||||
NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
|
||||
NS_FRAME_MAY_HAVE_GENERATED_CONTENT |
|
||||
NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
}
|
||||
if (mParent) {
|
||||
nsFrameState state = mParent->GetStateBits();
|
||||
|
|
|
@ -164,8 +164,10 @@ typedef uint64_t nsFrameState;
|
|||
// e.g., it is absolutely positioned or floated
|
||||
#define NS_FRAME_OUT_OF_FLOW NS_FRAME_STATE_BIT(8)
|
||||
|
||||
// This bit is available for re-use.
|
||||
//#define NS_FRAME_SELECTED_CONTENT NS_FRAME_STATE_BIT(9)
|
||||
// Frame can be an abs/fixed pos. container, if its style says so.
|
||||
// MarkAs[Not]AbsoluteContainingBlock will assert that this bit is set.
|
||||
// NS_FRAME_HAS_ABSPOS_CHILDREN must not be set when this bit is unset.
|
||||
#define NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN NS_FRAME_STATE_BIT(9)
|
||||
|
||||
// If this bit is set, then the frame and _all_ of its descendant frames need
|
||||
// to be reflowed.
|
||||
|
|
Загрузка…
Ссылка в новой задаче