diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp
index b994b7335d9..f5eecbd09d6 100644
--- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp
+++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp
@@ -1575,34 +1575,15 @@ HTMLStyleSheetImpl::ConstructDocElementFrame(nsIPresContext* aPresContext,
// Unless the 'overflow' policy forbids scrolling, wrap the frame in a
// scroll frame.
- nsIFrame* scrollFrame = nsnull;
- nsStyleDisplay* display = (nsStyleDisplay*)
- styleContext->GetMutableStyleData(eStyleStruct_Display);
-
- // XXX This needs to go away... Yes, but where.
- // Check the webshell and see if scrolling is enabled there.
- nsISupports* container;
- if (nsnull != aPresContext) {
- aPresContext->GetContainer(&container);
- if (nsnull != container) {
- nsIWebShell* webShell = nsnull;
- container->QueryInterface(kIWebShellIID, (void**) &webShell);
- if (nsnull != webShell) {
- PRInt32 scrolling = -1;
- webShell->GetScrolling(scrolling);
- if (-1 != scrolling) {
- display->mOverflow = scrolling;
- }
- NS_RELEASE(webShell);
- }
- NS_RELEASE(container);
- }
- }
+ nsIFrame* scrollFrame = nsnull;
- if (NS_STYLE_OVERFLOW_HIDDEN != display->mOverflow) {
+ const nsStyleDisplay* display = (const nsStyleDisplay*)
+ styleContext->GetStyleData(eStyleStruct_Display);
+
+ if (IsScrollable(aPresContext, display)) {
NS_NewScrollFrame(scrollFrame);
scrollFrame->Init(*aPresContext, aDocElement, aRootFrame, styleContext);
-
+
// The scrolled frame gets a pseudo element style context
nsIStyleContext* scrolledPseudoStyle =
aPresContext->ResolvePseudoStyleContextFor(nsnull,
@@ -1656,50 +1637,105 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame)
{
#ifdef NS_DEBUG
- nsIDocument* doc;
- nsIContent* rootContent;
+ nsIDocument* doc;
+ nsIContent* rootContent;
- // Verify that the content object is really the root content object
- aDocElement->GetDocument(doc);
- rootContent = doc->GetRootContent();
- NS_RELEASE(doc);
- NS_ASSERTION(rootContent == aDocElement, "unexpected content");
- NS_RELEASE(rootContent);
+ // Verify that the content object is really the root content object
+ aDocElement->GetDocument(doc);
+ rootContent = doc->GetRootContent();
+ NS_RELEASE(doc);
+ NS_ASSERTION(rootContent == aDocElement, "unexpected content");
+ NS_RELEASE(rootContent);
#endif
- nsIFrame* rootFrame;
+ nsIFrame* viewportFrame;
nsIStyleContext* rootPseudoStyle;
- // Create the root frame
- NS_NewRootFrame(rootFrame);
-
+ // Create the viewport frame
+ NS_NewViewportFrame(viewportFrame);
+
// Create a pseudo element style context
+ // XXX Use a different pseudo style context...
rootPseudoStyle = aPresContext->ResolvePseudoStyleContextFor(nsnull,
nsHTMLAtoms::rootPseudo, nsnull);
- // Initialize the root frame. It has a NULL content object
- rootFrame->Init(*aPresContext, nsnull, nsnull, rootPseudoStyle);
+ // Initialize the viewport frame. It has a NULL content object
+ viewportFrame->Init(*aPresContext, nsnull, nsnull, rootPseudoStyle);
- // Bind the root frame to the root view
+ // Bind the viewport frame to the root view
nsIPresShell* presShell = aPresContext->GetShell();
nsIViewManager* viewManager = presShell->GetViewManager();
nsIView* rootView;
-
+
NS_RELEASE(presShell);
viewManager->GetRootView(rootView);
- rootFrame->SetView(rootView);
+ viewportFrame->SetView(rootView);
NS_RELEASE(viewManager);
-
+
+ // As long as the webshell doesn't prohibit it, create a scroll frame
+ // that will act as the scolling mechanism for the viewport
+ // XXX We should only do this when presenting to the screen, i.e., for galley
+ // mode and print-preview, but not when printing
+ PRBool isScrollable = PR_TRUE;
+ nsISupports* container;
+ if (nsnull != aPresContext) {
+ aPresContext->GetContainer(&container);
+ if (nsnull != container) {
+ nsIWebShell* webShell = nsnull;
+ container->QueryInterface(kIWebShellIID, (void**) &webShell);
+ if (nsnull != webShell) {
+ PRInt32 scrolling = -1;
+ webShell->GetScrolling(scrolling);
+ if (NS_STYLE_OVERFLOW_HIDDEN == scrolling) {
+ isScrollable = PR_FALSE;
+ }
+ NS_RELEASE(webShell);
+ }
+ NS_RELEASE(container);
+ }
+ }
+
+ // If the viewport should offer a scrolling mechanism, then create a
+ // scroll frame
+ nsIFrame* scrollFrame;
+ if (isScrollable) {
+ NS_NewScrollFrame(scrollFrame);
+ scrollFrame->Init(*aPresContext, nsnull, viewportFrame, rootPseudoStyle);
+ }
+
+ // Create the root frame. The document element's frame is a child of the
+ // root frame.
+ //
+ // Note: the major reason we need the root frame is to implement margins for
+ // the document element's frame. If we didn't need to support margins on the
+ // document element's frame, then we could eliminate the root frame and make
+ // the document element frame a child of the viewport (or its scroll frame)
+ nsIFrame* rootFrame;
+ NS_NewRootFrame(rootFrame);
+
+ rootFrame->Init(*aPresContext, nsnull, isScrollable ? scrollFrame :
+ viewportFrame, rootPseudoStyle);
+ if (isScrollable) {
+ nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, rootFrame,
+ rootPseudoStyle, PR_TRUE);
+ }
+
// Create frames for the document element and its child elements
nsIFrame* docElementFrame;
ConstructDocElementFrame(aPresContext, aDocElement, rootFrame,
rootPseudoStyle, docElementFrame);
NS_RELEASE(rootPseudoStyle);
- // Set the root frame's initial child list
+ // Set the initial child lists
rootFrame->SetInitialChildList(*aPresContext, nsnull, docElementFrame);
+ if (isScrollable) {
+ scrollFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame);
+ viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
+ } else {
+ viewportFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame);
+ }
- aNewFrame = rootFrame;
+ aNewFrame = viewportFrame;
return NS_OK;
}
@@ -2977,40 +3013,35 @@ HTMLStyleSheetImpl::ReconstructFrames(nsIPresContext* aPresContext,
return rv;
}
- // XXX Currently we only know how to do this for XML documents
if (nsnull != document) {
nsIPresShell* shell = aPresContext->GetShell();
-// nsIXMLDocument* xmlDocument;
-// rv = document->QueryInterface(kIXMLDocumentIID, (void **)&xmlDocument);
-
if (NS_SUCCEEDED(rv)) {
+ // XXX This API needs changing, because it appears to be designed for
+ // an arbitrary content element, but yet it always constructs the document
+ // element's frame. Plus it has the problem noted above in the previous XXX
rv = aParentFrame->RemoveFrame(*aPresContext, *shell,
nsnull, aFrameSubTree);
+
if (NS_SUCCEEDED(rv)) {
- nsIFrame *newChild;
- // XXX See ConstructXMLContents for an explanation of why
- // we create this pseudostyle
+ nsIFrame* newChild;
nsIStyleContext* rootPseudoStyle;
- rootPseudoStyle = aPresContext->ResolvePseudoStyleContextFor(nsnull,
- nsHTMLAtoms::rootPseudo, nsnull);
-
+
+ aParentFrame->GetStyleContext(rootPseudoStyle);
rv = ConstructDocElementFrame(aPresContext, aContent,
aParentFrame, rootPseudoStyle, newChild);
+ NS_RELEASE(rootPseudoStyle);
if (NS_SUCCEEDED(rv)) {
rv = aParentFrame->InsertFrames(*aPresContext, *shell,
nsnull, nsnull, newChild);
}
- NS_IF_RELEASE(rootPseudoStyle);
}
-// NS_RELEASE(xmlDocument);
}
NS_RELEASE(document);
NS_RELEASE(shell);
}
return rv;
-
}
nsIFrame*
diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp
index e6c6cb0c334..1be209360ce 100644
--- a/mozilla/layout/base/nsPresShell.cpp
+++ b/mozilla/layout/base/nsPresShell.cpp
@@ -1170,18 +1170,23 @@ PresShell::ReconstructFrames(void)
{
nsresult rv = NS_OK;
if (nsnull != mRootFrame) {
- nsIFrame* childFrame;
- rv = mRootFrame->FirstChild(nsnull, childFrame);
-
if (nsnull != mDocument) {
- nsIContent* root = mDocument->GetRootContent();
- if (nsnull != root) {
+ nsIContent* rootContent = mDocument->GetRootContent();
+ if (nsnull != rootContent) {
+ nsIFrame* docElementFrame;
+ nsIFrame* parentFrame;
- EnterReflowLock();
- rv = mStyleSet->ReconstructFrames(mPresContext, root,
- mRootFrame, childFrame);
- ExitReflowLock();
- NS_RELEASE(root);
+ // Get the frame that corresponds to the document element
+ GetPrimaryFrameFor(rootContent, docElementFrame);
+ if (nsnull != docElementFrame) {
+ docElementFrame->GetParent(parentFrame);
+
+ EnterReflowLock();
+ rv = mStyleSet->ReconstructFrames(mPresContext, rootContent,
+ parentFrame, docElementFrame);
+ ExitReflowLock();
+ NS_RELEASE(rootContent);
+ }
}
}
}
diff --git a/mozilla/layout/generic/nsHTMLFrame.cpp b/mozilla/layout/generic/nsHTMLFrame.cpp
index 8a11793d8ea..9db67e9caf2 100644
--- a/mozilla/layout/generic/nsHTMLFrame.cpp
+++ b/mozilla/layout/generic/nsHTMLFrame.cpp
@@ -71,8 +71,14 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
+ // XXX Temporary hack...
+ NS_IMETHOD SetRect(const nsRect& aRect);
+
protected:
virtual PRIntn GetSkipSides() const;
+
+private:
+ nscoord mNaturalHeight;
};
//----------------------------------------------------------------------
@@ -97,6 +103,27 @@ RootFrame::SetInitialChildList(nsIPresContext& aPresContext,
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(const nsRect& aRect)
+{
+ nsresult rv = nsHTMLContainerFrame::SetRect(aRect);
+
+ // Make sure our child's frame is adjusted as well
+ nsIFrame* kidFrame = mFrames.FirstChild();
+ if (nsnull != kidFrame) {
+ nscoord yDelta = aRect.height - mNaturalHeight;
+ nsSize kidSize;
+
+ kidFrame->GetSize(kidSize);
+ kidFrame->SizeTo(kidSize.width, kidSize.height + yDelta);
+ }
+
+ return rv;
+}
+
NS_IMETHODIMP
RootFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -162,23 +189,23 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
}
// Reflow our one and only child frame
+ nsHTMLReflowMetrics kidDesiredSize(nsnull);
if (mFrames.NotEmpty()) {
- nsIFrame* myOnlyChild = mFrames.FirstChild();
+ nsIFrame* kidFrame = mFrames.FirstChild();
- // Note: the root frame does not have border or padding...
- nsHTMLReflowMetrics desiredSize(nsnull);
// We must pass in that the available height is unconstrained, because
// constrained is only for when we're paginated...
- nsHTMLReflowState kidReflowState(aPresContext, myOnlyChild,
- aReflowState,
+ nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState,
nsSize(aReflowState.availableWidth, NS_UNCONSTRAINEDSIZE));
if (isChildInitialReflow) {
kidReflowState.reason = eReflowReason_Initial;
kidReflowState.reflowCommand = nsnull;
}
+ // XXX TROY
+#if 0
// For a height that's 'auto', make the frame as big as the available space
- // minus and top and bottom margins
+ // minus any top and bottom margins
if (NS_AUTOHEIGHT == kidReflowState.computedHeight) {
kidReflowState.computedHeight = aReflowState.availableHeight -
kidReflowState.computedMargin.top - kidReflowState.computedMargin.bottom;
@@ -189,20 +216,28 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
kidReflowState.ComputeBorderPaddingFor(myOnlyChild, &aReflowState, borderPadding);
kidReflowState.computedHeight -= borderPadding.top + borderPadding.bottom;
}
+#endif
// Reflow the frame
nsIHTMLReflow* htmlReflow;
- if (NS_OK == myOnlyChild->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
- ReflowChild(myOnlyChild, aPresContext, desiredSize, kidReflowState,
+ if (NS_OK == kidFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
+ // XXX Temporary hack until the block/inline code changes. It expects
+ // the available width to be the space minus any margins...
+ kidReflowState.availableWidth -= kidReflowState.computedMargin.left +
+ kidReflowState.computedMargin.right;
+ ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus);
nsRect rect(kidReflowState.computedMargin.left, kidReflowState.computedMargin.top,
- desiredSize.width, desiredSize.height);
- myOnlyChild->SetRect(rect);
+ kidDesiredSize.width, kidDesiredSize.height);
+ kidFrame->SetRect(rect);
+ // XXX TROY
+#if 0
// XXX We should resolve the details of who/when DidReflow()
// notifications are sent...
htmlReflow->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
+#endif
}
// If this is a resize reflow then do a repaint
@@ -210,13 +245,18 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
nsRect damageRect(0, 0, aReflowState.availableWidth, aReflowState.availableHeight);
Invalidate(damageRect, PR_FALSE);
}
- }
- // Return the max size as our desired size
- aDesiredSize.width = aReflowState.availableWidth;
- aDesiredSize.height = aReflowState.availableHeight;
- aDesiredSize.ascent = aDesiredSize.height;
- aDesiredSize.descent = 0;
+ // Return our desired size
+ aDesiredSize.width = kidDesiredSize.width + kidReflowState.computedMargin.left +
+ kidReflowState.computedMargin.right;
+ aDesiredSize.height = kidDesiredSize.height + kidReflowState.computedMargin.top +
+ kidReflowState.computedMargin.bottom;
+ aDesiredSize.ascent = aDesiredSize.height;
+ aDesiredSize.descent = 0;
+
+ // XXX Temporary hack. Remember this for later when our parent resizes us
+ mNaturalHeight = aDesiredSize.height;
+ }
NS_FRAME_TRACE_REFLOW_OUT("RootFrame::Reflow", aStatus);
return NS_OK;
diff --git a/mozilla/layout/generic/nsHTMLParts.h b/mozilla/layout/generic/nsHTMLParts.h
index 1a26e173d11..051012d9f91 100644
--- a/mozilla/layout/generic/nsHTMLParts.h
+++ b/mozilla/layout/generic/nsHTMLParts.h
@@ -254,6 +254,7 @@ extern nsresult NS_NewHTMLFrameOuterFrame(nsIFrame*& aNewFrame);
//