зеркало из https://github.com/mozilla/pjs.git
Changed scrolling so it happens on the viewport instead of the HTML
element
This commit is contained in:
Родитель
d39e9d41ac
Коммит
b145640f92
|
@ -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*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -254,6 +254,7 @@ extern nsresult NS_NewHTMLFrameOuterFrame(nsIFrame*& aNewFrame);
|
|||
// <frameset>
|
||||
extern nsresult NS_NewHTMLFramesetFrame(nsIFrame*& aNewFrame);
|
||||
|
||||
extern nsresult NS_NewViewportFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewRootFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewImageFrame(nsIFrame*& aFrameResult);
|
||||
extern nsresult NS_NewInlineFrame(nsIFrame*& aNewFrame);
|
||||
|
|
|
@ -1 +1,128 @@
|
|||
// Just a placeholder for the time being...
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#include "nsHTMLParts.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
|
||||
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
||||
|
||||
/**
|
||||
* Viewport frame class.
|
||||
*
|
||||
* The viewport frame is the parent frame for the document element's frame.
|
||||
* It only supports having a single child frame which must be one of the
|
||||
* following:
|
||||
* - scroll frame
|
||||
* - root frame
|
||||
*
|
||||
* It has an additional named child list:
|
||||
* - "Fixed-list" which contains the fixed positioned frames
|
||||
*/
|
||||
class ViewportFrame : public nsContainerFrame {
|
||||
public:
|
||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewViewportFrame(nsIFrame*& aResult)
|
||||
{
|
||||
ViewportFrame* frame = new ViewportFrame;
|
||||
if (nsnull == frame) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aResult = frame;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ViewportFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
NS_FRAME_TRACE_REFLOW_IN("ViewportFrame::Reflow");
|
||||
NS_PRECONDITION(nsnull == aDesiredSize.maxElementSize, "unexpected request");
|
||||
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// Check for an incremental reflow
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
// See if we're the target frame
|
||||
nsIFrame* targetFrame;
|
||||
aReflowState.reflowCommand->GetTarget(targetFrame);
|
||||
if (this == targetFrame) {
|
||||
// The viewport does not support being the target of an incremental
|
||||
// reflow command
|
||||
NS_ASSERTION(PR_FALSE, "unexpected reflow command target");
|
||||
|
||||
} else {
|
||||
nsIFrame* nextFrame;
|
||||
// Get the next frame in the reflow chain
|
||||
aReflowState.reflowCommand->GetNext(nextFrame);
|
||||
NS_ASSERTION(nextFrame == mFrames.FirstChild(), "unexpected next reflow command frame");
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow our one and only child frame
|
||||
if (mFrames.NotEmpty()) {
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
nsSize availableSpace(aReflowState.availableWidth,
|
||||
aReflowState.availableHeight);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aReflowState, availableSpace);
|
||||
|
||||
// Reflow the frame
|
||||
nsIHTMLReflow* htmlReflow;
|
||||
if (NS_OK == kidFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
||||
kidReflowState.computedHeight = aReflowState.availableHeight;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||
aStatus);
|
||||
|
||||
nsRect rect(0, 0, desiredSize.width, desiredSize.height);
|
||||
kidFrame->SetRect(rect);
|
||||
|
||||
// XXX We should resolve the details of who/when DidReflow()
|
||||
// notifications are sent...
|
||||
htmlReflow->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the max size as our desired size
|
||||
aDesiredSize.width = aReflowState.availableWidth;
|
||||
aDesiredSize.height = aReflowState.availableHeight;
|
||||
aDesiredSize.ascent = aReflowState.availableHeight;
|
||||
aDesiredSize.descent = 0;
|
||||
|
||||
NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ViewportFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
return MakeFrameName("Viewport", aResult);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ CPPSRCS= \
|
|||
nsSplittableFrame.cpp \
|
||||
nsTextFrame.cpp \
|
||||
nsTextTransformer.cpp \
|
||||
nsViewportFrame.cpp \
|
||||
nsWBRFrame.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ CPPSRCS= \
|
|||
nsSplittableFrame.cpp \
|
||||
nsTextFrame.cpp \
|
||||
nsTextTransformer.cpp \
|
||||
nsViewportFrame.cpp \
|
||||
nsWBRFrame.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
@ -98,6 +99,7 @@ CPP_OBJS= \
|
|||
.\$(OBJDIR)\nsSplittableFrame.obj \
|
||||
.\$(OBJDIR)\nsTextFrame.obj \
|
||||
.\$(OBJDIR)\nsTextTransformer.obj \
|
||||
.\$(OBJDIR)\nsViewportFrame.obj \
|
||||
.\$(OBJDIR)\nsWBRFrame.obj \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -254,6 +254,7 @@ extern nsresult NS_NewHTMLFrameOuterFrame(nsIFrame*& aNewFrame);
|
|||
// <frameset>
|
||||
extern nsresult NS_NewHTMLFramesetFrame(nsIFrame*& aNewFrame);
|
||||
|
||||
extern nsresult NS_NewViewportFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewRootFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewImageFrame(nsIFrame*& aFrameResult);
|
||||
extern nsresult NS_NewInlineFrame(nsIFrame*& aNewFrame);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,9 +296,10 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
|
|||
kidReflowSize);
|
||||
nsHTMLReflowMetrics kidDesiredSize(aDesiredSize.maxElementSize);
|
||||
|
||||
// Recompute the computed width based on the scroll area size
|
||||
kidReflowState.computedWidth = scrollAreaSize.width - padding.left -
|
||||
padding.right;
|
||||
// Reset the computed width based on the scroll area size
|
||||
// XXX We should have a nsScrollReflowState which overrides the
|
||||
// InitConstraints() function...
|
||||
kidReflowState.computedWidth = scrollAreaSize.width - padding.left - padding.right;
|
||||
kidReflowState.computedHeight = NS_AUTOHEIGHT;
|
||||
|
||||
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
|
||||
|
@ -319,6 +320,41 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
|
|||
kidDesiredSize.height = yMost;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Speculative code...
|
||||
// Now if we're 'auto' scrolling and we don't need the vertical scrollbar
|
||||
// then reflow the child frame again, this time letting it reflow to the space
|
||||
// where the vertical scrollbar would be...
|
||||
if ((display->mOverflow != NS_STYLE_OVERFLOW_SCROLL) &&
|
||||
(NS_AUTOHEIGHT != aReflowState.computedHeight)) {
|
||||
if (kidDesiredSize.height < scrollAreaSize.height) {
|
||||
// No vertical scrollbar needed so reflow the document with a larger
|
||||
// computed width
|
||||
// XXX We need to be checking for horizontal scrolling...
|
||||
kidReflowState.availableWidth += NSToCoordRound(sbWidth);
|
||||
kidReflowState.computedWidth += NSToCoordRound(sbWidth);
|
||||
scrollAreaSize.width += NSToCoordRound(sbWidth);
|
||||
kidReflowState.reason = eReflowReason_Resize;
|
||||
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
|
||||
aStatus);
|
||||
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
|
||||
}
|
||||
|
||||
// If it's an area frame then get the total size, which includes the
|
||||
// space taken up by absolutely positioned child elements
|
||||
nsIAreaFrame* areaFrame;
|
||||
if (NS_SUCCEEDED(kidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
|
||||
nscoord xMost, yMost;
|
||||
|
||||
areaFrame->GetPositionedInfo(xMost, yMost);
|
||||
if (xMost > kidDesiredSize.width) {
|
||||
kidDesiredSize.width = xMost;
|
||||
}
|
||||
if (yMost > kidDesiredSize.height) {
|
||||
kidDesiredSize.height = yMost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the height of the scrolled frame fills the entire scroll area,
|
||||
// unless we're shrink wrapping
|
||||
|
@ -336,6 +372,7 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (kidDesiredSize.height <= scrollAreaSize.height) {
|
||||
// If the scrollbars are auto and the scrolled frame is fully visible
|
||||
// vertically then the vertical scrollbar will be hidden so increase the
|
||||
|
@ -344,6 +381,7 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
|
|||
kidDesiredSize.width += NSToCoordRound(sbWidth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// Make sure the width of the scrolled frame fills the entire scroll area
|
||||
if (kidDesiredSize.width < scrollAreaSize.width) {
|
||||
|
@ -351,7 +389,9 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
|
|||
}
|
||||
|
||||
// Place and size the child.
|
||||
nsRect rect(border.left, border.top, kidDesiredSize.width, kidDesiredSize.height);
|
||||
nscoord x = border.left;
|
||||
nscoord y = border.top;
|
||||
nsRect rect(x, y, kidDesiredSize.width, kidDesiredSize.height);
|
||||
kidFrame->SetRect(rect);
|
||||
|
||||
// XXX Moved to root frame
|
||||
|
@ -371,12 +411,20 @@ nsScrollFrame::Reflow(nsIPresContext& aPresContext,
|
|||
|
||||
// Compute our desired size
|
||||
aDesiredSize.width = scrollAreaSize.width;
|
||||
#if 0
|
||||
aDesiredSize.width += border.left + border.right + NSToCoordRound(sbWidth);
|
||||
#else
|
||||
aDesiredSize.width += border.left + border.right;
|
||||
if (kidDesiredSize.height > scrollAreaSize.height) {
|
||||
aDesiredSize.width += NSToCoordRound(sbWidth);
|
||||
}
|
||||
#endif
|
||||
|
||||
// For the height if we're shrink wrapping then use the child's desired size;
|
||||
// otherwise, use the scroll area size
|
||||
// For the height if we're shrink wrapping then use whatever is smaller between
|
||||
// the available height and the child's desired size; otherwise, use the scroll
|
||||
// area size
|
||||
if (NS_AUTOHEIGHT == aReflowState.computedHeight) {
|
||||
aDesiredSize.height = kidDesiredSize.height;
|
||||
aDesiredSize.height = PR_MIN(aReflowState.availableHeight, kidDesiredSize.height);
|
||||
} else {
|
||||
aDesiredSize.height = scrollAreaSize.height;
|
||||
}
|
||||
|
|
|
@ -1 +1,128 @@
|
|||
// Just a placeholder for the time being...
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#include "nsHTMLParts.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
|
||||
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
||||
|
||||
/**
|
||||
* Viewport frame class.
|
||||
*
|
||||
* The viewport frame is the parent frame for the document element's frame.
|
||||
* It only supports having a single child frame which must be one of the
|
||||
* following:
|
||||
* - scroll frame
|
||||
* - root frame
|
||||
*
|
||||
* It has an additional named child list:
|
||||
* - "Fixed-list" which contains the fixed positioned frames
|
||||
*/
|
||||
class ViewportFrame : public nsContainerFrame {
|
||||
public:
|
||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewViewportFrame(nsIFrame*& aResult)
|
||||
{
|
||||
ViewportFrame* frame = new ViewportFrame;
|
||||
if (nsnull == frame) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aResult = frame;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ViewportFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
NS_FRAME_TRACE_REFLOW_IN("ViewportFrame::Reflow");
|
||||
NS_PRECONDITION(nsnull == aDesiredSize.maxElementSize, "unexpected request");
|
||||
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// Check for an incremental reflow
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
// See if we're the target frame
|
||||
nsIFrame* targetFrame;
|
||||
aReflowState.reflowCommand->GetTarget(targetFrame);
|
||||
if (this == targetFrame) {
|
||||
// The viewport does not support being the target of an incremental
|
||||
// reflow command
|
||||
NS_ASSERTION(PR_FALSE, "unexpected reflow command target");
|
||||
|
||||
} else {
|
||||
nsIFrame* nextFrame;
|
||||
// Get the next frame in the reflow chain
|
||||
aReflowState.reflowCommand->GetNext(nextFrame);
|
||||
NS_ASSERTION(nextFrame == mFrames.FirstChild(), "unexpected next reflow command frame");
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow our one and only child frame
|
||||
if (mFrames.NotEmpty()) {
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
nsSize availableSpace(aReflowState.availableWidth,
|
||||
aReflowState.availableHeight);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aReflowState, availableSpace);
|
||||
|
||||
// Reflow the frame
|
||||
nsIHTMLReflow* htmlReflow;
|
||||
if (NS_OK == kidFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
||||
kidReflowState.computedHeight = aReflowState.availableHeight;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||
aStatus);
|
||||
|
||||
nsRect rect(0, 0, desiredSize.width, desiredSize.height);
|
||||
kidFrame->SetRect(rect);
|
||||
|
||||
// XXX We should resolve the details of who/when DidReflow()
|
||||
// notifications are sent...
|
||||
htmlReflow->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the max size as our desired size
|
||||
aDesiredSize.width = aReflowState.availableWidth;
|
||||
aDesiredSize.height = aReflowState.availableHeight;
|
||||
aDesiredSize.ascent = aReflowState.availableHeight;
|
||||
aDesiredSize.descent = 0;
|
||||
|
||||
NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ViewportFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
return MakeFrameName("Viewport", aResult);
|
||||
}
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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*
|
||||
|
|
Загрузка…
Ссылка в новой задаче