зеркало из https://github.com/mozilla/gecko-dev.git
Fix bug # 104127: speed up window closing by 10 to 20%. r=danm sr=ben a=asa
This commit is contained in:
Родитель
4198a0fc70
Коммит
d45cef4ce5
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче