From 9430750742daa9eaaf0db8ea3fe7ea01b0279d20 Mon Sep 17 00:00:00 2001 From: "troy%netscape.com" Date: Sun, 26 Sep 1999 20:40:29 +0000 Subject: [PATCH] Fixes for bug #2552 and bug #10961 --- layout/base/nsCSSFrameConstructor.cpp | 59 ++++++++++---- layout/generic/nsFrame.cpp | 77 ++++++++++++++++--- layout/generic/nsHTMLContainerFrame.cpp | 48 ++++++++++-- layout/html/base/src/nsFrame.cpp | 77 ++++++++++++++++--- layout/html/base/src/nsHTMLContainerFrame.cpp | 48 ++++++++++-- .../html/style/src/nsCSSFrameConstructor.cpp | 59 ++++++++++---- 6 files changed, 296 insertions(+), 72 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 3022609b7ded..7a9d4a1335dc 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -6431,27 +6431,52 @@ SyncAndInvalidateView(nsIView* aView, nsIFrame* aFrame, aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color); aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp); + // Set the view's opacity aViewManager->SetViewOpacity(aView, color->mOpacity); - PRBool viewVisible = (NS_STYLE_VISIBILITY_VISIBLE == disp->mVisible); - // XXX Troy, you need to hook in the leaf node logic here. - // XXX also need to set transparency in the view - if (! viewVisible) { - nsIView* parentView = nsnull; - aView->GetParent(parentView); - if (parentView) { - nsRect bounds; - aView->GetBounds(bounds); - aViewManager->UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC); + // See if the view should be hidden or visible + PRBool viewIsVisible = PR_TRUE; + PRBool viewHasTransparentContent = (color->mBackgroundFlags & + NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT; + + if (NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible) { + // If it's a scroll frame, then hide the view. This means that + // child elements can't override their parent's visibility, but + // it's not practical to leave it visible in all cases because + // the scrollbars will be showing + nsIAtom* frameType; + aFrame->GetFrameType(&frameType); + + if (frameType == nsLayoutAtoms::scrollFrame) { + viewIsVisible = PR_FALSE; + + } else { + // If it's a container element, then leave the view visible, but + // mark it as having transparent content. The reason we need to + // do this is that child elements can override their parent's + // hidden visibility and be visible anyway + nsIFrame* firstChild; + + aFrame->FirstChild(nsnull, &firstChild); + if (firstChild) { + // It's not a left frame, so the view needs to be visible, but + // marked as having transparent content + viewHasTransparentContent = PR_TRUE; + } else { + // It's a leaf frame so go ahead and hide the view + viewIsVisible = PR_FALSE; + } } - else { - // XXX??? how to deal with this??? Do we even have to? - } - aView->SetVisibility(nsViewVisibility_kHide); + NS_IF_RELEASE(frameType); } - else { - aView->SetVisibility(nsViewVisibility_kShow); - aViewManager->UpdateView(aView, nsnull, NS_VMREFRESH_NO_SYNC); + + // Make sure visibility is correct + aViewManager->SetViewVisibility(aView, viewIsVisible ? nsViewVisibility_kShow : + nsViewVisibility_kHide); + + // Make sure content transparency is correct + if (viewIsVisible) { + aViewManager->SetViewContentTransparency(aView, viewHasTransparentContent); } } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index f98ec88b3147..e9493a8993f9 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1093,22 +1093,77 @@ nsFrame::DidReflow(nsIPresContext& aPresContext, if (NS_FRAME_REFLOW_FINISHED == aStatus) { mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY); - // Size and position the view if requested - if ((nsnull != mView) && (NS_FRAME_SYNC_FRAME_AND_VIEW & mState)) { - // Position and size view relative to its parent, not relative to our - // parent frame (our parent frame may not have a view). - nsIView* parentWithView; - nsPoint origin; - GetOffsetFromView(origin, &parentWithView); + // Make sure the view is sized and positioned correctly and it's + // visibility, opacity, content transparency, and clip are correct + if (mView) { nsIViewManager *vm; mView->GetViewManager(vm); - vm->ResizeView(mView, mRect.width, mRect.height); - vm->MoveViewTo(mView, origin.x, origin.y); + + if (NS_FRAME_SYNC_FRAME_AND_VIEW & mState) { + // Position and size view relative to its parent, not relative to our + // parent frame (our parent frame may not have a view). + nsIView* parentWithView; + nsPoint origin; + GetOffsetFromView(origin, &parentWithView); + vm->ResizeView(mView, mRect.width, mRect.height); + vm->MoveViewTo(mView, origin.x, origin.y); + } - // Clip applies to block-level and replaced elements with overflow - // set to other than 'visible' + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); const nsStyleDisplay* display = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); + + // Set the view's opacity + vm->SetViewOpacity(mView, color->mOpacity); + + // See if the view should be hidden or visible + PRBool viewIsVisible = PR_TRUE; + PRBool viewHasTransparentContent = (color->mBackgroundFlags & + NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT; + + if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) { + // If it's a scroll frame, then hide the view. This means that + // child elements can't override their parent's visibility, but + // it's not practical to leave it visible in all cases because + // the scrollbars will be showing + nsIAtom* frameType; + GetFrameType(&frameType); + + if (frameType == nsLayoutAtoms::scrollFrame) { + viewIsVisible = PR_FALSE; + + } else { + // If we're a container element, then leave the view visible, but + // mark it as having transparent content. The reason we need to + // do this is that child elements can override their parent's + // hidden visibility and be visible anyway + nsIFrame* firstChild; + + FirstChild(nsnull, &firstChild); + if (firstChild) { + // Not a left frame, so the view needs to be visible, but marked + // as having transparent content + viewHasTransparentContent = PR_TRUE; + } else { + // Leaf frame so go ahead and hide the view + viewIsVisible = PR_FALSE; + } + } + NS_IF_RELEASE(frameType); + } + + // Make sure visibility is correct + vm->SetViewVisibility(mView, viewIsVisible ? nsViewVisibility_kShow : + nsViewVisibility_kHide); + + // Make sure content transparency is correct + if (viewIsVisible) { + vm->SetViewContentTransparency(mView, viewHasTransparentContent); + } + + // Clip applies to block-level and replaced elements with overflow + // set to other than 'visible' if (display->IsBlockLevel()) { if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) { nscoord left, top, right, bottom; diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp index a0cfff532863..161fc1de54bf 100644 --- a/layout/generic/nsHTMLContainerFrame.cpp +++ b/layout/generic/nsHTMLContainerFrame.cpp @@ -387,7 +387,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext, view->Init(viewManager, bounds, parentView); // If the frame has a fixed background attachment, then indicate that the - // view's contents should repainted and not bitblt'd + // view's contents should be repainted and not bitblt'd if (fixedBackgroundAttachment) { PRUint32 viewFlags; view->GetViewFlags(&viewFlags); @@ -403,13 +403,45 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext, viewManager->InsertChild(parentView, view, zIndex); } - // If the background color is transparent or the visibility is hidden, - // then mark the view as having transparent content. The reason we - // need to do it for hidden visibility is that child elements can - // override their parent's visibility and be visible. - if ((NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags) || - (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible)) { - viewManager->SetViewContentTransparency(view, PR_TRUE); + // See if the view should be hidden + PRBool viewIsVisible = PR_TRUE; + PRBool viewHasTransparentContent = (color->mBackgroundFlags & + NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT; + + if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) { + // If it's a container element, then leave the view visible, but + // mark it as having transparent content. The reason we need to + // do this is that child elements can override their parent's + // hidden visibility and be visible anyway + nsIContent* content; + + // Because this function is called before processing the content + // object's child elements, we can't tell if it's a leaf by looking + // at whether the frame has any child frames + aFrame->GetContent(&content); + if (content) { + PRBool isContainer; + + content->CanContainChildren(isContainer); + if (isContainer) { + // The view needs to be visible, but marked as having transparent + // content + viewHasTransparentContent = PR_TRUE; + } else { + // Go ahead and hide the view + viewIsVisible = PR_FALSE; + } + NS_RELEASE(content); + } + } + + if (viewIsVisible) { + if (viewHasTransparentContent) { + viewManager->SetViewContentTransparency(view, PR_TRUE); + } + + } else { + view->SetVisibility(nsViewVisibility_kHide); } // XXX If it's fixed positioned, then create a widget so it floats diff --git a/layout/html/base/src/nsFrame.cpp b/layout/html/base/src/nsFrame.cpp index f98ec88b3147..e9493a8993f9 100644 --- a/layout/html/base/src/nsFrame.cpp +++ b/layout/html/base/src/nsFrame.cpp @@ -1093,22 +1093,77 @@ nsFrame::DidReflow(nsIPresContext& aPresContext, if (NS_FRAME_REFLOW_FINISHED == aStatus) { mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY); - // Size and position the view if requested - if ((nsnull != mView) && (NS_FRAME_SYNC_FRAME_AND_VIEW & mState)) { - // Position and size view relative to its parent, not relative to our - // parent frame (our parent frame may not have a view). - nsIView* parentWithView; - nsPoint origin; - GetOffsetFromView(origin, &parentWithView); + // Make sure the view is sized and positioned correctly and it's + // visibility, opacity, content transparency, and clip are correct + if (mView) { nsIViewManager *vm; mView->GetViewManager(vm); - vm->ResizeView(mView, mRect.width, mRect.height); - vm->MoveViewTo(mView, origin.x, origin.y); + + if (NS_FRAME_SYNC_FRAME_AND_VIEW & mState) { + // Position and size view relative to its parent, not relative to our + // parent frame (our parent frame may not have a view). + nsIView* parentWithView; + nsPoint origin; + GetOffsetFromView(origin, &parentWithView); + vm->ResizeView(mView, mRect.width, mRect.height); + vm->MoveViewTo(mView, origin.x, origin.y); + } - // Clip applies to block-level and replaced elements with overflow - // set to other than 'visible' + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); const nsStyleDisplay* display = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); + + // Set the view's opacity + vm->SetViewOpacity(mView, color->mOpacity); + + // See if the view should be hidden or visible + PRBool viewIsVisible = PR_TRUE; + PRBool viewHasTransparentContent = (color->mBackgroundFlags & + NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT; + + if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) { + // If it's a scroll frame, then hide the view. This means that + // child elements can't override their parent's visibility, but + // it's not practical to leave it visible in all cases because + // the scrollbars will be showing + nsIAtom* frameType; + GetFrameType(&frameType); + + if (frameType == nsLayoutAtoms::scrollFrame) { + viewIsVisible = PR_FALSE; + + } else { + // If we're a container element, then leave the view visible, but + // mark it as having transparent content. The reason we need to + // do this is that child elements can override their parent's + // hidden visibility and be visible anyway + nsIFrame* firstChild; + + FirstChild(nsnull, &firstChild); + if (firstChild) { + // Not a left frame, so the view needs to be visible, but marked + // as having transparent content + viewHasTransparentContent = PR_TRUE; + } else { + // Leaf frame so go ahead and hide the view + viewIsVisible = PR_FALSE; + } + } + NS_IF_RELEASE(frameType); + } + + // Make sure visibility is correct + vm->SetViewVisibility(mView, viewIsVisible ? nsViewVisibility_kShow : + nsViewVisibility_kHide); + + // Make sure content transparency is correct + if (viewIsVisible) { + vm->SetViewContentTransparency(mView, viewHasTransparentContent); + } + + // Clip applies to block-level and replaced elements with overflow + // set to other than 'visible' if (display->IsBlockLevel()) { if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) { nscoord left, top, right, bottom; diff --git a/layout/html/base/src/nsHTMLContainerFrame.cpp b/layout/html/base/src/nsHTMLContainerFrame.cpp index a0cfff532863..161fc1de54bf 100644 --- a/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -387,7 +387,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext, view->Init(viewManager, bounds, parentView); // If the frame has a fixed background attachment, then indicate that the - // view's contents should repainted and not bitblt'd + // view's contents should be repainted and not bitblt'd if (fixedBackgroundAttachment) { PRUint32 viewFlags; view->GetViewFlags(&viewFlags); @@ -403,13 +403,45 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext, viewManager->InsertChild(parentView, view, zIndex); } - // If the background color is transparent or the visibility is hidden, - // then mark the view as having transparent content. The reason we - // need to do it for hidden visibility is that child elements can - // override their parent's visibility and be visible. - if ((NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags) || - (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible)) { - viewManager->SetViewContentTransparency(view, PR_TRUE); + // See if the view should be hidden + PRBool viewIsVisible = PR_TRUE; + PRBool viewHasTransparentContent = (color->mBackgroundFlags & + NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT; + + if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) { + // If it's a container element, then leave the view visible, but + // mark it as having transparent content. The reason we need to + // do this is that child elements can override their parent's + // hidden visibility and be visible anyway + nsIContent* content; + + // Because this function is called before processing the content + // object's child elements, we can't tell if it's a leaf by looking + // at whether the frame has any child frames + aFrame->GetContent(&content); + if (content) { + PRBool isContainer; + + content->CanContainChildren(isContainer); + if (isContainer) { + // The view needs to be visible, but marked as having transparent + // content + viewHasTransparentContent = PR_TRUE; + } else { + // Go ahead and hide the view + viewIsVisible = PR_FALSE; + } + NS_RELEASE(content); + } + } + + if (viewIsVisible) { + if (viewHasTransparentContent) { + viewManager->SetViewContentTransparency(view, PR_TRUE); + } + + } else { + view->SetVisibility(nsViewVisibility_kHide); } // XXX If it's fixed positioned, then create a widget so it floats diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index 3022609b7ded..7a9d4a1335dc 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -6431,27 +6431,52 @@ SyncAndInvalidateView(nsIView* aView, nsIFrame* aFrame, aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color); aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp); + // Set the view's opacity aViewManager->SetViewOpacity(aView, color->mOpacity); - PRBool viewVisible = (NS_STYLE_VISIBILITY_VISIBLE == disp->mVisible); - // XXX Troy, you need to hook in the leaf node logic here. - // XXX also need to set transparency in the view - if (! viewVisible) { - nsIView* parentView = nsnull; - aView->GetParent(parentView); - if (parentView) { - nsRect bounds; - aView->GetBounds(bounds); - aViewManager->UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC); + // See if the view should be hidden or visible + PRBool viewIsVisible = PR_TRUE; + PRBool viewHasTransparentContent = (color->mBackgroundFlags & + NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT; + + if (NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible) { + // If it's a scroll frame, then hide the view. This means that + // child elements can't override their parent's visibility, but + // it's not practical to leave it visible in all cases because + // the scrollbars will be showing + nsIAtom* frameType; + aFrame->GetFrameType(&frameType); + + if (frameType == nsLayoutAtoms::scrollFrame) { + viewIsVisible = PR_FALSE; + + } else { + // If it's a container element, then leave the view visible, but + // mark it as having transparent content. The reason we need to + // do this is that child elements can override their parent's + // hidden visibility and be visible anyway + nsIFrame* firstChild; + + aFrame->FirstChild(nsnull, &firstChild); + if (firstChild) { + // It's not a left frame, so the view needs to be visible, but + // marked as having transparent content + viewHasTransparentContent = PR_TRUE; + } else { + // It's a leaf frame so go ahead and hide the view + viewIsVisible = PR_FALSE; + } } - else { - // XXX??? how to deal with this??? Do we even have to? - } - aView->SetVisibility(nsViewVisibility_kHide); + NS_IF_RELEASE(frameType); } - else { - aView->SetVisibility(nsViewVisibility_kShow); - aViewManager->UpdateView(aView, nsnull, NS_VMREFRESH_NO_SYNC); + + // Make sure visibility is correct + aViewManager->SetViewVisibility(aView, viewIsVisible ? nsViewVisibility_kShow : + nsViewVisibility_kHide); + + // Make sure content transparency is correct + if (viewIsVisible) { + aViewManager->SetViewContentTransparency(aView, viewHasTransparentContent); } }