Mozilla/mozilla/webshell/src/nsLinkHandler.cpp
rpotts 0f96131583 Fixed up Post data to avoid leaks...
git-svn-id: svn://10.0.0.236/trunk@4802 18797224-902f-48f8-a5cc-f745e15eee43
1998-07-01 11:30:35 +00:00

215 lines
5.9 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsILinkHandler.h"
#include "nsIDocument.h"
#include "nsString.h"
#include "nsCRT.h"
#include "prthread.h"
#include "plevent.h"
static NS_DEFINE_IID(kILinkHandlerIID, NS_ILINKHANDLER_IID);
class LinkHandlerImpl : public nsILinkHandler {
public:
LinkHandlerImpl();
~LinkHandlerImpl();
void* operator new(size_t sz) {
void* rv = new char[sz];
nsCRT::zero(rv, sz);
return rv;
}
// nsISupports
NS_DECL_ISUPPORTS
// nsILinkHandler
NS_IMETHOD Init(nsIWebWidget* aWidget);
NS_IMETHOD GetWebWidget(nsIWebWidget** aResult);
NS_IMETHOD OnLinkClick(nsIFrame* aFrame,
const nsString& aURLSpec,
const nsString& aTargetSpec,
nsIPostData* aPostData = 0);
NS_IMETHOD OnOverLink(nsIFrame* aFrame,
const nsString& aURLSpec,
const nsString& aTargetSpec);
NS_IMETHOD GetLinkState(const nsString& aURLSpec, nsLinkState& aState);
void HandleLinkClickEvent(const nsString& aURLSpec,
const nsString& aTargetSpec,
nsIPostData* aPostDat = 0);
nsIWebWidget* mWidget;
nsIPostData* mPostData;
};
//----------------------------------------------------------------------
struct OnLinkClickEvent : public PLEvent {
OnLinkClickEvent(LinkHandlerImpl* aHandler, const nsString& aURLSpec,
const nsString& aTargetSpec, nsIPostData* aPostData = 0);
~OnLinkClickEvent();
void HandleEvent();
LinkHandlerImpl* mHandler;
nsString* mURLSpec;
nsString* mTargetSpec;
nsIPostData* mPostData;
};
static void PR_CALLBACK HandleEvent(OnLinkClickEvent* aEvent)
{
aEvent->HandleEvent();
}
static void PR_CALLBACK DestroyEvent(OnLinkClickEvent* aEvent)
{
delete aEvent;
}
OnLinkClickEvent::OnLinkClickEvent(LinkHandlerImpl* aHandler,
const nsString& aURLSpec,
const nsString& aTargetSpec,
nsIPostData* aPostData)
{
mHandler = aHandler;
NS_ADDREF(aHandler);
mURLSpec = new nsString(aURLSpec);
mTargetSpec = new nsString(aTargetSpec);
mPostData = aPostData;
NS_IF_ADDREF(mPostData);
#ifdef XP_PC
PL_InitEvent(this, nsnull,
(PLHandleEventProc) ::HandleEvent,
(PLDestroyEventProc) ::DestroyEvent);
PLEventQueue* eventQueue = PL_GetMainEventQueue();
PL_PostEvent(eventQueue, this);
#endif
}
OnLinkClickEvent::~OnLinkClickEvent()
{
NS_IF_RELEASE(mHandler);
NS_IF_RELEASE(mPostData);
if (nsnull != mURLSpec) delete mURLSpec;
if (nsnull != mTargetSpec) delete mTargetSpec;
}
void OnLinkClickEvent::HandleEvent()
{
mHandler->HandleLinkClickEvent(*mURLSpec, *mTargetSpec, mPostData);
}
//----------------------------------------------------------------------
LinkHandlerImpl::LinkHandlerImpl()
{
}
LinkHandlerImpl::~LinkHandlerImpl()
{
}
NS_IMPL_ISUPPORTS(LinkHandlerImpl, kILinkHandlerIID);
// this Init method assumes that the nsIWebWidget passed in owns this
// LinkHandlerImpl also, so it wont refcount the aWidget.
NS_IMETHODIMP
LinkHandlerImpl::Init(nsIWebWidget* aWidget)
{
NS_PRECONDITION(nsnull != aWidget, "null ptr");
NS_PRECONDITION(nsnull == mWidget, "init twice");
if (nsnull == aWidget) {
return NS_ERROR_NULL_POINTER;
}
if (nsnull != mWidget) {
return NS_ERROR_ALREADY_INITIALIZED;
}
mWidget = aWidget;
//NS_ADDREF(mWidget); // this widget is owned by the same owner of the LinkHandler, no circular ref.
return NS_OK;
}
NS_IMETHODIMP
LinkHandlerImpl::GetWebWidget(nsIWebWidget** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = mWidget;
NS_IF_ADDREF(mWidget);
return NS_OK;
}
NS_IMETHODIMP
LinkHandlerImpl::OnLinkClick(nsIFrame* aFrame,
const nsString& aURLSpec,
const nsString& aTargetSpec,
nsIPostData* aPostData)
{
new OnLinkClickEvent(this, aURLSpec, aTargetSpec, aPostData);
return NS_OK;
}
NS_IMETHODIMP
LinkHandlerImpl::OnOverLink(nsIFrame* aFrame,
const nsString& aURLSpec,
const nsString& aTargetSpec)
{
return NS_OK;
}
NS_IMETHODIMP
LinkHandlerImpl::GetLinkState(const nsString& aURLSpec, nsLinkState& aState)
{
// XXX not yet implemented
aState = eLinkState_Unvisited;
return NS_OK;
}
void
LinkHandlerImpl::HandleLinkClickEvent(const nsString& aURLSpec,
const nsString& aTargetSpec,
nsIPostData* aPostData)
{
if (nsnull != mWidget) {
nsIWebWidget* targetWidget = mWidget->GetTarget(aTargetSpec);
targetWidget->LoadURL(aURLSpec, nsnull, aPostData);
NS_RELEASE(targetWidget);
}
}
NS_WEB nsresult NS_NewLinkHandler(nsILinkHandler** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
LinkHandlerImpl* it = new LinkHandlerImpl();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kILinkHandlerIID, (void**) aInstancePtrResult);
}