Bug 1236400 part 2: Extend NeedsAnonFlexOrGridItem() & related code to wrap all inline-level -webkit-box children in an anonymous flex item. r=mats
MozReview-Commit-ID: LK4VW0xSI5m
This commit is contained in:
@@ -341,6 +341,15 @@ IsFlexOrGridContainer(const nsIFrame* aFrame)
|
||||
t == nsGkAtoms::gridContainerFrame;
|
||||
}
|
||||
|
||||
// Returns true if aFrame has "display: -webkit-{inline-}box"
|
||||
static inline bool
|
||||
IsWebkitBox(const nsIFrame* aFrame)
|
||||
{
|
||||
auto containerDisplay = aFrame->StyleDisplay()->mDisplay;
|
||||
return containerDisplay == NS_STYLE_DISPLAY_WEBKIT_BOX ||
|
||||
containerDisplay == NS_STYLE_DISPLAY_WEBKIT_INLINE_BOX;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
static void
|
||||
AssertAnonymousFlexOrGridItemParent(const nsIFrame* aChild,
|
||||
@@ -9752,10 +9761,13 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
|
||||
}
|
||||
|
||||
nsIAtom* containerType = aParentFrame->GetType();
|
||||
const bool isWebkitBox = IsWebkitBox(aParentFrame);
|
||||
|
||||
FCItemIterator iter(aItems);
|
||||
do {
|
||||
// Advance iter past children that don't want to be wrapped
|
||||
if (iter.SkipItemsThatDontNeedAnonFlexOrGridItem(aState, containerType)) {
|
||||
if (iter.SkipItemsThatDontNeedAnonFlexOrGridItem(aState, containerType,
|
||||
isWebkitBox)) {
|
||||
// Hit the end of the items without finding any remaining children that
|
||||
// need to be wrapped. We're finished!
|
||||
return;
|
||||
@@ -9777,8 +9789,10 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
|
||||
FCItemIterator afterWhitespaceIter(iter);
|
||||
bool hitEnd = afterWhitespaceIter.SkipWhitespace(aState);
|
||||
bool nextChildNeedsAnonItem =
|
||||
!hitEnd && afterWhitespaceIter.item().NeedsAnonFlexOrGridItem(aState,
|
||||
containerType);
|
||||
!hitEnd &&
|
||||
afterWhitespaceIter.item().NeedsAnonFlexOrGridItem(aState,
|
||||
containerType,
|
||||
isWebkitBox);
|
||||
|
||||
if (!nextChildNeedsAnonItem) {
|
||||
// There's nothing after the whitespace that we need to wrap, so we
|
||||
@@ -9792,7 +9806,8 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
|
||||
// we jump back to the beginning of the loop to skip over that child
|
||||
// (and anything else non-wrappable after it)
|
||||
MOZ_ASSERT(!iter.IsDone() &&
|
||||
!iter.item().NeedsAnonFlexOrGridItem(aState, containerType),
|
||||
!iter.item().NeedsAnonFlexOrGridItem(aState, containerType,
|
||||
isWebkitBox),
|
||||
"hitEnd and/or nextChildNeedsAnonItem lied");
|
||||
continue;
|
||||
}
|
||||
@@ -9802,7 +9817,8 @@ nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
|
||||
// anonymous flex/grid item. Now we see how many children after it also want
|
||||
// to be wrapped in an anonymous flex/grid item.
|
||||
FCItemIterator endIter(iter); // iterator to find the end of the group
|
||||
endIter.SkipItemsThatNeedAnonFlexOrGridItem(aState, containerType);
|
||||
endIter.SkipItemsThatNeedAnonFlexOrGridItem(aState, containerType,
|
||||
isWebkitBox);
|
||||
|
||||
NS_ASSERTION(iter != endIter,
|
||||
"Should've had at least one wrappable child to seek past");
|
||||
@@ -12042,8 +12058,10 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
|
||||
// Check if we're adding to-be-wrapped content right *after* an existing
|
||||
// anonymous flex or grid item (which would need to absorb this content).
|
||||
nsIAtom* containerType = aFrame->GetType();
|
||||
bool isWebkitBox = IsWebkitBox(aFrame);
|
||||
if (aPrevSibling && IsAnonymousFlexOrGridItem(aPrevSibling) &&
|
||||
iter.item().NeedsAnonFlexOrGridItem(aState, containerType)) {
|
||||
iter.item().NeedsAnonFlexOrGridItem(aState, containerType,
|
||||
isWebkitBox)) {
|
||||
RecreateFramesForContent(aFrame->GetContent(), true,
|
||||
REMOVE_FOR_RECONSTRUCTION, nullptr);
|
||||
return true;
|
||||
@@ -12055,7 +12073,8 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
|
||||
// Jump to the last entry in the list
|
||||
iter.SetToEnd();
|
||||
iter.Prev();
|
||||
if (iter.item().NeedsAnonFlexOrGridItem(aState, containerType)) {
|
||||
if (iter.item().NeedsAnonFlexOrGridItem(aState, containerType,
|
||||
isWebkitBox)) {
|
||||
RecreateFramesForContent(aFrame->GetContent(), true,
|
||||
REMOVE_FOR_RECONSTRUCTION, nullptr);
|
||||
return true;
|
||||
@@ -12082,7 +12101,8 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
|
||||
// they're perfectly happy to go here -- they won't cause a reframe.
|
||||
nsIFrame* containerFrame = aFrame->GetParent();
|
||||
if (!iter.SkipItemsThatNeedAnonFlexOrGridItem(aState,
|
||||
containerFrame->GetType())) {
|
||||
containerFrame->GetType(),
|
||||
IsWebkitBox(containerFrame))) {
|
||||
// We hit something that _doesn't_ need an anonymous flex item!
|
||||
// Rebuild the flex container to bust it out.
|
||||
RecreateFramesForContent(containerFrame->GetContent(), true,
|
||||
@@ -12534,10 +12554,14 @@ Iterator::SkipItemsNotWantingParentType(ParentType aParentType)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: we implement -webkit-box & -webkit-inline-box using
|
||||
// nsFlexContainerFrame, but we use different rules for what gets wrapped in an
|
||||
// anonymous flex item.
|
||||
bool
|
||||
nsCSSFrameConstructor::FrameConstructionItem::
|
||||
NeedsAnonFlexOrGridItem(const nsFrameConstructorState& aState,
|
||||
nsIAtom* aContainerType)
|
||||
nsIAtom* aContainerType,
|
||||
bool aIsWebkitBox)
|
||||
{
|
||||
if (mFCData->mBits & FCDATA_IS_LINE_PARTICIPANT) {
|
||||
// This will be an inline non-replaced box.
|
||||
@@ -12555,6 +12579,12 @@ nsCSSFrameConstructor::FrameConstructionItem::
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aIsWebkitBox &&
|
||||
mStyleContext->StyleDisplay()->IsInlineOutsideStyle()) {
|
||||
// In a -webkit-box, all inline-level content gets wrapped in an anon item.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12562,10 +12592,12 @@ inline bool
|
||||
nsCSSFrameConstructor::FrameConstructionItemList::
|
||||
Iterator::SkipItemsThatNeedAnonFlexOrGridItem(
|
||||
const nsFrameConstructorState& aState,
|
||||
nsIAtom* aContainerType)
|
||||
nsIAtom* aContainerType,
|
||||
bool aIsWebkitBox)
|
||||
{
|
||||
NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
|
||||
while (item().NeedsAnonFlexOrGridItem(aState, aContainerType)) {
|
||||
while (item().NeedsAnonFlexOrGridItem(aState, aContainerType,
|
||||
aIsWebkitBox)) {
|
||||
Next();
|
||||
if (IsDone()) {
|
||||
return true;
|
||||
@@ -12578,10 +12610,12 @@ inline bool
|
||||
nsCSSFrameConstructor::FrameConstructionItemList::
|
||||
Iterator::SkipItemsThatDontNeedAnonFlexOrGridItem(
|
||||
const nsFrameConstructorState& aState,
|
||||
nsIAtom* aContainerType)
|
||||
nsIAtom* aContainerType,
|
||||
bool aIsWebkitBox)
|
||||
{
|
||||
NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
|
||||
while (!(item().NeedsAnonFlexOrGridItem(aState, aContainerType))) {
|
||||
while (!(item().NeedsAnonFlexOrGridItem(aState, aContainerType,
|
||||
aIsWebkitBox))) {
|
||||
Next();
|
||||
if (IsDone()) {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user