gecko-dev/dom/src/base/nsGlobalWindow.cpp

2387 lines
64 KiB
C++
Raw Normal View History

1998-07-16 01:16:47 +00:00
/* -*- 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 "nsCOMPtr.h"
#include "nsGlobalWindow.h"
1998-07-16 01:16:47 +00:00
#include "nscore.h"
#include "nsRect.h"
#include "nslayout.h"
1998-07-16 01:16:47 +00:00
#include "prmem.h"
#include "prtime.h"
#include "plstr.h"
#include "prinrval.h"
#include "nsIFactory.h"
#include "nsIScriptContext.h"
#include "nsIDOMDocument.h"
#include "nsINetService.h"
#include "nsIServiceManager.h"
1998-07-16 01:16:47 +00:00
#include "nsITimer.h"
#include "nsEventListenerManager.h"
#include "nsIEventStateManager.h"
#include "nsDOMEvent.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMKeyListener.h"
#include "nsIDOMMouseMotionListener.h"
#include "nsIDOMFocusListener.h"
#include "nsIDOMFormListener.h"
#include "nsIDOMLoadListener.h"
#include "nsIDOMDragListener.h"
1998-10-06 20:59:39 +00:00
#include "nsIDOMPaintListener.h"
#include "nsIScriptEventListener.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIBrowserWindow.h"
#include "nsIWebShell.h"
#include "nsIScriptContextOwner.h"
#include "nsIDocument.h"
#include "nsIURL.h"
#include "nsIPref.h"
#include "nsCRT.h"
#include "nsRect.h"
#include "nsINetSupport.h"
1999-01-27 04:15:19 +00:00
#include "nsIContentViewer.h"
#include "nsScreen.h"
#include "nsHistory.h"
1998-07-16 01:16:47 +00:00
#if defined(OJI)
#include "nsIJVMManager.h"
#endif
#include "nsMimeTypeArray.h"
#include "nsPluginArray.h"
1998-07-16 01:16:47 +00:00
#include "jsapi.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIScriptEventListenerIID, NS_ISCRIPTEVENTLISTENER_IID);
1998-07-16 01:16:47 +00:00
static NS_DEFINE_IID(kIDOMWindowIID, NS_IDOMWINDOW_IID);
static NS_DEFINE_IID(kIDOMNavigatorIID, NS_IDOMNAVIGATOR_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
static NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
static NS_DEFINE_IID(kIDOMMouseMotionListenerIID, NS_IDOMMOUSEMOTIONLISTENER_IID);
static NS_DEFINE_IID(kIDOMFocusListenerIID, NS_IDOMFOCUSLISTENER_IID);
static NS_DEFINE_IID(kIDOMFormListenerIID, NS_IDOMFORMLISTENER_IID);
static NS_DEFINE_IID(kIDOMLoadListenerIID, NS_IDOMLOADLISTENER_IID);
static NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID);
1998-10-06 20:59:39 +00:00
static NS_DEFINE_IID(kIDOMPaintListenerIID, NS_IDOMPAINTLISTENER_IID);
static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID);
static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID);
static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID);
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
1999-03-28 22:19:42 +00:00
static NS_DEFINE_IID(kIDOMEventTargetIID, NS_IDOMEVENTTARGET_IID);
static NS_DEFINE_IID(kIBrowserWindowIID, NS_IBROWSER_WINDOW_IID);
static NS_DEFINE_IID(kIScriptContextOwnerIID, NS_ISCRIPTCONTEXTOWNER_IID);
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
static NS_DEFINE_IID(kINetServiceIID, NS_INETSERVICE_IID);
static NS_DEFINE_IID(kNetServiceCID, NS_NETSERVICE_CID);
static NS_DEFINE_IID(kINetSupportIID, NS_INETSUPPORT_IID);
1998-07-16 01:16:47 +00:00
static NS_DEFINE_IID(kIPrefIID, NS_IPREF_IID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
1998-07-16 01:16:47 +00:00
GlobalWindowImpl::GlobalWindowImpl()
{
NS_INIT_REFCNT();
1998-07-16 01:16:47 +00:00
mContext = nsnull;
mScriptObject = nsnull;
mDocument = nsnull;
mNavigator = nsnull;
mScreen = nsnull;
mHistory = nsnull;
1998-08-13 04:34:53 +00:00
mLocation = nsnull;
mFrames = nsnull;
mOpener = nsnull;
1998-07-16 01:16:47 +00:00
mTimeouts = nsnull;
mTimeoutInsertionPoint = nsnull;
mRunningTimeout = nsnull;
mTimeoutPublicIdCounter = 1;
mListenerManager = nsnull;
mFirstDocumentLoad = PR_TRUE;
mChromeDocument = nsnull;
1998-07-16 01:16:47 +00:00
}
GlobalWindowImpl::~GlobalWindowImpl()
{
if (nsnull != mScriptObject) {
mContext->RemoveReference(&mScriptObject, mScriptObject);
1998-07-16 01:16:47 +00:00
mScriptObject = nsnull;
}
NS_IF_RELEASE(mContext);
NS_IF_RELEASE(mDocument);
1998-07-16 01:16:47 +00:00
NS_IF_RELEASE(mNavigator);
NS_IF_RELEASE(mScreen);
NS_IF_RELEASE(mHistory);
1998-08-13 04:34:53 +00:00
NS_IF_RELEASE(mLocation);
NS_IF_RELEASE(mFrames);
NS_IF_RELEASE(mOpener);
NS_IF_RELEASE(mListenerManager);
1998-07-16 01:16:47 +00:00
}
NS_IMPL_ADDREF(GlobalWindowImpl)
NS_IMPL_RELEASE(GlobalWindowImpl)
nsresult
GlobalWindowImpl::QueryInterface(const nsIID& aIID,
void** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtrResult = (void*) ((nsIScriptObjectOwner*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptGlobalObjectIID)) {
*aInstancePtrResult = (void*) ((nsIScriptGlobalObject*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMWindowIID)) {
*aInstancePtrResult = (void*) ((nsIDOMWindow*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtrResult = (void*)(nsISupports*)(nsIScriptGlobalObject*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIJSScriptObjectIID)) {
*aInstancePtrResult = (void*)(nsISupports*)(nsIJSScriptObject*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMEventCapturerIID)) {
*aInstancePtrResult = (void*)(nsISupports*)(nsIDOMEventCapturer*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMEventReceiverIID)) {
*aInstancePtrResult = (void*)(nsISupports*)(nsIDOMEventReceiver*)this;
AddRef();
return NS_OK;
}
1999-03-28 22:19:42 +00:00
if (aIID.Equals(kIDOMEventTargetIID)) {
*aInstancePtrResult = (void*)(nsISupports*)(nsIDOMEventTarget*)this;
AddRef();
return NS_OK;
}
1998-07-16 01:16:47 +00:00
return NS_NOINTERFACE;
}
nsresult
GlobalWindowImpl::SetScriptObject(void *aScriptObject)
1998-07-16 01:16:47 +00:00
{
mScriptObject = aScriptObject;
1998-07-16 01:16:47 +00:00
return NS_OK;
}
nsresult
GlobalWindowImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptWindow(aContext, (nsIDOMWindow*)this,
nsnull, &mScriptObject);
aContext->AddNamedReference(&mScriptObject, mScriptObject,
"window_object");
1998-07-16 01:16:47 +00:00
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP_(void)
GlobalWindowImpl::SetContext(nsIScriptContext *aContext)
{
if (mContext) {
NS_RELEASE(mContext);
}
mContext = aContext;
NS_ADDREF(mContext);
}
1999-05-14 03:10:51 +00:00
NS_IMETHODIMP_(void)
GlobalWindowImpl::GetContext(nsIScriptContext **aContext)
{
*aContext = mContext;
NS_IF_ADDREF(*aContext);
}
1998-07-16 01:16:47 +00:00
NS_IMETHODIMP_(void)
GlobalWindowImpl::SetNewDocument(nsIDOMDocument *aDocument)
{
if (mFirstDocumentLoad) {
mFirstDocumentLoad = PR_FALSE;
mDocument = aDocument;
NS_IF_ADDREF(mDocument);
return;
}
ClearAllTimeouts();
1998-07-16 01:16:47 +00:00
if (nsnull != mScriptObject && nsnull != mContext) {
JS_ClearScope((JSContext *)mContext->GetNativeContext(),
(JSObject *)mScriptObject);
}
1998-07-16 01:16:47 +00:00
if (nsnull != mDocument)
1998-07-16 01:16:47 +00:00
NS_RELEASE(mDocument);
if (nsnull != mContext)
mContext->GC();
1998-07-16 01:16:47 +00:00
mDocument = aDocument;
if (nsnull != mDocument) {
NS_ADDREF(mDocument);
if (nsnull != mContext) {
mContext->InitContext(this);
}
}
}
NS_IMETHODIMP_(void)
GlobalWindowImpl::SetWebShell(nsIWebShell *aWebShell)
{
//mWebShell isn't refcnt'd here. WebShell calls SetWebShell(nsnull) when deleted.
mWebShell = aWebShell;
1998-08-13 04:34:53 +00:00
if (nsnull != mLocation) {
mLocation->SetWebShell(aWebShell);
}
if (nsnull != mHistory) {
mHistory->SetWebShell(aWebShell);
}
if (nsnull != mFrames) {
mFrames->SetWebShell(aWebShell);
}
// Get our enclosing chrome shell and retrieve its global window impl, so that we can
// do some forwarding to the chrome document.
nsCOMPtr<nsIWebShell> chromeShell;
mWebShell->GetContainingChromeShell(getter_AddRefs(chromeShell));
if (chromeShell) {
// Convert the chrome shell to a DOM window.
nsCOMPtr<nsIScriptContextOwner> contextOwner = do_QueryInterface(chromeShell);
if (contextOwner) {
nsCOMPtr<nsIScriptGlobalObject> globalObject;
if (NS_OK == contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject))) {
nsCOMPtr<nsIDOMWindow> chromeWindow = do_QueryInterface(globalObject);
if (chromeWindow) {
nsCOMPtr<nsIDOMDocument> chromeDoc;
chromeWindow->GetDocument(getter_AddRefs(chromeDoc));
nsCOMPtr<nsIDocument> realDoc = do_QueryInterface(chromeDoc);
mChromeDocument = realDoc.get(); // Don't addref it
}
}
}
}
}
1999-02-10 16:25:11 +00:00
NS_IMETHODIMP_(void) // XXX This may be temporary - rods
GlobalWindowImpl::GetWebShell(nsIWebShell **aWebShell)
{
if (nsnull != mWebShell) {
*aWebShell = mWebShell;
NS_ADDREF(mWebShell);
} else {
//*mWebShell = nsnull;
}
}
NS_IMETHODIMP_(void)
GlobalWindowImpl::SetOpenerWindow(nsIDOMWindow *aOpener)
{
NS_IF_RELEASE(mOpener);
mOpener = aOpener;
NS_IF_ADDREF(mOpener);
}
1998-07-16 01:16:47 +00:00
NS_IMETHODIMP
GlobalWindowImpl::GetWindow(nsIDOMWindow** aWindow)
{
*aWindow = this;
NS_ADDREF(this);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetSelf(nsIDOMWindow** aWindow)
{
*aWindow = this;
NS_ADDREF(this);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetDocument(nsIDOMDocument** aDocument)
{
*aDocument = mDocument;
NS_IF_ADDREF(mDocument);
1998-07-16 01:16:47 +00:00
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetNavigator(nsIDOMNavigator** aNavigator)
{
if (nsnull == mNavigator) {
mNavigator = new NavigatorImpl();
NS_IF_ADDREF(mNavigator);
}
*aNavigator = mNavigator;
NS_IF_ADDREF(mNavigator);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetScreen(nsIDOMScreen** aScreen)
{
if (nsnull == mScreen) {
mScreen = new ScreenImpl();
NS_IF_ADDREF(mScreen);
}
*aScreen = mScreen;
NS_IF_ADDREF(mScreen);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetHistory(nsIDOMHistory** aHistory)
{
if (nsnull == mHistory) {
mHistory = new HistoryImpl();
if (nsnull != mHistory) {
NS_ADDREF(mHistory);
mHistory->SetWebShell(mWebShell);
}
}
*aHistory = mHistory;
NS_IF_ADDREF(mHistory);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetOpener(nsIDOMWindow** aOpener)
{
*aOpener = mOpener;
NS_IF_ADDREF(*aOpener);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetOpener(nsIDOMWindow* aOpener)
{
NS_IF_RELEASE(mOpener);
mOpener = aOpener;
NS_IF_ADDREF(mOpener);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetParent(nsIDOMWindow** aParent)
{
nsresult ret = NS_OK;
nsIWebShell *mParentWebShell;
mWebShell->GetParent(mParentWebShell);
*aParent = nsnull;
if (nsnull != mParentWebShell) {
nsIScriptContextOwner *mParentContextOwner;
if (NS_OK == mParentWebShell->QueryInterface(kIScriptContextOwnerIID, (void**)&mParentContextOwner)) {
nsIScriptGlobalObject *mParentGlobalObject;
if (NS_OK == mParentContextOwner->GetScriptGlobalObject(&mParentGlobalObject)) {
ret = mParentGlobalObject->QueryInterface(kIDOMWindowIID, (void**)aParent);
NS_RELEASE(mParentGlobalObject);
}
NS_RELEASE(mParentContextOwner);
}
NS_RELEASE(mParentWebShell);
}
else {
*aParent = this;
NS_ADDREF(this);
}
return ret;
}
1998-08-13 04:34:53 +00:00
NS_IMETHODIMP
GlobalWindowImpl::GetLocation(nsIDOMLocation** aLocation)
{
if (nsnull == mLocation) {
mLocation = new LocationImpl(mWebShell);
NS_IF_ADDREF(mLocation);
}
*aLocation = mLocation;
NS_IF_ADDREF(mLocation);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetTop(nsIDOMWindow** aTop)
{
nsresult ret = NS_OK;
nsIWebShell *mRootWebShell;
mWebShell->GetRootWebShell(mRootWebShell);
*aTop = nsnull;
if (nsnull != mRootWebShell) {
nsIScriptContextOwner *mRootContextOwner;
if (NS_OK == mRootWebShell->QueryInterface(kIScriptContextOwnerIID, (void**)&mRootContextOwner)) {
nsIScriptGlobalObject *mRootGlobalObject;
if (NS_OK == mRootContextOwner->GetScriptGlobalObject(&mRootGlobalObject)) {
ret = mRootGlobalObject->QueryInterface(kIDOMWindowIID, (void**)aTop);
NS_RELEASE(mRootGlobalObject);
}
NS_RELEASE(mRootContextOwner);
}
NS_RELEASE(mRootWebShell);
}
return ret;
}
NS_IMETHODIMP
GlobalWindowImpl::GetClosed(PRBool* aClosed)
{
if (nsnull == mWebShell) {
*aClosed = PR_TRUE;
}
else {
*aClosed = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetFrames(nsIDOMWindowCollection** aFrames)
{
if (nsnull == mFrames) {
mFrames = new nsDOMWindowList(mWebShell);
if (nsnull == mFrames) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mFrames);
}
*aFrames = (nsIDOMWindowCollection *)mFrames;
NS_ADDREF(mFrames);
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetStatus(nsString& aStatus)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
1999-02-14 06:37:24 +00:00
const PRUnichar *status;
mBrowser->GetStatus(&status);
aStatus = status;
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetStatus(const nsString& aStatus)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
mBrowser->SetStatus(aStatus.GetUnicode());
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetDefaultStatus(nsString& aDefaultStatus)
{
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetDefaultStatus(const nsString& aDefaultStatus)
{
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetName(nsString& aName)
{
1999-02-14 06:37:24 +00:00
const PRUnichar *name;
mWebShell->GetName(&name);
aName = name;
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetName(const nsString& aName)
{
mWebShell->SetName(aName.GetUnicode());
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetInnerWidth(PRInt32* aInnerWidth)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetBounds(r);
*aInnerWidth = r.width;
NS_RELEASE(mBrowser);
}
else {
*aInnerWidth = 0;
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetInnerWidth(PRInt32 aInnerWidth)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetBounds(r);
mBrowser->SizeTo(aInnerWidth, r.height);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetInnerHeight(PRInt32* aInnerHeight)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetBounds(r);
*aInnerHeight = r.height;
NS_RELEASE(mBrowser);
}
else {
*aInnerHeight = 0;
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetInnerHeight(PRInt32 aInnerHeight)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetBounds(r);
mBrowser->SizeTo(r.width, aInnerHeight);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetOuterWidth(PRInt32* aOuterWidth)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
*aOuterWidth = r.width;
NS_RELEASE(mBrowser);
}
else {
*aOuterWidth = 0;
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetOuterWidth(PRInt32 aOuterWidth)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
mBrowser->SizeTo(aOuterWidth, r.height);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetOuterHeight(PRInt32* aOuterHeight)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
*aOuterHeight = r.height;
NS_RELEASE(mBrowser);
}
else {
*aOuterHeight = 0;
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetOuterHeight(PRInt32 aOuterHeight)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
mBrowser->SizeTo(r.width, aOuterHeight);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetScreenX(PRInt32* aScreenX)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
*aScreenX = r.x;
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetScreenX(PRInt32 aScreenX)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
mBrowser->MoveTo(aScreenX, r.y);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetScreenY(PRInt32* aScreenY)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
*aScreenY = r.y;
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetScreenY(PRInt32 aScreenY)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
mBrowser->MoveTo(r.x, aScreenY);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetPageXOffset(PRInt32* aPageXOffset)
{
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetPageXOffset(PRInt32 aPageXOffset)
{
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::GetPageYOffset(PRInt32* aPageYOffset)
{
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetPageYOffset(PRInt32 aPageYOffset)
{
return NS_OK;
}
1998-07-16 01:16:47 +00:00
NS_IMETHODIMP
GlobalWindowImpl::Dump(const nsString& aStr)
{
char *cstr = aStr.ToNewCString();
if (nsnull != cstr) {
printf("%s", cstr);
delete [] cstr;
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::Alert(const nsString& aStr)
{
nsresult ret;
nsIWebShell *rootWebShell;
ret = mWebShell->GetRootWebShell(rootWebShell);
if (nsnull != rootWebShell) {
nsIWebShellContainer *rootContainer;
ret = rootWebShell->GetContainer(rootContainer);
if (nsnull != rootContainer) {
nsINetSupport *support;
if (NS_OK == (ret = rootContainer->QueryInterface(kINetSupportIID, (void**)&support))) {
support->Alert(aStr);
NS_RELEASE(support);
}
NS_RELEASE(rootContainer);
}
NS_RELEASE(rootWebShell);
}
return ret;
1998-07-16 01:16:47 +00:00
// XXX Temporary
//return Dump(aStr);
1998-07-16 01:16:47 +00:00
}
NS_IMETHODIMP
GlobalWindowImpl::Focus()
{
mWebShell->SetFocus();
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::Blur()
{
mWebShell->RemoveFocus();
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::Close()
{
// Basic security check. If window has opener and therefore was opened from JS it can be
// closed. Need to add additional checks and privilege based closing
if (nsnull != mOpener) {
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
mBrowser->Close();
NS_RELEASE(mBrowser);
}
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::Forward()
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
//XXX tbi
//mBrowser->Forward();
NS_RELEASE(mBrowser);
} else {
mWebShell->Forward(); // I added this - rods
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::Back()
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
//XXX tbi
//mBrowser->Back();
NS_RELEASE(mBrowser);
} else {
mWebShell->Back();// I added this - rods
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::Home()
{
char *url = nsnull;
nsresult rv = NS_OK;
nsString homeURL;
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (NS_FAILED(rv) || (!prefs)) {
return rv;
}
// if we get here, we know prefs is not null
rv = prefs->CopyCharPref(PREF_BROWSER_STARTUP_HOMEPAGE, &url);
if (NS_FAILED(rv) || (!url)) {
// if all else fails, use this
homeURL = DEFAULT_HOME_PAGE;
}
else {
homeURL = url;
}
PR_FREEIF(url);
PRUnichar* urlToLoad = homeURL.ToNewUnicode();
mWebShell->LoadURL(urlToLoad);
1999-03-11 22:53:02 +00:00
delete[] urlToLoad;
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::Stop()
{
mWebShell->Stop();
return NS_OK;
}
1999-01-27 04:15:19 +00:00
NS_IMETHODIMP
GlobalWindowImpl::Print()
{
nsIContentViewer *viewer = nsnull;
mWebShell->GetContentViewer(&viewer);
if (nsnull != viewer)
{
viewer->Print();
NS_RELEASE(viewer);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::MoveTo(PRInt32 aXPos, PRInt32 aYPos)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
mBrowser->MoveTo(aXPos, aYPos);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::MoveBy(PRInt32 aXDif, PRInt32 aYDif)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
mBrowser->MoveTo(r.x + aXDif, r.y + aYDif);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::ResizeTo(PRInt32 aWidth, PRInt32 aHeight)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
mBrowser->SizeTo(aWidth, aHeight);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::ResizeBy(PRInt32 aWidthDif, PRInt32 aHeightDif)
{
nsIBrowserWindow *mBrowser;
if (NS_OK == GetBrowserWindowInterface(mBrowser)) {
nsRect r;
mBrowser->GetWindowBounds(r);
mBrowser->SizeTo(r.width + aWidthDif, r.height + aHeightDif);
NS_RELEASE(mBrowser);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll)
{
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::ScrollBy(PRInt32 aXScrollDif, PRInt32 aYScrollDif)
{
return NS_OK;
}
1998-07-16 01:16:47 +00:00
nsresult
GlobalWindowImpl::ClearTimeoutOrInterval(PRInt32 aTimerID)
{
PRUint32 public_id;
nsTimeoutImpl **top, *timeout;
public_id = (PRUint32)aTimerID;
if (!public_id) /* id of zero is reserved for internal use */
return NS_ERROR_FAILURE;
for (top = &mTimeouts; ((timeout = *top) != NULL); top = &timeout->next) {
if (timeout->public_id == public_id) {
if (mRunningTimeout == timeout) {
/* We're running from inside the timeout. Mark this
timeout for deferred deletion by the code in
win_run_timeout() */
timeout->interval = 0;
}
else {
/* Delete the timeout from the pending timeout list */
*top = timeout->next;
if (timeout->timer) {
timeout->timer->Cancel();
NS_RELEASE(timeout->timer);
DropTimeout(timeout);
}
DropTimeout(timeout);
}
break;
}
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::ClearTimeout(PRInt32 aTimerID)
{
return ClearTimeoutOrInterval(aTimerID);
}
NS_IMETHODIMP
GlobalWindowImpl::ClearInterval(PRInt32 aTimerID)
{
return ClearTimeoutOrInterval(aTimerID);
}
void
GlobalWindowImpl::ClearAllTimeouts()
{
nsTimeoutImpl *timeout, *next;
for (timeout = mTimeouts; timeout; timeout = next) {
/* If RunTimeout() is higher up on the stack for this
window, e.g. as a result of document.write from a timeout,
then we need to reset the list insertion point for
newly-created timeouts in case the user adds a timeout,
before we pop the stack back to RunTimeout. */
if (mRunningTimeout == timeout)
mTimeoutInsertionPoint = nsnull;
next = timeout->next;
if (timeout->timer) {
timeout->timer->Cancel();
NS_RELEASE(timeout->timer);
// Drop the count since the timer isn't going to hold on
// anymore.
DropTimeout(timeout);
}
// Drop the count since we're removing it from the list.
DropTimeout(timeout);
}
mTimeouts = NULL;
}
void
GlobalWindowImpl::HoldTimeout(nsTimeoutImpl *aTimeout)
{
aTimeout->ref_count++;
}
void
GlobalWindowImpl::DropTimeout(nsTimeoutImpl *aTimeout)
{
JSContext *cx;
if (--aTimeout->ref_count > 0) {
return;
}
cx = (JSContext *)mContext->GetNativeContext();
if (aTimeout->expr) {
PR_FREEIF(aTimeout->expr);
}
else if (aTimeout->funobj) {
JS_RemoveRoot(cx, &aTimeout->funobj);
if (aTimeout->argv) {
int i;
for (i = 0; i < aTimeout->argc; i++)
JS_RemoveRoot(cx, &aTimeout->argv[i]);
PR_FREEIF(aTimeout->argv);
}
}
NS_IF_RELEASE(aTimeout->timer);
PR_FREEIF(aTimeout->filename);
NS_IF_RELEASE(aTimeout->window);
PR_DELETE(aTimeout);
}
void
GlobalWindowImpl::InsertTimeoutIntoList(nsTimeoutImpl **aList,
nsTimeoutImpl *aTimeout)
{
nsTimeoutImpl *to;
while ((to = *aList) != nsnull) {
if (LL_CMP(to->when, >, aTimeout->when))
break;
aList = &to->next;
}
aTimeout->next = to;
*aList = aTimeout;
// Increment the ref_count since we're in the list
HoldTimeout(aTimeout);
}
void
nsGlobalWindow_RunTimeout(nsITimer *aTimer, void *aClosure)
{
nsTimeoutImpl *timeout = (nsTimeoutImpl *)aClosure;
timeout->window->RunTimeout(timeout);
// Drop the ref_count since the timer won't be holding on to the
// timeout struct anymore
timeout->window->DropTimeout(timeout);
}
void
GlobalWindowImpl::RunTimeout(nsTimeoutImpl *aTimeout)
{
nsTimeoutImpl *next, *timeout;
nsTimeoutImpl *last_expired_timeout;
nsTimeoutImpl dummy_timeout;
JSContext *cx;
PRInt64 now;
jsval result;
nsITimer *timer;
timer = aTimeout->timer;
cx = (JSContext *)mContext->GetNativeContext();
/*
* A native timer has gone off. See which of our timeouts need
* servicing
*/
LL_I2L(now, PR_IntervalNow());
/* The timeout list is kept in deadline order. Discover the
latest timeout whose deadline has expired. On some platforms,
native timeout events fire "early", so we need to test the
timer as well as the deadline. */
last_expired_timeout = nsnull;
for (timeout = mTimeouts; timeout; timeout = timeout->next) {
if ((timeout == aTimeout) || !LL_CMP(timeout->when, >, now))
last_expired_timeout = timeout;
}
/* Maybe the timeout that the event was fired for has been deleted
and there are no others timeouts with deadlines that make them
eligible for execution yet. Go away. */
if (!last_expired_timeout)
return;
/* Insert a dummy timeout into the list of timeouts between the portion
of the list that we are about to process now and those timeouts that
will be processed in a future call to win_run_timeout(). This dummy
timeout serves as the head of the list for any timeouts inserted as
a result of running a timeout. */
dummy_timeout.timer = NULL;
dummy_timeout.public_id = 0;
dummy_timeout.next = last_expired_timeout->next;
last_expired_timeout->next = &dummy_timeout;
/* Don't let ClearWindowTimeouts throw away our stack-allocated
dummy timeout. */
dummy_timeout.ref_count = 2;
mTimeoutInsertionPoint = &dummy_timeout.next;
for (timeout = mTimeouts; timeout != &dummy_timeout; timeout = next) {
next = timeout->next;
/* Hold the timeout in case expr or funobj releases its doc. */
mRunningTimeout = timeout;
if (timeout->expr) {
/* Evaluate the timeout expression. */
1999-03-12 22:24:30 +00:00
#if 0
// V says it would be nice if we could have a chokepoint
// for calling scripts instead of making a bunch of
// ScriptEvaluated() calls to clean things up. MMP
PRBool isundefined;
mContext->EvaluateString(nsAutoString(timeout->expr),
timeout->filename,
timeout->lineno, nsAutoString(""), &isundefined);
#endif
1998-07-16 01:16:47 +00:00
JS_EvaluateScript(cx, (JSObject *)mScriptObject,
timeout->expr,
PL_strlen(timeout->expr),
timeout->filename, timeout->lineno,
&result);
}
else {
PRInt64 lateness64;
PRInt32 lateness;
/* Add "secret" final argument that indicates timeout
lateness in milliseconds */
LL_SUB(lateness64, now, timeout->when);
LL_L2I(lateness, lateness64);
lateness = PR_IntervalToMilliseconds(lateness);
timeout->argv[timeout->argc] = INT_TO_JSVAL((jsint)lateness);
JS_CallFunctionValue(cx, (JSObject *)mScriptObject,
OBJECT_TO_JSVAL(timeout->funobj),
timeout->argc + 1, timeout->argv, &result);
}
1999-03-12 22:24:30 +00:00
mContext->ScriptEvaluated();
1998-07-16 01:16:47 +00:00
mRunningTimeout = nsnull;
/* If we have a regular interval timer, we re-fire the
* timeout, accounting for clock drift.
*/
if (timeout->interval) {
/* Compute time to next timeout for interval timer. */
PRInt32 delay32;
PRInt64 interval, delay;
LL_I2L(interval, PR_MillisecondsToInterval(timeout->interval));
LL_ADD(timeout->when, timeout->when, interval);
LL_I2L(now, PR_IntervalNow());
LL_SUB(delay, timeout->when, now);
LL_L2I(delay32, delay);
/* If the next interval timeout is already supposed to
* have happened then run the timeout immediately.
*/
if (delay32 < 0) {
delay32 = 0;
}
delay32 = PR_IntervalToMilliseconds(delay32);
NS_IF_RELEASE(timeout->timer);
/* Reschedule timeout. Account for possible error return in
code below that checks for zero toid. */
nsresult err = NS_NewTimer(&timeout->timer);
if (NS_OK != err) {
return;
}
err = timeout->timer->Init(nsGlobalWindow_RunTimeout, timeout,
delay32);
if (NS_OK != err) {
return;
}
// Increment ref_count to indicate that this timer is holding
// on to the timeout struct.
HoldTimeout(timeout);
}
/* Running a timeout can cause another timeout to be deleted,
so we need to reset the pointer to the following timeout. */
next = timeout->next;
mTimeouts = next;
// Drop timeout struct since it's out of the list
DropTimeout(timeout);
/* Free the timeout if this is not a repeating interval
* timeout (or if it was an interval timeout, but we were
* unsuccessful at rescheduling it.)
*/
if (timeout->interval && timeout->timer) {
/* Reschedule an interval timeout */
/* Insert interval timeout onto list sorted in deadline order. */
InsertTimeoutIntoList(mTimeoutInsertionPoint, timeout);
}
}
/* Take the dummy timeout off the head of the list */
mTimeouts = dummy_timeout.next;
mTimeoutInsertionPoint = nsnull;
}
static const char *kSetIntervalStr = "setInterval";
static const char *kSetTimeoutStr = "setTimeout";
nsresult
GlobalWindowImpl::SetTimeoutOrInterval(JSContext *cx,
jsval *argv,
PRUint32 argc,
PRInt32* aReturn,
PRBool aIsInterval)
{
char *expr = nsnull;
JSObject *funobj = nsnull;
JSString *str;
nsTimeoutImpl *timeout, **insertion_point;
jsdouble interval;
PRInt64 now, delta;
if (argc >= 2) {
if (!JS_ValueToNumber(cx, argv[1], &interval)) {
JS_ReportError(cx, "Second argument to %s must be a millisecond interval",
aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
return NS_ERROR_ILLEGAL_VALUE;
}
switch (JS_TypeOfValue(cx, argv[0])) {
case JSTYPE_FUNCTION:
funobj = JSVAL_TO_OBJECT(argv[0]);
break;
case JSTYPE_STRING:
case JSTYPE_OBJECT:
if (!(str = JS_ValueToString(cx, argv[0])))
return NS_ERROR_FAILURE;
expr = PL_strdup(JS_GetStringBytes(str));
if (nsnull == expr)
return NS_ERROR_OUT_OF_MEMORY;
break;
default:
JS_ReportError(cx, "useless %s call (missing quotes around argument?)", aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
return NS_ERROR_FAILURE;
}
timeout = PR_NEWZAP(nsTimeoutImpl);
if (nsnull == timeout) {
PR_FREEIF(expr);
return NS_ERROR_OUT_OF_MEMORY;
}
// Initial ref_count to indicate that this timeout struct will
// be held as the closure of a timer.
timeout->ref_count = 1;
if (aIsInterval)
timeout->interval = (PRInt32)interval;
timeout->expr = expr;
timeout->funobj = funobj;
1998-09-18 00:35:55 +00:00
timeout->principals = nsnull;
1998-07-16 01:16:47 +00:00
if (expr) {
timeout->argv = 0;
timeout->argc = 0;
}
else {
int i;
/* Leave an extra slot for a secret final argument that
indicates to the called function how "late" the timeout is. */
timeout->argv = (jsval *)PR_MALLOC((argc - 1) * sizeof(jsval));
if (nsnull == timeout->argv) {
DropTimeout(timeout);
return NS_ERROR_OUT_OF_MEMORY;
}
if (!JS_AddNamedRoot(cx, &timeout->funobj, "timeout.funobj")) {
DropTimeout(timeout);
return NS_ERROR_FAILURE;
}
timeout->argc = 0;
for (i = 2; (PRUint32)i < argc; i++) {
timeout->argv[i - 2] = argv[i];
if (!JS_AddNamedRoot(cx, &timeout->argv[i - 2], "timeout.argv[i]")) {
DropTimeout(timeout);
return NS_ERROR_FAILURE;
}
timeout->argc++;
}
}
LL_I2L(now, PR_IntervalNow());
LL_D2L(delta, PR_MillisecondsToInterval((PRUint32)interval));
LL_ADD(timeout->when, now, delta);
nsresult err = NS_NewTimer(&timeout->timer);
if (NS_OK != err) {
DropTimeout(timeout);
return err;
}
err = timeout->timer->Init(nsGlobalWindow_RunTimeout, timeout,
(PRInt32)interval);
if (NS_OK != err) {
DropTimeout(timeout);
return err;
}
timeout->window = this;
NS_ADDREF(this);
if (mTimeoutInsertionPoint == NULL)
insertion_point = &mTimeouts;
else
insertion_point = mTimeoutInsertionPoint;
InsertTimeoutIntoList(insertion_point, timeout);
timeout->public_id = ++mTimeoutPublicIdCounter;
*aReturn = timeout->public_id;
}
else {
JS_ReportError(cx, "Function %s requires at least 2 parameters", aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::SetTimeout(JSContext *cx,
jsval *argv,
PRUint32 argc,
PRInt32* aReturn)
{
return SetTimeoutOrInterval(cx, argv, argc, aReturn, PR_FALSE);
}
NS_IMETHODIMP
GlobalWindowImpl::SetInterval(JSContext *cx,
jsval *argv,
PRUint32 argc,
PRInt32* aReturn)
{
return SetTimeoutOrInterval(cx, argv, argc, aReturn, PR_TRUE);
}
NS_IMETHODIMP
GlobalWindowImpl::Open(JSContext *cx,
jsval *argv,
PRUint32 argc,
nsIDOMWindow** aReturn)
{
return OpenInternal(cx, argv, argc, PR_FALSE, aReturn);
}
// like Open, but attaches to the new window any extra parameters past [features]
// as a JS property named "arguments"
NS_IMETHODIMP
GlobalWindowImpl::OpenDialog(JSContext *cx,
jsval *argv,
PRUint32 argc,
nsIDOMWindow** aReturn)
{
return OpenInternal(cx, argv, argc, PR_TRUE, aReturn);
}
nsresult
GlobalWindowImpl::OpenInternal(JSContext *cx,
jsval *argv,
PRUint32 argc,
PRBool aAttachArguments,
nsIDOMWindow** aReturn)
{
PRUint32 chromeFlags;
1998-09-18 00:35:55 +00:00
nsAutoString mAbsURL, name;
JSString* str;
char* options;
*aReturn = nsnull;
if (argc > 0) {
JSString *mJSStrURL = JS_ValueToString(cx, argv[0]);
if (nsnull == mJSStrURL || nsnull == mDocument) {
return NS_ERROR_FAILURE;
}
nsAutoString mURL, mEmpty;
1999-03-05 04:40:14 +00:00
nsIURL* mDocURL = 0;
nsIDocument* mDoc;
mURL.SetString(JS_GetStringChars(mJSStrURL));
if (NS_OK == mDocument->QueryInterface(kIDocumentIID, (void**)&mDoc)) {
mDocURL = mDoc->GetDocumentURL();
NS_RELEASE(mDoc);
}
if (NS_OK != NS_MakeAbsoluteURL(mDocURL, mEmpty, mURL, mAbsURL)) {
return NS_ERROR_FAILURE;
}
}
/* Sanity-check the optional window_name argument. */
if (argc > 1) {
JSString *mJSStrName = JS_ValueToString(cx, argv[1]);
if (nsnull == mJSStrName) {
return NS_ERROR_FAILURE;
}
1998-09-18 00:35:55 +00:00
name.SetString(JS_GetStringChars(mJSStrName));
1998-09-18 00:35:55 +00:00
if (NS_OK != CheckWindowName(cx, name)) {
return NS_ERROR_FAILURE;
}
}
else {
1998-09-18 00:35:55 +00:00
name.SetString("");
}
options = nsnull;
if (argc > 2) {
if (!(str = JS_ValueToString(cx, argv[2]))) {
return NS_ERROR_FAILURE;
}
options = JS_GetStringBytes(str);
}
chromeFlags = CalculateChromeFlags(options);
1999-04-20 22:35:11 +00:00
nsIWebShell *newOuterShell = nsnull;
nsIWebShellContainer *webShellContainer;
/* XXX check for existing window of same name. If exists, set url and
* update chrome */
1998-09-18 00:35:55 +00:00
if (NS_OK == mWebShell->GetContainer(webShellContainer) && nsnull != webShellContainer) {
// Check for existing window of same name.
1999-04-20 22:35:11 +00:00
webShellContainer->FindWebShellWithName(name.GetUnicode(), newOuterShell);
if (nsnull == newOuterShell) {
// No window of that name, and we are allowed to create a new one now.
webShellContainer->NewWebShell(chromeFlags, PR_FALSE, newOuterShell);
1998-09-18 00:35:55 +00:00
}
1999-04-20 22:35:11 +00:00
if (nsnull != newOuterShell) {
if (NS_SUCCEEDED(ReadyOpenedWebShell(newOuterShell, aReturn))) {
if (aAttachArguments && argc > 3)
AttachArguments(*aReturn, argv+3, argc-3);
newOuterShell->SetName(name.GetUnicode());
newOuterShell->LoadURL(mAbsURL.GetUnicode());
SizeAndShowOpenedWebShell(newOuterShell, options);
}
NS_RELEASE(newOuterShell);
}
NS_RELEASE(webShellContainer);
}
return NS_OK;
}
// attach the given array of JS values to the given window, as a property array
// named "arguments"
nsresult
GlobalWindowImpl::AttachArguments(nsIDOMWindow *aWindow, jsval *argv, PRUint32 argc)
{
if (argc == 0)
return NS_OK;
// copy the extra parameters into a JS Array and attach it
JSObject *args;
JSObject *scriptObject;
nsIScriptGlobalObject *scriptGlobal;
nsIScriptObjectOwner *owner;
JSContext *jsContext;
nsIScriptContext *scriptContext;
if (NS_SUCCEEDED(aWindow->QueryInterface(kIScriptGlobalObjectIID, (void **)&scriptGlobal))) {
scriptGlobal->GetContext(&scriptContext);
if (scriptContext) {
jsContext = (JSContext *) scriptContext->GetNativeContext();
if (NS_SUCCEEDED(aWindow->QueryInterface(kIScriptObjectOwnerIID, (void**)&owner))) {
owner->GetScriptObject(scriptContext, (void **) &scriptObject);
args = JS_NewArrayObject(jsContext, argc, argv);
if (args) {
jsval argsVal = OBJECT_TO_JSVAL(args);
// JS_DefineProperty(jsContext, scriptObject, "arguments",
// argsVal, NULL, NULL, JSPROP_PERMANENT);
JS_SetProperty(jsContext, scriptObject, "arguments", &argsVal);
}
NS_RELEASE(owner);
}
NS_RELEASE(scriptContext);
}
NS_RELEASE(scriptGlobal);
}
return NS_OK;
}
PRUint32
GlobalWindowImpl::CalculateChromeFlags(char *aFeatures) {
PRUint32 chromeFlags = 0;
if (nsnull == aFeatures)
return NS_CHROME_ALL_CHROME;
chromeFlags |= WinHasOption(aFeatures, "toolbar") ? NS_CHROME_TOOL_BAR_ON : 0;
chromeFlags |= WinHasOption(aFeatures, "location") ? NS_CHROME_LOCATION_BAR_ON : 0;
chromeFlags |= (WinHasOption(aFeatures, "directories") | WinHasOption(aFeatures, "personalbar"))
? NS_CHROME_PERSONAL_TOOLBAR_ON : 0;
chromeFlags |= WinHasOption(aFeatures, "status") ? NS_CHROME_STATUS_BAR_ON : 0;
chromeFlags |= WinHasOption(aFeatures, "menubar") ? NS_CHROME_MENU_BAR_ON : 0;
chromeFlags |= WinHasOption(aFeatures, "scrollbars") ? NS_CHROME_SCROLLBARS_ON : 0;
chromeFlags |= WinHasOption(aFeatures, "resizable") ? NS_CHROME_WINDOW_RESIZE_ON : 0;
chromeFlags |= NS_CHROME_WINDOW_CLOSE_ON;
chromeFlags |= WinHasOption(aFeatures, "chrome") ? NS_CHROME_OPEN_AS_CHROME : 0;
/*z-ordering, history, dependent
chromeFlags->topmost = WinHasOption(aFeatures, "alwaysRaised");
chromeFlags->bottommost = WinHasOption(aFeatures, "alwaysLowered");
chromeFlags->z_lock = WinHasOption(aFeatures, "z-lock");
chromeFlags->is_modal = WinHasOption(aFeatures, "modal");
chromeFlags->hide_title_bar = !(WinHasOption(aFeatures, "titlebar"));
chromeFlags->dependent = WinHasOption(aFeatures, "dependent");
chromeFlags->copy_history = FALSE;
*/
/* Allow disabling of commands only if there is no menubar */
/*if (!chromeFlags & NS_CHROME_MENU_BAR_ON) {
chromeFlags->disable_commands = !WinHasOption(aFeatures, "hotkeys");
if (XP_STRCASESTR(aFeatures,"hotkeys")==NULL)
chromeFlags->disable_commands = FALSE;
}*/
/* If titlebar condition not specified, default to shown */
/*if (XP_STRCASESTR(aFeatures,"titlebar")==0)*/
chromeFlags |= NS_CHROME_TITLEBAR_ON;
/* XXX Add security check on z-ordering, modal, hide title, disable hotkeys */
/* XXX Add security check for sizing and positioning.
* See mozilla/lib/libmocha/lm_win.c for current constraints */
return chromeFlags;
}
// set the newly opened webshell's (window) size, and show it
nsresult
GlobalWindowImpl::SizeAndShowOpenedWebShell(nsIWebShell *aOuterShell, char *aFeatures)
1999-05-14 03:10:51 +00:00
{
if (nsnull == aOuterShell)
return NS_ERROR_NULL_POINTER;
1999-05-14 03:10:51 +00:00
nsRect defaultBounds;
PRInt32 top = 0, left = 0, height = 0, width = 0;
nsIBrowserWindow *thisWindow,
*openedWindow = nsnull;
// use this window's size as the default
if (NS_SUCCEEDED(GetBrowserWindowInterface(thisWindow))) {
thisWindow->GetWindowBounds(defaultBounds);
NS_RELEASE(thisWindow);
}
// get the nsIBrowserWindow corresponding to the given aOuterShell
nsIWebShell *rootShell;
aOuterShell->GetRootWebShellEvenIfChrome(rootShell);
if (nsnull != rootShell) {
nsIWebShellContainer *newContainer;
rootShell->GetContainer(newContainer);
if (nsnull != newContainer) {
if (NS_FAILED(newContainer->QueryInterface(kIBrowserWindowIID, (void**)&openedWindow)))
openedWindow = nsnull;
NS_RELEASE(newContainer);
}
NS_RELEASE(rootShell);
}
// set size
if (nsnull != openedWindow) {
if (nsnull != aFeatures) {
width = WinHasOption(aFeatures, "innerWidth") | WinHasOption(aFeatures, "width");
height = WinHasOption(aFeatures, "innerHeight") | WinHasOption(aFeatures, "height");
// width = WinHasOption(aFeatures, "outerWidth");
// height = WinHasOption(aFeatures, "outerHeight");
left = WinHasOption(aFeatures, "left") | WinHasOption(aFeatures, "screenX");
top = WinHasOption(aFeatures, "top") | WinHasOption(aFeatures, "screenY");
}
1999-05-14 03:10:51 +00:00
// beard: don't resize/reposition the window if it is the same web shell.
if (aOuterShell != mWebShell) {
openedWindow->SizeTo(width ? width : defaultBounds.width, height ? height : defaultBounds.height);
openedWindow->MoveTo(left ? left : defaultBounds.x, top ? top : defaultBounds.y);
openedWindow->Show();
}
NS_RELEASE(openedWindow);
}
return NS_OK;
}
// return the nsIDOMWindow corresponding to the given nsIWebShell
// note this forces the creation of a script context, if one has not already been created
// note it also sets the window's opener to this -- because it's just convenient, that's all
nsresult
GlobalWindowImpl::ReadyOpenedWebShell(nsIWebShell *aWebShell, nsIDOMWindow **aDOMWindow)
{
nsIScriptContextOwner *newContextOwner = nsnull;
nsIScriptGlobalObject *newGlobalObject = nsnull;
nsresult res;
*aDOMWindow = nsnull;
res = aWebShell->QueryInterface(kIScriptContextOwnerIID, (void**)&newContextOwner);
if (NS_SUCCEEDED(res)) {
res = newContextOwner->GetScriptGlobalObject(&newGlobalObject);
1999-05-14 03:10:51 +00:00
if (NS_SUCCEEDED(res)) {
res = newGlobalObject->QueryInterface(kIDOMWindowIID, (void**)aDOMWindow);
newGlobalObject->SetOpenerWindow(this); // damnit
NS_RELEASE(newGlobalObject);
1999-05-14 03:10:51 +00:00
}
NS_RELEASE(newContextOwner);
1999-05-14 03:10:51 +00:00
}
return res;
}
NS_IMETHODIMP
GlobalWindowImpl::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent,
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& aPopupAlignment)
{
// Pass this off to the parent.
nsCOMPtr<nsIWebShellContainer> webShellContainer = do_QueryInterface(mWebShell);
if (webShellContainer) {
webShellContainer->CreatePopup(aElement, aPopupContent, aXPos, aYPos, aPopupType,
aPopupAlignment, this);
}
return NS_OK;
}
NS_IMETHODIMP
GlobalWindowImpl::CreateAnchoredPopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent,
const nsString& anAnchorAlignment,
const nsString& aPopupType, const nsString& aPopupAlignment)
{
return NS_OK;
}
1998-08-13 04:34:53 +00:00
nsresult
GlobalWindowImpl::CheckWindowName(JSContext *cx, nsString& aName)
{
PRInt32 index;
PRUnichar mChar;
for (index = 0; index < aName.Length(); index++) {
mChar = aName.CharAt(index);
if (!nsString::IsAlpha(mChar) && !nsString::IsDigit(mChar) && mChar != '_') {
char* cp = aName.ToNewCString();
JS_ReportError(cx,
"illegal character '%c' ('\\%o') in window name %s",
mChar, mChar, cp);
delete [] cp;
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
PRInt32
1998-08-13 04:34:53 +00:00
GlobalWindowImpl::WinHasOption(char *options, char *name)
{
char *comma, *equal;
PRInt32 found = 0;
for (;;) {
comma = strchr(options, ',');
if (comma) *comma = '\0';
equal = strchr(options, '=');
if (equal) *equal = '\0';
if (nsCRT::strcasecmp(options, name) == 0) {
if (!equal || nsCRT::strcasecmp(equal + 1, "yes") == 0)
found = 1;
else
found = atoi(equal + 1);
}
if (equal) *equal = '=';
if (comma) *comma = ',';
if (found || !comma)
break;
options = comma + 1;
}
return found;
}
1998-08-13 04:34:53 +00:00
nsresult
GlobalWindowImpl::GetBrowserWindowInterface(nsIBrowserWindow*& aBrowser)
{
nsresult ret;
nsIWebShell *mRootWebShell;
mWebShell->GetRootWebShellEvenIfChrome(mRootWebShell);
if (nsnull != mRootWebShell) {
nsIWebShellContainer *mRootContainer;
mRootWebShell->GetContainer(mRootContainer);
if (nsnull != mRootContainer) {
ret = mRootContainer->QueryInterface(kIBrowserWindowIID, (void**)&aBrowser);
NS_RELEASE(mRootContainer);
}
NS_RELEASE(mRootWebShell);
}
return ret;
}
PRBool
GlobalWindowImpl::CheckForEventListener(JSContext *aContext, nsString& aPropName)
{
nsIEventListenerManager *mManager = nsnull;
if (aPropName == "onmousedown" || aPropName == "onmouseup" || aPropName == "onclick" ||
aPropName == "onmouseover" || aPropName == "onmouseout") {
if (NS_OK == GetListenerManager(&mManager)) {
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseListenerIID)) {
NS_RELEASE(mManager);
return PR_FALSE;
}
}
}
else if (aPropName == "onkeydown" || aPropName == "onkeyup" || aPropName == "onkeypress") {
if (NS_OK == GetListenerManager(&mManager)) {
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMKeyListenerIID)) {
NS_RELEASE(mManager);
return PR_FALSE;
}
}
}
else if (aPropName == "onmousemove") {
if (NS_OK == GetListenerManager(&mManager)) {
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseMotionListenerIID)) {
NS_RELEASE(mManager);
return PR_FALSE;
}
}
}
else if (aPropName == "onfocus" || aPropName == "onblur") {
if (NS_OK == GetListenerManager(&mManager)) {
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFocusListenerIID)) {
NS_RELEASE(mManager);
return PR_FALSE;
}
}
}
1998-11-02 23:05:46 +00:00
else if (aPropName == "onsubmit" || aPropName == "onreset" || aPropName == "onchange") {
if (NS_OK == GetListenerManager(&mManager)) {
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFormListenerIID)) {
NS_RELEASE(mManager);
return PR_FALSE;
}
}
}
else if (aPropName == "onload" || aPropName == "onunload" || aPropName == "onabort" ||
aPropName == "onerror") {
if (NS_OK == GetListenerManager(&mManager)) {
nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext);
if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMLoadListenerIID)) {
NS_RELEASE(mManager);
return PR_FALSE;
}
}
}
1998-10-06 20:59:39 +00:00
else if (aPropName == "onpaint") {
if (NS_OK == GetListenerManager(&mManager)) {
nsIScriptContext *mScriptCX = (nsIScriptContext *)
JS_GetContextPrivate(aContext);
if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this,
kIDOMPaintListenerIID)) {
NS_RELEASE(mManager);
return PR_FALSE;
}
}
}
NS_IF_RELEASE(mManager);
return PR_TRUE;
}
PRBool
1998-08-13 04:34:53 +00:00
GlobalWindowImpl::AddProperty(JSContext *aContext, jsval aID, jsval *aVp)
{
if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) {
nsString mPropName;
nsAutoString mPrefix;
mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID)));
mPrefix.SetString(mPropName.GetUnicode(), 2);
if (mPrefix == "on") {
return CheckForEventListener(aContext, mPropName);
}
}
return PR_TRUE;
}
1998-08-13 04:34:53 +00:00
PRBool
GlobalWindowImpl::DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp)
{
return PR_TRUE;
}
1998-08-13 04:34:53 +00:00
PRBool
GlobalWindowImpl::GetProperty(JSContext *aContext, jsval aID, jsval *aVp)
{
1998-08-13 04:34:53 +00:00
if (JSVAL_IS_STRING(aID) &&
PL_strcmp("location", JS_GetStringBytes(JS_ValueToString(aContext, aID))) == 0) {
nsIDOMLocation *location;
if (NS_OK == GetLocation(&location)) {
if (location != nsnull) {
nsIScriptObjectOwner *owner = nsnull;
if (NS_OK == location->QueryInterface(kIScriptObjectOwnerIID,
(void**)&owner)) {
JSObject *object = nsnull;
nsIScriptContext *script_cx = (nsIScriptContext *)JS_GetContextPrivate(aContext);
if (NS_OK == owner->GetScriptObject(script_cx, (void**)&object)) {
// set the return value
*aVp = OBJECT_TO_JSVAL(object);
}
NS_RELEASE(owner);
}
NS_RELEASE(location);
}
else {
*aVp = JSVAL_NULL;
}
}
else {
return PR_FALSE;
}
}
return PR_TRUE;
}
PRBool
1998-08-13 04:34:53 +00:00
GlobalWindowImpl::SetProperty(JSContext *aContext, jsval aID, jsval *aVp)
{
if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) {
nsString mPropName;
nsAutoString mPrefix;
mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID)));
mPrefix.SetString(mPropName.GetUnicode(), 2);
if (mPrefix == "on") {
return CheckForEventListener(aContext, mPropName);
}
}
1998-08-13 04:34:53 +00:00
else if (JSVAL_IS_STRING(aID) &&
PL_strcmp("location", JS_GetStringBytes(JS_ValueToString(aContext, aID))) == 0) {
JSString *jsstring = JS_ValueToString(aContext, *aVp);
if (nsnull != jsstring) {
nsIDOMLocation *location;
nsAutoString locationStr;
locationStr.SetString(JS_GetStringChars(jsstring));
if (NS_OK == GetLocation(&location)) {
if (NS_OK != location->SetHref(locationStr)) {
NS_RELEASE(location);
return PR_FALSE;
}
NS_RELEASE(location);
}
else {
return PR_FALSE;
}
}
}
return PR_TRUE;
}
1998-08-13 04:34:53 +00:00
PRBool
GlobalWindowImpl::EnumerateProperty(JSContext *aContext)
{
return PR_TRUE;
}
1998-08-13 04:34:53 +00:00
PRBool
GlobalWindowImpl::Resolve(JSContext *aContext, jsval aID)
{
if (JSVAL_IS_STRING(aID) &&
PL_strcmp("location", JS_GetStringBytes(JS_ValueToString(aContext, aID))) == 0) {
::JS_DefineProperty(aContext, (JSObject *)mScriptObject, "location",
JSVAL_NULL, nsnull, nsnull, 0);
}
return PR_TRUE;
}
1998-08-13 04:34:53 +00:00
PRBool
GlobalWindowImpl::Convert(JSContext *aContext, jsval aID)
{
return PR_TRUE;
}
1998-08-13 04:34:53 +00:00
void
GlobalWindowImpl::Finalize(JSContext *aContext)
{
}
1998-08-13 04:34:53 +00:00
nsresult
GlobalWindowImpl::GetListenerManager(nsIEventListenerManager **aInstancePtrResult)
{
if (nsnull != mListenerManager) {
return mListenerManager->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult);;
}
//This is gonna get ugly. Can't use NS_NewEventListenerManager because of a circular link problem.
nsIDOMEventCapturer *mDoc;
if (nsnull != mDocument && NS_OK == mDocument->QueryInterface(kIDOMEventCapturerIID, (void**)&mDoc)) {
if (NS_OK == mDoc->GetNewListenerManager(aInstancePtrResult)) {
mListenerManager = *aInstancePtrResult;
NS_ADDREF(mListenerManager);
NS_RELEASE(mDoc);
return NS_OK;
}
NS_IF_RELEASE(mDoc);
}
return NS_ERROR_FAILURE;
}
//XXX I need another way around the circular link problem.
1998-08-13 04:34:53 +00:00
nsresult
GlobalWindowImpl::GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult)
{
return NS_ERROR_FAILURE;
}
1998-08-13 04:34:53 +00:00
nsresult
GlobalWindowImpl::HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus)
{
nsresult mRet = NS_OK;
nsIDOMEvent* mDOMEvent = nsnull;
1999-03-28 22:19:42 +00:00
if (NS_EVENT_FLAG_INIT == aFlags) {
aDOMEvent = &mDOMEvent;
}
//Capturing stage
if (NS_EVENT_FLAG_BUBBLE != aFlags && mChromeDocument) {
// Check chrome document capture here
mChromeDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
//Local handling stage
if (nsnull != mListenerManager) {
1999-03-28 22:19:42 +00:00
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}
//Bubbling stage
if (NS_EVENT_FLAG_CAPTURE != aFlags && mChromeDocument) {
// Bubble to a chrome document if it exists
mChromeDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_BUBBLE, aEventStatus);
}
1999-03-28 22:19:42 +00:00
if (NS_EVENT_FLAG_INIT == aFlags) {
// We're leaving the DOM event loop so if we created a DOM event, release here.
if (nsnull != *aDOMEvent) {
nsrefcnt rc;
NS_RELEASE2(*aDOMEvent, rc);
if (0 != rc) {
//Okay, so someone in the DOM loop (a listener, JS object) still has a ref to the DOM Event but
//the internal data hasn't been malloc'd. Force a copy of the data here so the DOM Event is still valid.
nsIPrivateDOMEvent *mPrivateEvent;
if (NS_OK == (*aDOMEvent)->QueryInterface(kIPrivateDOMEventIID, (void**)&mPrivateEvent)) {
mPrivateEvent->DuplicatePrivateData();
NS_RELEASE(mPrivateEvent);
}
}
}
aDOMEvent = nsnull;
}
return mRet;
}
1998-08-13 04:34:53 +00:00
nsresult
1999-03-28 22:19:42 +00:00
GlobalWindowImpl::AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsIEventListenerManager *mManager;
if (NS_OK == GetListenerManager(&mManager)) {
1999-03-28 22:19:42 +00:00
mManager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
NS_RELEASE(mManager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
1998-08-13 04:34:53 +00:00
nsresult
1999-03-28 22:19:42 +00:00
GlobalWindowImpl::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
if (nsnull != mListenerManager) {
1999-03-28 22:19:42 +00:00
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
GlobalWindowImpl::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
manager->AddEventListenerByType(aListener, aType, flags);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
GlobalWindowImpl::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
if (nsnull != mListenerManager) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
1998-08-13 04:34:53 +00:00
nsresult
GlobalWindowImpl::CaptureEvent(const nsString& aType)
{
nsIEventListenerManager *mManager;
if (NS_OK == GetListenerManager(&mManager)) {
//mManager->CaptureEvent(aListener);
NS_RELEASE(mManager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
1998-08-13 04:34:53 +00:00
nsresult
GlobalWindowImpl::ReleaseEvent(const nsString& aType)
{
if (nsnull != mListenerManager) {
//mListenerManager->ReleaseEvent(aListener);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
1998-07-16 01:16:47 +00:00
extern "C" NS_DOM nsresult
NS_NewScriptGlobalObject(nsIScriptGlobalObject **aResult)
{
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = NULL;
GlobalWindowImpl *global = new GlobalWindowImpl();
if (nsnull == global) {
return NS_ERROR_OUT_OF_MEMORY;
}
return global->QueryInterface(kIScriptGlobalObjectIID, (void **)aResult);
}
//
// Navigator class implementation
//
NavigatorImpl::NavigatorImpl()
{
NS_INIT_REFCNT();
1998-07-16 01:16:47 +00:00
mScriptObject = nsnull;
mMimeTypes = nsnull;
mPlugins = nsnull;
1998-07-16 01:16:47 +00:00
}
NavigatorImpl::~NavigatorImpl()
{
NS_IF_RELEASE(mMimeTypes);
NS_IF_RELEASE(mPlugins);
1998-07-16 01:16:47 +00:00
}
NS_IMPL_ADDREF(NavigatorImpl)
NS_IMPL_RELEASE(NavigatorImpl)
nsresult
NavigatorImpl::QueryInterface(const nsIID& aIID,
void** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtrResult = (void*) ((nsIScriptObjectOwner*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMNavigatorIID)) {
*aInstancePtrResult = (void*) ((nsIDOMNavigator*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtrResult = (void*)(nsISupports*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsresult
NavigatorImpl::SetScriptObject(void *aScriptObject)
1998-07-16 01:16:47 +00:00
{
mScriptObject = aScriptObject;
1998-07-16 01:16:47 +00:00
return NS_OK;
}
nsresult
NavigatorImpl::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
res = NS_NewScriptNavigator(aContext, (nsISupports *)(nsIDOMNavigator *)this, global, &mScriptObject);
1998-07-16 01:16:47 +00:00
NS_IF_RELEASE(global);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
NavigatorImpl::GetUserAgent(nsString& aUserAgent)
{
nsINetService *service = nsnull;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID,
(nsISupports **)&service);
1998-07-16 01:16:47 +00:00
if ((NS_OK == res) && (nsnull != service)) {
res = service->GetUserAgent(aUserAgent);
NS_RELEASE(service);
}
return res;
1998-07-16 01:16:47 +00:00
}
NS_IMETHODIMP
NavigatorImpl::GetAppCodeName(nsString& aAppCodeName)
{
nsINetService *service;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
res = service->GetAppCodeName(aAppCodeName);
NS_RELEASE(service);
1998-07-16 01:16:47 +00:00
}
return res;
1998-07-16 01:16:47 +00:00
}
NS_IMETHODIMP
NavigatorImpl::GetAppVersion(nsString& aAppVersion)
{
nsINetService *service;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
res = service->GetAppVersion(aAppVersion);
NS_RELEASE(service);
1998-07-16 01:16:47 +00:00
}
return res;
1998-07-16 01:16:47 +00:00
}
NS_IMETHODIMP
NavigatorImpl::GetAppName(nsString& aAppName)
{
nsINetService *service;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
res = service->GetAppName(aAppName);
NS_RELEASE(service);
1998-07-16 01:16:47 +00:00
}
return res;
1998-07-16 01:16:47 +00:00
}
NS_IMETHODIMP
NavigatorImpl::GetLanguage(nsString& aLanguage)
{
nsINetService *service;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
res = service->GetLanguage(aLanguage);
NS_RELEASE(service);
1998-07-16 01:16:47 +00:00
}
return res;
1998-07-16 01:16:47 +00:00
}
NS_IMETHODIMP
NavigatorImpl::GetPlatform(nsString& aPlatform)
{
nsINetService *service;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
res = service->GetPlatform(aPlatform);
NS_RELEASE(service);
1998-07-16 01:16:47 +00:00
}
return res;
1998-07-16 01:16:47 +00:00
}
NS_IMETHODIMP
NavigatorImpl::GetSecurityPolicy(nsString& aSecurityPolicy)
{
return NS_OK;
}
NS_IMETHODIMP
NavigatorImpl::GetMimeTypes(nsIDOMMimeTypeArray** aMimeTypes)
{
if (nsnull == mMimeTypes) {
mMimeTypes = new MimeTypeArrayImpl(this);
NS_IF_ADDREF(mMimeTypes);
}
*aMimeTypes = mMimeTypes;
NS_IF_ADDREF(mMimeTypes);
return NS_OK;
}
NS_IMETHODIMP
NavigatorImpl::GetPlugins(nsIDOMPluginArray** aPlugins)
{
if (nsnull == mPlugins) {
mPlugins = new PluginArrayImpl(this);
NS_IF_ADDREF(mPlugins);
}
*aPlugins = mPlugins;
NS_IF_ADDREF(mPlugins);
return NS_OK;
}
1998-07-16 01:16:47 +00:00
NS_IMETHODIMP
NavigatorImpl::JavaEnabled(PRBool* aReturn)
{
nsresult rv = NS_OK;
1998-07-16 01:16:47 +00:00
*aReturn = PR_FALSE;
// determine whether user has enabled java.
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (NS_FAILED(rv) || (prefs == nsnull)) {
return rv;
}
rv = prefs->GetBoolPref("security.enable_java", aReturn);
#if 0
nsIJVMManager* manager = NULL;
rv = nsServiceManager::GetService(nsIJVMManager::GetCID(),
nsIJVMManager::GetIID(),
(nsISupports **)&manager);
if (rv == NS_OK && manager != NULL) {
rv = manager->IsJavaEnabled(aReturn);
nsServiceManager::ReleaseService(nsIJVMManager::GetCID(), manager);
}
#endif
return rv;
1998-07-16 01:16:47 +00:00
}