mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
partial nsWindowMediator embedding analogue (not yet hooked up to build) r=sfraser,valeski
This commit is contained in:
parent
e240f6ab6e
commit
ac3d61825f
52
embedding/components/build/makefile.win
Normal file
52
embedding/components/build/makefile.win
Normal file
@ -0,0 +1,52 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications, Inc. Portions created by Netscape are
|
||||
# Copyright (C) 2001, Mozilla. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
MODULE=embedcomponents
|
||||
|
||||
MAKE_OBJ_TYPE=DLL
|
||||
DLLNAME=embedcomponents
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
|
||||
LCFLAGS = -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsModule.obj \
|
||||
$(NULL)
|
||||
|
||||
LLIBS = \
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\windowwatcher_s.lib \
|
||||
$(NULL)
|
||||
|
||||
INCS = $(INCS) \
|
||||
-I$(DEPTH)\embedding\components\windowwatcher\src \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
$(RM) $(DIST)\bin\components\$(DLLNAME).dll
|
||||
$(RM) $(DIST)\lib\$(DLLNAME).lib
|
34
embedding/components/build/nsModule.cpp
Normal file
34
embedding/components/build/nsModule.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsWindowWatcher.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowWatcher, Init)
|
||||
|
||||
static nsModuleComponentInfo components[] = {
|
||||
|
||||
{ "Window Watcher", NS_WINDOWWATCHER_CID, NS_WINDOWWATCHER_CONTRACTID, nsWindowWatcherConstructor }
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("windowwatcher", components)
|
||||
|
28
embedding/components/makefile.win
Normal file
28
embedding/components/makefile.win
Normal file
@ -0,0 +1,28 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications, Inc. Portions created by Netscape are
|
||||
# Copyright (C) 2001, Mozilla. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..
|
||||
|
||||
DIRS= \
|
||||
windowwatcher \
|
||||
build \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
25
embedding/components/windowwatcher/makefile.win
Normal file
25
embedding/components/windowwatcher/makefile.win
Normal file
@ -0,0 +1,25 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications, Inc. Portions created by Netscape are
|
||||
# Copyright (C) 2001, Mozilla. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
DIRS=public src
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
2
embedding/components/windowwatcher/public/MANIFEST_IDL
Normal file
2
embedding/components/windowwatcher/public/MANIFEST_IDL
Normal file
@ -0,0 +1,2 @@
|
||||
nsIWindowWatcher.idl
|
||||
nsPIWindowWatcher.idl
|
31
embedding/components/windowwatcher/public/makefile.win
Normal file
31
embedding/components/windowwatcher/public/makefile.win
Normal file
@ -0,0 +1,31 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications, Inc. Portions created by Netscape are
|
||||
# Copyright (C) 2001, Mozilla. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
MODULE=windowwatcher
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsIWindowWatcher.idl \
|
||||
.\nsPIWindowWatcher.idl \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
141
embedding/components/windowwatcher/public/nsIWindowWatcher.idl
Normal file
141
embedding/components/windowwatcher/public/nsIWindowWatcher.idl
Normal file
@ -0,0 +1,141 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
|
||||
* The Original Code is mozilla.org code.
|
||||
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications, Inc. Portions created by Netscape are
|
||||
* Copyright (C) 2001, Mozilla. All Rights Reserved.
|
||||
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/*
|
||||
nsIWindowWatcher is the keeper of Gecko/DOM Windows. It maintains
|
||||
opens and closes windows, and maintains a traversable list of open
|
||||
windows.
|
||||
|
||||
Usage notes:
|
||||
|
||||
This component has an |activeWindow| property. Clients may expect
|
||||
this property to be always current, so to properly integrate this component
|
||||
the application will need to keep it current by setting the property
|
||||
as the active window changes.
|
||||
This component does automatically keep an accurate list of extant
|
||||
windows; windows need not be added or removed by hand (and there's no
|
||||
interface for doing so).
|
||||
Windows referenced will not be refcounted; the implementation will
|
||||
claim no ownership. Since it's the nature of this service to always
|
||||
hold a ("weak") reference to an open window, this requirement removes
|
||||
a potential reference loop. It should be safe because it's a
|
||||
design requirement that clients explicitly maintain |activeWindow| and
|
||||
|currentWindow|, and that windows remove themselves from the service
|
||||
when they are closed.
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
interface nsIObserver;
|
||||
interface nsISimpleEnumerator;
|
||||
|
||||
[scriptable, uuid(002286a8-494b-43b3-8ddd-49e3fc50622b)]
|
||||
|
||||
/*
|
||||
Subject to change without revision of CID until further notice.
|
||||
|
||||
Assumptions:
|
||||
|
||||
For now I'm assuming we'll use this component to track the current
|
||||
"networking context." That is, the window currently being serviced by
|
||||
the network libraries, and therefore the proper parent of any alerts
|
||||
those libraries may need to pose. I'm not yet convinced that this will
|
||||
actually work or be necessary.
|
||||
The "networking context" must provide two things: an nsIDOMWindow
|
||||
to provide a script context and a native window to act as a parent
|
||||
for a networking dialog. This implies the nsIDOMWindow will be able
|
||||
to walk up some chain to find its container native embedding window.
|
||||
In fact, I believe I can always pull a JS context off that stack
|
||||
of the things that people keep around when they're switching back and forth
|
||||
between C++ and JS, so all I really need to create a window is a (native)
|
||||
parent.
|
||||
All windows must inform the Watcher when they're being closed (perhaps
|
||||
automatically through the DOMWindow's destructor), so the Watcher can
|
||||
trust all its windows to be real, so there's no need for the Watcher to
|
||||
addref any of its windows. This means, for instance, that setCurrentContext
|
||||
won't cause a leak if you don't unset it. It would be an error to fail
|
||||
to set the current context before getting into a situation where one
|
||||
might be necessary.
|
||||
*/
|
||||
|
||||
interface nsIWindowWatcher : nsISupports {
|
||||
|
||||
/** Create a new window. It will automatically be added to our list
|
||||
(via addWindow()).
|
||||
@param aParent parent window, if any. null if not.
|
||||
@param aURL window URL from JS window.open
|
||||
@param aName window name from JS window.open
|
||||
@param aFeatures window features from JS window.open
|
||||
@return the new window
|
||||
*/
|
||||
nsIDOMWindow openWindow(in nsIDOMWindow aParent, in string aUrl,
|
||||
in string aName, in string aFeatures);
|
||||
|
||||
/** Clients of this service can register themselves to be notified
|
||||
when a window is opened or closed (added to or removed from this
|
||||
service). This method adds an aObserver to the list of objects
|
||||
to be notified.
|
||||
@param aObserver the object to be notified when windows are
|
||||
opened or closed. Its Observe method will be
|
||||
called with the following parameters:
|
||||
@param aSubject (parameter to aObserver::Observe) the window being
|
||||
opened or closed, sent as an nsISupports
|
||||
which can be QIed to an nsIDOMWindow.
|
||||
@param aTopic (parameter to aObserver::Observe) a wstring, either
|
||||
"domwindowopened" or "domwindowclosed".
|
||||
@param someData (parameter to aObserver::Observe) not used.
|
||||
*/
|
||||
void registerNotification(in nsIObserver aObserver);
|
||||
|
||||
/** Clients of this service can register themselves to be notified
|
||||
when a window is opened or closed (added to or removed from this
|
||||
service). This method removes an aObserver from the list of objects
|
||||
to be notified.
|
||||
@param aObserver the observer to be removed.
|
||||
*/
|
||||
void unregisterNotification(in nsIObserver aObserver);
|
||||
|
||||
/** iterates over currently open windows in the order they were opened,
|
||||
guaranteeing that each will be visited exactly once.
|
||||
@return an enumerator which will itself return an nsISupports which
|
||||
can be QIed to an nsIDOMWindow
|
||||
*/
|
||||
|
||||
nsISimpleEnumerator getWindowEnumerator();
|
||||
|
||||
/** The Watcher serves as a global storage facility for the current active
|
||||
(frontmost non-floating-palette-type) window, storing and returning
|
||||
it on demand. Users must keep this attribute current, including after
|
||||
the topmost window is closed. This attribute obviously can return null
|
||||
if no windows are open, but should otherwise always return a valid
|
||||
window.
|
||||
*/
|
||||
attribute nsIDOMWindow activeWindow;
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
// {002286a8-494b-43b3-8ddd-49e3fc50622b}
|
||||
#define NS_WINDOWWATCHER_IID \
|
||||
{0x002286a8, 0x494b, 0x43b3, {0x8d, 0xdd, 0x49, 0xe3, 0xfc, 0x50, 0x62, 0x2b}}
|
||||
%}
|
||||
|
@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
|
||||
* The Original Code is mozilla.org code.
|
||||
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications, Inc. Portions created by Netscape are
|
||||
* Copyright (C) 2001, Mozilla. All Rights Reserved.
|
||||
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
interface nsISimpleEnumerator;
|
||||
|
||||
[uuid(d535806e-afaf-47d1-8d89-783ad088c62a)]
|
||||
|
||||
interface nsPIWindowWatcher : nsISupports
|
||||
{
|
||||
/** A window has been created. Add it to our list.
|
||||
@param aWindow the window to add
|
||||
*/
|
||||
void addWindow(in nsIDOMWindow aWindow);
|
||||
|
||||
/** A window has been closed. Remove it from our list.
|
||||
@param aWindow the window to remove
|
||||
*/
|
||||
void removeWindow(in nsIDOMWindow aWindow);
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
// {d535806e-afaf-47d1-8d89-783ad088c62a}
|
||||
#define NS_PWINDOWWATCHER_IID \
|
||||
{0xd535806e, 0xafaf, 0x47d1, {0x8d, 0x89, 0x78, 0x3a, 0xd0, 0x88, 0xc6, 0x2a}}
|
||||
%}
|
||||
|
36
embedding/components/windowwatcher/src/makefile.win
Normal file
36
embedding/components/windowwatcher/src/makefile.win
Normal file
@ -0,0 +1,36 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications, Inc. Portions created by Netscape are
|
||||
# Copyright (C) 2001, Mozilla. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
MODULE=embedcomponents
|
||||
LIBRARY_NAME=windowwatcher_s
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsWindowWatcher.obj \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
432
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
Normal file
432
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
Normal file
@ -0,0 +1,432 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
//#define USEWEAKREFS // (haven't quite figured that out yet)
|
||||
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsWindowWatcher.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIObserverService.h"
|
||||
#ifdef USEWEAKREFS
|
||||
#include "nsIWeakReference.h"
|
||||
#endif
|
||||
|
||||
#define NOTIFICATION_OPENED NS_LITERAL_STRING("domwindowopened")
|
||||
#define NOTIFICATION_CLOSED NS_LITERAL_STRING("domwindowclosed")
|
||||
|
||||
/****************************************************************
|
||||
************************* winfowInfo ***************************
|
||||
****************************************************************/
|
||||
|
||||
class nsWindowWatcher;
|
||||
|
||||
struct WindowInfo {
|
||||
|
||||
#ifdef USEWEAKREFS
|
||||
WindowInfo(nsIDOMWindow* inWindow) {
|
||||
mWindow = getter_AddRefs(NS_GetWeakReference(inWindow));
|
||||
#else
|
||||
WindowInfo(nsIDOMWindow* inWindow) :
|
||||
mWindow(inWindow) {
|
||||
#endif
|
||||
ReferenceSelf();
|
||||
}
|
||||
~WindowInfo() {}
|
||||
|
||||
void InsertAfter(WindowInfo *inOlder);
|
||||
void Unlink();
|
||||
void ReferenceSelf();
|
||||
|
||||
#ifdef USEWEAKREFS
|
||||
nsCOMPtr<nsIWeakReference> mWindow;
|
||||
#else
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
#endif
|
||||
// each struct is in a circular, doubly-linked list
|
||||
WindowInfo *mYounger, // next younger in sequence
|
||||
*mOlder;
|
||||
};
|
||||
|
||||
void WindowInfo::InsertAfter(WindowInfo *inOlder)
|
||||
{
|
||||
if (inOlder) {
|
||||
mOlder = inOlder;
|
||||
mYounger = inOlder->mYounger;
|
||||
mOlder->mYounger = this;
|
||||
if (mOlder->mOlder == mOlder)
|
||||
mOlder->mOlder = this;
|
||||
mYounger->mOlder = this;
|
||||
if (mYounger->mYounger == mYounger)
|
||||
mYounger->mYounger = this;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowInfo::Unlink() {
|
||||
|
||||
mOlder->mYounger = mYounger;
|
||||
mYounger->mOlder = mOlder;
|
||||
ReferenceSelf();
|
||||
}
|
||||
|
||||
void WindowInfo::ReferenceSelf() {
|
||||
|
||||
mYounger = this;
|
||||
mOlder = this;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
********************* nsWindowEnumerator ***********************
|
||||
****************************************************************/
|
||||
|
||||
class nsWindowEnumerator : public nsISimpleEnumerator {
|
||||
|
||||
public:
|
||||
nsWindowEnumerator(nsWindowWatcher *inWatcher);
|
||||
~nsWindowEnumerator();
|
||||
NS_IMETHOD HasMoreElements(PRBool *retval);
|
||||
NS_IMETHOD GetNext(nsISupports **retval);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
private:
|
||||
friend class nsWindowWatcher;
|
||||
|
||||
WindowInfo *FindNext();
|
||||
void WindowRemoved(WindowInfo *inInfo);
|
||||
|
||||
nsWindowWatcher *mWindowWatcher;
|
||||
WindowInfo *mCurrentPosition;
|
||||
};
|
||||
|
||||
NS_IMPL_ADDREF(nsWindowEnumerator);
|
||||
NS_IMPL_RELEASE(nsWindowEnumerator);
|
||||
NS_IMPL_QUERY_INTERFACE1(nsWindowEnumerator, nsISimpleEnumerator);
|
||||
|
||||
nsWindowEnumerator::nsWindowEnumerator(nsWindowWatcher *inWatcher)
|
||||
: mWindowWatcher(inWatcher),
|
||||
mCurrentPosition(inWatcher->mOldestWindow)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mWindowWatcher->AddEnumerator(this);
|
||||
mWindowWatcher->AddRef();
|
||||
}
|
||||
|
||||
nsWindowEnumerator::~nsWindowEnumerator()
|
||||
{
|
||||
mWindowWatcher->RemoveEnumerator(this);
|
||||
mWindowWatcher->Release();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowEnumerator::HasMoreElements(PRBool *retval)
|
||||
{
|
||||
if (!retval)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
*retval = mCurrentPosition? PR_TRUE : PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowEnumerator::GetNext(nsISupports **retval)
|
||||
{
|
||||
if (!retval)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
*retval = NULL;
|
||||
|
||||
#ifdef USEWEAKREFS
|
||||
while (mCurrentPosition) {
|
||||
CallQueryReferent(mCurrentPosition->mWindow, retval);
|
||||
if (*retval) {
|
||||
mCurrentPosition = FindNext();
|
||||
break;
|
||||
} else // window is gone!
|
||||
mWindowWatcher->RemoveWindow(mCurrentPosition);
|
||||
}
|
||||
NS_IF_ADDREF(*retval);
|
||||
#else
|
||||
if (mCurrentPosition) {
|
||||
CallQueryInterface(mCurrentPosition->mWindow, retval);
|
||||
mCurrentPosition = FindNext();
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
WindowInfo *
|
||||
nsWindowEnumerator::FindNext()
|
||||
{
|
||||
WindowInfo *info;
|
||||
|
||||
if (!mCurrentPosition)
|
||||
return 0;
|
||||
|
||||
info = mCurrentPosition->mYounger;
|
||||
return info == mWindowWatcher->mOldestWindow ? 0 : info;
|
||||
}
|
||||
|
||||
// if a window is being removed adjust the iterator's current position
|
||||
void nsWindowEnumerator::WindowRemoved(WindowInfo *inInfo) {
|
||||
|
||||
if (mCurrentPosition == inInfo)
|
||||
mCurrentPosition = mCurrentPosition != inInfo->mYounger ?
|
||||
inInfo->mYounger : 0;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
*********************** nsWindowWatcher ************************
|
||||
****************************************************************/
|
||||
|
||||
NS_IMPL_ADDREF(nsWindowWatcher);
|
||||
NS_IMPL_RELEASE(nsWindowWatcher);
|
||||
NS_IMPL_QUERY_INTERFACE2(nsWindowWatcher, nsIWindowWatcher, nsPIWindowWatcher)
|
||||
|
||||
nsWindowWatcher::nsWindowWatcher() :
|
||||
mEnumeratorList(),
|
||||
mOldestWindow(0),
|
||||
mActiveWindow(0),
|
||||
mListLock(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsWindowWatcher::~nsWindowWatcher()
|
||||
{
|
||||
// delete data
|
||||
while (mOldestWindow)
|
||||
RemoveWindow(mOldestWindow);
|
||||
|
||||
if (mListLock)
|
||||
PR_DestroyLock(mListLock);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWindowWatcher::Init()
|
||||
{
|
||||
mListLock = PR_NewLock();
|
||||
if (!mListLock)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
|
||||
const char *aUrl,
|
||||
const char *aName,
|
||||
const char *aFeatures,
|
||||
nsIDOMWindow **_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::RegisterNotification(nsIObserver *aObserver)
|
||||
{
|
||||
// just a convenience method; it delegates to nsIObserverService
|
||||
nsresult rv;
|
||||
|
||||
if (!aObserver)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
|
||||
if (os) {
|
||||
rv = os->AddObserver(aObserver, NOTIFICATION_OPENED);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = os->AddObserver(aObserver, NOTIFICATION_CLOSED);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::UnregisterNotification(nsIObserver *aObserver)
|
||||
{
|
||||
// just a convenience method; it delegates to nsIObserverService
|
||||
nsresult rv;
|
||||
|
||||
if (!aObserver)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
|
||||
if (os) {
|
||||
os->RemoveObserver(aObserver, NOTIFICATION_OPENED);
|
||||
os->RemoveObserver(aObserver, NOTIFICATION_CLOSED);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::GetWindowEnumerator(nsISimpleEnumerator** _retval)
|
||||
{
|
||||
if (!_retval)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsAutoLock lock(mListLock);
|
||||
nsWindowEnumerator *enumerator = new nsWindowEnumerator(this);
|
||||
if (enumerator)
|
||||
return CallQueryInterface(enumerator, _retval);
|
||||
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::GetActiveWindow(nsIDOMWindow * *aActiveWindow)
|
||||
{
|
||||
if (!aActiveWindow)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
*aActiveWindow = mActiveWindow;
|
||||
NS_IF_ADDREF(mActiveWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::SetActiveWindow(nsIDOMWindow * aActiveWindow)
|
||||
{
|
||||
mActiveWindow = aActiveWindow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::AddWindow(nsIDOMWindow *aWindow)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!aWindow)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// create window info struct and add to list of windows
|
||||
WindowInfo* info = new WindowInfo(aWindow);
|
||||
if (!info)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsAutoLock lock(mListLock);
|
||||
if (mOldestWindow)
|
||||
info->InsertAfter(mOldestWindow->mOlder);
|
||||
else
|
||||
mOldestWindow = info;
|
||||
|
||||
// a window being added to us signifies a newly opened window.
|
||||
// send notifications.
|
||||
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
|
||||
if (os) {
|
||||
nsCOMPtr<nsISupports> domwin(do_QueryInterface(aWindow));
|
||||
rv = os->Notify(domwin, NOTIFICATION_OPENED, 0);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::RemoveWindow(nsIDOMWindow *aWindow)
|
||||
{
|
||||
// find the corresponding WindowInfo, remove it
|
||||
WindowInfo *info,
|
||||
*listEnd;
|
||||
#ifdef USEWEAKREFS
|
||||
nsresult rv;
|
||||
PRBool found;
|
||||
#endif
|
||||
|
||||
if (!aWindow)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
info = mOldestWindow;
|
||||
listEnd = 0;
|
||||
#ifdef USEWEAKREFS
|
||||
rv = NS_OK;
|
||||
found = PR_FALSE;
|
||||
while (info != listEnd && NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIDOMWindow> infoWindow(do_QueryReferent(info->mWindow));
|
||||
if (!infoWindow)
|
||||
rv = RemoveWindow(info);
|
||||
else if (infoWindow.get() == aWindow) {
|
||||
found = PR_TRUE;
|
||||
rv = RemoveWindow(info);
|
||||
}
|
||||
info = info->mYounger;
|
||||
listEnd = mOldestWindow;
|
||||
}
|
||||
return found ? rv : NS_ERROR_INVALID_ARG;
|
||||
#else
|
||||
while (info != listEnd) {
|
||||
if (info->mWindow.get() == aWindow)
|
||||
return RemoveWindow(info);
|
||||
info = info->mYounger;
|
||||
listEnd = mOldestWindow;
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsWindowWatcher::RemoveWindow(WindowInfo *inInfo)
|
||||
{
|
||||
PRInt32 ctr,
|
||||
count = mEnumeratorList.Count();
|
||||
nsresult rv;
|
||||
|
||||
{
|
||||
// notify the enumerators
|
||||
nsAutoLock lock(mListLock);
|
||||
for (ctr = 0; ctr < count; ++ctr)
|
||||
((nsWindowEnumerator*)mEnumeratorList[ctr])->WindowRemoved(inInfo);
|
||||
|
||||
// remove the element from the list
|
||||
if (inInfo == mOldestWindow)
|
||||
mOldestWindow = inInfo->mYounger == mOldestWindow ? 0 : inInfo->mYounger;
|
||||
inInfo->Unlink();
|
||||
}
|
||||
|
||||
// a window being removed from us signifies a newly closed window.
|
||||
// send notifications.
|
||||
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
|
||||
if (os) {
|
||||
#ifdef USEWEAKREFS
|
||||
nsCOMPtr<nsISupports> domwin(do_QueryReferent(inInfo->mWindow));
|
||||
if (domwin)
|
||||
rv = os->Notify(domwin, NOTIFICATION_CLOSED, 0);
|
||||
// else bummer. since the window is gone, there's nothing to notify with.
|
||||
#else
|
||||
nsCOMPtr<nsISupports> domwin(do_QueryInterface(inInfo->mWindow));
|
||||
rv = os->Notify(domwin, NOTIFICATION_CLOSED, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
delete inInfo;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsWindowWatcher::AddEnumerator(nsWindowEnumerator* inEnumerator)
|
||||
{
|
||||
// (requires a lock; assumes it's called by someone holding the lock)
|
||||
return mEnumeratorList.AppendElement(inEnumerator);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsWindowWatcher::RemoveEnumerator(nsWindowEnumerator* inEnumerator)
|
||||
{
|
||||
// (requires a lock; assumes it's called by someone holding the lock)
|
||||
return mEnumeratorList.RemoveElement(inEnumerator);
|
||||
}
|
||||
|
70
embedding/components/windowwatcher/src/nsWindowWatcher.h
Normal file
70
embedding/components/windowwatcher/src/nsWindowWatcher.h
Normal file
@ -0,0 +1,70 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef __nsWindowWatcher_h__
|
||||
#define __nsWindowWatcher_h__
|
||||
|
||||
// {a21bfa01-f349-4394-a84c-8de5cf0737d0}
|
||||
#define NS_WINDOWWATCHER_CID \
|
||||
{0xa21bfa01, 0xf349, 0x4394, {0xa8, 0x4c, 0x8d, 0xe5, 0xcf, 0x7, 0x37, 0xd0}}
|
||||
#define NS_WINDOWWATCHER_CONTRACTID \
|
||||
"@mozilla.org/apputil/window-watcher;1"
|
||||
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsPIWindowWatcher.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
class nsWindowEnumerator;
|
||||
struct WindowInfo;
|
||||
struct PRLock;
|
||||
|
||||
class nsWindowWatcher :
|
||||
public nsIWindowWatcher,
|
||||
public nsPIWindowWatcher
|
||||
{
|
||||
friend class nsWindowEnumerator;
|
||||
|
||||
public:
|
||||
nsWindowWatcher();
|
||||
virtual ~nsWindowWatcher();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_DECL_NSIWINDOWWATCHER
|
||||
NS_DECL_NSPIWINDOWWATCHER
|
||||
|
||||
private:
|
||||
PRBool AddEnumerator(nsWindowEnumerator* inEnumerator);
|
||||
PRBool RemoveEnumerator(nsWindowEnumerator* inEnumerator);
|
||||
|
||||
NS_IMETHOD RemoveWindow(WindowInfo *inInfo);
|
||||
|
||||
nsVoidArray mEnumeratorList;
|
||||
WindowInfo *mOldestWindow;
|
||||
nsIDOMWindow *mActiveWindow;
|
||||
PRLock *mListLock;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user