Fixes for bug #2552 and bug #10961

This commit is contained in:
troy%netscape.com 1999-09-26 20:40:29 +00:00
parent 2f6757146f
commit 9430750742
6 changed files with 296 additions and 72 deletions

View File

@ -6431,27 +6431,52 @@ SyncAndInvalidateView(nsIView* aView, nsIFrame* aFrame,
aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color); aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color);
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp); aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp);
// Set the view's opacity
aViewManager->SetViewOpacity(aView, color->mOpacity); 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 // See if the view should be hidden or visible
if (! viewVisible) { PRBool viewIsVisible = PR_TRUE;
nsIView* parentView = nsnull; PRBool viewHasTransparentContent = (color->mBackgroundFlags &
aView->GetParent(parentView); NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT;
if (parentView) {
nsRect bounds; if (NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible) {
aView->GetBounds(bounds); // If it's a scroll frame, then hide the view. This means that
aViewManager->UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC); // 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 { NS_IF_RELEASE(frameType);
// XXX??? how to deal with this??? Do we even have to?
}
aView->SetVisibility(nsViewVisibility_kHide);
} }
else {
aView->SetVisibility(nsViewVisibility_kShow); // Make sure visibility is correct
aViewManager->UpdateView(aView, nsnull, NS_VMREFRESH_NO_SYNC); aViewManager->SetViewVisibility(aView, viewIsVisible ? nsViewVisibility_kShow :
nsViewVisibility_kHide);
// Make sure content transparency is correct
if (viewIsVisible) {
aViewManager->SetViewContentTransparency(aView, viewHasTransparentContent);
} }
} }

View File

@ -1093,22 +1093,77 @@ nsFrame::DidReflow(nsIPresContext& aPresContext,
if (NS_FRAME_REFLOW_FINISHED == aStatus) { if (NS_FRAME_REFLOW_FINISHED == aStatus) {
mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY); mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY);
// Size and position the view if requested // Make sure the view is sized and positioned correctly and it's
if ((nsnull != mView) && (NS_FRAME_SYNC_FRAME_AND_VIEW & mState)) { // visibility, opacity, content transparency, and clip are correct
// Position and size view relative to its parent, not relative to our if (mView) {
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
GetOffsetFromView(origin, &parentWithView);
nsIViewManager *vm; nsIViewManager *vm;
mView->GetViewManager(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 const nsStyleColor* color =
// set to other than 'visible' (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
const nsStyleDisplay* display = const nsStyleDisplay* display =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_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->IsBlockLevel()) {
if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) { if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) {
nscoord left, top, right, bottom; nscoord left, top, right, bottom;

View File

@ -387,7 +387,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
view->Init(viewManager, bounds, parentView); view->Init(viewManager, bounds, parentView);
// If the frame has a fixed background attachment, then indicate that the // 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) { if (fixedBackgroundAttachment) {
PRUint32 viewFlags; PRUint32 viewFlags;
view->GetViewFlags(&viewFlags); view->GetViewFlags(&viewFlags);
@ -403,13 +403,45 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
viewManager->InsertChild(parentView, view, zIndex); viewManager->InsertChild(parentView, view, zIndex);
} }
// If the background color is transparent or the visibility is hidden, // See if the view should be hidden
// then mark the view as having transparent content. The reason we PRBool viewIsVisible = PR_TRUE;
// need to do it for hidden visibility is that child elements can PRBool viewHasTransparentContent = (color->mBackgroundFlags &
// override their parent's visibility and be visible. NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT;
if ((NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags) ||
(NS_STYLE_VISIBILITY_HIDDEN == display->mVisible)) { if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) {
viewManager->SetViewContentTransparency(view, PR_TRUE); // 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 // XXX If it's fixed positioned, then create a widget so it floats

View File

@ -1093,22 +1093,77 @@ nsFrame::DidReflow(nsIPresContext& aPresContext,
if (NS_FRAME_REFLOW_FINISHED == aStatus) { if (NS_FRAME_REFLOW_FINISHED == aStatus) {
mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY); mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY);
// Size and position the view if requested // Make sure the view is sized and positioned correctly and it's
if ((nsnull != mView) && (NS_FRAME_SYNC_FRAME_AND_VIEW & mState)) { // visibility, opacity, content transparency, and clip are correct
// Position and size view relative to its parent, not relative to our if (mView) {
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
GetOffsetFromView(origin, &parentWithView);
nsIViewManager *vm; nsIViewManager *vm;
mView->GetViewManager(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 const nsStyleColor* color =
// set to other than 'visible' (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
const nsStyleDisplay* display = const nsStyleDisplay* display =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_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->IsBlockLevel()) {
if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) { if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) {
nscoord left, top, right, bottom; nscoord left, top, right, bottom;

View File

@ -387,7 +387,7 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
view->Init(viewManager, bounds, parentView); view->Init(viewManager, bounds, parentView);
// If the frame has a fixed background attachment, then indicate that the // 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) { if (fixedBackgroundAttachment) {
PRUint32 viewFlags; PRUint32 viewFlags;
view->GetViewFlags(&viewFlags); view->GetViewFlags(&viewFlags);
@ -403,13 +403,45 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
viewManager->InsertChild(parentView, view, zIndex); viewManager->InsertChild(parentView, view, zIndex);
} }
// If the background color is transparent or the visibility is hidden, // See if the view should be hidden
// then mark the view as having transparent content. The reason we PRBool viewIsVisible = PR_TRUE;
// need to do it for hidden visibility is that child elements can PRBool viewHasTransparentContent = (color->mBackgroundFlags &
// override their parent's visibility and be visible. NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT;
if ((NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags) ||
(NS_STYLE_VISIBILITY_HIDDEN == display->mVisible)) { if (NS_STYLE_VISIBILITY_HIDDEN == display->mVisible) {
viewManager->SetViewContentTransparency(view, PR_TRUE); // 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 // XXX If it's fixed positioned, then create a widget so it floats

View File

@ -6431,27 +6431,52 @@ SyncAndInvalidateView(nsIView* aView, nsIFrame* aFrame,
aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color); aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color);
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp); aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp);
// Set the view's opacity
aViewManager->SetViewOpacity(aView, color->mOpacity); 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 // See if the view should be hidden or visible
if (! viewVisible) { PRBool viewIsVisible = PR_TRUE;
nsIView* parentView = nsnull; PRBool viewHasTransparentContent = (color->mBackgroundFlags &
aView->GetParent(parentView); NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT;
if (parentView) {
nsRect bounds; if (NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible) {
aView->GetBounds(bounds); // If it's a scroll frame, then hide the view. This means that
aViewManager->UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC); // 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 { NS_IF_RELEASE(frameType);
// XXX??? how to deal with this??? Do we even have to?
}
aView->SetVisibility(nsViewVisibility_kHide);
} }
else {
aView->SetVisibility(nsViewVisibility_kShow); // Make sure visibility is correct
aViewManager->UpdateView(aView, nsnull, NS_VMREFRESH_NO_SYNC); aViewManager->SetViewVisibility(aView, viewIsVisible ? nsViewVisibility_kShow :
nsViewVisibility_kHide);
// Make sure content transparency is correct
if (viewIsVisible) {
aViewManager->SetViewContentTransparency(aView, viewHasTransparentContent);
} }
} }