зеркало из https://github.com/mozilla/pjs.git
Back out roc's checkin for bug 288117 to isolate performance regressions during tinderbox downtime.
This commit is contained in:
Родитель
a96b514ea0
Коммит
84a42982ba
|
@ -110,6 +110,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsBoxFrame.h"
|
||||
#include "nsScrollBoxFrame.h"
|
||||
#include "nsIBoxLayout.h"
|
||||
#ifdef MOZ_ENABLE_CAIRO
|
||||
#include "nsCanvasFrame.h"
|
||||
|
@ -322,6 +323,9 @@ NS_NewMenuPopupFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|||
nsresult
|
||||
NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewMenuFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRUint32 aFlags );
|
||||
|
||||
|
@ -4171,6 +4175,9 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
|||
|
||||
^
|
||||
|
|
||||
ScrollBox
|
||||
|
||||
^
|
||||
|
|
||||
AreaFrame or BoxFrame (InitialContainingBlock)
|
||||
|
||||
|
@ -4184,15 +4191,18 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
|||
// ----- reattach gfx scrollbars ------
|
||||
// Gfx scrollframes were created in the root frame but the primary frame map may have been destroyed if a
|
||||
// new style sheet was loaded so lets reattach the frames to their content.
|
||||
// XXX this seems truly bogus, we wipe out mGfxScrollFrame below
|
||||
if (mGfxScrollFrame) {
|
||||
nsIFrame* gfxScrollbarFrame1 = mGfxScrollFrame->GetFirstChild(nsnull);
|
||||
nsIFrame* scrollBox = mGfxScrollFrame->GetFirstChild(nsnull);
|
||||
|
||||
nsIFrame* gfxScrollbarFrame1 = nsnull;
|
||||
nsIFrame* gfxScrollbarFrame2 = nsnull;
|
||||
gfxScrollbarFrame1 = scrollBox->GetNextSibling();
|
||||
if (gfxScrollbarFrame1) {
|
||||
// XXX This works, but why?
|
||||
aState.mFrameManager->
|
||||
SetPrimaryFrameFor(gfxScrollbarFrame1->GetContent(), gfxScrollbarFrame1);
|
||||
|
||||
nsIFrame* gfxScrollbarFrame2 = gfxScrollbarFrame1->GetNextSibling();
|
||||
gfxScrollbarFrame2 = gfxScrollbarFrame1->GetNextSibling();
|
||||
if (gfxScrollbarFrame2) {
|
||||
// XXX This works, but why?
|
||||
aState.mFrameManager->
|
||||
|
@ -4250,6 +4260,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
|||
|
||||
// build a scrollframe
|
||||
if (isScrollable) {
|
||||
nsIFrame* newScrollFrame = nsnull;
|
||||
nsRefPtr<nsStyleContext> newContext;
|
||||
|
||||
newContext = BeginBuildingScrollFrame( aState,
|
||||
|
@ -4259,10 +4270,11 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsFrameConstructorState& aState,
|
|||
nsnull,
|
||||
nsCSSAnonBoxes::scrolledContent,
|
||||
PR_FALSE,
|
||||
scrollFrame);
|
||||
scrollFrame,
|
||||
newScrollFrame);
|
||||
|
||||
styleContext = newContext;
|
||||
aParentFrame = scrollFrame;
|
||||
aParentFrame = newScrollFrame;
|
||||
}
|
||||
|
||||
nsIFrame* contentFrame = nsnull;
|
||||
|
@ -4400,6 +4412,10 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
|||
|
|
||||
ScrollFrame
|
||||
|
||||
^
|
||||
|
|
||||
ScrollBox <--- RootScrollableView
|
||||
|
||||
^
|
||||
|
|
||||
RootFrame(DocElementContainingBlock)
|
||||
|
@ -4490,6 +4506,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
|||
// will act as the scrolling mechanism for the viewport.
|
||||
// XXX Do we even need a viewport when printing to a printer?
|
||||
|
||||
//isScrollable = PR_FALSE;
|
||||
|
||||
// As long as the webshell doesn't prohibit it, and the device supports
|
||||
// it, create a scroll frame that will act as the scolling mechanism for
|
||||
// the viewport.
|
||||
|
@ -4517,6 +4535,31 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
|||
isScrollable = PR_FALSE;
|
||||
}
|
||||
|
||||
// Don't create a scrollframe when we're inside a frame or iframe with
|
||||
// scrolling="no". This makes the frame hierarchy inconsistent and is
|
||||
// unnecessary for correctness (since
|
||||
// nsGfxScrollFrameInner::GetScrollbarStyles handles all the necessary
|
||||
// cases), but it seems to be needed for performance.
|
||||
if (isScrollable) {
|
||||
nsresult rv;
|
||||
if (presContext) {
|
||||
nsCOMPtr<nsISupports> container = presContext->GetContainer();
|
||||
if (container) {
|
||||
nsCOMPtr<nsIScrollable> scrollableContainer = do_QueryInterface(container, &rv);
|
||||
if (NS_SUCCEEDED(rv) && scrollableContainer) {
|
||||
PRInt32 scrolling = -1;
|
||||
scrollableContainer->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,&scrolling);
|
||||
if (nsIScrollable::Scrollbar_Never == scrolling) {
|
||||
scrollableContainer->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,&scrolling);
|
||||
if (nsIScrollable::Scrollbar_Never == scrolling) {
|
||||
isScrollable = PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPaginated) {
|
||||
if (isPrintPreview) {
|
||||
isScrollable = presContext->HasPaginatedScrolling();
|
||||
|
@ -4540,11 +4583,12 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
|||
nsIFrame* parentFrame = viewportFrame;
|
||||
|
||||
// If paginated, make sure we don't put scrollbars in
|
||||
if (!isScrollable) {
|
||||
if (isPaginated && !isPrintPreview)
|
||||
rootPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
|
||||
rootPseudo,
|
||||
viewportPseudoStyle);
|
||||
} else {
|
||||
else if (isScrollable) {
|
||||
|
||||
// Build the frame. We give it the content we are wrapping which is the document,
|
||||
// the root frame, the parent view port frame, and we should get back the new
|
||||
// frame and the scrollable view if one was created.
|
||||
|
@ -4562,6 +4606,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
|||
// scroll style to 'hidden' --- dynamic style changes might put
|
||||
// scrollbars back on the viewport and we don't want to have to
|
||||
// reframe the viewport to create the scrollbar content.
|
||||
nsIFrame* newScrollableFrame = nsnull;
|
||||
|
||||
newFrame = nsnull;
|
||||
rootPseudoStyle = BeginBuildingScrollFrame( state,
|
||||
aDocElement,
|
||||
|
@ -4570,19 +4616,61 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement,
|
|||
nsnull,
|
||||
rootPseudo,
|
||||
PR_TRUE,
|
||||
newFrame);
|
||||
newFrame,
|
||||
newScrollableFrame);
|
||||
|
||||
nsIScrollableFrame* scrollable;
|
||||
CallQueryInterface(newFrame, &scrollable);
|
||||
NS_ENSURE_TRUE(scrollable, NS_ERROR_FAILURE);
|
||||
// Inform the view manager about the root scrollable view
|
||||
nsIView* view = newScrollableFrame->GetView();
|
||||
NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
|
||||
|
||||
nsIScrollableView* scrollableView = scrollable->GetScrollableView();
|
||||
nsIScrollableView* scrollableView = view->ToScrollableView();
|
||||
NS_ENSURE_TRUE(scrollableView, NS_ERROR_FAILURE);
|
||||
|
||||
viewManager->SetRootScrollableView(scrollableView);
|
||||
parentFrame = newFrame;
|
||||
parentFrame = newScrollableFrame;
|
||||
|
||||
mGfxScrollFrame = newFrame;
|
||||
|
||||
} else {
|
||||
// If no scrollbars and xul, don't build a scrollframe at all.
|
||||
if (isXUL) {
|
||||
rootPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
|
||||
rootPseudo,
|
||||
viewportPseudoStyle);
|
||||
} else {
|
||||
// if HTML the always create a scrollframe so anchors work. That way you can scroll to
|
||||
// anchors even if we don't have scrollbars.
|
||||
|
||||
// create a style context for the scrollport of the viewport
|
||||
nsRefPtr<nsStyleContext> scrollPseudoStyle;
|
||||
scrollPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
|
||||
nsCSSAnonBoxes::scrolledContent,
|
||||
viewportPseudoStyle);
|
||||
|
||||
// create scrollframe
|
||||
nsIFrame* scrollFrame = nsnull;
|
||||
NS_NewScrollBoxFrame(mPresShell, &scrollFrame);
|
||||
NS_ENSURE_TRUE(scrollFrame, NS_ERROR_FAILURE);
|
||||
|
||||
scrollFrame->Init(presContext, nsnull, parentFrame, scrollPseudoStyle, nsnull);
|
||||
|
||||
// resolve a new style for the root frame
|
||||
rootPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
|
||||
rootPseudo,
|
||||
scrollPseudoStyle);
|
||||
|
||||
// Inform the view manager about the root scrollable view
|
||||
nsIView* view = scrollFrame->GetView();
|
||||
NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
|
||||
|
||||
nsIScrollableView* scrollableView = view->ToScrollableView();
|
||||
NS_ENSURE_TRUE(scrollableView, NS_ERROR_FAILURE);
|
||||
|
||||
viewManager->SetRootScrollableView(scrollableView);
|
||||
|
||||
parentFrame = scrollFrame;
|
||||
newFrame = scrollFrame;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6197,7 +6285,8 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
|
|||
nsIFrame* aContentParentFrame,
|
||||
nsIAtom* aScrolledPseudo,
|
||||
PRBool aIsRoot,
|
||||
nsIFrame*& aNewFrame)
|
||||
nsIFrame*& aNewFrame,
|
||||
nsIFrame*& aScrollableFrame)
|
||||
{
|
||||
// Check to see the type of parent frame so we know whether we need to
|
||||
// turn off/on scaling for the scrollbars
|
||||
|
@ -6215,6 +6304,7 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
|
|||
}
|
||||
}
|
||||
|
||||
nsIFrame* scrollFrame = nsnull;
|
||||
nsIFrame* parentFrame = nsnull;
|
||||
nsIFrame* gfxScrollFrame = aNewFrame;
|
||||
|
||||
|
@ -6223,9 +6313,9 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
|
|||
nsRefPtr<nsStyleContext> contentStyle = aContentStyle;
|
||||
|
||||
if (!gfxScrollFrame) {
|
||||
// Build a XULScrollFrame when the child is a box, otherwise an
|
||||
// HTMLScrollFrame
|
||||
if (IsXULDisplayType(aContentStyle->GetStyleDisplay())) {
|
||||
// Build a XULScrollFrame when the parent is a box, because XULScrollFrames
|
||||
// do box layout well. Otherwise build an HTMLScrollFrame.
|
||||
if (aParentFrame->IsBoxFrame()) {
|
||||
NS_NewXULScrollFrame(mPresShell, &gfxScrollFrame, aIsRoot);
|
||||
} else {
|
||||
NS_NewHTMLScrollFrame(mPresShell, &gfxScrollFrame, aIsRoot);
|
||||
|
@ -6239,11 +6329,11 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
|
|||
aContentParentFrame, PR_FALSE);
|
||||
}
|
||||
|
||||
// if there are any anonymous children for the scroll frame, create
|
||||
// frames for them.
|
||||
CreateAnonymousFrames(aState, aContent, mDocument, gfxScrollFrame, PR_FALSE,
|
||||
PR_FALSE, anonymousItems, nsnull, nsnull, PR_FALSE);
|
||||
InitGfxScrollFrame(aState, aContent, mDocument,
|
||||
aParentFrame, aContentParentFrame, contentStyle,
|
||||
aIsRoot, gfxScrollFrame, anonymousItems);
|
||||
|
||||
scrollFrame = anonymousItems.childList; // get the scrollport from the anonymous list
|
||||
parentFrame = gfxScrollFrame;
|
||||
aNewFrame = gfxScrollFrame;
|
||||
|
||||
|
@ -6256,15 +6346,23 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
|
|||
contentStyle);
|
||||
|
||||
contentStyle = scrollPseudoStyle;
|
||||
InitAndRestoreFrame(aState, aContent, parentFrame, contentStyle, nsnull,
|
||||
scrollFrame);
|
||||
|
||||
nsStyleContext* aScrolledChildStyle = styleSet->ResolvePseudoStyleFor(aContent,
|
||||
aScrolledPseudo,
|
||||
contentStyle).get();
|
||||
|
||||
aScrollableFrame = scrollFrame;
|
||||
|
||||
// set the child frame for the gfxscrollbar if the is one. This frames will be the
|
||||
// 2 scrollbars and the scrolled frame.
|
||||
if (gfxScrollFrame) {
|
||||
gfxScrollFrame->SetInitialChildList(aState.mPresContext, nsnull,
|
||||
anonymousItems.childList);
|
||||
}
|
||||
|
||||
|
||||
if (isPrintPreview && noScalingOfTwips) {
|
||||
aState.mPresContext->SetScalingOfTwips(PR_TRUE);
|
||||
}
|
||||
|
@ -6276,22 +6374,12 @@ void
|
|||
nsCSSFrameConstructor::FinishBuildingScrollFrame(nsIFrame* aScrollFrame,
|
||||
nsIFrame* aScrolledFrame)
|
||||
{
|
||||
aScrollFrame->AppendFrames(nsnull, aScrolledFrame);
|
||||
|
||||
// force the scrolled frame to have a view
|
||||
// create a view
|
||||
// XXXbz should we be passing in a non-null aContentParentFrame?
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aScrolledFrame, nsnull, PR_TRUE);
|
||||
nsIView* view = aScrolledFrame->GetView();
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
// reparent the view from the scrollframe's view to its inner scrolling view
|
||||
nsIScrollableFrame* scrollable;
|
||||
CallQueryInterface(aScrollFrame, &scrollable);
|
||||
if (scrollable) {
|
||||
nsIViewManager* vm = view->GetViewManager();
|
||||
vm->RemoveChild(view);
|
||||
vm->InsertChild(scrollable->GetScrollableView()->View(), view, nsnull, PR_TRUE);
|
||||
}
|
||||
// the the scroll frames child list
|
||||
aScrollFrame->SetInitialChildList(aScrollFrame->GetPresContext(), nsnull, aScrolledFrame);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6304,13 +6392,18 @@ nsCSSFrameConstructor::FinishBuildingScrollFrame(nsIFrame* aScrollFrame,
|
|||
* ScrollFrame
|
||||
* ^
|
||||
* |
|
||||
* ScrollBox
|
||||
* ^
|
||||
* |
|
||||
* Frame (scrolled frame you passed in)
|
||||
*
|
||||
*
|
||||
*-----------------------------------
|
||||
* LEGEND:
|
||||
*
|
||||
* ScrollFrame: This is a frame that manages gfx cross platform frame based scrollbars.
|
||||
* GfxScrollFrame: This is a frame that manages gfx cross platform frame based scrollbars.
|
||||
*
|
||||
* ScrollBox: This clips and scrolls its children with a native scrolling window.
|
||||
*
|
||||
* @param aContent the content node of the child to wrap.
|
||||
* @param aScrolledFrame The frame of the content to wrap. This should not be
|
||||
|
@ -6336,15 +6429,25 @@ nsCSSFrameConstructor::BuildScrollFrame(nsFrameConstructorState& aState,
|
|||
nsIFrame*& aNewFrame,
|
||||
nsStyleContext*& aScrolledContentStyle)
|
||||
{
|
||||
nsRefPtr<nsStyleContext> scrolledContentStyle =
|
||||
BeginBuildingScrollFrame(aState, aContent, aContentStyle, aParentFrame,
|
||||
aContentParentFrame, nsCSSAnonBoxes::scrolledContent,
|
||||
PR_FALSE, aNewFrame);
|
||||
nsIFrame *scrollFrame;
|
||||
|
||||
InitAndRestoreFrame(aState, aContent, aNewFrame, scrolledContentStyle,
|
||||
nsRefPtr<nsStyleContext> scrolledContentStyle;
|
||||
|
||||
|
||||
scrolledContentStyle = BeginBuildingScrollFrame(aState,
|
||||
aContent,
|
||||
aContentStyle,
|
||||
aParentFrame,
|
||||
aContentParentFrame,
|
||||
nsCSSAnonBoxes::scrolledContent,
|
||||
PR_FALSE,
|
||||
aNewFrame,
|
||||
scrollFrame);
|
||||
|
||||
InitAndRestoreFrame(aState, aContent, scrollFrame, scrolledContentStyle,
|
||||
nsnull, aScrolledFrame);
|
||||
|
||||
FinishBuildingScrollFrame(aNewFrame, aScrolledFrame);
|
||||
FinishBuildingScrollFrame(scrollFrame, aScrolledFrame);
|
||||
|
||||
aScrolledContentStyle = scrolledContentStyle;
|
||||
|
||||
|
@ -6354,6 +6457,34 @@ nsCSSFrameConstructor::BuildScrollFrame(nsFrameConstructorState& aState,
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* If we are building GFX scrollframes this will create one
|
||||
* if aNewFrame gets a frame passed in, we'll use it instead
|
||||
* of creating a new frame
|
||||
*/
|
||||
nsresult
|
||||
nsCSSFrameConstructor::InitGfxScrollFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIDocument* aDocument,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aContentParentFrame,
|
||||
nsStyleContext* aStyleContext,
|
||||
PRBool aIsRoot,
|
||||
nsIFrame*& aNewFrame,
|
||||
nsFrameItems& aAnonymousFrames)
|
||||
{
|
||||
nsIFrame* scrollBox;
|
||||
NS_NewScrollBoxFrame(mPresShell, &scrollBox);
|
||||
|
||||
aAnonymousFrames.AddChild(scrollBox);
|
||||
|
||||
// if there are any anonymous children for the scroll frame, create frames for them.
|
||||
CreateAnonymousFrames(aState, aContent, aDocument, aNewFrame, PR_FALSE,
|
||||
PR_FALSE, aAnonymousFrames, nsnull, nsnull, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::ConstructFrameByDisplayType(nsFrameConstructorState& aState,
|
||||
const nsStyleDisplay* aDisplay,
|
||||
|
@ -6402,12 +6533,14 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsFrameConstructorState& aSta
|
|||
ProcessPseudoFrames(aState, aFrameItems);
|
||||
}
|
||||
|
||||
nsIFrame *scrollFrame;
|
||||
nsRefPtr<nsStyleContext> scrolledContentStyle
|
||||
= BeginBuildingScrollFrame(aState, aContent, aStyleContext,
|
||||
aState.GetGeometricParent(aDisplay, aParentFrame),
|
||||
aParentFrame,
|
||||
nsCSSAnonBoxes::scrolledContent,
|
||||
PR_FALSE, newFrame);
|
||||
PR_FALSE,
|
||||
newFrame, scrollFrame);
|
||||
|
||||
// Initialize it
|
||||
nsIFrame* scrolledFrame = nsnull;
|
||||
|
@ -6416,11 +6549,11 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsFrameConstructorState& aSta
|
|||
nsFrameItems blockItem;
|
||||
rv = ConstructBlock(aState,
|
||||
scrolledContentStyle->GetStyleDisplay(), aContent,
|
||||
newFrame, newFrame, scrolledContentStyle,
|
||||
scrollFrame, scrollFrame, scrolledContentStyle,
|
||||
&scrolledFrame, blockItem, aDisplay->IsPositioned());
|
||||
NS_ASSERTION(blockItem.childList == scrolledFrame,
|
||||
"Scrollframe's frameItems should be exactly the scrolled frame");
|
||||
FinishBuildingScrollFrame(newFrame, scrolledFrame);
|
||||
FinishBuildingScrollFrame(scrollFrame, scrolledFrame);
|
||||
|
||||
rv = aState.AddChild(newFrame, aFrameItems, aDisplay, aContent,
|
||||
aStyleContext, aParentFrame);
|
||||
|
@ -7673,6 +7806,7 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchy()
|
|||
//
|
||||
// (HTML)
|
||||
// nsHTMLScrollFrame(html)<
|
||||
// nsScrollBoxFrame(html)<
|
||||
// Canvas(-1)<
|
||||
// Area(html)<
|
||||
// (etc.)
|
||||
|
@ -7680,6 +7814,7 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchy()
|
|||
// (XUL #1)
|
||||
// RootBoxFrame(window)<
|
||||
// nsXULScrollFrame<
|
||||
// nsScrollBoxFrame(window)<
|
||||
// (etc.)
|
||||
//
|
||||
// (XUL #2)
|
||||
|
|
|
@ -671,7 +671,8 @@ private:
|
|||
nsIFrame* aContentParentFrame,
|
||||
nsIAtom* aScrolledPseudo,
|
||||
PRBool aIsRoot,
|
||||
nsIFrame*& aNewFrame);
|
||||
nsIFrame*& aNewFrame,
|
||||
nsIFrame*& aScrollableFrame);
|
||||
|
||||
// Completes the building of the scrollframe:
|
||||
// Creates a view for the scrolledframe and makes it the child of the scrollframe.
|
||||
|
@ -679,6 +680,20 @@ private:
|
|||
FinishBuildingScrollFrame(nsIFrame* aScrollFrame,
|
||||
nsIFrame* aScrolledFrame);
|
||||
|
||||
// Creates a new GfxScrollFrame, Initializes it, and creates a scroll port for it
|
||||
//
|
||||
nsresult
|
||||
InitGfxScrollFrame(nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIDocument* aDocument,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIFrame* aContentParentFrame,
|
||||
nsStyleContext* aStyleContext,
|
||||
PRBool aIsRoot,
|
||||
nsIFrame*& aNewFrame,
|
||||
nsFrameItems& aAnonymousFrames);
|
||||
|
||||
|
||||
// InitializeSelectFrame puts scrollFrame in aFrameItems if aBuildCombobox is false
|
||||
nsresult
|
||||
InitializeSelectFrame(nsFrameConstructorState& aState,
|
||||
|
|
|
@ -355,6 +355,10 @@ nsLayoutUtils::GetScrollableFrameFor(nsIFrame *aScrolledFrame)
|
|||
if (!frame) {
|
||||
return nsnull;
|
||||
}
|
||||
frame = frame->GetParent();
|
||||
if (!frame) {
|
||||
return nsnull;
|
||||
}
|
||||
nsIScrollableFrame *sf;
|
||||
CallQueryInterface(frame, &sf);
|
||||
return sf;
|
||||
|
@ -364,8 +368,8 @@ nsLayoutUtils::GetScrollableFrameFor(nsIFrame *aScrolledFrame)
|
|||
nsIScrollableFrame*
|
||||
nsLayoutUtils::GetScrollableFrameFor(nsIScrollableView *aScrollableView)
|
||||
{
|
||||
nsIFrame *frame = GetFrameFor(aScrollableView->View()->GetParent());
|
||||
if (frame) {
|
||||
nsIFrame *frame = GetFrameFor(aScrollableView->View());
|
||||
if (frame && ((frame = frame->GetParent()))) {
|
||||
nsIScrollableFrame *sf;
|
||||
CallQueryInterface(frame, &sf);
|
||||
return sf;
|
||||
|
@ -412,7 +416,7 @@ nsLayoutUtils::GetNearestScrollingView(nsIView* aView, Direction aDirection)
|
|||
nscoord totalWidth, totalHeight;
|
||||
scrollableView->GetContainerSize(&totalWidth, &totalHeight);
|
||||
// Get size of currently visible area
|
||||
nsSize visibleSize = aView->GetBounds().Size();
|
||||
nsSize visibleSize = GetFrameFor(aView)->GetSize();
|
||||
// aDirection can be eHorizontal, eVertical, or eEither
|
||||
// If scrolling in a specific direction, require visible scrollbars or
|
||||
// something to scroll to in that direction.
|
||||
|
|
|
@ -432,25 +432,70 @@ nsContainerFrame::ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild)
|
|||
void
|
||||
nsContainerFrame::PositionFrameView(nsIFrame* aKidFrame)
|
||||
{
|
||||
nsIFrame* parentFrame = aKidFrame->GetParent();
|
||||
if (!aKidFrame->HasView() || !parentFrame)
|
||||
return;
|
||||
if (aKidFrame->HasView()) {
|
||||
nsIView* view = aKidFrame->GetView();
|
||||
// Position view relative to its parent, not relative to aKidFrame's
|
||||
// frame which may not have a view
|
||||
nsIView* parentView = view->GetParent();
|
||||
|
||||
nsIView* view = aKidFrame->GetView();
|
||||
nsIViewManager* vm = view->GetViewManager();
|
||||
nsPoint pt;
|
||||
nsIView* ancestorView = parentFrame->GetClosestView(&pt);
|
||||
nsIView* containingView;
|
||||
nsPoint origin;
|
||||
aKidFrame->GetOffsetFromView(origin, &containingView);
|
||||
|
||||
if (ancestorView != view->GetParent()) {
|
||||
NS_ASSERTION(ancestorView == view->GetParent()->GetParent(),
|
||||
"Allowed only one anonymous view between frames");
|
||||
// parentFrame is responsible for positioning aKidFrame's view
|
||||
// explicitly
|
||||
return;
|
||||
nsIViewManager* vm = view->GetViewManager();
|
||||
|
||||
// it's possible for the parentView to be nonnull but containingView to be
|
||||
// null, when the parent view doesn't belong to this frame tree but to
|
||||
// the frame tree of some enclosing document. We do nothing in that case,
|
||||
// but we have to check that containingView is nonnull or we will crash.
|
||||
if (nsnull != containingView && containingView != parentView) {
|
||||
NS_ERROR("This hack should not be needed now!!! See bug 126263.");
|
||||
|
||||
// XXX roc this should be no longer needed, but it still is for printing/print preview
|
||||
|
||||
// it is possible for parent view not to have a frame attached to it
|
||||
// kind of an anonymous view. This happens with native scrollbars and
|
||||
// the clip view. To fix this we need to go up and parentView chain
|
||||
// until we find a view with client data. This is total HACK to fix
|
||||
// the HACK below. COMBO box code should NOT be in the container code!!!
|
||||
// And the case it looks from does not just happen for combo boxes. Native
|
||||
// scrollframes get in this situation too!!
|
||||
while (parentView) {
|
||||
void *data = parentView->GetClientData();
|
||||
if (data)
|
||||
break;
|
||||
|
||||
origin -= parentView->GetPosition();
|
||||
parentView = parentView->GetParent();
|
||||
}
|
||||
|
||||
if (containingView != parentView)
|
||||
{
|
||||
// Huh, the view's parent view isn't the same as the containing view.
|
||||
// This happens for combo box drop-down frames.
|
||||
//
|
||||
// We have the origin in the coordinate space of the containing view,
|
||||
// but we need it in the coordinate space of the parent view so do a
|
||||
// view translation
|
||||
origin += containingView->GetOffsetTo(parentView);
|
||||
}
|
||||
}
|
||||
|
||||
if (parentView) {
|
||||
// If the parent view is scrollable, then adjust the origin by
|
||||
// the parent's scroll position.
|
||||
nsIScrollableView* scrollable = parentView->ToScrollableView();
|
||||
if (scrollable) {
|
||||
nscoord scrollX = 0, scrollY = 0;
|
||||
scrollable->GetScrollPosition(scrollX, scrollY);
|
||||
|
||||
origin.x -= scrollX;
|
||||
origin.y -= scrollY;
|
||||
}
|
||||
}
|
||||
|
||||
vm->MoveViewTo(view, origin.x, origin.y);
|
||||
}
|
||||
|
||||
pt += aKidFrame->GetPosition();
|
||||
vm->MoveViewTo(view, pt.x, pt.y);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
|
@ -815,10 +860,6 @@ nsContainerFrame::SyncFrameViewProperties(nsPresContext* aPresContext,
|
|||
PRBool
|
||||
nsContainerFrame::FrameNeedsView(nsIFrame* aFrame)
|
||||
{
|
||||
if (aFrame->TypeAlwaysNeedsView()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsStyleContext* sc = aFrame->GetStyleContext();
|
||||
const nsStyleDisplay* display = sc->GetStyleDisplay();
|
||||
if (display->mOpacity != 1.0f) {
|
||||
|
@ -845,6 +886,10 @@ nsContainerFrame::FrameNeedsView(nsIFrame* aFrame)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aFrame->GetType() == nsLayoutAtoms::objectFrame) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// See if the frame is block-level and has 'overflow' set to
|
||||
// '-moz-hidden-unscrollable'. If so, then we need to give it a view
|
||||
// so clipping of any child views works correctly. Note that if it's
|
||||
|
|
|
@ -2031,7 +2031,7 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
|||
nsIView *closestView = closestFrame->GetClosestView();
|
||||
|
||||
if (closestView && view != closestView)
|
||||
newPoint -= closestView->GetOffsetTo(view);
|
||||
newPoint -= closestView->GetPosition();
|
||||
|
||||
// printf(" 0x%.8x 0x%.8x %4d %4d\n",
|
||||
// closestFrame, closestView, closestXDistance, closestYDistance);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsHTMLContainerFrame.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsGfxScrollFrame.h"
|
||||
#include "nsScrollBoxFrame.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
@ -190,14 +191,13 @@ nsHTMLScrollFrame::Destroy(nsPresContext* aPresContext)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLScrollFrame::
|
||||
SetInitialChildList(nsPresContext* aPresContext,
|
||||
nsHTMLScrollFrame::SetInitialChildList(nsPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::SetInitialChildList(aPresContext, aListName,
|
||||
aChildList);
|
||||
mInner.CreateScrollableView();
|
||||
|
||||
mInner.ReloadChildFrames();
|
||||
|
||||
// listen for scroll events.
|
||||
|
@ -253,6 +253,25 @@ nsHTMLScrollFrame::GetPadding(nsMargin& aMargin)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLScrollFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent)
|
||||
{
|
||||
//we need to translate the coordinates to the inner
|
||||
nsIView *view = GetClosestView();
|
||||
if (!view)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIView *innerView = mInner.mScrollAreaBox->GetClosestView();
|
||||
nsPoint point = aPoint - innerView->GetOffsetTo(view);
|
||||
|
||||
return mInner.mScrollAreaBox->GetContentAndOffsetsFromPoint(aCX, point, aNewContent, aContentOffset, aContentOffsetEnd, aBeginFrameContent);
|
||||
}
|
||||
|
||||
PRIntn
|
||||
nsHTMLScrollFrame::GetSkipSides() const
|
||||
{
|
||||
|
@ -269,10 +288,7 @@ NS_IMETHODIMP
|
|||
nsHTMLScrollFrame::GetAscent(nsBoxLayoutState& aState, nscoord& aAscent)
|
||||
{
|
||||
aAscent = 0;
|
||||
if (!mInner.mScrolledFrame)
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = mInner.mScrolledFrame->GetAscent(aState, aAscent);
|
||||
nsresult rv = mInner.mScrollAreaBox->GetAscent(aState, aAscent);
|
||||
nsMargin m(0,0,0,0);
|
||||
GetBorderAndPadding(m);
|
||||
aAscent += m.top;
|
||||
|
@ -312,7 +328,7 @@ nsHTMLScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
//
|
||||
// Details: We're going to pass our width (or height) constraint
|
||||
// down to nsBoxToBlockAdaptor. Then when we call
|
||||
// mScrolledFrame->GetPrefSize below, it will reflow the scrolled
|
||||
// mScrollAreaBox->GetPrefSize below, it will reflow the scrolled
|
||||
// block with this width (or height) constraint, and report the resulting
|
||||
// height (or width) of the block. So if possible we'll be sized exactly to the
|
||||
// height (or width) of the block, which is what we want because 'overflow'
|
||||
|
@ -358,7 +374,7 @@ nsHTMLScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
aState.SetScrolledBlockSizeConstraint(nsSize(-1,-1));
|
||||
}
|
||||
|
||||
nsresult rv = mInner.mScrolledFrame->GetPrefSize(aState, aSize);
|
||||
nsresult rv = mInner.mScrollAreaBox->GetPrefSize(aState, aSize);
|
||||
|
||||
// Restore old constraint.
|
||||
aState.SetScrolledBlockSizeConstraint(oldConstrainedSize);
|
||||
|
@ -387,7 +403,7 @@ nsHTMLScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
nsBox::AddMargin(mInner.mVScrollbarBox, vSize);
|
||||
}
|
||||
|
||||
// Scrolled frames don't have their own margins
|
||||
nsBox::AddMargin(mInner.mScrollAreaBox, aSize);
|
||||
|
||||
aSize.width += vSize.width;
|
||||
aSize.height += hSize.height;
|
||||
|
@ -406,7 +422,7 @@ nsHTMLScrollFrame::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
PropagateDebug(aState);
|
||||
#endif
|
||||
|
||||
aSize = mInner.mScrolledFrame->GetMinSizeForScrollArea(aState);
|
||||
nsresult rv = mInner.mScrollAreaBox->GetMinSize(aState, aSize);
|
||||
|
||||
nsGfxScrollFrameInner::ScrollbarStyles styles = GetScrollbarStyles();
|
||||
|
||||
|
@ -433,7 +449,7 @@ nsHTMLScrollFrame::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMinSize(aState, this, aSize);
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -683,7 +699,6 @@ nsXULScrollFrame::SetInitialChildList(nsPresContext* aPresContext,
|
|||
nsresult rv = nsBoxFrame::SetInitialChildList(aPresContext, aListName,
|
||||
aChildList);
|
||||
|
||||
mInner.CreateScrollableView();
|
||||
mInner.ReloadChildFrames();
|
||||
|
||||
// listen for scroll events.
|
||||
|
@ -739,6 +754,25 @@ nsXULScrollFrame::GetPadding(nsMargin& aMargin)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULScrollFrame::GetContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent)
|
||||
{
|
||||
//we need to translate the coordinates to the inner
|
||||
nsIView *view = GetClosestView();
|
||||
if (!view)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIView *innerView = mInner.mScrollAreaBox->GetClosestView();
|
||||
nsPoint point = aPoint - innerView->GetOffsetTo(view);
|
||||
|
||||
return mInner.mScrollAreaBox->GetContentAndOffsetsFromPoint(aCX, point, aNewContent, aContentOffset, aContentOffsetEnd, aBeginFrameContent);
|
||||
}
|
||||
|
||||
PRIntn
|
||||
nsXULScrollFrame::GetSkipSides() const
|
||||
{
|
||||
|
@ -755,10 +789,7 @@ NS_IMETHODIMP
|
|||
nsXULScrollFrame::GetAscent(nsBoxLayoutState& aState, nscoord& aAscent)
|
||||
{
|
||||
aAscent = 0;
|
||||
if (!mInner.mScrolledFrame)
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = mInner.mScrolledFrame->GetAscent(aState, aAscent);
|
||||
nsresult rv = mInner.mScrollAreaBox->GetAscent(aState, aAscent);
|
||||
nsMargin m(0,0,0,0);
|
||||
GetBorderAndPadding(m);
|
||||
aAscent += m.top;
|
||||
|
@ -798,7 +829,7 @@ nsXULScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
//
|
||||
// Details: We're going to pass our width (or height) constraint
|
||||
// down to nsBoxToBlockAdaptor. Then when we call
|
||||
// mScrolledFrame->GetPrefSize below, it will reflow the scrolled
|
||||
// mScrollAreaBox->GetPrefSize below, it will reflow the scrolled
|
||||
// block with this width (or height) constraint, and report the resulting
|
||||
// height (or width) of the block. So if possible we'll be sized exactly to the
|
||||
// height (or width) of the block, which is what we want because 'overflow'
|
||||
|
@ -844,7 +875,7 @@ nsXULScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
aState.SetScrolledBlockSizeConstraint(nsSize(-1,-1));
|
||||
}
|
||||
|
||||
nsresult rv = mInner.mScrolledFrame->GetPrefSize(aState, aSize);
|
||||
nsresult rv = mInner.mScrollAreaBox->GetPrefSize(aState, aSize);
|
||||
|
||||
// Restore old constraint.
|
||||
aState.SetScrolledBlockSizeConstraint(oldConstrainedSize);
|
||||
|
@ -873,7 +904,7 @@ nsXULScrollFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
nsBox::AddMargin(mInner.mVScrollbarBox, vSize);
|
||||
}
|
||||
|
||||
// scrolled frames don't have their own margins
|
||||
nsBox::AddMargin(mInner.mScrollAreaBox, aSize);
|
||||
|
||||
aSize.width += vSize.width;
|
||||
aSize.height += hSize.height;
|
||||
|
@ -892,7 +923,7 @@ nsXULScrollFrame::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
PropagateDebug(aState);
|
||||
#endif
|
||||
|
||||
aSize = mInner.mScrolledFrame->GetMinSizeForScrollArea(aState);
|
||||
nsresult rv = mInner.mScrollAreaBox->GetMinSize(aState, aSize);
|
||||
|
||||
nsGfxScrollFrameInner::ScrollbarStyles styles = GetScrollbarStyles();
|
||||
|
||||
|
@ -919,7 +950,7 @@ nsXULScrollFrame::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
|
|||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMinSize(aState, this, aSize);
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1035,10 +1066,9 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
|||
//-------------------- Inner ----------------------
|
||||
|
||||
nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsBoxFrame* aOuter)
|
||||
: mScrollableView(nsnull),
|
||||
mHScrollbarBox(nsnull),
|
||||
: mHScrollbarBox(nsnull),
|
||||
mVScrollbarBox(nsnull),
|
||||
mScrolledFrame(nsnull),
|
||||
mScrollAreaBox(nsnull),
|
||||
mScrollCornerBox(nsnull),
|
||||
mOnePixel(20),
|
||||
mOuter(aOuter),
|
||||
|
@ -1052,9 +1082,7 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsBoxFrame* aOuter)
|
|||
mHasHorizontalScrollbar(PR_FALSE),
|
||||
mViewInitiatedScroll(PR_FALSE),
|
||||
mFrameInitiatedScroll(PR_FALSE),
|
||||
mDidHistoryRestore(PR_FALSE),
|
||||
mHorizontalOverflow(PR_FALSE),
|
||||
mVerticalOverflow(PR_FALSE)
|
||||
mDidHistoryRestore(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1070,74 +1098,6 @@ NS_IMETHODIMP_(nsrefcnt) nsGfxScrollFrameInner::Release(void)
|
|||
|
||||
NS_IMPL_QUERY_INTERFACE1(nsGfxScrollFrameInner, nsIScrollPositionListener)
|
||||
|
||||
PRBool
|
||||
nsGfxScrollFrameInner::NeedsClipWidget() const
|
||||
{
|
||||
// Scrollports contained in form controls (e.g., listboxes) don't get
|
||||
// widgets.
|
||||
for (nsIFrame* parentFrame = mOuter->GetParent(); parentFrame;
|
||||
parentFrame = parentFrame->GetParent()) {
|
||||
nsIFormControlFrame* fcFrame;
|
||||
if ((NS_SUCCEEDED(parentFrame->QueryInterface(NS_GET_IID(nsIFormControlFrame), (void**)&fcFrame)))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Scrollports that don't ever show associated scrollbars don't get
|
||||
// widgets, because they will seldom actually be scrolled.
|
||||
nsIScrollableFrame *scrollableFrame;
|
||||
CallQueryInterface(mOuter, &scrollableFrame);
|
||||
ScrollbarStyles scrollbars = scrollableFrame->GetScrollbarStyles();
|
||||
if ((scrollbars.mHorizontal == NS_STYLE_OVERFLOW_HIDDEN
|
||||
|| scrollbars.mHorizontal == NS_STYLE_OVERFLOW_VISIBLE)
|
||||
&& (scrollbars.mVertical == NS_STYLE_OVERFLOW_HIDDEN
|
||||
|| scrollbars.mVertical == NS_STYLE_OVERFLOW_VISIBLE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGfxScrollFrameInner::GetChildContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent)
|
||||
{
|
||||
// We need to overrride this to ensure that scrollbars are ignored
|
||||
|
||||
// Since we definitely have a view, aPoint is relative to this frame's view. We
|
||||
// need to make it relative to the scrolled frame.
|
||||
nsPoint point = aPoint - mScrollableView->View()->GetOffsetTo(mOuter->GetView());
|
||||
|
||||
return mScrolledFrame->GetContentAndOffsetsFromPoint(aCX, point, aNewContent,
|
||||
aContentOffset, aContentOffsetEnd,
|
||||
aBeginFrameContent);
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::CreateScrollableView()
|
||||
{
|
||||
nsIView* outerView = mOuter->GetView();
|
||||
NS_ASSERTION(outerView, "scrollframes must have views");
|
||||
nsIViewManager* viewManager = outerView->GetViewManager();
|
||||
mScrollableView = viewManager->CreateScrollableView(mOuter->GetRect(), outerView);
|
||||
if (!mScrollableView)
|
||||
return;
|
||||
|
||||
nsIView* view = mScrollableView->View();
|
||||
|
||||
// Insert the view into the view hierarchy
|
||||
viewManager->InsertChild(outerView, view, nsnull, PR_TRUE);
|
||||
|
||||
// Have the scrolling view create its internal widgets
|
||||
if (NeedsClipWidget()) {
|
||||
mScrollableView->CreateScrollControls();
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleScrollPref(nsIScrollable *aScrollable, PRInt32 aOrientation,
|
||||
PRUint8& aValue)
|
||||
{
|
||||
|
@ -1251,49 +1211,50 @@ nsGfxScrollFrameInner::ScrollToRestoredPosition()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::PostScrollPortEvent(PRBool aOverflow, nsScrollPortEvent::orientType aType)
|
||||
{
|
||||
nsScrollPortEvent* event = new nsScrollPortEvent(aOverflow ?
|
||||
NS_SCROLLPORT_OVERFLOW :
|
||||
NS_SCROLLPORT_UNDERFLOW);
|
||||
event->orient = aType;
|
||||
mOuter->GetPresContext()->PresShell()->PostDOMEvent(mOuter->GetContent(), event);
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::ReloadChildFrames()
|
||||
{
|
||||
mScrolledFrame = nsnull;
|
||||
mScrollAreaBox = nsnull;
|
||||
mHScrollbarBox = nsnull;
|
||||
mVScrollbarBox = nsnull;
|
||||
mScrollCornerBox = nsnull;
|
||||
|
||||
nsIFrame* frame = mOuter->GetFirstChild(nsnull);
|
||||
while (frame) {
|
||||
nsIContent* content = frame->GetContent();
|
||||
if (content == mOuter->GetContent()) {
|
||||
NS_ASSERTION(!mScrolledFrame, "Already found the scrolled frame");
|
||||
mScrolledFrame = frame;
|
||||
} else {
|
||||
nsAutoString value;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_None,
|
||||
nsXULAtoms::orient, value)) {
|
||||
// probably a scrollbar then
|
||||
if (value.LowerCaseEqualsLiteral("horizontal")) {
|
||||
NS_ASSERTION(!mHScrollbarBox, "Found multiple horizontal scrollbars?");
|
||||
mHScrollbarBox = frame;
|
||||
} else {
|
||||
NS_ASSERTION(!mVScrollbarBox, "Found multiple vertical scrollbars?");
|
||||
mVScrollbarBox = frame;
|
||||
}
|
||||
PRBool understood = PR_FALSE;
|
||||
|
||||
if (frame->IsBoxFrame()) {
|
||||
if (frame->GetType() == nsLayoutAtoms::scrollFrame) {
|
||||
NS_ASSERTION(!mScrollAreaBox, "Found multiple scroll areas?");
|
||||
mScrollAreaBox = frame;
|
||||
understood = PR_TRUE;
|
||||
} else {
|
||||
// probably a scrollcorner
|
||||
NS_ASSERTION(!mScrollCornerBox, "Found multiple scrollcorners");
|
||||
mScrollCornerBox = frame;
|
||||
nsIContent* content = frame->GetContent();
|
||||
if (content) {
|
||||
nsAutoString value;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_None,
|
||||
nsXULAtoms::orient, value)) {
|
||||
// probably a scrollbar then
|
||||
if (value.LowerCaseEqualsLiteral("horizontal")) {
|
||||
NS_ASSERTION(!mHScrollbarBox, "Found multiple horizontal scrollbars?");
|
||||
mHScrollbarBox = frame;
|
||||
} else {
|
||||
NS_ASSERTION(!mVScrollbarBox, "Found multiple vertical scrollbars?");
|
||||
mVScrollbarBox = frame;
|
||||
}
|
||||
understood = PR_TRUE;
|
||||
} else {
|
||||
// probably a scrollcorner
|
||||
NS_ASSERTION(!mScrollCornerBox, "Found multiple scrollcorners");
|
||||
mScrollCornerBox = frame;
|
||||
understood = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(understood, "What is this frame doing here?");
|
||||
|
||||
frame = frame->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
@ -1505,6 +1466,22 @@ void nsGfxScrollFrameInner::CurPosAttributeChanged(nsIContent* aContent, PRInt32
|
|||
}
|
||||
}
|
||||
|
||||
nsIScrollableView*
|
||||
nsGfxScrollFrameInner::GetScrollableView() const
|
||||
{
|
||||
if (!mScrollAreaBox) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIView* view = mScrollAreaBox->GetView();
|
||||
if (!view) return nsnull;
|
||||
|
||||
nsIScrollableView* scrollingView = view->ToScrollableView();
|
||||
NS_ASSERTION(scrollingView,
|
||||
"assertion gfx scrollframe does not contain a scrollframe");
|
||||
return scrollingView;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGfxScrollFrameInner::AddHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnTop)
|
||||
{
|
||||
|
@ -1695,131 +1672,6 @@ nsGfxScrollFrameInner::AdjustReflowStateBack(nsBoxLayoutState& aState, PRBool aS
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::LayoutScrollArea(nsBoxLayoutState& aState, const nsRect& aRect)
|
||||
{
|
||||
nsIView* scrollView = mScrollableView->View();
|
||||
nsIViewManager* vm = scrollView->GetViewManager();
|
||||
vm->MoveViewTo(scrollView, aRect.x, aRect.y);
|
||||
vm->ResizeView(scrollView, nsRect(nsPoint(0, 0), aRect.Size()), PR_TRUE);
|
||||
|
||||
PRUint32 oldflags = aState.LayoutFlags();
|
||||
// set the origin of childRect to (0,0) even though we might have borders or
|
||||
// a left-hand-side scrollbar. We're going to account for that by positioning the
|
||||
// anonymous mScrollableView.
|
||||
nsRect childRect = nsRect(nsPoint(0, 0), aRect.Size());
|
||||
PRBool isBoxWrapped = mScrolledFrame->IsBoxWrapped();
|
||||
|
||||
// see if our child is html. If it is then
|
||||
// never include the overflow. The child will be the size
|
||||
// given but its view will include the overflow size.
|
||||
if (isBoxWrapped)
|
||||
mScrolledFrame->SetIncludeOverflow(PR_FALSE);
|
||||
|
||||
PRInt32 flags = NS_FRAME_NO_MOVE_VIEW;
|
||||
|
||||
// if the child is not a box, then we can't use
|
||||
// min size. the child technically can get as small as it wants
|
||||
// to.
|
||||
if (!isBoxWrapped) {
|
||||
nsSize min(0,0);
|
||||
mScrolledFrame->GetMinSize(aState, min);
|
||||
|
||||
if (min.height > childRect.height)
|
||||
childRect.height = min.height;
|
||||
|
||||
if (min.width > childRect.width)
|
||||
childRect.width = min.width;
|
||||
} else {
|
||||
// don't size the view if our child isn't a box
|
||||
flags |= NS_FRAME_NO_SIZE_VIEW;
|
||||
}
|
||||
|
||||
aState.SetLayoutFlags(flags);
|
||||
mScrolledFrame->SetBounds(aState, childRect);
|
||||
mScrolledFrame->Layout(aState);
|
||||
|
||||
childRect = mScrolledFrame->GetRect();
|
||||
|
||||
// now size the view to the size including our overflow.
|
||||
if (isBoxWrapped) {
|
||||
nsSize overflow(0,0);
|
||||
mScrolledFrame->GetOverflow(overflow);
|
||||
childRect.width = overflow.width;
|
||||
childRect.height = overflow.height;
|
||||
}
|
||||
|
||||
if (childRect.width < aRect.width || childRect.height < aRect.height)
|
||||
{
|
||||
childRect.width = PR_MAX(childRect.width, aRect.width);
|
||||
childRect.height = PR_MAX(childRect.height, aRect.height);
|
||||
|
||||
// remove overflow area when we update the bounds,
|
||||
// because we've already accounted for it
|
||||
mScrolledFrame->SetBounds(aState, childRect, PR_TRUE);
|
||||
}
|
||||
|
||||
aState.SetLayoutFlags(oldflags);
|
||||
|
||||
if (isBoxWrapped) {
|
||||
nsRect r(0, 0, childRect.width, childRect.height);
|
||||
nsContainerFrame::SyncFrameViewAfterReflow(mScrolledFrame->GetPresContext(), mScrolledFrame,
|
||||
mScrolledFrame->GetView(), &r, NS_FRAME_NO_MOVE_VIEW);
|
||||
}
|
||||
|
||||
mScrollableView->ComputeScrollOffsets(PR_TRUE);
|
||||
|
||||
childRect = mScrolledFrame->GetRect();
|
||||
|
||||
// first see what changed
|
||||
PRBool vertChanged = PR_FALSE;
|
||||
PRBool horizChanged = PR_FALSE;
|
||||
|
||||
if (mVerticalOverflow && childRect.height <= aRect.height) {
|
||||
mVerticalOverflow = PR_FALSE;
|
||||
vertChanged = PR_TRUE;
|
||||
} else if (childRect.height > aRect.height) {
|
||||
// XXX we fire an event every time we reflow with overflowing height. Do
|
||||
// we really need to?
|
||||
if (!mVerticalOverflow) {
|
||||
mVerticalOverflow = PR_TRUE;
|
||||
}
|
||||
vertChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
if (mHorizontalOverflow && childRect.width <= aRect.width) {
|
||||
mHorizontalOverflow = PR_FALSE;
|
||||
horizChanged = PR_TRUE;
|
||||
} else if (childRect.width > aRect.width) {
|
||||
// XXX we fire an event every time we reflow with overflowing width. Do
|
||||
// we really need to?
|
||||
if (!mHorizontalOverflow) {
|
||||
mHorizontalOverflow = PR_TRUE;
|
||||
}
|
||||
horizChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
// if either changed
|
||||
if (vertChanged || horizChanged)
|
||||
{
|
||||
// are there 2 events or 1?
|
||||
if (vertChanged && horizChanged) {
|
||||
if (mVerticalOverflow == mHorizontalOverflow)
|
||||
{
|
||||
// both either overflowed or underflowed. 1 event
|
||||
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::both);
|
||||
} else {
|
||||
// one overflowed and one underflowed
|
||||
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
|
||||
PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
|
||||
}
|
||||
} else if (vertChanged) // only one changed either vert or horiz
|
||||
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
|
||||
else
|
||||
PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflow the scroll area if it needs it and return its size. Also determine if the reflow will
|
||||
* cause any of the scrollbars to need to be reflowed.
|
||||
|
@ -1905,10 +1757,11 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
|
|||
if (mHasVerticalScrollbar)
|
||||
AddVerticalScrollbar(aState, scrollAreaRect, scrollBarRight);
|
||||
|
||||
nsRect oldScrollAreaBounds = mScrollableView->View()->GetBounds();
|
||||
nsRect oldScrollAreaBounds;
|
||||
mScrollAreaBox->GetClientRect(oldScrollAreaBounds);
|
||||
|
||||
// layout our the scroll area
|
||||
LayoutScrollArea(aState, scrollAreaRect);
|
||||
LayoutBox(aState, mScrollAreaBox, scrollAreaRect);
|
||||
|
||||
// now look at the content area and see if we need scrollbars or not
|
||||
PRBool needsLayout = PR_FALSE;
|
||||
|
@ -1944,7 +1797,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
|
|||
resizeState.SetLayoutReason(nsBoxLayoutState::Resize);
|
||||
PRBool setBack;
|
||||
AdjustReflowStateForPrintPreview(aState, setBack);
|
||||
LayoutScrollArea(resizeState, scrollAreaRect);
|
||||
LayoutBox(resizeState, mScrollAreaBox, scrollAreaRect);
|
||||
AdjustReflowStateBack(aState, setBack);
|
||||
needsLayout = PR_FALSE;
|
||||
}
|
||||
|
@ -1984,6 +1837,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
|
|||
if (textControl) {
|
||||
needsLayout = PR_TRUE;
|
||||
reflowState->mRightEdge = scrolledContentSize.width;
|
||||
mScrollAreaBox->MarkDirty(aState);
|
||||
}
|
||||
}
|
||||
#endif // IBMBIDI
|
||||
|
@ -2004,7 +1858,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
|
|||
resizeState.SetLayoutReason(nsBoxLayoutState::Resize);
|
||||
PRBool setBack;
|
||||
AdjustReflowStateForPrintPreview(aState, setBack);
|
||||
LayoutScrollArea(resizeState, scrollAreaRect);
|
||||
LayoutBox(resizeState, mScrollAreaBox, scrollAreaRect);
|
||||
AdjustReflowStateBack(aState, setBack);
|
||||
needsLayout = PR_FALSE;
|
||||
#ifdef IBMBIDI
|
||||
|
@ -2110,7 +1964,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
|
|||
if (needsLayout) {
|
||||
nsBoxLayoutState resizeState(aState);
|
||||
resizeState.SetLayoutReason(nsBoxLayoutState::Resize);
|
||||
LayoutScrollArea(resizeState, scrollAreaRect);
|
||||
LayoutBox(resizeState, mScrollAreaBox, scrollAreaRect);
|
||||
needsLayout = PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2212,18 +2066,33 @@ nsGfxScrollFrameInner::SetAttribute(nsIBox* aBox, nsIAtom* aAtom, nscoord aSize,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the area that lies inside the scrollbars but clips the scrolled frame
|
||||
*/
|
||||
nsSize
|
||||
nsGfxScrollFrameInner::GetScrolledSize() const
|
||||
{
|
||||
nsRect r = mScrolledFrame->GetOverflowRect();
|
||||
return nsSize(r.XMost(), r.YMost());
|
||||
// our scrolled size is the size of our scrolled view.
|
||||
nsIBox* child = nsnull;
|
||||
mScrollAreaBox->GetChildBox(&child);
|
||||
nsIView* view = child->GetView();
|
||||
NS_ASSERTION(view,"Scrolled frame must have a view!!!");
|
||||
|
||||
nsRect rect = view->GetBounds();
|
||||
nsSize size(rect.width, rect.height);
|
||||
|
||||
nsBox::AddMargin(child, size);
|
||||
nsBox::AddBorderAndPadding(mScrollAreaBox, size);
|
||||
nsBox::AddInset(mScrollAreaBox, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
nsMargin
|
||||
nsGfxScrollFrameInner::GetActualScrollbarSizes() const {
|
||||
nsRect contentRect;
|
||||
mOuter->GetClientRect(contentRect);
|
||||
nsRect scrollArea = mScrollableView->View()->GetBounds();
|
||||
nsRect scrollArea = mScrollAreaBox->GetRect();
|
||||
|
||||
return nsMargin(scrollArea.x - contentRect.x, scrollArea.y - contentRect.y,
|
||||
contentRect.XMost() - scrollArea.XMost(),
|
||||
|
@ -2359,6 +2228,7 @@ nsGfxScrollFrameInner::RestoreState(nsPresState* aState)
|
|||
if (scrollingView) {
|
||||
scrollingView->GetScrollPosition(mLastPos.x, mLastPos.y);
|
||||
} else {
|
||||
// Our scrollboxframe probably hasn't been constructed yet.
|
||||
mLastPos = nsPoint(0, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
class nsISupportsArray;
|
||||
class nsIScrollableView;
|
||||
|
@ -70,18 +69,8 @@ public:
|
|||
// reload our child frame list.
|
||||
// We need this if a scrollbar frame is recreated.
|
||||
void ReloadChildFrames();
|
||||
PRBool NeedsClipWidget() const;
|
||||
void CreateScrollableView();
|
||||
|
||||
void CreateAnonymousContent(nsISupportsArray& aAnonymousChildren);
|
||||
void PostScrollPortEvent(PRBool aOverflow, nsScrollPortEvent::orientType aType);
|
||||
|
||||
nsresult GetChildContentAndOffsetsFromPoint(nsPresContext* aCX,
|
||||
const nsPoint& aPoint,
|
||||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent);
|
||||
|
||||
// nsIScrollPositionListener
|
||||
|
||||
|
@ -97,38 +86,41 @@ public:
|
|||
|
||||
nsresult Layout(nsBoxLayoutState& aState);
|
||||
nsresult LayoutBox(nsBoxLayoutState& aState, nsIBox* aBox, const nsRect& aRect);
|
||||
void LayoutScrollArea(nsBoxLayoutState& aState, const nsRect& aRect);
|
||||
|
||||
// Like ScrollPositionDidChange, but initiated by this frame rather than from the
|
||||
// scrolling view
|
||||
void InternalScrollPositionDidChange(nscoord aX, nscoord aY);
|
||||
|
||||
PRBool AddRemoveScrollbar(PRBool& aHasScrollbar,
|
||||
nscoord& aXY,
|
||||
nscoord& aSize,
|
||||
nscoord aSbSize,
|
||||
PRBool aOnRightOrBottom,
|
||||
PRBool aAdd);
|
||||
PRBool AddRemoveScrollbar (PRBool& aHasScrollbar,
|
||||
nscoord& aXY,
|
||||
nscoord& aSize,
|
||||
nscoord aSbSize,
|
||||
PRBool aOnRightOrBottom,
|
||||
PRBool aAdd);
|
||||
|
||||
PRBool AddRemoveScrollbar(nsBoxLayoutState& aState,
|
||||
nsRect& aScrollAreaSize,
|
||||
PRBool aOnTop,
|
||||
PRBool aHorizontal,
|
||||
PRBool aAdd);
|
||||
PRBool AddRemoveScrollbar(nsBoxLayoutState& aState,
|
||||
nsRect& aScrollAreaSize,
|
||||
PRBool aOnTop,
|
||||
PRBool aHorizontal,
|
||||
PRBool aAdd);
|
||||
|
||||
PRBool AddHorizontalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
|
||||
PRBool AddVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
|
||||
void RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
|
||||
void RemoveVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
|
||||
PRBool AddHorizontalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
|
||||
PRBool AddVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
|
||||
void RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
|
||||
void RemoveVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
|
||||
|
||||
nsIScrollableView* GetScrollableView() const { return mScrollableView; }
|
||||
nsIScrollableView* GetScrollableView() const;
|
||||
|
||||
void ScrollToRestoredPosition();
|
||||
|
||||
nsPresState* SaveState();
|
||||
void RestoreState(nsPresState* aState);
|
||||
|
||||
nsIFrame* GetScrolledFrame() const { return mScrolledFrame; }
|
||||
nsIFrame* GetScrolledFrame() const {
|
||||
nsIFrame* childBox;
|
||||
mScrollAreaBox->GetChildBox(&childBox);
|
||||
return childBox;
|
||||
}
|
||||
|
||||
void ScrollbarChanged(nsPresContext* aPresContext, nscoord aX, nscoord aY, PRUint32 aFlags);
|
||||
|
||||
|
@ -139,10 +131,9 @@ public:
|
|||
void AdjustReflowStateForPrintPreview(nsBoxLayoutState& aState, PRBool& aSetBack);
|
||||
void AdjustReflowStateBack(nsBoxLayoutState& aState, PRBool aSetBack);
|
||||
|
||||
nsIScrollableView* mScrollableView;
|
||||
nsIBox* mHScrollbarBox;
|
||||
nsIBox* mVScrollbarBox;
|
||||
nsIFrame* mScrolledFrame;
|
||||
nsIBox* mScrollAreaBox;
|
||||
nsIBox* mScrollCornerBox;
|
||||
nscoord mOnePixel;
|
||||
nsBoxFrame* mOuter;
|
||||
|
@ -156,15 +147,14 @@ public:
|
|||
// value that indicates "not set")
|
||||
PRInt16 mLastDir;
|
||||
|
||||
PRPackedBool mNeverHasVerticalScrollbar:1;
|
||||
PRPackedBool mNeverHasHorizontalScrollbar:1;
|
||||
PRPackedBool mHasVerticalScrollbar:1;
|
||||
PRPackedBool mHasHorizontalScrollbar:1;
|
||||
PRPackedBool mViewInitiatedScroll:1;
|
||||
PRPackedBool mFrameInitiatedScroll:1;
|
||||
PRPackedBool mDidHistoryRestore:1;
|
||||
PRPackedBool mHorizontalOverflow:1;
|
||||
PRPackedBool mVerticalOverflow:1;
|
||||
PRPackedBool mNeverHasVerticalScrollbar;
|
||||
PRPackedBool mNeverHasHorizontalScrollbar;
|
||||
|
||||
PRPackedBool mHasVerticalScrollbar;
|
||||
PRPackedBool mHasHorizontalScrollbar;
|
||||
PRPackedBool mViewInitiatedScroll;
|
||||
PRPackedBool mFrameInitiatedScroll;
|
||||
PRPackedBool mDidHistoryRestore;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -218,22 +208,12 @@ public:
|
|||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent) {
|
||||
return mInner.GetChildContentAndOffsetsFromPoint(aCX, aPoint, aNewContent, aContentOffset,
|
||||
aContentOffsetEnd, aBeginFrameContent);
|
||||
}
|
||||
PRBool& aBeginFrameContent);
|
||||
|
||||
virtual nsIFrame* GetContentInsertionFrame() {
|
||||
return mInner.GetScrolledFrame()->GetContentInsertionFrame();
|
||||
}
|
||||
|
||||
virtual nsIView* GetMouseCapturer() const {
|
||||
return mInner.GetScrolledFrame()->GetView();
|
||||
}
|
||||
|
||||
virtual PRBool TypeAlwaysNeedsView() { return PR_TRUE; }
|
||||
virtual PRBool DoesClipChildren() { return PR_TRUE; }
|
||||
|
||||
// nsIAnonymousContentCreator
|
||||
NS_IMETHOD CreateAnonymousContent(nsPresContext* aPresContext,
|
||||
nsISupportsArray& aAnonymousItems);
|
||||
|
@ -366,22 +346,12 @@ public:
|
|||
nsIContent ** aNewContent,
|
||||
PRInt32& aContentOffset,
|
||||
PRInt32& aContentOffsetEnd,
|
||||
PRBool& aBeginFrameContent) {
|
||||
return mInner.GetChildContentAndOffsetsFromPoint(aCX, aPoint, aNewContent, aContentOffset,
|
||||
aContentOffsetEnd, aBeginFrameContent);
|
||||
}
|
||||
PRBool& aBeginFrameContent);
|
||||
|
||||
virtual nsIFrame* GetContentInsertionFrame() {
|
||||
return mInner.GetScrolledFrame()->GetContentInsertionFrame();
|
||||
}
|
||||
|
||||
virtual nsIView* GetMouseCapturer() const {
|
||||
return mInner.GetScrolledFrame()->GetView();
|
||||
}
|
||||
|
||||
virtual PRBool TypeAlwaysNeedsView() { return PR_TRUE; }
|
||||
virtual PRBool DoesClipChildren() { return PR_TRUE; }
|
||||
|
||||
// nsIAnonymousContentCreator
|
||||
NS_IMETHOD CreateAnonymousContent(nsPresContext* aPresContext,
|
||||
nsISupportsArray& aAnonymousItems);
|
||||
|
|
|
@ -706,17 +706,12 @@ public:
|
|||
nsFramePaintLayer aWhichLayer,
|
||||
PRUint32 aFlags = 0) = 0;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Does the frame paint its background? If not, then all or part of it will be
|
||||
* painted by ancestors.
|
||||
*/
|
||||
virtual PRBool CanPaintBackground() { return PR_TRUE; }
|
||||
|
||||
/**
|
||||
* Does this frame type always need a view?
|
||||
*/
|
||||
virtual PRBool TypeAlwaysNeedsView() { return PR_FALSE; }
|
||||
|
||||
/**
|
||||
* Event handling of GUI events.
|
||||
*
|
||||
|
|
|
@ -86,7 +86,6 @@ public:
|
|||
|
||||
virtual nsIAtom* GetType() const;
|
||||
virtual PRBool SupportsVisibilityHidden() { return PR_FALSE; }
|
||||
virtual PRBool TypeAlwaysNeedsView() { return PR_TRUE; }
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsCSSRendering.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsScrollBoxFrame.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsBoxLayoutState.h"
|
||||
#include "nsIScrollbarMediator.h"
|
||||
|
@ -60,6 +61,524 @@
|
|||
#include "nsITimer.h"
|
||||
#include "nsRepeatService.h"
|
||||
|
||||
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsScrollBoxFrame* it = new (aPresShell) nsScrollBoxFrame (aPresShell);
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsScrollBoxFrame::nsScrollBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell), mVerticalOverflow(PR_FALSE), mHorizontalOverflow(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsScrollBoxFrame::NeedsClipWidget()
|
||||
{
|
||||
// Scrollports contained in form controls (e.g., listboxes) don't get
|
||||
// widgets.
|
||||
for (nsIFrame* parentFrame = GetParent(); parentFrame;
|
||||
parentFrame = parentFrame->GetParent()) {
|
||||
nsIFormControlFrame* fcFrame;
|
||||
if ((NS_SUCCEEDED(parentFrame->QueryInterface(NS_GET_IID(nsIFormControlFrame), (void**)&fcFrame)))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Scrollports that don't ever show associated scrollbars don't get
|
||||
// widgets, because they will seldom actually be scrolled.
|
||||
nsIFrame* parent = GetParent();
|
||||
if (!parent)
|
||||
return nsnull;
|
||||
nsCOMPtr<nsIScrollableFrame> scrollFrame = do_QueryInterface(parent);
|
||||
if (scrollFrame) {
|
||||
nsGfxScrollFrameInner::ScrollbarStyles scrollbars
|
||||
= scrollFrame->GetScrollbarStyles();
|
||||
if ((scrollbars.mHorizontal == NS_STYLE_OVERFLOW_HIDDEN
|
||||
|| scrollbars.mHorizontal == NS_STYLE_OVERFLOW_VISIBLE)
|
||||
&& (scrollbars.mVertical == NS_STYLE_OVERFLOW_HIDDEN
|
||||
|| scrollbars.mVertical == NS_STYLE_OVERFLOW_VISIBLE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::Init(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::Init(aPresContext, aContent,
|
||||
aParent, aStyleContext,
|
||||
aPrevInFlow);
|
||||
|
||||
// Create the scrolling view
|
||||
CreateScrollingView();
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::SetInitialChildList(nsPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::SetInitialChildList(aPresContext, aListName,
|
||||
aChildList);
|
||||
|
||||
SetUpScrolledFrame();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollBoxFrame::SetUpScrolledFrame()
|
||||
{
|
||||
NS_ASSERTION(mFrames.GetLength() <= 1, "ScrollBoxes can only have 1 child!");
|
||||
|
||||
|
||||
nsIFrame* frame = mFrames.FirstChild();
|
||||
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
// create a view if we don't already have one.
|
||||
nsHTMLContainerFrame::CreateViewForFrame(frame, nsnull, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::AppendFrames(nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::AppendFrames(aListName, aFrameList);
|
||||
|
||||
// make sure we only have 1 child.
|
||||
NS_ASSERTION(!mFrames.FirstChild()->GetNextSibling(), "Error ScrollBoxes can only have 1 child");
|
||||
|
||||
SetUpScrolledFrame();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::InsertFrames(nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::InsertFrames(aListName, aPrevFrame, aFrameList);
|
||||
|
||||
// make sure we only have 1 child.
|
||||
NS_ASSERTION(!mFrames.FirstChild()->GetNextSibling(), "Error ScrollBoxes can only have 1 child");
|
||||
|
||||
SetUpScrolledFrame();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::RemoveFrame(aListName, aOldFrame);
|
||||
|
||||
SetUpScrolledFrame();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollBoxFrame::CreateScrollingViewWidget(nsIView* aView, const nsStyleDisplay* aDisplay)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// If it's fixed positioned, then create a widget
|
||||
if (NS_STYLE_POSITION_FIXED == aDisplay->mPosition) {
|
||||
rv = aView->CreateWidget(kWidgetCID);
|
||||
}
|
||||
|
||||
return(rv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollBoxFrame::GetScrollingParentView(nsIFrame* aParent,
|
||||
nsIView** aParentView)
|
||||
{
|
||||
*aParentView = aParent->GetView();
|
||||
NS_ASSERTION(*aParentView, "GetParentWithView failed");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIView*
|
||||
nsScrollBoxFrame::GetMouseCapturer() const
|
||||
{
|
||||
nsIScrollableView* scrollingView = GetView()->ToScrollableView();
|
||||
NS_ASSERTION(scrollingView,
|
||||
"Scrollbox does not contain a scrolling view?");
|
||||
nsIView* view;
|
||||
scrollingView->GetScrolledView(view);
|
||||
NS_ASSERTION(view, "Scrolling view does not have a scrolled view");
|
||||
return view;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollBoxFrame::CreateScrollingView()
|
||||
{
|
||||
//Get parent frame
|
||||
nsIFrame* parent = GetAncestorWithView();
|
||||
NS_ASSERTION(parent, "GetParentWithView failed");
|
||||
|
||||
// Get parent view
|
||||
nsIView* parentView = nsnull;
|
||||
GetScrollingParentView(parent, &parentView);
|
||||
|
||||
// Get the view manager
|
||||
nsIViewManager* viewManager = parentView->GetViewManager();
|
||||
|
||||
// Create the scrolling view
|
||||
nsIScrollableView* scrollingView = viewManager->CreateScrollableView(mRect, parentView);
|
||||
|
||||
if (scrollingView) {
|
||||
// Initialize the scrolling view
|
||||
nsIView* view = scrollingView->View();
|
||||
|
||||
SyncFrameViewProperties(GetPresContext(), this, mStyleContext, view);
|
||||
|
||||
// Insert the view into the view hierarchy
|
||||
// XXX Put view last in document order until we know how to do better
|
||||
viewManager->InsertChild(parentView, view, nsnull, PR_TRUE);
|
||||
|
||||
// If it's fixed positioned, then create a widget too
|
||||
CreateScrollingViewWidget(view, GetStyleDisplay());
|
||||
|
||||
// Have the scrolling view create its internal widgets
|
||||
if (NeedsClipWidget()) {
|
||||
scrollingView->CreateScrollControls();
|
||||
}
|
||||
|
||||
// Remember our view
|
||||
SetView(view);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetMargin(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetPadding(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetBorder(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::DoLayout(nsBoxLayoutState& aState)
|
||||
{
|
||||
PRUint32 oldflags = aState.LayoutFlags();
|
||||
|
||||
nsRect clientRect(0,0,0,0);
|
||||
GetClientRect(clientRect);
|
||||
nsIBox* kid = nsnull;
|
||||
GetChildBox(&kid);
|
||||
nsRect childRect(clientRect);
|
||||
nsMargin margin(0,0,0,0);
|
||||
kid->GetMargin(margin);
|
||||
childRect.Deflate(margin);
|
||||
|
||||
nsPresContext* presContext = aState.PresContext();
|
||||
|
||||
PRBool isBoxWrapped = kid->IsBoxWrapped();
|
||||
|
||||
// see if our child is html. If it is then
|
||||
// never include the overflow. The child will be the size
|
||||
// given but its view will include the overflow size.
|
||||
if (isBoxWrapped)
|
||||
kid->SetIncludeOverflow(PR_FALSE);
|
||||
|
||||
PRInt32 flags = NS_FRAME_NO_MOVE_VIEW;
|
||||
|
||||
// if the child is not a box, then we can't use
|
||||
// min size. the child technically can get as small as it wants
|
||||
// to.
|
||||
if (!isBoxWrapped) {
|
||||
nsSize min(0,0);
|
||||
kid->GetMinSize(aState, min);
|
||||
|
||||
if (min.height > childRect.height)
|
||||
childRect.height = min.height;
|
||||
|
||||
if (min.width > childRect.width)
|
||||
childRect.width = min.width;
|
||||
} else {
|
||||
// don't size the view if our child isn't a box
|
||||
flags |= NS_FRAME_NO_SIZE_VIEW;
|
||||
}
|
||||
|
||||
aState.SetLayoutFlags(flags);
|
||||
kid->SetBounds(aState, childRect);
|
||||
kid->Layout(aState);
|
||||
|
||||
childRect = kid->GetRect();
|
||||
|
||||
clientRect.Inflate(margin);
|
||||
|
||||
// now size the view to the size including our overflow.
|
||||
if (isBoxWrapped) {
|
||||
nsSize overflow(0,0);
|
||||
kid->GetOverflow(overflow);
|
||||
childRect.width = overflow.width;
|
||||
childRect.height = overflow.height;
|
||||
}
|
||||
|
||||
if (childRect.width < clientRect.width || childRect.height < clientRect.height)
|
||||
{
|
||||
if (childRect.width < clientRect.width)
|
||||
childRect.width = clientRect.width;
|
||||
|
||||
if (childRect.height < clientRect.height)
|
||||
childRect.height = clientRect.height;
|
||||
|
||||
clientRect.Deflate(margin);
|
||||
|
||||
// remove overflow area when we update the bounds,
|
||||
// because we've already accounted for it
|
||||
kid->SetBounds(aState, childRect, PR_TRUE);
|
||||
}
|
||||
|
||||
aState.SetLayoutFlags(oldflags);
|
||||
|
||||
SyncLayout(aState);
|
||||
|
||||
if (isBoxWrapped) {
|
||||
nsRect r(0, 0, childRect.width, childRect.height);
|
||||
nsContainerFrame::SyncFrameViewAfterReflow(presContext, kid,
|
||||
kid->GetView(), &r, NS_FRAME_NO_MOVE_VIEW);
|
||||
}
|
||||
|
||||
nsIView* view = GetView();
|
||||
nsIScrollableView* scrollingView = view->ToScrollableView();
|
||||
if (scrollingView) {
|
||||
scrollingView->ComputeScrollOffsets(PR_TRUE);
|
||||
}
|
||||
|
||||
childRect = kid->GetRect();
|
||||
|
||||
// first see what changed
|
||||
PRBool vertChanged = PR_FALSE;
|
||||
PRBool horizChanged = PR_FALSE;
|
||||
|
||||
if (mVerticalOverflow && childRect.height <= mRect.height) {
|
||||
mVerticalOverflow = PR_FALSE;
|
||||
vertChanged = PR_TRUE;
|
||||
} else if (childRect.height > mRect.height) {
|
||||
if (!mVerticalOverflow) {
|
||||
mVerticalOverflow = PR_TRUE;
|
||||
}
|
||||
vertChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
if (mHorizontalOverflow && childRect.width <= mRect.width) {
|
||||
mHorizontalOverflow = PR_FALSE;
|
||||
horizChanged = PR_TRUE;
|
||||
} else if (childRect.width > mRect.width) {
|
||||
if (!mHorizontalOverflow) {
|
||||
mHorizontalOverflow = PR_TRUE;
|
||||
}
|
||||
horizChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
// if either changed
|
||||
if (vertChanged || horizChanged)
|
||||
{
|
||||
// are there 2 events or 1?
|
||||
if (vertChanged && horizChanged) {
|
||||
if (mVerticalOverflow == mHorizontalOverflow)
|
||||
{
|
||||
// both either overflowed or underflowed. 1 event
|
||||
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::both);
|
||||
} else {
|
||||
// one overflowed and one underflowed
|
||||
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
|
||||
PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
|
||||
}
|
||||
} else if (vertChanged) // only one changed either vert or horiz
|
||||
PostScrollPortEvent(mVerticalOverflow, nsScrollPortEvent::vertical);
|
||||
else
|
||||
PostScrollPortEvent(mHorizontalOverflow, nsScrollPortEvent::horizontal);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollBoxFrame::PostScrollPortEvent(PRBool aOverflow, nsScrollPortEvent::orientType aType)
|
||||
{
|
||||
if (!mContent)
|
||||
return;
|
||||
|
||||
nsScrollPortEvent* event = new nsScrollPortEvent(aOverflow ?
|
||||
NS_SCROLLPORT_OVERFLOW :
|
||||
NS_SCROLLPORT_UNDERFLOW);
|
||||
event->orient = aType;
|
||||
GetPresContext()->PresShell()->PostDOMEvent(mContent, event);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetAscent(nsBoxLayoutState& aState, nscoord& aAscent)
|
||||
{
|
||||
aAscent = 0;
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetAscent(aState, aAscent);
|
||||
nsMargin m(0,0,0,0);
|
||||
GetBorderAndPadding(m);
|
||||
aAscent += m.top;
|
||||
GetMargin(m);
|
||||
aAscent += m.top;
|
||||
GetInset(m);
|
||||
aAscent += m.top;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetPrefSize(aBoxLayoutState, aSize);
|
||||
AddMargin(child, aSize);
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, aSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
aSize = child->GetMinSizeForScrollArea(aBoxLayoutState);
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMinSize(aBoxLayoutState, this, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetMaxSize(aBoxLayoutState, aSize);
|
||||
AddMargin(child, aSize);
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMaxSize(aBoxLayoutState, this, aSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::Paint(nsPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsFramePaintLayer aWhichLayer,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
|
||||
// Only paint the border and background if we're visible
|
||||
|
||||
if (GetStyleVisibility()->IsVisibleOrCollapsed()) {
|
||||
// Paint our border only (no background)
|
||||
const nsStyleBorder* border = GetStyleBorder();
|
||||
|
||||
nsRect rect(0, 0, mRect.width, mRect.height);
|
||||
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
|
||||
aDirtyRect, rect, *border, mStyleContext, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Paint our children
|
||||
nsBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
|
||||
|
||||
// Call nsFrame::Paint to draw selection border when appropriate
|
||||
return nsFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollBoxFrame::GetContentOf(nsIContent** aContent)
|
||||
{
|
||||
*aContent = GetContent();
|
||||
NS_IF_ADDREF(*aContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
nsScrollBoxFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::scrollFrame;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("ScrollBox"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsScrollBoxFrame::AddRef(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsScrollBoxFrame::Release(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsScrollBoxFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIBox)
|
||||
#ifdef NS_DEBUG
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFrameDebug)
|
||||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBox)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
|
||||
class nsAutoRepeatBoxFrame : public nsButtonBoxFrame,
|
||||
public nsITimerCallback
|
||||
{
|
||||
|
|
|
@ -41,4 +41,102 @@
|
|||
#include "nsIStatefulFrame.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
/**
|
||||
* The scroll frame creates and manages the scrolling view
|
||||
*
|
||||
* It only supports having a single child frame that typically is an area
|
||||
* frame, but doesn't have to be. The child frame must have a view, though
|
||||
*
|
||||
* Scroll frames don't support incremental changes, i.e. you can't replace
|
||||
* or remove the scrolled frame
|
||||
*/
|
||||
class nsScrollBoxFrame : public nsBoxFrame {
|
||||
public:
|
||||
friend nsresult NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD Init(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
// Called to set the one and only child frame. Returns NS_ERROR_INVALID_ARG
|
||||
// if the child frame is NULL, and NS_ERROR_UNEXPECTED if the child list
|
||||
// contains more than one frame
|
||||
NS_IMETHOD SetInitialChildList(nsPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList);
|
||||
|
||||
// Because there can be only one child frame, these two function return
|
||||
// NS_ERROR_FAILURE
|
||||
NS_IMETHOD AppendFrames(nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
// This function returns NS_ERROR_NOT_IMPLEMENTED
|
||||
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
|
||||
NS_IMETHOD Paint(nsPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsFramePaintLayer aWhichLayer,
|
||||
PRUint32 aFlags = 0);
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::scrollFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
/**
|
||||
* This frame does clip its child (the scrolled frame).
|
||||
*/
|
||||
virtual PRBool DoesClipChildren() { return PR_TRUE; }
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||
#endif
|
||||
|
||||
// nsIBox methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
|
||||
NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
|
||||
NS_IMETHOD GetPadding(nsMargin& aMargin);
|
||||
NS_IMETHOD GetBorder(nsMargin& aMargin);
|
||||
NS_IMETHOD GetMargin(nsMargin& aMargin);
|
||||
|
||||
virtual nsresult GetContentOf(nsIContent** aContent);
|
||||
|
||||
virtual nsIView* GetMouseCapturer() const;
|
||||
|
||||
protected:
|
||||
nsScrollBoxFrame(nsIPresShell* aShell);
|
||||
|
||||
// Creation of the widget for the scrolling view is factored into a virtual method so
|
||||
// that sub-classes may control widget creation.
|
||||
virtual nsresult CreateScrollingViewWidget(nsIView* aView, const nsStyleDisplay* aDisplay);
|
||||
// Getting the view for scollframe may be overriden to provide a parent view for te scroll frame
|
||||
virtual nsresult GetScrollingParentView(nsIFrame* aParent,
|
||||
nsIView** aParentView);
|
||||
|
||||
private:
|
||||
nsresult CreateScrollingView();
|
||||
PRPackedBool mVerticalOverflow;
|
||||
PRPackedBool mHorizontalOverflow;
|
||||
|
||||
protected:
|
||||
virtual PRBool NeedsClipWidget();
|
||||
virtual void PostScrollPortEvent(PRBool aOverflow, nsScrollPortEvent::orientType aType);
|
||||
virtual void SetUpScrolledFrame();
|
||||
};
|
||||
|
||||
#endif /* nsScrollBoxFrame_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче