Back out roc's checkin for bug 288117 to isolate performance regressions during tinderbox downtime.

This commit is contained in:
dbaron%dbaron.org 2005-03-31 18:04:50 +00:00
Родитель a96b514ea0
Коммит 84a42982ba
11 изменённых файлов: 1052 добавлений и 402 удалений

Просмотреть файл

@ -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___ */