зеркало из https://github.com/mozilla/pjs.git
Bug 344228. Fix up some naughty uses of nsIScrollbarMediator. r=enndeakin,sr=bzbarsky
This commit is contained in:
Родитель
6720414ade
Коммит
361de71875
|
@ -2584,11 +2584,11 @@ nsGfxScrollFrameInner::SetScrollbarVisibility(nsIBox* aScrollbar, PRBool aVisibl
|
|||
if (!aScrollbar)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIScrollbarFrame> scrollbar(do_QueryInterface(aScrollbar));
|
||||
nsIScrollbarFrame* scrollbar;
|
||||
CallQueryInterface(aScrollbar, &scrollbar);
|
||||
if (scrollbar) {
|
||||
// See if we have a mediator.
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
scrollbar->GetScrollbarMediator(getter_AddRefs(mediator));
|
||||
nsIScrollbarMediator* mediator = scrollbar->GetScrollbarMediator();
|
||||
if (mediator) {
|
||||
// Inform the mediator of the visibility change.
|
||||
mediator->VisibilityChanged(scrollbar, aVisible);
|
||||
|
@ -2688,12 +2688,14 @@ nsGfxScrollFrameInner::SaveState(nsIStatefulFrame::SpecialStateID aStateID)
|
|||
if (mIsRoot && aStateID == nsIStatefulFrame::eNoID) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
// XXX can this actually get hit? I don't think so
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
nsIFrame* first = GetScrolledFrame();
|
||||
mediator = do_QueryInterface(first);
|
||||
if (mediator) {
|
||||
// Child manages its own scrolling. Bail.
|
||||
NS_ERROR("This code shouldn't be hit; alert robert@ocallahan.org");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,9 @@
|
|||
#ifndef nsIScrollbarFrame_h___
|
||||
#define nsIScrollbarFrame_h___
|
||||
|
||||
// {9A6B0416-4A5D-4550-BEB5-C94D18A69A94}
|
||||
// {660e5ed6-1cf7-47ff-b094-c588c21986e8}
|
||||
#define NS_ISCROLLBARFRAME_IID \
|
||||
{ 0x9a6b0416, 0x4a5d, 0x4550, { 0xbe, 0xb5, 0xc9, 0x4d, 0x18, 0xa6, 0x9a, 0x94 } }
|
||||
{ 0x660e5ed6, 0x1cf7, 0x47ff, { 0xb0, 0x94, 0xc5, 0x88, 0xc2, 0x19, 0x86, 0xe8 } }
|
||||
|
||||
static NS_DEFINE_IID(kIScrollbarFrameIID, NS_ISCROLLBARFRAME_IID);
|
||||
|
||||
|
@ -52,11 +52,14 @@ class nsIScrollbarFrame : public nsISupports {
|
|||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCROLLBARFRAME_IID)
|
||||
|
||||
NS_IMETHOD GetScrollbarMediator(nsIScrollbarMediator** aResult) = 0;
|
||||
NS_IMETHOD SetScrollbarMediator(nsIScrollbarMediator* aMediator) = 0;
|
||||
// Sets the scrollbar mediator content. We will try to get its primary frame
|
||||
// and then QI that to nsIScrollbarMediator as necessary.
|
||||
virtual void SetScrollbarMediatorContent(nsIContent* aMediator) = 0;
|
||||
|
||||
// Do NOT hold on to this.
|
||||
virtual nsIScrollbarMediator* GetScrollbarMediator() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScrollbarFrame, NS_ISCROLLBARFRAME_IID)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ nsListBoxBodyFrame::Init(nsIContent* aContent,
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIScrollbarFrame> scrollbarFrame(do_QueryInterface(verticalScrollbar));
|
||||
scrollbarFrame->SetScrollbarMediator(this);
|
||||
scrollbarFrame->SetScrollbarMediatorContent(GetContent());
|
||||
|
||||
nsBoxLayoutState boxLayoutState(presContext);
|
||||
|
||||
|
|
|
@ -64,19 +64,19 @@ NS_NewNativeScrollbarFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|||
//
|
||||
// QueryInterface
|
||||
//
|
||||
NS_INTERFACE_MAP_BEGIN(nsNativeScrollbarFrame)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
nsNativeScrollbarFrame::~nsNativeScrollbarFrame ( )
|
||||
NS_IMETHODIMP
|
||||
nsNativeScrollbarFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
// frame is going away, unhook the native scrollbar from
|
||||
// the content node just to be safe about lifetime issues
|
||||
nsCOMPtr<nsINativeScrollbar> scrollbar ( do_QueryInterface(mScrollbar) );
|
||||
if ( scrollbar )
|
||||
scrollbar->SetContent(nsnull, nsnull, nsnull);
|
||||
if (!aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsIScrollbarMediator))) {
|
||||
*aInstancePtr = (void*) ((nsIScrollbarMediator*) this);
|
||||
return NS_OK;
|
||||
}
|
||||
return nsBoxFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Init
|
||||
//
|
||||
|
@ -119,37 +119,41 @@ nsNativeScrollbarFrame::Init(nsIContent* aContent,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsNativeScrollbarFrame::Destroy()
|
||||
{
|
||||
nsCOMPtr<nsINativeScrollbar> scrollbar(do_QueryInterface(mScrollbar));
|
||||
if (scrollbar) {
|
||||
// frame is going away, unhook the native scrollbar from
|
||||
// the content node just to be safe about lifetime issues
|
||||
scrollbar->SetContent(nsnull, nsnull, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FindScrollbar
|
||||
// FindParts
|
||||
//
|
||||
// Walk up the parent frame tree and find the content node of the frame
|
||||
// with the tag "scrollbar". This is the content node that the GFX Scroll Frame
|
||||
// is watching for attribute changes.
|
||||
// is watching for attribute changes. We return the associated frame and
|
||||
// any mediator.
|
||||
//
|
||||
nsresult
|
||||
nsNativeScrollbarFrame::FindScrollbar(nsIFrame* start, nsIFrame** outFrame,
|
||||
nsIContent** outContent)
|
||||
nsNativeScrollbarFrame::Parts
|
||||
nsNativeScrollbarFrame::FindParts()
|
||||
{
|
||||
*outContent = nsnull;
|
||||
*outFrame = nsnull;
|
||||
|
||||
while ( start ) {
|
||||
start = start->GetParent();
|
||||
if ( start ) {
|
||||
// get the content node
|
||||
nsIContent* currContent = start->GetContent();
|
||||
nsIFrame* f;
|
||||
for (f = GetParent(); f; f = f->GetParent()) {
|
||||
nsIContent* currContent = f->GetContent();
|
||||
|
||||
if (currContent && currContent->Tag() == nsXULAtoms::scrollbar) {
|
||||
*outContent = currContent;
|
||||
*outFrame = start;
|
||||
NS_ADDREF(*outContent);
|
||||
return NS_OK;
|
||||
}
|
||||
if (currContent && currContent->Tag() == nsXULAtoms::scrollbar) {
|
||||
nsIScrollbarFrame* sb;
|
||||
CallQueryInterface(f, &sb);
|
||||
if (sb)
|
||||
return Parts(f, sb, sb->GetScrollbarMediator());
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return Parts(nsnull, nsnull, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -213,20 +217,15 @@ nsNativeScrollbarFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
PRInt32 oldPosition = (PRInt32)current;
|
||||
PRInt32 curPosition = maxValue;
|
||||
|
||||
nsCOMPtr<nsIContent> scrollbarContent;
|
||||
nsIFrame* sbFrame = nsnull;
|
||||
FindScrollbar(this, &sbFrame, getter_AddRefs(scrollbarContent));
|
||||
nsCOMPtr<nsIScrollbarFrame> scrollbarFrame(do_QueryInterface(sbFrame));
|
||||
if (scrollbarFrame) {
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
scrollbarFrame->GetScrollbarMediator(getter_AddRefs(mediator));
|
||||
if (mediator)
|
||||
mediator->PositionChanged(scrollbarFrame, oldPosition, /* inout */ curPosition);
|
||||
Parts parts = FindParts();
|
||||
if (parts.mMediator) {
|
||||
parts.mMediator->PositionChanged(parts.mIScrollbarFrame, oldPosition, /* inout */ curPosition);
|
||||
}
|
||||
|
||||
nsAutoString currentStr;
|
||||
currentStr.AppendInt(curPosition);
|
||||
scrollbarContent->SetAttr(kNameSpaceID_None, nsXULAtoms::curpos, currentStr, PR_TRUE);
|
||||
parts.mScrollbarFrame->GetContent()->
|
||||
SetAttr(kNameSpaceID_None, nsXULAtoms::curpos, currentStr, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,25 +289,18 @@ nsNativeScrollbarFrame::Hookup()
|
|||
if (!mScrollbarNeedsContent)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> scrollbarContent;
|
||||
nsIFrame* scrollbarFrame = nsnull;
|
||||
FindScrollbar(this, &scrollbarFrame, getter_AddRefs(scrollbarContent));
|
||||
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
nsCOMPtr<nsIScrollbarFrame> sb(do_QueryInterface(scrollbarFrame));
|
||||
if (!sb) {
|
||||
NS_WARNING("ScrollbarFrame doesn't implement nsIScrollbarFrame");
|
||||
return;
|
||||
}
|
||||
|
||||
sb->GetScrollbarMediator(getter_AddRefs(mediator));
|
||||
nsCOMPtr<nsINativeScrollbar> scrollbar(do_QueryInterface(mScrollbar));
|
||||
if (!mScrollbar) {
|
||||
if (!scrollbar) {
|
||||
NS_WARNING("Native scrollbar widget doesn't implement nsINativeScrollbar");
|
||||
return;
|
||||
}
|
||||
|
||||
scrollbar->SetContent(scrollbarContent, sb, mediator);
|
||||
Parts parts = FindParts();
|
||||
// We can't just pass 'mediator' to the widget, because 'mediator' might go away.
|
||||
// So pass a pointer to us. When we go away, we can tell the widget.
|
||||
nsIContent* scrollbarContent = parts.mScrollbarFrame->GetContent();
|
||||
scrollbar->SetContent(scrollbarContent,
|
||||
parts.mIScrollbarFrame, parts.mMediator ? this : nsnull);
|
||||
mScrollbarNeedsContent = PR_FALSE;
|
||||
|
||||
if (!scrollbarContent)
|
||||
|
@ -328,3 +320,29 @@ nsNativeScrollbarFrame::Hookup()
|
|||
scrollbar->SetPosition(curpos);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeScrollbarFrame::PositionChanged(nsISupports* aScrollbar, PRInt32 aOldIndex, PRInt32& aNewIndex)
|
||||
{
|
||||
Parts parts = FindParts();
|
||||
if (!parts.mMediator)
|
||||
return NS_OK;
|
||||
return parts.mMediator->PositionChanged(aScrollbar, aOldIndex, aNewIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeScrollbarFrame::ScrollbarButtonPressed(nsISupports* aScrollbar, PRInt32 aOldIndex, PRInt32 aNewIndex)
|
||||
{
|
||||
Parts parts = FindParts();
|
||||
if (!parts.mMediator)
|
||||
return NS_OK;
|
||||
return parts.mMediator->ScrollbarButtonPressed(aScrollbar, aOldIndex, aNewIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeScrollbarFrame::VisibilityChanged(nsISupports* aScrollbar, PRBool aVisible)
|
||||
{
|
||||
Parts parts = FindParts();
|
||||
if (!parts.mMediator)
|
||||
return NS_OK;
|
||||
return parts.mMediator->VisibilityChanged(aScrollbar, aVisible);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include "nsScrollbarFrame.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIScrollbarMediator.h"
|
||||
|
||||
class nsISupportsArray;
|
||||
class nsIPresShell;
|
||||
|
@ -58,12 +59,11 @@ class nsStyleContext;
|
|||
|
||||
nsIFrame* NS_NewNativeScrollbarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
class nsNativeScrollbarFrame : public nsBoxFrame
|
||||
class nsNativeScrollbarFrame : public nsBoxFrame, public nsIScrollbarMediator
|
||||
{
|
||||
public:
|
||||
nsNativeScrollbarFrame(nsIPresShell* aShell, nsStyleContext* aContext):
|
||||
nsBoxFrame(aShell, aContext), mScrollbarNeedsContent(PR_TRUE) {}
|
||||
virtual ~nsNativeScrollbarFrame ( ) ;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const {
|
||||
|
@ -88,15 +88,30 @@ public:
|
|||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize);
|
||||
|
||||
|
||||
virtual void Destroy();
|
||||
|
||||
// nsIScrollbarMediator forwarding
|
||||
NS_IMETHOD PositionChanged(nsISupports* aScrollbar, PRInt32 aOldIndex, PRInt32& aNewIndex);
|
||||
NS_IMETHOD ScrollbarButtonPressed(nsISupports* aScrollbar, PRInt32 aOldIndex, PRInt32 aNewIndex);
|
||||
NS_IMETHOD VisibilityChanged(nsISupports* aScrollbar, PRBool aVisible);
|
||||
|
||||
protected:
|
||||
|
||||
void Hookup();
|
||||
|
||||
nsresult FindScrollbar(nsIFrame* start, nsIFrame** outFrame, nsIContent** outContent);
|
||||
|
||||
struct Parts {
|
||||
nsIFrame* mScrollbarFrame;
|
||||
nsIScrollbarFrame* mIScrollbarFrame;
|
||||
nsIScrollbarMediator* mMediator;
|
||||
|
||||
Parts(nsIFrame* aFrame, nsIScrollbarFrame* aIScrollbarFrame, nsIScrollbarMediator* aMediator) :
|
||||
mScrollbarFrame(aFrame), mIScrollbarFrame(aIScrollbarFrame), mMediator(aMediator) {}
|
||||
};
|
||||
Parts FindParts();
|
||||
|
||||
PRBool IsVertical() const { return mIsVertical; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
PRPackedBool mIsVertical;
|
||||
|
|
|
@ -253,10 +253,10 @@ nsScrollbarButtonFrame::DoButtonAction(PRBool aSmoothScroll)
|
|||
else if (curpos > maxpos)
|
||||
curpos = maxpos;
|
||||
|
||||
nsCOMPtr<nsIScrollbarFrame> sb(do_QueryInterface(scrollbar));
|
||||
nsIScrollbarFrame* sb;
|
||||
CallQueryInterface(scrollbar, &sb);
|
||||
if (sb) {
|
||||
nsCOMPtr<nsIScrollbarMediator> m;
|
||||
sb->GetScrollbarMediator(getter_AddRefs(m));
|
||||
nsIScrollbarMediator* m = sb->GetScrollbarMediator();
|
||||
if (m) {
|
||||
m->ScrollbarButtonPressed(sb, oldpos, curpos);
|
||||
return;
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
|
||||
#include "nsIScrollbarMediator.h"
|
||||
|
||||
//
|
||||
// NS_NewToolbarFrame
|
||||
|
@ -176,3 +176,22 @@ nsScrollbarFrame::HandleRelease(nsPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarFrame::SetScrollbarMediatorContent(nsIContent* aMediator)
|
||||
{
|
||||
mScrollbarMediator = aMediator;
|
||||
}
|
||||
|
||||
nsIScrollbarMediator*
|
||||
nsScrollbarFrame::GetScrollbarMediator()
|
||||
{
|
||||
if (!mScrollbarMediator)
|
||||
return nsnull;
|
||||
nsIFrame* f =
|
||||
GetPresContext()->PresShell()->GetPrimaryFrameFor(mScrollbarMediator);
|
||||
if (!f)
|
||||
return nsnull;
|
||||
nsIScrollbarMediator* sbm;
|
||||
CallQueryInterface(f, &sbm);
|
||||
return sbm;
|
||||
}
|
||||
|
|
|
@ -100,8 +100,8 @@ public:
|
|||
virtual PRBool IsContainingBlock() const;
|
||||
|
||||
// nsIScrollbarFrame
|
||||
NS_IMETHOD SetScrollbarMediator(nsIScrollbarMediator* aMediator) { mScrollbarMediator = aMediator; return NS_OK; };
|
||||
NS_IMETHOD GetScrollbarMediator(nsIScrollbarMediator** aResult) { *aResult = mScrollbarMediator; return NS_OK; };
|
||||
virtual void SetScrollbarMediatorContent(nsIContent* aMediator);
|
||||
virtual nsIScrollbarMediator* GetScrollbarMediator();
|
||||
|
||||
// nsBox methods
|
||||
|
||||
|
@ -113,8 +113,9 @@ public:
|
|||
* hide the children too.
|
||||
*/
|
||||
virtual PRBool DoesClipChildren() { return PR_TRUE; }
|
||||
|
||||
private:
|
||||
nsIScrollbarMediator* mScrollbarMediator;
|
||||
nsCOMPtr<nsIContent> mScrollbarMediator;
|
||||
}; // class nsScrollbarFrame
|
||||
|
||||
#endif
|
||||
|
|
|
@ -252,10 +252,10 @@ nsSliderFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
current = max;
|
||||
|
||||
// set the new position and notify observers
|
||||
nsCOMPtr<nsIScrollbarFrame> scrollbarFrame(do_QueryInterface(scrollbarBox));
|
||||
nsIScrollbarFrame* scrollbarFrame;
|
||||
CallQueryInterface(scrollbarBox, &scrollbarFrame);
|
||||
if (scrollbarFrame) {
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
scrollbarFrame->GetScrollbarMediator(getter_AddRefs(mediator));
|
||||
nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator();
|
||||
if (mediator) {
|
||||
mediator->PositionChanged(scrollbarFrame, GetCurrentPosition(scrollbar), current);
|
||||
}
|
||||
|
@ -738,14 +738,15 @@ nsSliderFrame::SetCurrentPosition(nsIContent* scrollbar, nsIFrame* aThumbFrame,
|
|||
newpos = maxpos;
|
||||
|
||||
nsIBox* scrollbarBox = GetScrollbar();
|
||||
nsCOMPtr<nsIScrollbarFrame> scrollbarFrame(do_QueryInterface(scrollbarBox));
|
||||
nsIScrollbarFrame* scrollbarFrame;
|
||||
CallQueryInterface(scrollbarBox, &scrollbarFrame);
|
||||
|
||||
if (scrollbarFrame) {
|
||||
// See if we have a mediator.
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
scrollbarFrame->GetScrollbarMediator(getter_AddRefs(mediator));
|
||||
nsIScrollbarMediator* mediator = scrollbarFrame->GetScrollbarMediator();
|
||||
if (mediator) {
|
||||
mediator->PositionChanged(scrollbarFrame, GetCurrentPosition(scrollbar), newpos);
|
||||
// 'mediator' might be dangling now...
|
||||
UpdateAttribute(scrollbar, newpos, PR_FALSE, aIsSmooth);
|
||||
CurrentPositionChanged(GetPresContext());
|
||||
return;
|
||||
|
|
|
@ -779,13 +779,13 @@ nsTreeBodyFrame::ScrollParts nsTreeBodyFrame::GetScrollParts()
|
|||
// dumb! We should know where these frames are.
|
||||
FindScrollParts(treeFrame, &result);
|
||||
if (result.mHScrollbar) {
|
||||
result.mHScrollbar->SetScrollbarMediator(this);
|
||||
result.mHScrollbar->SetScrollbarMediatorContent(GetContent());
|
||||
nsIFrame* f;
|
||||
CallQueryInterface(result.mHScrollbar, &f);
|
||||
result.mHScrollbarContent = f->GetContent();
|
||||
}
|
||||
if (result.mVScrollbar) {
|
||||
result.mVScrollbar->SetScrollbarMediator(this);
|
||||
result.mVScrollbar->SetScrollbarMediatorContent(GetContent());
|
||||
nsIFrame* f;
|
||||
CallQueryInterface(result.mVScrollbar, &f);
|
||||
result.mVScrollbarContent = f->GetContent();
|
||||
|
|
Загрузка…
Ссылка в новой задаче