diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index bc45c28c13d..d929b923861 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -3062,6 +3062,40 @@ nsCSSFrameConstructor::ConstructDocElementTableFrame(nsIPresShell* aPresS return NS_OK; } +static PRBool +IsCanvasFrame(nsIFrame* aFrame) +{ + nsCOMPtr parentType; + + aFrame->GetFrameType(getter_AddRefs(parentType)); + return parentType.get() == nsLayoutAtoms::canvasFrame; +} + +static void +PropagateBackgroundToParent(nsIStyleContext* aStyleContext, + const nsStyleColor* aColor, + nsIStyleContext* aParentStyleContext) +{ + nsStyleColor* mutableColor; + mutableColor = (nsStyleColor*)aParentStyleContext->GetMutableStyleData(eStyleStruct_Color); + + mutableColor->mBackgroundAttachment = aColor->mBackgroundAttachment; + mutableColor->mBackgroundFlags = aColor->mBackgroundFlags | NS_STYLE_BG_PROPAGATED_FROM_CHILD; + mutableColor->mBackgroundRepeat = aColor->mBackgroundRepeat; + mutableColor->mBackgroundColor = aColor->mBackgroundColor; + mutableColor->mBackgroundXPosition = aColor->mBackgroundXPosition; + mutableColor->mBackgroundYPosition = aColor->mBackgroundYPosition; + mutableColor->mBackgroundImage = aColor->mBackgroundImage; + + // Reset the BODY's background to transparent + mutableColor = (nsStyleColor*)aStyleContext->GetMutableStyleData(eStyleStruct_Color); + mutableColor->mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | + NS_STYLE_BG_IMAGE_NONE | + NS_STYLE_BG_PROPAGATED_TO_PARENT; + mutableColor->mBackgroundImage.SetLength(0); + mutableColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; +} + /** * New one */ @@ -3141,6 +3175,8 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, const nsStyleDisplay* display = (const nsStyleDisplay*)styleContext->GetStyleData(eStyleStruct_Display); + const nsStyleColor* color = + (const nsStyleColor*)styleContext->GetStyleData(eStyleStruct_Color); PRBool docElemIsTable = IsTableRelated(display->mDisplay); @@ -3249,8 +3285,6 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, // Note: the reason we wait until after processing the document element's // children is because of special treatment of the background for the HTML // element. See BodyFixupRule::MapStyleInto() for details - const nsStyleColor* color; - color = (const nsStyleColor*)styleContext->GetStyleData(eStyleStruct_Color); if (NS_STYLE_BG_ATTACHMENT_FIXED == color->mBackgroundAttachment) { // Fixed background attachments are handled by setting the // NS_VIEW_PUBLIC_FLAG_DONT_BITBLT flag bit on the view. @@ -3299,6 +3333,19 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, aState.mFloatedItems.childList); } } + + // Section 14.2 of the CSS2 spec says that the background of the root element + // covers the entire canvas. See if a background was specified for the root + // element + if (!color->BackgroundIsTransparent() && IsCanvasFrame(aParentFrame)) { + nsIStyleContext* parentContext; + + // Propagate the document element's background to the canvas so that it + // renders the background over the entire canvas + aParentFrame->GetStyleContext(&parentContext); + PropagateBackgroundToParent(styleContext, color, parentContext); + NS_RELEASE(parentContext); + } } return NS_OK; @@ -3402,7 +3449,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell, // // The root frame serves two purposes: // - reserves space for any margins needed for the document element's frame - // - makes sure that the document element's frame covers the entire canvas + // - renders the document element's background. This ensures the background covers + // the entire canvas as specified by the CSS2 spec PRBool isPaginated = PR_FALSE; aPresContext->IsPaginated(&isPaginated); @@ -3416,7 +3464,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell, { NS_NewRootBoxFrame(aPresShell, &rootFrame); } else { - NS_NewRootFrame(aPresShell, &rootFrame); + NS_NewCanvasFrame(aPresShell, &rootFrame); } rootPseudo = nsLayoutAtoms::canvasPseudo; diff --git a/mozilla/layout/base/nsFrameTraversal.cpp b/mozilla/layout/base/nsFrameTraversal.cpp index a17e20edc31..27fcc27f7c2 100644 --- a/mozilla/layout/base/nsFrameTraversal.cpp +++ b/mozilla/layout/base/nsFrameTraversal.cpp @@ -208,7 +208,15 @@ nsLeafIterator::nsLeafIterator(nsIPresContext* aPresContext, nsIFrame *aStart) setLast(aStart); } - +static PRBool +IsRootFrame(nsIFrame* aFrame) +{ + nsCOMPtratom; + + aFrame->GetFrameType(getter_AddRefs(atom)); + return (atom.get() == nsLayoutAtoms::canvasFrame) || + (atom.get() == nsLayoutAtoms::rootFrame); +} NS_IMETHODIMP nsLeafIterator::Next() @@ -230,8 +238,7 @@ nsLeafIterator::Next() result = parent; } else { - nsCOMPtratom; - while(parent && NS_SUCCEEDED(parent->GetFrameType(getter_AddRefs(atom))) && atom.get() != nsLayoutAtoms::rootFrame){ + while(parent && !IsRootFrame(parent)) { if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){ parent = result; while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result) @@ -242,7 +249,9 @@ nsLeafIterator::Next() break; } else - if (NS_FAILED(parent->GetParent(&result)) || !result || (NS_SUCCEEDED(result->GetFrameType(getter_AddRefs(atom))) && atom.get() == nsLayoutAtoms::rootFrame)){ + { + parent->GetParent(&result); + if (!result || IsRootFrame(result)) { result = nsnull; break; } @@ -252,6 +261,7 @@ nsLeafIterator::Next() if (mExtensive) break; } + } } } setCurrent(result); diff --git a/mozilla/layout/base/src/nsFrameTraversal.cpp b/mozilla/layout/base/src/nsFrameTraversal.cpp index a17e20edc31..27fcc27f7c2 100644 --- a/mozilla/layout/base/src/nsFrameTraversal.cpp +++ b/mozilla/layout/base/src/nsFrameTraversal.cpp @@ -208,7 +208,15 @@ nsLeafIterator::nsLeafIterator(nsIPresContext* aPresContext, nsIFrame *aStart) setLast(aStart); } - +static PRBool +IsRootFrame(nsIFrame* aFrame) +{ + nsCOMPtratom; + + aFrame->GetFrameType(getter_AddRefs(atom)); + return (atom.get() == nsLayoutAtoms::canvasFrame) || + (atom.get() == nsLayoutAtoms::rootFrame); +} NS_IMETHODIMP nsLeafIterator::Next() @@ -230,8 +238,7 @@ nsLeafIterator::Next() result = parent; } else { - nsCOMPtratom; - while(parent && NS_SUCCEEDED(parent->GetFrameType(getter_AddRefs(atom))) && atom.get() != nsLayoutAtoms::rootFrame){ + while(parent && !IsRootFrame(parent)) { if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){ parent = result; while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result) @@ -242,7 +249,9 @@ nsLeafIterator::Next() break; } else - if (NS_FAILED(parent->GetParent(&result)) || !result || (NS_SUCCEEDED(result->GetFrameType(getter_AddRefs(atom))) && atom.get() == nsLayoutAtoms::rootFrame)){ + { + parent->GetParent(&result); + if (!result || IsRootFrame(result)) { result = nsnull; break; } @@ -252,6 +261,7 @@ nsLeafIterator::Next() if (mExtensive) break; } + } } } setCurrent(result); diff --git a/mozilla/layout/build/dlldeps.cpp b/mozilla/layout/build/dlldeps.cpp index 08a4c514a37..a6746b1be37 100644 --- a/mozilla/layout/build/dlldeps.cpp +++ b/mozilla/layout/build/dlldeps.cpp @@ -53,7 +53,7 @@ void XXXNeverCalled() NS_NewObjectFrame(ps, &f); NS_NewSpacerFrame(ps, &f); NS_NewHTMLFramesetFrame(ps, &f); - NS_NewRootFrame(ps, &f); + NS_NewCanvasFrame(ps, &f); NS_NewScrollFrame(ps, &f); NS_NewSimplePageSequenceFrame(ps, &f); nsINameSpaceManager* nsm; diff --git a/mozilla/layout/generic/nsHTMLFrame.cpp b/mozilla/layout/generic/nsHTMLFrame.cpp index a2e7a3c080f..d16b29f0532 100644 --- a/mozilla/layout/generic/nsHTMLFrame.cpp +++ b/mozilla/layout/generic/nsHTMLFrame.cpp @@ -55,7 +55,7 @@ static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID); * It only supports having a single child frame which must be an area * frame */ -class RootFrame : public nsHTMLContainerFrame { +class CanvasFrame : public nsHTMLContainerFrame { public: NS_IMETHOD AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, @@ -90,7 +90,7 @@ public: /** * Get the "type" of the frame * - * @see nsLayoutAtoms::rootFrame + * @see nsLayoutAtoms::canvasFrame */ NS_IMETHOD GetFrameType(nsIAtom** aType) const; @@ -99,26 +99,20 @@ public: NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; #endif - // XXX Temporary hack... - NS_IMETHOD SetRect(nsIPresContext* aPresContext, const nsRect& aRect); - protected: virtual PRIntn GetSkipSides() const; - -private: - nscoord mNaturalHeight; }; //---------------------------------------------------------------------- nsresult -NS_NewRootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +NS_NewCanvasFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { NS_PRECONDITION(aNewFrame, "null OUT ptr"); if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - RootFrame* it = new (aPresShell) RootFrame; + CanvasFrame* it = new (aPresShell)CanvasFrame; if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -126,41 +120,11 @@ NS_NewRootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -// XXX Temporary hack until we support the CSS2 'min-width', 'max-width', -// 'min-height', and 'max-height' properties. Then we can do this in a top-down -// fashion NS_IMETHODIMP -RootFrame::SetRect(nsIPresContext* aPresContext, const nsRect& aRect) -{ - nsresult rv = nsHTMLContainerFrame::SetRect(aPresContext, aRect); - - // If our height is larger than our natural height (the height we returned - // as our desired height), then make sure the document element's frame is - // increased as well. This happens because the scroll frame will make sure - // that our height fills the entire scroll area. - // Note: only do this if the document element's 'height' is 'auto' - nsIFrame* kidFrame = mFrames.FirstChild(); - if (nsnull != kidFrame) { - nsStylePosition* kidPosition; - kidFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)kidPosition); - - if (eStyleUnit_Auto == kidPosition->mHeight.GetUnit()) { - nscoord yDelta = aRect.height - mNaturalHeight; - nsSize kidSize; - - kidFrame->GetSize(kidSize); - kidFrame->SizeTo(aPresContext, kidSize.width, kidSize.height + yDelta); - } - } - - return rv; -} - -NS_IMETHODIMP -RootFrame::AppendFrames(nsIPresContext* aPresContext, - nsIPresShell& aPresShell, - nsIAtom* aListName, - nsIFrame* aFrameList) +CanvasFrame::AppendFrames(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList) { nsresult rv; @@ -194,11 +158,11 @@ RootFrame::AppendFrames(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::InsertFrames(nsIPresContext* aPresContext, - nsIPresShell& aPresShell, - nsIAtom* aListName, - nsIFrame* aPrevFrame, - nsIFrame* aFrameList) +CanvasFrame::InsertFrames(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList) { nsresult rv; @@ -215,10 +179,10 @@ RootFrame::InsertFrames(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::RemoveFrame(nsIPresContext* aPresContext, - nsIPresShell& aPresShell, - nsIAtom* aListName, - nsIFrame* aOldFrame) +CanvasFrame::RemoveFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame) { nsresult rv; @@ -253,12 +217,12 @@ RootFrame::RemoveFrame(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) +CanvasFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) { - NS_FRAME_TRACE_REFLOW_IN("RootFrame::Reflow"); + NS_FRAME_TRACE_REFLOW_IN("CanvasFrame::Reflow"); NS_PRECONDITION(nsnull == aDesiredSize.maxElementSize, "unexpected request"); // Initialize OUT parameter @@ -389,26 +353,22 @@ RootFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.descent = 0; // XXX Don't completely ignore NS_FRAME_OUTSIDE_CHILDREN for child frames // that stick out on the left or top edges... - - // XXX Temporary hack. Remember this for later when our parent resizes us. - // See SetRect() - mNaturalHeight = aDesiredSize.height; } - NS_FRAME_TRACE_REFLOW_OUT("RootFrame::Reflow", aStatus); + NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus); return NS_OK; } PRIntn -RootFrame::GetSkipSides() const +CanvasFrame::GetSkipSides() const { return 0; } NS_IMETHODIMP -RootFrame::HandleEvent(nsIPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +CanvasFrame::HandleEvent(nsIPresContext* aPresContext, + nsGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { @@ -421,7 +381,7 @@ RootFrame::HandleEvent(nsIPresContext* aPresContext, aEvent->message == NS_MOUSE_MOVE ) { nsIFrame *firstChild; nsresult rv = FirstChild(aPresContext,nsnull,&firstChild); - //root frame needs to pass mouse events to its area frame so that mouse movement + //canvas frame needs to pass mouse events to its area frame so that mouse movement //and selection code will work properly. this will still have the necessary effects //that would have happened if nsFrame::HandleEvent was called. if (NS_SUCCEEDED(rv) && firstChild) @@ -434,33 +394,33 @@ RootFrame::HandleEvent(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::GetFrameForPoint(nsIPresContext* aPresContext, - const nsPoint& aPoint, - nsFramePaintLayer aWhichLayer, - nsIFrame** aFrame) +CanvasFrame::GetFrameForPoint(nsIPresContext* aPresContext, + const nsPoint& aPoint, + nsFramePaintLayer aWhichLayer, + nsIFrame** aFrame) { // this should act like a block, so we need to override return GetFrameForPointUsing(aPresContext, aPoint, nsnull, aWhichLayer, (aWhichLayer == NS_FRAME_PAINT_LAYER_BACKGROUND), aFrame); } NS_IMETHODIMP -RootFrame::GetFrameType(nsIAtom** aType) const +CanvasFrame::GetFrameType(nsIAtom** aType) const { NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); - *aType = nsLayoutAtoms::rootFrame; + *aType = nsLayoutAtoms::canvasFrame; NS_ADDREF(*aType); return NS_OK; } #ifdef DEBUG NS_IMETHODIMP -RootFrame::GetFrameName(nsString& aResult) const +CanvasFrame::GetFrameName(nsString& aResult) const { - return MakeFrameName("Root", aResult); + return MakeFrameName("Canvas", aResult); } NS_IMETHODIMP -RootFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const +CanvasFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { if (!aResult) { return NS_ERROR_NULL_POINTER; diff --git a/mozilla/layout/generic/nsHTMLParts.h b/mozilla/layout/generic/nsHTMLParts.h index 8b9724d3b04..2753e3e1e12 100644 --- a/mozilla/layout/generic/nsHTMLParts.h +++ b/mozilla/layout/generic/nsHTMLParts.h @@ -327,7 +327,7 @@ extern nsresult NS_NewHTMLFrameOuterFrame(nsIPresShell* aPresShell, nsIFrame** a extern nsresult NS_NewHTMLFramesetFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); extern nsresult NS_NewViewportFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); -extern nsresult NS_NewRootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); +extern nsresult NS_NewCanvasFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); extern nsresult NS_NewImageFrame(nsIPresShell* aPresShell, nsIFrame** aFrameResult); extern nsresult NS_NewInlineFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); extern nsresult NS_NewPositionedInlineFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); diff --git a/mozilla/layout/html/base/src/nsHTMLFrame.cpp b/mozilla/layout/html/base/src/nsHTMLFrame.cpp index a2e7a3c080f..d16b29f0532 100644 --- a/mozilla/layout/html/base/src/nsHTMLFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLFrame.cpp @@ -55,7 +55,7 @@ static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID); * It only supports having a single child frame which must be an area * frame */ -class RootFrame : public nsHTMLContainerFrame { +class CanvasFrame : public nsHTMLContainerFrame { public: NS_IMETHOD AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, @@ -90,7 +90,7 @@ public: /** * Get the "type" of the frame * - * @see nsLayoutAtoms::rootFrame + * @see nsLayoutAtoms::canvasFrame */ NS_IMETHOD GetFrameType(nsIAtom** aType) const; @@ -99,26 +99,20 @@ public: NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; #endif - // XXX Temporary hack... - NS_IMETHOD SetRect(nsIPresContext* aPresContext, const nsRect& aRect); - protected: virtual PRIntn GetSkipSides() const; - -private: - nscoord mNaturalHeight; }; //---------------------------------------------------------------------- nsresult -NS_NewRootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +NS_NewCanvasFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { NS_PRECONDITION(aNewFrame, "null OUT ptr"); if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - RootFrame* it = new (aPresShell) RootFrame; + CanvasFrame* it = new (aPresShell)CanvasFrame; if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -126,41 +120,11 @@ NS_NewRootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -// XXX Temporary hack until we support the CSS2 'min-width', 'max-width', -// 'min-height', and 'max-height' properties. Then we can do this in a top-down -// fashion NS_IMETHODIMP -RootFrame::SetRect(nsIPresContext* aPresContext, const nsRect& aRect) -{ - nsresult rv = nsHTMLContainerFrame::SetRect(aPresContext, aRect); - - // If our height is larger than our natural height (the height we returned - // as our desired height), then make sure the document element's frame is - // increased as well. This happens because the scroll frame will make sure - // that our height fills the entire scroll area. - // Note: only do this if the document element's 'height' is 'auto' - nsIFrame* kidFrame = mFrames.FirstChild(); - if (nsnull != kidFrame) { - nsStylePosition* kidPosition; - kidFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)kidPosition); - - if (eStyleUnit_Auto == kidPosition->mHeight.GetUnit()) { - nscoord yDelta = aRect.height - mNaturalHeight; - nsSize kidSize; - - kidFrame->GetSize(kidSize); - kidFrame->SizeTo(aPresContext, kidSize.width, kidSize.height + yDelta); - } - } - - return rv; -} - -NS_IMETHODIMP -RootFrame::AppendFrames(nsIPresContext* aPresContext, - nsIPresShell& aPresShell, - nsIAtom* aListName, - nsIFrame* aFrameList) +CanvasFrame::AppendFrames(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList) { nsresult rv; @@ -194,11 +158,11 @@ RootFrame::AppendFrames(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::InsertFrames(nsIPresContext* aPresContext, - nsIPresShell& aPresShell, - nsIAtom* aListName, - nsIFrame* aPrevFrame, - nsIFrame* aFrameList) +CanvasFrame::InsertFrames(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList) { nsresult rv; @@ -215,10 +179,10 @@ RootFrame::InsertFrames(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::RemoveFrame(nsIPresContext* aPresContext, - nsIPresShell& aPresShell, - nsIAtom* aListName, - nsIFrame* aOldFrame) +CanvasFrame::RemoveFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame) { nsresult rv; @@ -253,12 +217,12 @@ RootFrame::RemoveFrame(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) +CanvasFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) { - NS_FRAME_TRACE_REFLOW_IN("RootFrame::Reflow"); + NS_FRAME_TRACE_REFLOW_IN("CanvasFrame::Reflow"); NS_PRECONDITION(nsnull == aDesiredSize.maxElementSize, "unexpected request"); // Initialize OUT parameter @@ -389,26 +353,22 @@ RootFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.descent = 0; // XXX Don't completely ignore NS_FRAME_OUTSIDE_CHILDREN for child frames // that stick out on the left or top edges... - - // XXX Temporary hack. Remember this for later when our parent resizes us. - // See SetRect() - mNaturalHeight = aDesiredSize.height; } - NS_FRAME_TRACE_REFLOW_OUT("RootFrame::Reflow", aStatus); + NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus); return NS_OK; } PRIntn -RootFrame::GetSkipSides() const +CanvasFrame::GetSkipSides() const { return 0; } NS_IMETHODIMP -RootFrame::HandleEvent(nsIPresContext* aPresContext, - nsGUIEvent* aEvent, - nsEventStatus* aEventStatus) +CanvasFrame::HandleEvent(nsIPresContext* aPresContext, + nsGUIEvent* aEvent, + nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { @@ -421,7 +381,7 @@ RootFrame::HandleEvent(nsIPresContext* aPresContext, aEvent->message == NS_MOUSE_MOVE ) { nsIFrame *firstChild; nsresult rv = FirstChild(aPresContext,nsnull,&firstChild); - //root frame needs to pass mouse events to its area frame so that mouse movement + //canvas frame needs to pass mouse events to its area frame so that mouse movement //and selection code will work properly. this will still have the necessary effects //that would have happened if nsFrame::HandleEvent was called. if (NS_SUCCEEDED(rv) && firstChild) @@ -434,33 +394,33 @@ RootFrame::HandleEvent(nsIPresContext* aPresContext, } NS_IMETHODIMP -RootFrame::GetFrameForPoint(nsIPresContext* aPresContext, - const nsPoint& aPoint, - nsFramePaintLayer aWhichLayer, - nsIFrame** aFrame) +CanvasFrame::GetFrameForPoint(nsIPresContext* aPresContext, + const nsPoint& aPoint, + nsFramePaintLayer aWhichLayer, + nsIFrame** aFrame) { // this should act like a block, so we need to override return GetFrameForPointUsing(aPresContext, aPoint, nsnull, aWhichLayer, (aWhichLayer == NS_FRAME_PAINT_LAYER_BACKGROUND), aFrame); } NS_IMETHODIMP -RootFrame::GetFrameType(nsIAtom** aType) const +CanvasFrame::GetFrameType(nsIAtom** aType) const { NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); - *aType = nsLayoutAtoms::rootFrame; + *aType = nsLayoutAtoms::canvasFrame; NS_ADDREF(*aType); return NS_OK; } #ifdef DEBUG NS_IMETHODIMP -RootFrame::GetFrameName(nsString& aResult) const +CanvasFrame::GetFrameName(nsString& aResult) const { - return MakeFrameName("Root", aResult); + return MakeFrameName("Canvas", aResult); } NS_IMETHODIMP -RootFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const +CanvasFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { if (!aResult) { return NS_ERROR_NULL_POINTER; diff --git a/mozilla/layout/html/base/src/nsHTMLParts.h b/mozilla/layout/html/base/src/nsHTMLParts.h index 8b9724d3b04..2753e3e1e12 100644 --- a/mozilla/layout/html/base/src/nsHTMLParts.h +++ b/mozilla/layout/html/base/src/nsHTMLParts.h @@ -327,7 +327,7 @@ extern nsresult NS_NewHTMLFrameOuterFrame(nsIPresShell* aPresShell, nsIFrame** a extern nsresult NS_NewHTMLFramesetFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); extern nsresult NS_NewViewportFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); -extern nsresult NS_NewRootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); +extern nsresult NS_NewCanvasFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); extern nsresult NS_NewImageFrame(nsIPresShell* aPresShell, nsIFrame** aFrameResult); extern nsresult NS_NewInlineFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); extern nsresult NS_NewPositionedInlineFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index bc45c28c13d..d929b923861 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -3062,6 +3062,40 @@ nsCSSFrameConstructor::ConstructDocElementTableFrame(nsIPresShell* aPresS return NS_OK; } +static PRBool +IsCanvasFrame(nsIFrame* aFrame) +{ + nsCOMPtr parentType; + + aFrame->GetFrameType(getter_AddRefs(parentType)); + return parentType.get() == nsLayoutAtoms::canvasFrame; +} + +static void +PropagateBackgroundToParent(nsIStyleContext* aStyleContext, + const nsStyleColor* aColor, + nsIStyleContext* aParentStyleContext) +{ + nsStyleColor* mutableColor; + mutableColor = (nsStyleColor*)aParentStyleContext->GetMutableStyleData(eStyleStruct_Color); + + mutableColor->mBackgroundAttachment = aColor->mBackgroundAttachment; + mutableColor->mBackgroundFlags = aColor->mBackgroundFlags | NS_STYLE_BG_PROPAGATED_FROM_CHILD; + mutableColor->mBackgroundRepeat = aColor->mBackgroundRepeat; + mutableColor->mBackgroundColor = aColor->mBackgroundColor; + mutableColor->mBackgroundXPosition = aColor->mBackgroundXPosition; + mutableColor->mBackgroundYPosition = aColor->mBackgroundYPosition; + mutableColor->mBackgroundImage = aColor->mBackgroundImage; + + // Reset the BODY's background to transparent + mutableColor = (nsStyleColor*)aStyleContext->GetMutableStyleData(eStyleStruct_Color); + mutableColor->mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | + NS_STYLE_BG_IMAGE_NONE | + NS_STYLE_BG_PROPAGATED_TO_PARENT; + mutableColor->mBackgroundImage.SetLength(0); + mutableColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; +} + /** * New one */ @@ -3141,6 +3175,8 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, const nsStyleDisplay* display = (const nsStyleDisplay*)styleContext->GetStyleData(eStyleStruct_Display); + const nsStyleColor* color = + (const nsStyleColor*)styleContext->GetStyleData(eStyleStruct_Color); PRBool docElemIsTable = IsTableRelated(display->mDisplay); @@ -3249,8 +3285,6 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, // Note: the reason we wait until after processing the document element's // children is because of special treatment of the background for the HTML // element. See BodyFixupRule::MapStyleInto() for details - const nsStyleColor* color; - color = (const nsStyleColor*)styleContext->GetStyleData(eStyleStruct_Color); if (NS_STYLE_BG_ATTACHMENT_FIXED == color->mBackgroundAttachment) { // Fixed background attachments are handled by setting the // NS_VIEW_PUBLIC_FLAG_DONT_BITBLT flag bit on the view. @@ -3299,6 +3333,19 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell, aState.mFloatedItems.childList); } } + + // Section 14.2 of the CSS2 spec says that the background of the root element + // covers the entire canvas. See if a background was specified for the root + // element + if (!color->BackgroundIsTransparent() && IsCanvasFrame(aParentFrame)) { + nsIStyleContext* parentContext; + + // Propagate the document element's background to the canvas so that it + // renders the background over the entire canvas + aParentFrame->GetStyleContext(&parentContext); + PropagateBackgroundToParent(styleContext, color, parentContext); + NS_RELEASE(parentContext); + } } return NS_OK; @@ -3402,7 +3449,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell, // // The root frame serves two purposes: // - reserves space for any margins needed for the document element's frame - // - makes sure that the document element's frame covers the entire canvas + // - renders the document element's background. This ensures the background covers + // the entire canvas as specified by the CSS2 spec PRBool isPaginated = PR_FALSE; aPresContext->IsPaginated(&isPaginated); @@ -3416,7 +3464,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell, { NS_NewRootBoxFrame(aPresShell, &rootFrame); } else { - NS_NewRootFrame(aPresShell, &rootFrame); + NS_NewCanvasFrame(aPresShell, &rootFrame); } rootPseudo = nsLayoutAtoms::canvasPseudo;