Place position:absolute, fixed, relative elements above non positioned elements. b=137853 r=roc+moz sr=kin

This commit is contained in:
kmcclusk%netscape.com 2002-07-02 12:50:14 +00:00
Родитель 7df6d07dcb
Коммит 353410cea2
12 изменённых файлов: 109 добавлений и 42 удалений

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

@ -650,18 +650,23 @@ nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
// Make sure z-index is correct
PRInt32 zIndex = 0;
PRInt32 oldZIndex;
PRBool oldAutoZIndex;
PRBool oldTopMost;
PRBool autoZIndex = PR_FALSE;
const nsStylePosition* position;
aView->GetZIndex(oldZIndex, oldAutoZIndex, oldTopMost);
aFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
if (position->mZIndex.GetUnit() == eStyleUnit_Integer) {
zIndex = position->mZIndex.GetIntValue();
} else if (position->mZIndex.GetUnit() == eStyleUnit_Auto) {
autoZIndex = PR_TRUE;
}
vm->SetViewZIndex(aView, autoZIndex, zIndex);
}
vm->SetViewZIndex(aView, autoZIndex, zIndex, oldTopMost);
// There are two types of clipping:
// - 'clip' which only applies to absolutely positioned elements, and is

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

@ -449,6 +449,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
nsIFrame* aContentParentFrame,
PRBool aForce)
{
PRBool isTopMostView = PR_FALSE;
nsIView* view;
aFrame->GetView(aPresContext, &view);
// If we don't yet have a view, see if we need a view
@ -489,12 +490,18 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
("nsHTMLContainerFrame::CreateViewForFrame: frame=%p relatively positioned",
aFrame));
aForce = PR_TRUE;
isTopMostView = PR_TRUE;
} else if (display->IsAbsolutelyPositioned()) {
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("nsHTMLContainerFrame::CreateViewForFrame: frame=%p absolutely positioned",
aFrame));
aForce = PR_TRUE;
}
isTopMostView = PR_TRUE;
}
}
if (NS_STYLE_POSITION_FIXED == display->mPosition) {
isTopMostView = PR_TRUE;
}
// See if the frame is a scrolled frame
@ -585,7 +592,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
autoZIndex = PR_TRUE;
}
viewManager->SetViewZIndex(view, autoZIndex, zIndex);
viewManager->SetViewZIndex(view, autoZIndex, zIndex, isTopMostView);
// XXX Drop it at the end of the document order until we can do better
viewManager->InsertChild(parentView, view, nsnull, PR_TRUE);
@ -600,7 +607,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
if (nsnull == zParentView) {
nsIFrame* zParentFrame = nsnull;
aContentParentFrame->GetParentWithView(aPresContext, &zParentFrame);
NS_ASSERTION(zParentFrame, "GetParentWithView failed");
zParentFrame->GetView(aPresContext, &zParentView);

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

@ -650,18 +650,23 @@ nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
// Make sure z-index is correct
PRInt32 zIndex = 0;
PRInt32 oldZIndex;
PRBool oldAutoZIndex;
PRBool oldTopMost;
PRBool autoZIndex = PR_FALSE;
const nsStylePosition* position;
aView->GetZIndex(oldZIndex, oldAutoZIndex, oldTopMost);
aFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
if (position->mZIndex.GetUnit() == eStyleUnit_Integer) {
zIndex = position->mZIndex.GetIntValue();
} else if (position->mZIndex.GetUnit() == eStyleUnit_Auto) {
autoZIndex = PR_TRUE;
}
vm->SetViewZIndex(aView, autoZIndex, zIndex);
}
vm->SetViewZIndex(aView, autoZIndex, zIndex, oldTopMost);
// There are two types of clipping:
// - 'clip' which only applies to absolutely positioned elements, and is

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

