Bug 1271714. When creating the wrap list item that contains the display list for a frame make sure to use a scroll clip that includes content in the display list. r=mstange

In nsIFrame::BuildDisplayListForChild for certain types of frames we create wrap list items to wrap the constructed display list to make those items inseperable.

We were using the current scroll clip by default when creating these items, but that scroll clip may not contain all the content in the display list if we traversed into an out of flow frame whose containing block is an ancestor of the current frame. The CurrentAncestorScrollClipForStackingContextContents keeps track of exactly this. (Its name might be a little misleading as we may not be dealing with a true stacking context here. Nevertheless it does contain the correct clip.)

We also need to initialize the value of mStackingContextAncestorSC when we create an AutoSaveRestore because we are now using that value sometimes without calling Enter/ExitStackingContext (which initializes mStackingContextAncestorSC).
This commit is contained in:
Timothy Nikkel 2016-07-13 01:08:18 -05:00
Родитель ae674679d8
Коммит 8dab980fec
2 изменённых файлов: 12 добавлений и 6 удалений

Просмотреть файл

@ -216,6 +216,8 @@ DisplayListClipState::AutoSaveRestore::AutoSaveRestore(nsDisplayListBuilder* aBu
, mRestored(false)
#endif
, mClearedForStackingContextContents(false)
{}
{
mState.mStackingContextAncestorSC = mState.GetCurrentInnermostScrollClip();
}
} // namespace mozilla

Просмотреть файл

@ -2599,7 +2599,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
static nsDisplayItem*
WrapInWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
nsIFrame* aFrame, nsDisplayList* aList,
const DisplayItemScrollClip* aScrollClip)
{
nsDisplayItem* item = aList->GetBottom();
if (!item) {
@ -2617,7 +2618,7 @@ WrapInWrapList(nsDisplayListBuilder* aBuilder,
}
if (item->GetAbove() || itemFrame != aFrame) {
return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList);
return new (aBuilder) nsDisplayWrapList(aBuilder, aFrame, aList, aScrollClip);
}
aList->RemoveBottom();
return item;
@ -2908,17 +2909,20 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
}
buildingForChild.RestoreBuildingInvisibleItemsValue();
// Clear clip rect for the construction of the items below. Since we're
// clipping all their contents, they themselves don't need to be clipped.
clipState.Clear();
const DisplayItemScrollClip* containerItemScrollClip =
aBuilder->ClipState().CurrentAncestorScrollClipForStackingContextContents();
if (isPositioned || isVisuallyAtomic ||
(aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
// Genuine stacking contexts, and positioned pseudo-stacking-contexts,
// go in this level.
if (!list.IsEmpty()) {
nsDisplayItem* item = WrapInWrapList(aBuilder, child, &list);
nsDisplayItem* item = WrapInWrapList(aBuilder, child, &list, containerItemScrollClip);
if (isSVG) {
aLists.Content()->AppendNewToTop(item);
} else {
@ -2927,7 +2931,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
}
} else if (!isSVG && disp->IsFloating(child)) {
if (!list.IsEmpty()) {
aLists.Floats()->AppendNewToTop(WrapInWrapList(aBuilder, child, &list));
aLists.Floats()->AppendNewToTop(WrapInWrapList(aBuilder, child, &list, containerItemScrollClip));
}
} else {
aLists.Content()->AppendToTop(&list);