зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1088228 part 5. Use the new CloneFunctionObject in XBL. r=peterv
This commit is contained in:
Родитель
7156407be9
Коммит
e08b9cd7ca
|
@ -18,6 +18,7 @@
|
|||
#include "nsIXPConnect.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsXBLPrototypeBinding.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -269,6 +270,7 @@ nsXBLProtoImplMethod::Write(nsIObjectOutputStream* aStream)
|
|||
nsresult
|
||||
nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAddonId)
|
||||
{
|
||||
MOZ_ASSERT(aBoundElement->IsElement());
|
||||
NS_PRECONDITION(IsCompiled(), "Can't execute uncompiled method");
|
||||
|
||||
if (!GetCompiledMethod()) {
|
||||
|
@ -295,23 +297,22 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
|
|||
|
||||
JS::Rooted<JSObject*> globalObject(cx, global->GetGlobalJSObject());
|
||||
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
nsresult rv = nsContentUtils::WrapNative(cx, aBoundElement, &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JS::Rooted<JSObject*> thisObject(cx, &v.toObject());
|
||||
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, aAddonId));
|
||||
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
JSAutoCompartment ac(cx, scopeObject);
|
||||
if (!JS_WrapObject(cx, &thisObject))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
JS::AutoObjectVector scopeChain(cx);
|
||||
if (!nsJSUtils::GetScopeChainForElement(cx, aBoundElement->AsElement(),
|
||||
scopeChain)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
MOZ_ASSERT(scopeChain.length() != 0);
|
||||
|
||||
// Clone the function object, using thisObject as the parent so "this" is in
|
||||
// the scope chain of the resulting function (for backwards compat to the
|
||||
// days when this was an event handler).
|
||||
// Clone the function object, using our scope chain (for backwards
|
||||
// compat to the days when this was an event handler).
|
||||
JS::Rooted<JSObject*> jsMethodObject(cx, GetCompiledMethod());
|
||||
JS::Rooted<JSObject*> method(cx, ::JS_CloneFunctionObject(cx, jsMethodObject, thisObject));
|
||||
JS::Rooted<JSObject*> method(cx, JS::CloneFunctionObject(cx, jsMethodObject,
|
||||
scopeChain));
|
||||
if (!method)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -325,7 +326,7 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
|
|||
if (scriptAllowed) {
|
||||
JS::Rooted<JS::Value> retval(cx);
|
||||
JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method));
|
||||
ok = ::JS::Call(cx, thisObject, methodVal, JS::HandleValueArray::empty(), &retval);
|
||||
ok = ::JS::Call(cx, scopeChain[0], methodVal, JS::HandleValueArray::empty(), &retval);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/EventHandlerBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "xpcpublic.h"
|
||||
|
@ -300,16 +301,15 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
|
||||
MOZ_ASSERT(!js::IsCrossCompartmentWrapper(genericHandler));
|
||||
|
||||
// Wrap the native into the XBL scope. This creates a reflector in the document
|
||||
// scope if one doesn't already exist, and potentially wraps it cross-
|
||||
// compartment into our scope (via aAllowWrapping=true).
|
||||
JS::Rooted<JS::Value> targetV(cx, JS::UndefinedValue());
|
||||
rv = nsContentUtils::WrapNative(cx, scriptTarget, &targetV);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Build a scope chain in the XBL scope.
|
||||
nsRefPtr<Element> targetElement = do_QueryObject(scriptTarget);
|
||||
JS::AutoObjectVector scopeChain(cx);
|
||||
ok = nsJSUtils::GetScopeChainForElement(cx, targetElement, scopeChain);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Next, clone the generic handler to be parented to the target.
|
||||
JS::Rooted<JSObject*> target(cx, &targetV.toObject());
|
||||
JS::Rooted<JSObject*> bound(cx, JS_CloneFunctionObject(cx, genericHandler, target));
|
||||
// Next, clone the generic handler with our desired scope chain.
|
||||
JS::Rooted<JSObject*> bound(cx, JS::CloneFunctionObject(cx, genericHandler,
|
||||
scopeChain));
|
||||
NS_ENSURE_TRUE(bound, NS_ERROR_FAILURE);
|
||||
|
||||
nsRefPtr<EventHandlerNonNull> handlerCallback =
|
||||
|
|
Загрузка…
Ссылка в новой задаче