event handler holds weak reference to frame. fixes bug 14885. r:buster

git-svn-id: svn://10.0.0.236/trunk@49582 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
danm%netscape.com 1999-10-01 15:04:15 +00:00
parent 1cfea69ffd
commit f8f515a025
2 changed files with 43 additions and 20 deletions

View File

@ -194,7 +194,7 @@ nsGfxTextControlFrame::nsGfxTextControlFrame()
mIsProcessing(PR_FALSE),
mDummyFrame(0), mNeedsStyleInit(PR_TRUE),
mDummyInitialized(PR_FALSE), // DUMMY
mCachedState(nsnull)
mCachedState(nsnull),mWeakReferent(this)
{
}
@ -1878,7 +1878,6 @@ NS_IMPL_RELEASE(nsEnderKeyListener)
nsEnderKeyListener::nsEnderKeyListener()
{
NS_INIT_REFCNT();
mFrame = nsnull;
mView = nsnull;
}
@ -1889,10 +1888,10 @@ nsEnderKeyListener::~nsEnderKeyListener()
NS_IMETHODIMP
nsEnderKeyListener::SetFrame(nsGfxTextControlFrame *aFrame)
{
mFrame = aFrame;
if (mFrame)
mFrame.SetReference(aFrame->WeakReferent());
if (aFrame)
{
mFrame->GetContent(getter_AddRefs(mContent));
aFrame->GetContent(getter_AddRefs(mContent));
}
return NS_OK;
}
@ -1939,6 +1938,7 @@ nsresult
nsEnderKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
{
nsCOMPtr<nsIDOMUIEvent>uiEvent;
nsGfxTextControlFrame *gfxFrame;
uiEvent = do_QueryInterface(aKeyEvent);
if (!uiEvent) { //non-key event passed to keydown. bad things.
return NS_OK;
@ -1946,7 +1946,8 @@ nsEnderKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
nsresult result = NS_OK;
if (mFrame && mContent)
gfxFrame = mFrame.Reference();
if (gfxFrame && mContent)
{
nsEventStatus status = nsEventStatus_eIgnore;
nsKeyEvent event;
@ -1966,7 +1967,7 @@ nsEnderKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
if (NS_SUCCEEDED(result) && manager)
{
//1. Give event to event manager for pre event state changes and generation of synthetic events.
result = manager->PreHandleEvent(*mContext, &event, mFrame, status, mView);
result = manager->PreHandleEvent(*mContext, &event, gfxFrame, status, mView);
//2. Give event to the DOM for third party and JS use.
if (NS_SUCCEEDED(result)) {
@ -1976,8 +1977,9 @@ nsEnderKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
//3. In this case, the frame does no processing of the event
//4. Give event to event manager for post event state changes and generation of synthetic events.
if (NS_SUCCEEDED(result)) {
result = manager->PostHandleEvent(*mContext, &event, mFrame, status, mView);
gfxFrame = mFrame.Reference(); // check for deletion
if (gfxFrame && NS_SUCCEEDED(result)) {
result = manager->PostHandleEvent(*mContext, &event, gfxFrame, status, mView);
}
NS_RELEASE(manager);
}
@ -1989,6 +1991,8 @@ nsresult
nsEnderKeyListener::KeyUp(nsIDOMEvent* aKeyEvent)
{
nsCOMPtr<nsIDOMUIEvent>uiEvent;
nsGfxTextControlFrame *gfxFrame;
uiEvent = do_QueryInterface(aKeyEvent);
if (!uiEvent) { //non-key event passed to keydown. bad things.
return NS_OK;
@ -1996,7 +2000,8 @@ nsEnderKeyListener::KeyUp(nsIDOMEvent* aKeyEvent)
nsresult result = NS_OK;
if (mFrame && mContent)
gfxFrame = mFrame.Reference();
if (gfxFrame && mContent)
{
nsEventStatus status = nsEventStatus_eIgnore;
nsKeyEvent event;
@ -2016,7 +2021,7 @@ nsEnderKeyListener::KeyUp(nsIDOMEvent* aKeyEvent)
if (NS_SUCCEEDED(result) && manager)
{
//1. Give event to event manager for pre event state changes and generation of synthetic events.
result = manager->PreHandleEvent(*mContext, &event, mFrame, status, mView);
result = manager->PreHandleEvent(*mContext, &event, gfxFrame, status, mView);
//2. Give event to the DOM for third party and JS use.
if (NS_SUCCEEDED(result)) {
@ -2026,8 +2031,9 @@ nsEnderKeyListener::KeyUp(nsIDOMEvent* aKeyEvent)
//3. In this case, the frame does no processing of the event
//4. Give event to event manager for post event state changes and generation of synthetic events.
if (NS_SUCCEEDED(result)) {
result = manager->PostHandleEvent(*mContext, &event, mFrame, status, mView);
gfxFrame = mFrame.Reference(); // check for deletion
if (gfxFrame && NS_SUCCEEDED(result)) {
result = manager->PostHandleEvent(*mContext, &event, gfxFrame, status, mView);
}
NS_RELEASE(manager);
}
@ -2039,6 +2045,8 @@ nsresult
nsEnderKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
{
nsCOMPtr<nsIDOMUIEvent>uiEvent;
nsGfxTextControlFrame *gfxFrame;
uiEvent = do_QueryInterface(aKeyEvent);
if (!uiEvent) { //non-key event passed to keydown. bad things.
return NS_OK;
@ -2046,7 +2054,8 @@ nsEnderKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
nsresult result = NS_OK;
if (mFrame && mContent && mContext && mView)
gfxFrame = mFrame.Reference();
if (gfxFrame && mContent && mContext && mView)
{
nsEventStatus status = nsEventStatus_eIgnore;
nsKeyEvent event;
@ -2066,7 +2075,7 @@ nsEnderKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
if (NS_SUCCEEDED(result) && manager)
{
//1. Give event to event manager for pre event state changes and generation of synthetic events.
result = manager->PreHandleEvent(*mContext, &event, mFrame, status, mView);
result = manager->PreHandleEvent(*mContext, &event, gfxFrame, status, mView);
//2. Give event to the DOM for third party and JS use.
if (NS_SUCCEEDED(result)) {
@ -2074,13 +2083,15 @@ nsEnderKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
}
//3. Give event to the frame for browser default processing
if (NS_SUCCEEDED(result)) {
result = mFrame->HandleEvent(*mContext, &event, status);
gfxFrame = mFrame.Reference(); // check for deletion
if (gfxFrame && NS_SUCCEEDED(result)) {
result = gfxFrame->HandleEvent(*mContext, &event, status);
}
//4. Give event to event manager for post event state changes and generation of synthetic events.
if (NS_SUCCEEDED(result)) {
result = manager->PostHandleEvent(*mContext, &event, mFrame, status, mView);
gfxFrame = mFrame.Reference(); // check for deletion
if (gfxFrame && NS_SUCCEEDED(result)) {
result = manager->PostHandleEvent(*mContext, &event, gfxFrame, status, mView);
}
NS_RELEASE(manager);
}

View File

@ -19,6 +19,8 @@
#ifndef nsGfxTextControlFrame_h___
#define nsGfxTextControlFrame_h___
#include "nsCOMPtr.h"
#include "nsCWeakReference.h"
#include "nsFormControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsIStreamObserver.h"
@ -219,10 +221,15 @@ protected:
nsEnderKeyListener();
protected:
nsGfxTextControlFrame *mFrame; // not ref counted
nsCWeakReference<nsGfxTextControlFrame> mFrame;
nsIView *mView; // not ref counted
nsCOMPtr<nsIPresContext> mContext; // ref counted
nsCOMPtr<nsIContent> mContent; // ref counted
// note nsGfxTextControlFrame is held as a weak ptr
// because the frame can be deleted in the middle
// of event processing. See the KeyUp handler
// for places where this is a problem, and see
// nsCWeakReference.h for notes on use.
};
/******************************************************************************
@ -469,6 +476,9 @@ public:
void RemoveNewlines(nsString &aString);
nsCWeakReferent *WeakReferent()
{ return &mWeakReferent; }
protected:
@ -520,6 +530,8 @@ protected:
nsIPresContext *mFramePresContext; // not ref counted
nsString* mCachedState; // this is used for caching changed between frame creation
// and full initialization
nsCWeakReferent mWeakReferent; // so this obj can be used as a weak ptr
};
#endif