Bug 346035. Force <stack> children to be full-fledged stacking contexts and put their display items in the Content display list. r+sr=dbaron
git-svn-id: svn://10.0.0.236/trunk@206519 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1368,7 +1368,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
PRBool isComposited = disp->mOpacity != 1.0f;
|
||||
PRBool isPositioned = disp->IsPositioned();
|
||||
if (isComposited || isPositioned) {
|
||||
if (isComposited || isPositioned || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
|
||||
// If you change this, also change IsPseudoStackingContextFromStyle()
|
||||
pseudoStackingContext = PR_TRUE;
|
||||
}
|
||||
@@ -1405,7 +1405,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList extraPositionedDescendants;
|
||||
const nsStylePosition* pos = aChild->GetStylePosition();
|
||||
if ((isPositioned && pos->mZIndex.GetUnit() == eStyleUnit_Integer) ||
|
||||
isComposited) {
|
||||
isComposited || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
|
||||
// True stacking context
|
||||
rv = aChild->BuildDisplayListForStackingContext(aBuilder, dirty, &list);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@@ -1453,7 +1453,8 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (isPositioned || isComposited) {
|
||||
if (isPositioned || isComposited ||
|
||||
(aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
|
||||
// Genuine stacking contexts, and positioned pseudo-stacking-contexts,
|
||||
// go in this level.
|
||||
rv = aLists.PositionedDescendants()->AppendNewToTop(new (aBuilder)
|
||||
|
||||
@@ -762,16 +762,17 @@ public:
|
||||
|
||||
enum {
|
||||
DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT = 0x01,
|
||||
DISPLAY_CHILD_INLINE = 0x02
|
||||
};
|
||||
DISPLAY_CHILD_FORCE_STACKING_CONTEXT = 0x02,
|
||||
DISPLAY_CHILD_INLINE = 0x04
|
||||
};
|
||||
/**
|
||||
* Adjusts aDirtyRect for the child's offset, checks that the dirty rect
|
||||
* actually intersects the child (or its descendants), calls BuildDisplayList
|
||||
* on the child if necessary, and puts things in the right lists if the child
|
||||
* is positioned.
|
||||
*
|
||||
* @param aFlags combination of DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT
|
||||
* and DISPLAY_CHILD_INLINE
|
||||
* @param aFlags combination of DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT,
|
||||
* DISPLAY_CHILD_FORCE_STACKING_CONTEXT and DISPLAY_CHILD_INLINE
|
||||
*/
|
||||
nsresult BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aChild,
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsBoxLayoutState.h"
|
||||
#include "nsStackLayout.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
nsIFrame*
|
||||
NS_NewStackFrame (nsIPresShell* aPresShell, nsStyleContext* aContext, nsIBoxLayout* aLayoutManager)
|
||||
@@ -88,12 +89,17 @@ nsStackFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists)
|
||||
{
|
||||
// BuildDisplayListForChild puts stacking contexts into the PositionedDescendants
|
||||
// list. So we need to map that list to aLists.Content(). This is an easy way to
|
||||
// do that.
|
||||
nsDisplayList* content = aLists.Content();
|
||||
nsDisplayListSet kidLists(content, content, content, content, content, content);
|
||||
nsIFrame* kid = mFrames.FirstChild();
|
||||
while (kid) {
|
||||
// Force each child into its own stacking context.
|
||||
// Force each child into its own true stacking context.
|
||||
nsresult rv =
|
||||
BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists,
|
||||
DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT);
|
||||
BuildDisplayListForChild(aBuilder, kid, aDirtyRect, kidLists,
|
||||
DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
kid = kid->GetNextSibling();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user