Fix bug # 104127: speed up window closing by 10 to 20%. r=danm sr=ben a=asa

This commit is contained in:
rjc%netscape.com 2002-03-09 02:54:13 +00:00
Родитель 4198a0fc70
Коммит d45cef4ce5
2 изменённых файлов: 730 добавлений и 360 удалений

Просмотреть файл

@ -94,7 +94,9 @@ static void GetWindowType( nsIXULWindow* inWindow, nsAutoString& outType);
static inline PRUint32 GetWindowZ( nsIXULWindow *inWindow);
nsresult GetDOMWindow( nsIXULWindow* inWindow, nsCOMPtr< nsIDOMWindowInternal>& outDOMWindow)
nsresult
GetDOMWindow( nsIXULWindow* inWindow, nsCOMPtr< nsIDOMWindowInternal>& outDOMWindow)
{
nsCOMPtr<nsIDocShell> docShell;
@ -104,7 +106,9 @@ nsresult GetDOMWindow( nsIXULWindow* inWindow, nsCOMPtr< nsIDOMWindowInternal>&
}
nsCOMPtr<nsIDOMNode> GetDOMNodeFromDocShell(nsIDocShell *aShell)
nsCOMPtr<nsIDOMNode>
GetDOMNodeFromDocShell(nsIDocShell *aShell)
{
nsCOMPtr<nsIDOMNode> node;
@ -131,7 +135,9 @@ nsCOMPtr<nsIDOMNode> GetDOMNodeFromDocShell(nsIDocShell *aShell)
}
void GetAttribute( nsIXULWindow* inWindow,
void
GetAttribute( nsIXULWindow* inWindow,
const nsAString& inAttribute, nsAString& outValue)
{
nsCOMPtr<nsIDocShell> shell;
@ -149,20 +155,28 @@ void GetAttribute( nsIXULWindow* inWindow,
}
}
void GetWindowType(nsIXULWindow* inWindow, nsAString& outType)
void
GetWindowType(nsIXULWindow* inWindow, nsAString& outType)
{
GetAttribute(inWindow, NS_LITERAL_STRING("windowtype"), outType);
}
/* return an integer corresponding to the relative z order of the window.
should probably be an explicit read-only method on nsIXULWindow */
PRUint32 GetWindowZ(nsIXULWindow *inWindow)
PRUint32
GetWindowZ(nsIXULWindow *inWindow)
{
PRUint32 order;
inWindow->GetZlevel(&order);
return order;
}
nsIRDFResource *nsWindowMediator::kNC_WindowMediatorRoot = NULL;
nsIRDFResource *nsWindowMediator::kNC_Name = NULL;
nsIRDFResource *nsWindowMediator::kNC_URL = NULL;
@ -173,9 +187,10 @@ nsIRDFContainer *nsWindowMediator::mContainer = NULL;
nsIRDFDataSource *nsWindowMediator::mInner = NULL;
nsWindowMediator::nsWindowMediator() :
mEnumeratorList(), mOldestWindow(0), mTopmostWindow(0),
mTimeStamp(0), mListLock(0)
mTimeStamp(0), mListLock(0), mUpdateBatchNest(0)
{
NS_INIT_REFCNT();
@ -239,7 +254,10 @@ NS_IMETHODIMP nsWindowMediator::RegisterWindow(nsIXULWindow* inWindow)
return NS_OK;
}
NS_IMETHODIMP nsWindowMediator::UnregisterWindow(nsIXULWindow* inWindow)
NS_IMETHODIMP
nsWindowMediator::UnregisterWindow(nsIXULWindow* inWindow)
{
// Find Window info
nsWindowInfo *info,
@ -259,15 +277,16 @@ NS_IMETHODIMP nsWindowMediator::UnregisterWindow(nsIXULWindow* inWindow)
}
NS_IMETHODIMP nsWindowMediator::UnregisterWindow(nsWindowInfo *inInfo)
NS_IMETHODIMP
nsWindowMediator::UnregisterWindow(nsWindowInfo *inInfo)
{
// Inform the iterators
PRInt32 index = -1;
while (++index < mEnumeratorList.Count())
((nsAppShellWindowEnumerator*)mEnumeratorList[index])->WindowRemoved(inInfo);
// Remove From RDF
mContainer->RemoveElement(inInfo->mRDFID, PR_TRUE);
(void)RemoveAndUpdateSynthetics(inInfo->mRDFID);
// Remove from the lists and free up
if (inInfo == mOldestWindow)
@ -297,7 +316,9 @@ NS_IMETHODIMP nsWindowMediator::UnregisterWindow(nsWindowInfo *inInfo)
}
NS_METHOD nsWindowMediator::GetEnumerator( const PRUnichar* inType, nsISimpleEnumerator** outEnumerator)
NS_METHOD
nsWindowMediator::GetEnumerator( const PRUnichar* inType, nsISimpleEnumerator** outEnumerator)
{
if (outEnumerator == NULL)
return NS_ERROR_INVALID_ARG;
@ -310,7 +331,10 @@ NS_METHOD nsWindowMediator::GetEnumerator( const PRUnichar* inType, nsISimpleEnu
return NS_ERROR_OUT_OF_MEMORY;
}
NS_METHOD nsWindowMediator::GetXULWindowEnumerator(const PRUnichar* inType, nsISimpleEnumerator** outEnumerator)
NS_METHOD
nsWindowMediator::GetXULWindowEnumerator(const PRUnichar* inType, nsISimpleEnumerator** outEnumerator)
{
if (outEnumerator == NULL)
return NS_ERROR_INVALID_ARG;
@ -323,7 +347,10 @@ NS_METHOD nsWindowMediator::GetXULWindowEnumerator(const PRUnichar* inType, nsIS
return NS_ERROR_OUT_OF_MEMORY;
}
NS_METHOD nsWindowMediator::GetZOrderDOMWindowEnumerator(
NS_METHOD
nsWindowMediator::GetZOrderDOMWindowEnumerator(
const PRUnichar *aWindowType, PRBool aFrontToBack,
nsISimpleEnumerator **_retval)
{
@ -342,7 +369,10 @@ NS_METHOD nsWindowMediator::GetZOrderDOMWindowEnumerator(
return NS_ERROR_OUT_OF_MEMORY;
}
NS_METHOD nsWindowMediator::GetZOrderXULWindowEnumerator(
NS_METHOD
nsWindowMediator::GetZOrderXULWindowEnumerator(
const PRUnichar *aWindowType, PRBool aFrontToBack,
nsISimpleEnumerator **_retval)
{
@ -361,22 +391,31 @@ NS_METHOD nsWindowMediator::GetZOrderXULWindowEnumerator(
return NS_ERROR_OUT_OF_MEMORY;
}
PRInt32 nsWindowMediator::AddEnumerator(nsAppShellWindowEnumerator * inEnumerator)
PRInt32
nsWindowMediator::AddEnumerator(nsAppShellWindowEnumerator * inEnumerator)
{
return mEnumeratorList.AppendElement(inEnumerator);
}
PRInt32 nsWindowMediator::RemoveEnumerator( nsAppShellWindowEnumerator * inEnumerator)
PRInt32
nsWindowMediator::RemoveEnumerator( nsAppShellWindowEnumerator * inEnumerator)
{
return mEnumeratorList.RemoveElement(inEnumerator);
}
/*
Returns the window of type inType ( if null return any window type ) which has the most recent
time stamp
*/
NS_IMETHODIMP nsWindowMediator::GetMostRecentWindow( const PRUnichar* inType, nsIDOMWindowInternal** outWindow) {
NS_IMETHODIMP
nsWindowMediator::GetMostRecentWindow( const PRUnichar* inType, nsIDOMWindowInternal** outWindow)
{
NS_ENSURE_ARG_POINTER(outWindow);
*outWindow = NULL;
@ -400,6 +439,7 @@ NS_IMETHODIMP nsWindowMediator::GetMostRecentWindow( const PRUnichar* inType, ns
}
nsWindowInfo *
nsWindowMediator::MostRecentWindowInfo(const PRUnichar* inType)
{
@ -429,7 +469,9 @@ nsWindowMediator::MostRecentWindowInfo(const PRUnichar* inType)
}
NS_IMETHODIMP nsWindowMediator::UpdateWindowTimeStamp( nsIXULWindow* inWindow)
NS_IMETHODIMP
nsWindowMediator::UpdateWindowTimeStamp( nsIXULWindow* inWindow)
{
nsWindowInfo *info,
*listEnd;
@ -459,7 +501,10 @@ NS_IMETHODIMP nsWindowMediator::UpdateWindowTimeStamp( nsIXULWindow* inWindow)
}
NS_IMETHODIMP nsWindowMediator::UpdateWindowTitle( nsIXULWindow* inWindow, const PRUnichar* inTitle )
NS_IMETHODIMP
nsWindowMediator::UpdateWindowTitle( nsIXULWindow* inWindow,
const PRUnichar* inTitle )
{
nsWindowInfo *info,
*listEnd;
@ -476,7 +521,8 @@ NS_IMETHODIMP nsWindowMediator::UpdateWindowTitle( nsIXULWindow* inWindow, cons
nsIRDFResource* window = info->mRDFID;
// Get rid of the old value
nsIRDFNode* target = NULL;
if ( NS_SUCCEEDED(mInner->GetTarget( window, kNC_Name, PR_TRUE, &target) ) && (target != nsnull) )
if ( NS_SUCCEEDED(mInner->GetTarget( window, kNC_Name, PR_TRUE,
&target) ) && (target != nsnull) )
{
mInner->Unassert( window, kNC_Name, target );
NS_IF_RELEASE( target );
@ -484,7 +530,8 @@ NS_IMETHODIMP nsWindowMediator::UpdateWindowTitle( nsIXULWindow* inWindow, cons
// Add new title
nsCOMPtr<nsIRDFLiteral> newTitle;
if ( gRDFService && NS_FAILED(rv = gRDFService->GetLiteral( inTitle, getter_AddRefs(newTitle) ) ) )
if ( gRDFService && NS_FAILED(rv = gRDFService->GetLiteral( inTitle,
getter_AddRefs(newTitle) ) ) )
{
NS_ERROR("unable to create literal for window name");
return rv;
@ -509,13 +556,16 @@ NS_IMETHODIMP nsWindowMediator::UpdateWindowTitle( nsIXULWindow* inWindow, cons
return NS_ERROR_FAILURE;
}
/* This method's plan is to intervene only when absolutely necessary.
We will get requests to place our windows behind unknown windows.
For the most part, we need to leave those alone (turning them into
explicit requests to be on top breaks Windows.) So generally we
calculate a change as seldom as possible.
*/
NS_IMETHODIMP nsWindowMediator::CalculateZPosition(
NS_IMETHODIMP
nsWindowMediator::CalculateZPosition(
nsIXULWindow *inWindow,
PRUint32 inPosition,
nsIWidget *inBelow,
@ -663,7 +713,10 @@ NS_IMETHODIMP nsWindowMediator::CalculateZPosition(
return result;
}
NS_IMETHODIMP nsWindowMediator::SetZPosition(
NS_IMETHODIMP
nsWindowMediator::SetZPosition(
nsIXULWindow *inWindow,
PRUint32 inPosition,
nsIXULWindow *inBelow) {
@ -730,7 +783,11 @@ NS_IMETHODIMP nsWindowMediator::SetZPosition(
return NS_OK;
}
NS_IMETHODIMP nsWindowMediator::GetWindowForResource( const PRUnichar* inResource, nsIDOMWindowInternal** outWindow )
NS_IMETHODIMP
nsWindowMediator::GetWindowForResource( const PRUnichar* inResource,
nsIDOMWindowInternal** outWindow )
{
if ( outWindow == NULL )
return NS_ERROR_INVALID_ARG;
@ -772,16 +829,23 @@ NS_IMETHODIMP nsWindowMediator::GetWindowForResource( const PRUnichar* inResour
return NS_OK;
}
NS_IMETHODIMP nsWindowMediator::ConvertISupportsToDOMWindow( nsISupports* inInterface, nsIDOMWindowInternal** outWindow )
NS_IMETHODIMP
nsWindowMediator::ConvertISupportsToDOMWindow( nsISupports* inInterface,
nsIDOMWindowInternal** outWindow )
{
return inInterface->QueryInterface(NS_GET_IID(nsIDOMWindowInternal) , (void**) outWindow );
}
// COM
NS_IMPL_ADDREF( nsWindowMediator );
NS_IMPL_RELEASE( nsWindowMediator );
NS_IMPL_QUERY_INTERFACE2(nsWindowMediator, nsIWindowMediator, nsIRDFDataSource)
NS_IMPL_QUERY_INTERFACE3(nsWindowMediator, nsIWindowMediator, nsIRDFDataSource, nsIRDFObserver);
// RDF
nsresult
@ -789,13 +853,14 @@ nsWindowMediator::Init()
{
nsresult rv;
if (gRefCnt++ == 0) {
if (gRefCnt++ == 0)
{
mListLock = PR_NewLock();
if (!mListLock)
return NS_ERROR_OUT_OF_MEMORY;
rv = nsServiceManager::GetService( kRDFServiceCID, NS_GET_IID(nsIRDFService), (nsISupports**) &gRDFService );
rv = nsServiceManager::GetService( kRDFServiceCID, NS_GET_IID(nsIRDFService),
(nsISupports**) &gRDFService );
if (NS_FAILED(rv)) return rv;
if ( gRDFService == NULL )
return NS_ERROR_NULL_POINTER;
@ -809,10 +874,16 @@ nsWindowMediator::Init()
if (NS_FAILED(rv))
return rv;
rv = mInner->AddObserver(this);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIRDFContainerUtils> rdfc = do_GetService(kRDFContainerUtilsCID, &rv);
if (NS_FAILED(rv))
return rv;
rv = rdfc->MakeSeq(mInner, kNC_WindowMediatorRoot, &mContainer );
// note: use "this" instead of "mInner" so that we can use batching
rv = rdfc->MakeSeq(this, kNC_WindowMediatorRoot, &mContainer );
NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to make NC:WindowMediatorRoot a sequence");
if (NS_FAILED(rv))
return rv;
@ -826,7 +897,43 @@ nsWindowMediator::Init()
return gRDFService->RegisterDataSource(this, PR_FALSE);
}
NS_IMETHODIMP nsWindowMediator::GetTarget(nsIRDFResource* source,
NS_IMETHODIMP
nsWindowMediator::GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsISimpleEnumerator** sources)
{
return mInner->GetSources(property, target, tv, sources);
}
NS_IMETHODIMP
nsWindowMediator::GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsISimpleEnumerator** targets)
{
return mInner->GetTargets(source, property, tv, targets);
}
NS_IMETHODIMP
nsWindowMediator::GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source)
{
return mInner->GetSource(property, target, tv, source);
}
NS_IMETHODIMP
nsWindowMediator::GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFNode** target)
@ -850,7 +957,68 @@ NS_IMETHODIMP nsWindowMediator::GetTarget(nsIRDFResource* source,
return mInner->GetTarget(source, property, tv, target);
}
NS_IMETHODIMP nsWindowMediator::Assert(nsIRDFResource* aSource,
NS_IMETHODIMP
nsWindowMediator::HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion)
{
return mInner->HasAssertion(source, property, target, tv, hasAssertion);
}
NS_IMETHODIMP
nsWindowMediator::HasArcIn(nsIRDFNode *aNode,
nsIRDFResource *aArc,
PRBool *_retval)
{
return mInner->HasArcIn(aNode, aArc, _retval);
}
NS_IMETHODIMP
nsWindowMediator::HasArcOut(nsIRDFResource *aSource,
nsIRDFResource *aArc,
PRBool *_retval)
{
return mInner->HasArcOut(aSource, aArc, _retval);
}
NS_IMETHODIMP
nsWindowMediator::ArcLabelsIn( nsIRDFNode* node,
nsISimpleEnumerator** labels)
{
return mInner->ArcLabelsIn(node, labels);
}
NS_IMETHODIMP
nsWindowMediator::ArcLabelsOut( nsIRDFResource* source,
nsISimpleEnumerator** labels)
{
return mInner->ArcLabelsOut(source, labels);
}
NS_IMETHODIMP
nsWindowMediator::GetAllResources(nsISimpleEnumerator** aCursor)
{
return mInner->GetAllResources(aCursor);
}
NS_IMETHODIMP
nsWindowMediator::Assert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue)
@ -859,7 +1027,10 @@ NS_IMETHODIMP nsWindowMediator::Assert(nsIRDFResource* aSource,
return mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
}
NS_IMETHODIMP nsWindowMediator::Unassert(nsIRDFResource* aSource,
NS_IMETHODIMP
nsWindowMediator::Unassert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
@ -868,7 +1039,9 @@ NS_IMETHODIMP nsWindowMediator::Unassert(nsIRDFResource* aSource,
}
NS_IMETHODIMP nsWindowMediator::Change(nsIRDFResource* aSource,
NS_IMETHODIMP
nsWindowMediator::Change(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget)
@ -877,7 +1050,10 @@ NS_IMETHODIMP nsWindowMediator::Change(nsIRDFResource* aSource,
return mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
}
NS_IMETHODIMP nsWindowMediator::Move(nsIRDFResource* aOldSource,
NS_IMETHODIMP
nsWindowMediator::Move(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
@ -887,21 +1063,239 @@ NS_IMETHODIMP nsWindowMediator::Move(nsIRDFResource* aOldSource,
}
NS_IMETHODIMP nsWindowMediator::GetAllCommands(nsIRDFResource* source,
NS_IMETHODIMP
nsWindowMediator::AddObserver(nsIRDFObserver* aObserver)
{
if (! aObserver)
return NS_ERROR_NULL_POINTER;
if (! mObservers) {
nsresult rv;
rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
if (NS_FAILED(rv)) return rv;
}
mObservers->AppendElement(aObserver);
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::RemoveObserver(nsIRDFObserver* aObserver)
{
if (! aObserver)
return NS_ERROR_NULL_POINTER;
if (mObservers) {
mObservers->RemoveElement(aObserver);
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::OnAssert(nsIRDFDataSource* aDataSource,
nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
if (mUpdateBatchNest != 0)
return(NS_OK);
if (mObservers) {
nsresult rv;
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = 0; i < PRInt32(count); ++i) {
nsIRDFObserver* obs =
NS_REINTERPRET_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
(void) obs->OnAssert(this, aSource, aProperty, aTarget);
NS_RELEASE(obs);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::OnUnassert(nsIRDFDataSource* aDataSource,
nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
if (mUpdateBatchNest != 0)
return(NS_OK);
if (mObservers) {
nsresult rv;
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = 0; i < PRInt32(count); ++i) {
nsIRDFObserver* obs =
NS_REINTERPRET_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
(void) obs->OnUnassert(this, aSource, aProperty, aTarget);
NS_RELEASE(obs);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::OnChange(nsIRDFDataSource* aDataSource,
nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget)
{
if (mUpdateBatchNest != 0)
return(NS_OK);
if (mObservers) {
nsresult rv;
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = 0; i < PRInt32(count); ++i) {
nsIRDFObserver* obs =
NS_REINTERPRET_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
(void) obs->OnChange(this, aSource, aProperty, aOldTarget, aNewTarget);
NS_RELEASE(obs);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::OnMove(nsIRDFDataSource* aDataSource,
nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
if (mUpdateBatchNest != 0)
return(NS_OK);
if (mObservers) {
nsresult rv;
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = 0; i < PRInt32(count); ++i) {
nsIRDFObserver* obs =
NS_REINTERPRET_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
(void) obs->OnMove(this, aOldSource, aNewSource, aProperty, aTarget);
NS_RELEASE(obs);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::BeginUpdateBatch(nsIRDFDataSource* aDataSource)
{
if ((mUpdateBatchNest++ == 0) && mObservers)
{
nsresult rv;
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = 0; i < PRInt32(count); ++i) {
nsIRDFObserver* obs =
NS_REINTERPRET_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
(void) obs->BeginUpdateBatch(aDataSource);
NS_RELEASE(obs);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::EndUpdateBatch(nsIRDFDataSource* aDataSource)
{
if (mUpdateBatchNest > 0)
{
--mUpdateBatchNest;
}
if ((mUpdateBatchNest == 0) && mObservers)
{
nsresult rv;
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = 0; i < PRInt32(count); ++i) {
nsIRDFObserver* obs =
NS_REINTERPRET_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
(void) obs->EndUpdateBatch(aDataSource);
NS_RELEASE(obs);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsWindowMediator::GetAllCommands(nsIRDFResource* source,
nsIEnumerator/*<nsIRDFResource>*/** commands)
{
NS_NOTYETIMPLEMENTED("write me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWindowMediator::GetAllCmds(nsIRDFResource* source,
NS_IMETHODIMP
nsWindowMediator::GetAllCmds(nsIRDFResource* source,
nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
{
NS_NOTYETIMPLEMENTED("write me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWindowMediator::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
NS_IMETHODIMP
nsWindowMediator::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments,
PRBool* aResult)
@ -910,7 +1304,10 @@ NS_IMETHODIMP nsWindowMediator::IsCommandEnabled(nsISupportsArray/*<nsIRDFResour
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsWindowMediator::DoCommand(nsISupportsArray* aSources,
NS_IMETHODIMP
nsWindowMediator::DoCommand(nsISupportsArray* aSources,
nsIRDFResource* aCommand,
nsISupportsArray* aArguments)
{
@ -919,8 +1316,26 @@ NS_IMETHODIMP nsWindowMediator::DoCommand(nsISupportsArray* aSources,
}
NS_IMETHODIMP
nsWindowMediator::GetURI(char* *uri)
{
NS_PRECONDITION(uri != nsnull, "null ptr");
if (! uri)
return NS_ERROR_NULL_POINTER;
*uri = nsCRT::strdup("rdf:window-mediator");
if (! *uri)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
// Private helpers
nsresult nsWindowMediator::AddWindowToRDF( nsWindowInfo* ioWindowInfo )
nsresult
nsWindowMediator::AddWindowToRDF( nsWindowInfo* ioWindowInfo )
{
if ( !ioWindowInfo || !(ioWindowInfo->mWindow) || !gRDFService )
return NS_ERROR_NULL_POINTER;
@ -959,7 +1374,8 @@ nsresult nsWindowMediator::AddWindowToRDF( nsWindowInfo* ioWindowInfo )
}
#endif
// Add the element to the container
if (NS_FAILED(rv = mContainer->AppendElement( window ) ) /* rdf_ContainerAppendElement(mInner, kNC_WindowMediatorRoot, window) */ )
rv = mContainer->AppendElement( window ); /* rdf_ContainerAppendElement(mInner, kNC_WindowMediatorRoot, window) */
if (NS_FAILED(rv))
{
NS_ERROR("unable to add window to container");
return rv;
@ -967,3 +1383,65 @@ nsresult nsWindowMediator::AddWindowToRDF( nsWindowInfo* ioWindowInfo )
return NS_OK;
}
nsresult
nsWindowMediator::RemoveAndUpdateSynthetics(nsIRDFNode *winNode)
{
// key current synthetic kNC_KeyIndex value, if any
nsCOMPtr<nsIRDFResource> winRes = do_QueryInterface(winNode);
nsCOMPtr<nsIRDFNode> oldKeyNode;
nsCOMPtr<nsIRDFInt> oldKeyInt;
nsresult rv;
if (NS_SUCCEEDED(rv = GetTarget(winRes, kNC_KeyIndex, PR_TRUE,
getter_AddRefs(oldKeyNode))) && (rv != NS_RDF_NO_VALUE))
{
oldKeyInt = do_QueryInterface(oldKeyNode);
}
PRInt32 winIndex = -1;
(void)mContainer->IndexOf(winNode, &winIndex);
// remove window
mContainer->RemoveElement(winNode, PR_TRUE);
// fake out any observers who might care about synthetic
// properties such as kNC_KeyIndex
nsCOMPtr<nsISimpleEnumerator> children;
if (NS_FAILED(rv = mContainer->GetElements(getter_AddRefs(children))))
return(rv);
PRBool more = PR_FALSE;
while (NS_SUCCEEDED(rv = children->HasMoreElements(&more)) && (more))
{
nsCOMPtr<nsISupports> iSupports;
if (NS_FAILED(rv = children->GetNext(getter_AddRefs(iSupports))))
break;
nsCOMPtr<nsIRDFResource> aWindow = do_QueryInterface(iSupports);
if (!aWindow)
break;
PRInt32 aIndex = -1;
(void)mContainer->IndexOf(aWindow, &aIndex);
// can skip updating windows with lower indexes
// than the window that was removed
if (aIndex < winIndex)
continue;
nsCOMPtr<nsIRDFNode> val;
nsCOMPtr<nsIRDFInt> newKeyInt;
if (NS_SUCCEEDED(rv = this->GetTarget(aWindow, kNC_KeyIndex, PR_TRUE,
getter_AddRefs(val))) && (rv != NS_RDF_NO_VALUE))
{
newKeyInt = do_QueryInterface(val);
}
if (oldKeyInt && newKeyInt)
(void)OnChange(this, aWindow, kNC_KeyIndex, oldKeyInt, newKeyInt);
else if (newKeyInt)
(void)OnAssert(this, aWindow, kNC_KeyIndex, newKeyInt);
else if (oldKeyInt)
(void)OnUnassert(this, aWindow, kNC_KeyIndex, oldKeyInt);
}
return(rv);
}

Просмотреть файл

@ -47,6 +47,7 @@
#include "nsIRDFObserver.h"
#include "nsIRDFContainer.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFObserver.h"
class nsAppShellWindowEnumerator;
class nsASXULWindowEarlyToLateEnumerator;
@ -59,7 +60,8 @@ struct nsWindowInfo;
struct PRLock;
class nsWindowMediator : public nsIWindowMediator,
public nsIRDFDataSource
public nsIRDFDataSource,
public nsIRDFObserver
{
friend class nsAppShellWindowEnumerator;
friend class nsASXULWindowEarlyToLateEnumerator;
@ -79,124 +81,11 @@ public:
// COM and RDF
NS_DECL_ISUPPORTS
// RDF
// nsIRDFDataSource
NS_IMETHOD GetURI(char* *uri)
{
NS_PRECONDITION(uri != nsnull, "null ptr");
if (! uri)
return NS_ERROR_NULL_POINTER;
NS_DECL_NSIRDFDATASOURCE
*uri = nsCRT::strdup("rdf:window-mediator");
if (! *uri)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHOD GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source)
{
return mInner->GetSource(property, target, tv, source);
}
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsISimpleEnumerator** sources)
{
return mInner->GetSources(property, target, tv, sources);
}
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsISimpleEnumerator** targets)
{
return mInner->GetTargets(source, property, tv, targets);
}
NS_IMETHOD GetTarget(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
PRBool aTruthValue,
nsIRDFNode** target);
NS_IMETHOD Assert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue);
NS_IMETHOD Unassert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget);
NS_IMETHOD Change(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget);
NS_IMETHOD Move(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget);
NS_IMETHOD HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion)
{
return mInner->HasAssertion(source, property, target, tv, hasAssertion);
}
NS_IMETHOD AddObserver(nsIRDFObserver* n)
{
return mInner->AddObserver(n);
}
NS_IMETHOD RemoveObserver(nsIRDFObserver* n)
{
return mInner->RemoveObserver(n);
}
NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, PRBool *_retval) {
return mInner->HasArcIn(aNode, aArc, _retval);
}
NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, PRBool *_retval) {
return mInner->HasArcOut(aSource, aArc, _retval);
}
NS_IMETHOD ArcLabelsIn( nsIRDFNode* node, nsISimpleEnumerator** labels)
{
return mInner->ArcLabelsIn(node, labels);
}
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source, nsISimpleEnumerator** labels)
{
return mInner->ArcLabelsOut(source, labels);
}
NS_IMETHOD GetAllResources(nsISimpleEnumerator** aCursor)
{
return mInner->GetAllResources(aCursor);
}
NS_IMETHOD GetAllCommands(nsIRDFResource* source,
nsIEnumerator** commands);
NS_IMETHOD GetAllCmds(nsIRDFResource* source,
nsISimpleEnumerator** commands);
NS_IMETHOD IsCommandEnabled(nsISupportsArray* aSources,
nsIRDFResource* aCommand,
nsISupportsArray* aArguments,
PRBool* aResult);
NS_IMETHOD DoCommand(nsISupportsArray* aSources,
nsIRDFResource* aCommand,
nsISupportsArray* aArguments);
// nsIRDFObserver
NS_DECL_NSIRDFOBSERVER
private:
// Helper functions
@ -204,6 +93,7 @@ private:
PRInt32 AddEnumerator( nsAppShellWindowEnumerator* inEnumerator );
PRInt32 RemoveEnumerator( nsAppShellWindowEnumerator* inEnumerator);
nsWindowInfo *MostRecentWindowInfo(const PRUnichar* inType);
nsresult RemoveAndUpdateSynthetics(nsIRDFNode *node);
NS_IMETHOD UnregisterWindow( nsWindowInfo *inInfo );
@ -211,8 +101,10 @@ private:
nsWindowInfo *mOldestWindow,
*mTopmostWindow;
PRInt32 mTimeStamp;
PRInt32 mUpdateBatchNest;
PRLock *mListLock;
nsCOMPtr<nsIWindowWatcher> mWatcher;
nsCOMPtr<nsISupportsArray> mObservers;
// pseudo-constants for RDF
static nsIRDFResource* kNC_WindowMediatorRoot;