@ -449,6 +449,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
nsIFrame* aContentParentFrame,
PRBool aForce)
{
PRBool isTopMostView = PR_FALSE;
nsIView* view;
aFrame->GetView(aPresContext, &view);
// If we don't yet have a view, see if we need a view
@ -489,12 +490,18 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
("nsHTMLContainerFrame::CreateViewForFrame: frame=%p relatively positioned",
aFrame));
aForce = PR_TRUE;
isTopMostView = PR_TRUE;
} else if (display->IsAbsolutelyPositioned()) {
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
("nsHTMLContainerFrame::CreateViewForFrame: frame=%p absolutely positioned",
aFrame));
aForce = PR_TRUE;
}
isTopMostView = PR_TRUE;
}
}
if (NS_STYLE_POSITION_FIXED == display->mPosition) {
isTopMostView = PR_TRUE;
}
// See if the frame is a scrolled frame
@ -585,7 +592,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
autoZIndex = PR_TRUE;
}
viewManager->SetViewZIndex(view, autoZIndex, zIndex);
viewManager->SetViewZIndex(view, autoZIndex, zIndex, isTopMostView);
// XXX Drop it at the end of the document order until we can do better
viewManager->InsertChild(parentView, view, nsnull, PR_TRUE);
@ -600,7 +607,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
if (nsnull == zParentView) {
nsIFrame* zParentFrame = nsnull;
aContentParentFrame->GetParentWithView(aPresContext, &zParentFrame);
NS_ASSERTION(zParentFrame, "GetParentWithView failed");
zParentFrame->GetView(aPresContext, &zParentView);

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

@ -144,9 +144,14 @@ public:
/**
* Called to query the z-index of a view.
* The z-index is relative to all siblings of the view.
* @result current z depth
* @param aAuto PR_TRUE if the view is zindex:auto
* @param aZIndex explicit z-index value.
* @param aTopMost used when this view is zindex:auto
* PR_TRUE if the view is topmost when compared
* with another z-index:auto view
*
*/
NS_IMETHOD GetZIndex(PRBool &aAuto, PRInt32 &aZIndex) const = 0;
NS_IMETHOD GetZIndex(PRBool &aAuto, PRInt32 &aZIndex, PRBool &aTopMost) const = 0;
/**
* Get whether the view "floats" above all other views,

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

@ -288,9 +288,13 @@ public:
* which means that the z-indicies of the view's children are
* relative to the view's siblings.
* @param aView view to change z depth of
* @param zindex new z depth
* @param aZindex explicit z depth
* @param aTopMost used when this view is z-index:auto to compare against
* other z-index:auto views.
* PR_TRUE if the view should be topmost when compared with
* other z-index:auto views.
*/
NS_IMETHOD SetViewZIndex(nsIView *aView, PRBool aAutoZIndex, PRInt32 aZindex) = 0;
NS_IMETHOD SetViewZIndex(nsIView *aView, PRBool aAutoZIndex, PRInt32 aZindex, PRBool aTopMost = PR_FALSE) = 0;
/**
* Set whether the view "floats" above all other views,

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

@ -950,17 +950,17 @@ NS_IMETHODIMP nsScrollingView::SetWidget(nsIWidget *aWidget)
return NS_OK;
}
NS_IMETHODIMP nsScrollingView::SetZIndex(PRBool aAuto, PRInt32 aZIndex)
NS_IMETHODIMP nsScrollingView::SetZIndex(PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost)
{
nsView::SetZIndex(aAuto, aZIndex);
nsView::SetZIndex(aAuto, aZIndex, aTopMost);
// inform all views that the z-index has changed.
// XXX why are we doing this? they're all a child of this view, so they
// shouldn't need to be re-z-indexed.
if (mClipView) mViewManager->SetViewZIndex(mClipView, aAuto, aZIndex);
if (mCornerView) mViewManager->SetViewZIndex(mCornerView, aAuto, aZIndex);
if (mVScrollBarView) mViewManager->SetViewZIndex(mVScrollBarView, aAuto, aZIndex);
if (mHScrollBarView) mViewManager->SetViewZIndex(mHScrollBarView, aAuto, aZIndex);
if (mClipView) mViewManager->SetViewZIndex(mClipView, aAuto, aZIndex, aTopMost);
if (mCornerView) mViewManager->SetViewZIndex(mCornerView, aAuto, aZIndex, aTopMost);
if (mVScrollBarView) mViewManager->SetViewZIndex(mVScrollBarView, aAuto, aZIndex, aTopMost);
if (mHScrollBarView) mViewManager->SetViewZIndex(mHScrollBarView, aAuto, aZIndex, aTopMost);
return NS_OK;
}

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

@ -68,7 +68,7 @@ public:
NS_IMETHOD SetVisibility(nsViewVisibility visibility);
NS_IMETHOD SetWidget(nsIWidget *aWidget);
NS_IMETHOD SetZIndex(PRBool aAuto, PRInt32 aZIndex);
NS_IMETHOD SetZIndex(PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost);
//nsIScrollableView interface
NS_IMETHOD CreateScrollControls(nsNativeWidget aNative = nsnull);

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

@ -607,10 +607,11 @@ NS_IMETHODIMP nsView::GetVisibility(nsViewVisibility &aVisibility) const
return NS_OK;
}
NS_IMETHODIMP nsView::GetZIndex(PRBool &aAuto, PRInt32 &aZIndex) const
NS_IMETHODIMP nsView::GetZIndex(PRBool &aAuto, PRInt32 &aZIndex, PRBool &aTopMost) const
{
aAuto = (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0;
aAuto = (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0;
aZIndex = mZIndex;
aTopMost = (mVFlags & NS_VIEW_FLAG_TOPMOST) != 0;
return NS_OK;
}
@ -825,11 +826,12 @@ NS_IMETHODIMP nsView::CreateWidget(const nsIID &aWindowIID,
return NS_OK;
}
void nsView::SetZIndex(PRBool aAuto, PRInt32 aZIndex)
void nsView::SetZIndex(PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost)
{
mVFlags = (mVFlags & ~NS_VIEW_FLAG_AUTO_ZINDEX) | (aAuto ? NS_VIEW_FLAG_AUTO_ZINDEX : 0);
mZIndex = aZIndex;
SetTopMost(aTopMost);
if (nsnull != mWindow) {
mWindow->SetZIndex(aZIndex);
}

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

@ -84,6 +84,10 @@ public:
// set if our widget moved.
#define NS_VIEW_FLAG_WIDGET_MOVED 0x0100
#define NS_VIEW_FLAG_CLIPCHILDREN 0x0200
// if set it indicates that this view should be
// displayed above z-index:auto views if this view
// is z-index:auto also
#define NS_VIEW_FLAG_TOPMOST 0x0400
//indicates that the view should not be bitblt'd when moved
//or scrolled and instead must be repainted
#define NS_VIEW_FLAG_DONT_BITBLT 0x0010
@ -110,7 +114,7 @@ public:
NS_IMETHOD GetPosition(nscoord *x, nscoord *y) const;
NS_IMETHOD GetBounds(nsRect &aBounds) const;
NS_IMETHOD GetVisibility(nsViewVisibility &aVisibility) const;
NS_IMETHOD GetZIndex(PRBool &aAuto, PRInt32 &aZIndex) const;
NS_IMETHOD GetZIndex(PRBool &aAuto, PRInt32 &aZIndex, PRBool &aTopMost) const;
PRInt32 GetZIndex() const { return mZIndex; }
PRBool GetZIndexIsAuto() const { return (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0; }
NS_IMETHOD GetFloating(PRBool &aFloatingView) const;
@ -218,7 +222,7 @@ public:
* relative to the view's siblings.
* @param zindex new z depth
*/
void SetZIndex(PRBool aAuto, PRInt32 aZIndex);
void SetZIndex(PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost);
/**
* Set/Get whether the view "floats" above all other views,
@ -315,6 +319,9 @@ public: // NOT in nsIView, so only available in view module
PRUint32 GetViewFlags() const { return mVFlags; }
void SetViewFlags(PRUint32 aFlags) { mVFlags = aFlags; }
void SetTopMost(PRBool aTopMost) { aTopMost ? mVFlags |= NS_VIEW_FLAG_TOPMOST : mVFlags &= ~NS_VIEW_FLAG_TOPMOST; }
PRBool IsTopMost() { return((mVFlags & NS_VIEW_FLAG_TOPMOST) != 0); }
void ConvertToParentCoords(nscoord* aX, nscoord* aY) const { *aX += mPosX; *aY += mPosY; }
void ConvertFromParentCoords(nscoord* aX, nscoord* aY) const { *aX -= mPosX; *aY -= mPosY; }

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

@ -252,6 +252,26 @@ nsInvalidateEvent::nsInvalidateEvent(nsViewManager* aViewManager)
//-------------- End Invalidate Event Definition ---------------------------
// Compare two Z-index values taking into account topmost and
// auto flags. the topmost flag is only used when both views are
// zindex:auto.
//
// returns 0 if equal
// > 0 if first z-index is greater than the second
// < 0 if first z-index is less than the second
static PRInt32 CompareZIndex(PRInt32 aZIndex1, PRBool aTopMost1, PRBool aIsAuto1,
PRInt32 aZIndex2, PRBool aTopMost2, PRBool aIsAuto2)
{
NS_ASSERTION(!aIsAuto1 || aZIndex1 == 0,"auto is set and the z-index is not 0");
NS_ASSERTION(!aIsAuto2 || aZIndex2 == 0,"auto is set and the z-index is not 0");
if (aZIndex1 != aZIndex2) {
return aZIndex1 - aZIndex2;
} else {
return aTopMost1 - aTopMost2;
}
}
void
nsViewManager::PostInvalidateEvent()
@ -526,7 +546,7 @@ NS_IMETHODIMP nsViewManager::SetRootView(nsIView *aView, nsIWidget* aWidget)
parent->InsertChild(mRootView, nsnull);
}
mRootView->SetZIndex(PR_FALSE, 0);
mRootView->SetZIndex(PR_FALSE, 0, PR_FALSE);
mRootView->GetWidget(mRootWindow);
if (nsnull != mRootWindow) {
@ -1807,7 +1827,7 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
obs->HandleEvent(view, aEvent, aStatus, PR_TRUE, handled);
}
}
break;
break;
default:
{
@ -2205,7 +2225,8 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIV
{
PRInt32 idx = kid->GetZIndex();
if (zIndex >= idx)
if (CompareZIndex(zIndex, child->IsTopMost(), child->GetZIndexIsAuto(),
idx, kid->IsTopMost(), kid->GetZIndexIsAuto()) >= 0)
break;
prev = kid;
@ -2248,7 +2269,7 @@ NS_IMETHODIMP nsViewManager::InsertZPlaceholder(nsIView *aParent, nsIView *aChil
// mark the placeholder as "shown" so that it will be included in a built display list
placeholder->Init(this, bounds, parent, nsViewVisibility_kShow);
placeholder->SetReparentedView(child);
placeholder->SetZIndex(child->GetZIndexIsAuto(), child->GetZIndex());
placeholder->SetZIndex(child->GetZIndexIsAuto(), child->GetZIndex(), child->IsTopMost());
child->SetZParent(placeholder);
return InsertChild(parent, placeholder, aSibling, aAfter);
@ -2273,8 +2294,10 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, PRIn
{
PRInt32 idx = kid->GetZIndex();
if (aZIndex >= idx)
if (CompareZIndex(aZIndex, child->IsTopMost(), child->GetZIndexIsAuto(),
idx, kid->IsTopMost(), kid->GetZIndexIsAuto()) >= 0) {
break;
}
//get the next sibling view
@ -2284,7 +2307,7 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, PRIn
//in case this hasn't been set yet... maybe we should not do this? MMP
child->SetZIndex(child->GetZIndexIsAuto(), aZIndex);
child->SetZIndex(child->GetZIndexIsAuto(), aZIndex, child->IsTopMost());
parent->InsertChild(child, prev);
UpdateTransCnt(nsnull, child);
@ -2704,7 +2727,7 @@ PRBool nsViewManager::IsViewInserted(nsView *aView)
}
}
NS_IMETHODIMP nsViewManager::SetViewZIndex(nsIView *aView, PRBool aAutoZIndex, PRInt32 aZIndex)
NS_IMETHODIMP nsViewManager::SetViewZIndex(nsIView *aView, PRBool aAutoZIndex, PRInt32 aZIndex, PRBool aTopMost)
{
nsView* view = NS_STATIC_CAST(nsView*, aView);
nsresult rv = NS_OK;
@ -2717,16 +2740,19 @@ NS_IMETHODIMP nsViewManager::SetViewZIndex(nsIView *aView, PRBool aAutoZIndex, P
return rv;
}
PRBool oldTopMost = view->IsTopMost();
PRBool oldIsAuto = view->GetZIndexIsAuto();
if (aAutoZIndex) {
aZIndex = 0;
}
PRInt32 oldidx = view->GetZIndex();
view->SetZIndex(aAutoZIndex, aZIndex);
view->SetZIndex(aAutoZIndex, aZIndex, aTopMost);
if (IsViewInserted(view)) {
if (oldidx != aZIndex) {
if (CompareZIndex(oldidx, oldTopMost, oldIsAuto,
aZIndex, aTopMost, aAutoZIndex) != 0) {
nsView *parent = view->GetParent();
if (nsnull != parent) {
//we don't just call the view manager's RemoveChild()
@ -2748,7 +2774,7 @@ NS_IMETHODIMP nsViewManager::SetViewZIndex(nsIView *aView, PRBool aAutoZIndex, P
nsZPlaceholderView* zParentView = view->GetZParent();
if (nsnull != zParentView) {
SetViewZIndex(zParentView, aAutoZIndex, aZIndex);
SetViewZIndex(zParentView, aAutoZIndex, aZIndex, aTopMost);
}
}

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

@ -180,8 +180,7 @@ public:
NS_IMETHOD SetViewVisibility(nsIView *aView, nsViewVisibility aVisible);
NS_IMETHOD SetViewZIndex(nsIView *aView, PRBool aAuto, PRInt32 aZIndex);
NS_IMETHOD SetViewZIndex(nsIView *aView, PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost=PR_FALSE);
NS_IMETHOD SetViewContentTransparency(nsIView *aView, PRBool aTransparent);
NS_IMETHOD SetViewOpacity(nsIView *aView, float aOpacity);