mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
Bug 461861, r=mrbkap, sr=jst
--HG-- extra : rebase_source : a5aea484f992785a3d67bb03d7fe074ce4f7f95a
This commit is contained in:
parent
35ec9a36b8
commit
61994c29ad
@ -1490,6 +1490,9 @@ public:
|
||||
|
||||
// Returns PR_FALSE if something erroneous happened.
|
||||
PRBool Push(nsPIDOMEventTarget *aCurrentTarget);
|
||||
// If nothing has been pushed to stack, this works like Push.
|
||||
// Otherwise if context will change, Pop and Push will be called.
|
||||
PRBool RePush(nsPIDOMEventTarget *aCurrentTarget);
|
||||
// If a null JSContext is passed to Push(), that will cause no
|
||||
// push to happen and false to be returned.
|
||||
PRBool Push(JSContext *cx);
|
||||
|
@ -2736,6 +2736,34 @@ nsCxPusher::Push(nsPIDOMEventTarget *aCurrentTarget)
|
||||
return Push(cx);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCxPusher::RePush(nsPIDOMEventTarget *aCurrentTarget)
|
||||
{
|
||||
if (!mPushedSomething) {
|
||||
return Push(aCurrentTarget);
|
||||
}
|
||||
|
||||
if (aCurrentTarget) {
|
||||
nsresult rv;
|
||||
nsIScriptContext* scx =
|
||||
aCurrentTarget->GetContextForEventHandlers(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
Pop();
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// If we have the same script context and native context is still
|
||||
// alive, no need to Pop/Push.
|
||||
if (scx && scx == mScx &&
|
||||
scx->GetNativeContext()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Pop();
|
||||
return Push(aCurrentTarget);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCxPusher::Push(JSContext *cx)
|
||||
{
|
||||
|
@ -1082,10 +1082,7 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
|
||||
}
|
||||
}
|
||||
|
||||
// nsCxPusher will push and pop (automatically) the current cx onto the
|
||||
// context stack
|
||||
nsCxPusher pusher;
|
||||
if (NS_SUCCEEDED(result) && pusher.Push(aCurrentTarget)) {
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// nsIDOMEvent::currentTarget is set in nsEventDispatcher.
|
||||
result = aListener->HandleEvent(aDOMEvent);
|
||||
}
|
||||
@ -1157,6 +1154,7 @@ found:
|
||||
nsAutoTObserverArray<nsListenerStruct, 2>::EndLimitedIterator iter(mListeners);
|
||||
nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent));
|
||||
PRBool hasListener = PR_FALSE;
|
||||
nsCxPusher pusher;
|
||||
while (iter.HasMore()) {
|
||||
nsListenerStruct* ls = &iter.GetNext();
|
||||
PRBool useTypeInterface =
|
||||
@ -1180,9 +1178,11 @@ found:
|
||||
if (*aDOMEvent) {
|
||||
nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = ls->mListener;
|
||||
if (useTypeInterface) {
|
||||
pusher.Pop();
|
||||
DispatchToInterface(*aDOMEvent, ls->mListener,
|
||||
dispData->method, *typeData->iid);
|
||||
} else if (useGenericInterface) {
|
||||
} else if (useGenericInterface &&
|
||||
pusher.RePush(aCurrentTarget)) {
|
||||
HandleEventSubType(ls, ls->mListener, *aDOMEvent,
|
||||
aCurrentTarget, aFlags);
|
||||
}
|
||||
|
@ -42,6 +42,9 @@
|
||||
/* Implement global service to track stack of JSContext per thread. */
|
||||
|
||||
#include "xpcprivate.h"
|
||||
#include "XPCWrapper.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -113,6 +116,20 @@ XPCJSContextStack::Pop(JSContext * *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsIPrincipal*
|
||||
GetPrincipalFromCx(JSContext *cx)
|
||||
{
|
||||
nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx);
|
||||
if(scriptContext)
|
||||
{
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> globalData =
|
||||
do_QueryInterface(scriptContext->GetGlobalObject());
|
||||
if(globalData)
|
||||
return globalData->GetPrincipal();
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/* void push (in JSContext cx); */
|
||||
NS_IMETHODIMP
|
||||
XPCJSContextStack::Push(JSContext * cx)
|
||||
@ -122,8 +139,28 @@ XPCJSContextStack::Push(JSContext * cx)
|
||||
if(mStack.Length() > 1)
|
||||
{
|
||||
XPCJSContextInfo & e = mStack[mStack.Length() - 2];
|
||||
if(e.cx && e.cx != cx)
|
||||
if(e.cx)
|
||||
{
|
||||
if(e.cx == cx)
|
||||
{
|
||||
nsIScriptSecurityManager* ssm = XPCWrapper::GetSecurityManager();
|
||||
if(ssm)
|
||||
{
|
||||
nsIPrincipal* globalObjectPrincipal =
|
||||
GetPrincipalFromCx(cx);
|
||||
if(globalObjectPrincipal)
|
||||
{
|
||||
nsIPrincipal* subjectPrincipal = ssm->GetCxSubjectPrincipal(cx);
|
||||
PRBool equals = PR_FALSE;
|
||||
globalObjectPrincipal->Equals(subjectPrincipal, &equals);
|
||||
if(equals)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.frame = JS_SaveFrameChain(e.cx);
|
||||
|
||||
if(JS_GetContextThread(e.cx))
|
||||
|
Loading…
x
Reference in New Issue
Block a user