Bug 648801 (new DOM list bindings) - Add a pref (dom.new_bindings) to enable/disable new bindings. r=bz/jst/mrbkap.

--HG--
extra : rebase_source : 055a7bdac534147baa29d8735794970234c98145
This commit is contained in:
Peter Van der Beken 2011-06-29 19:17:37 +02:00
Родитель 9039eb76d6
Коммит 2375b7e89a
17 изменённых файлов: 106 добавлений и 43 удалений

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

@ -186,9 +186,10 @@ NS_IMPL_ADDREF_INHERITED(nsSimpleContentList, nsBaseContentList)
NS_IMPL_RELEASE_INHERITED(nsSimpleContentList, nsBaseContentList)
JSObject*
nsSimpleContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope)
nsSimpleContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *failed)
{
return xpc::dom::NodeListBase::create(cx, scope, this);
return xpc::dom::NodeListBase::create(cx, scope, this, failed);
}
// nsFormContentList
@ -502,11 +503,12 @@ nsContentList::~nsContentList()
}
JSObject*
nsContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope)
nsContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *failed)
{
return xpc::dom::NodeListBase::create(cx, scope,
static_cast<nsIHTMLCollection*>(this),
this);
this, failed);
}
DOMCI_DATA(ContentList, nsContentList)

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

@ -129,7 +129,8 @@ public:
virtual PRInt32 IndexOf(nsIContent *aContent, bool aDoFlush);
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope) = 0;
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap) = 0;
protected:
nsCOMArray<nsIContent> mElements;
@ -152,7 +153,8 @@ public:
{
return mRoot;
}
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope);
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
private:
// This has to be a strong reference, the root might go away before the list.
@ -284,7 +286,8 @@ public:
virtual ~nsContentList();
// nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope);
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
// nsIDOMHTMLCollection
NS_DECL_NSIDOMHTMLCOLLECTION

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

@ -1556,9 +1556,10 @@ NS_INTERFACE_TABLE_HEAD(nsChildContentList)
NS_INTERFACE_MAP_END
JSObject*
nsChildContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope)
nsChildContentList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return xpc::dom::NodeListBase::create(cx, scope, this);
return xpc::dom::NodeListBase::create(cx, scope, this, triedToWrap);
}
NS_IMETHODIMP

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

@ -107,7 +107,8 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsChildContentList)
// nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope);
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
// nsIDOMNodeList interface
NS_DECL_NSIDOMNODELIST

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

@ -162,9 +162,10 @@ public:
nsresult GetSortedControls(nsTArray<nsGenericHTMLFormElement*>& aControls) const;
// nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope)
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return xpc::dom::NodeListBase::create(cx, scope, this, this);
return xpc::dom::NodeListBase::create(cx, scope, this, this, triedToWrap);
}
nsHTMLFormElement* mForm; // WEAK - the form owns me

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

@ -84,9 +84,10 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TableRowsCollection)
// nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope)
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return xpc::dom::NodeListBase::create(cx, scope, this, this);
return xpc::dom::NodeListBase::create(cx, scope, this, this, triedToWrap);
}
protected:

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

@ -115,9 +115,10 @@ public:
nsXBLInsertionPoint* GetInsertionPointAt(PRInt32 i) { return static_cast<nsXBLInsertionPoint*>(mElements->ElementAt(i)); }
void RemoveInsertionPointAt(PRInt32 i) { mElements->RemoveElementAt(i); }
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope)
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return xpc::dom::NodeListBase::create(cx, scope, this);
return xpc::dom::NodeListBase::create(cx, scope, this, triedToWrap);
}
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ANONYMOUS_CONTENT_LIST_IID)

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

@ -6174,10 +6174,10 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
xpc::dom::DefineInterface define =
sClassInfoData[name_struct->mDOMClassInfoID].mDefineDOMInterface;
if (define && xpc::dom::DefineConstructor(cx, obj, define)) {
*did_resolve = true;
if (define && xpc::dom::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
return NS_OK;
return rv;
}
}

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

@ -120,10 +120,17 @@ public:
/**
* Wrap the object corresponding to this wrapper cache. If non-null is
* returned, the object has already been stored in the wrapper cache.
* Wrap the object corresponding to this wrapper cache. If non-null is
* returned, the object has already been stored in the wrapper cache and the
* value set in triedToWrap is meaningless. If null is returned then
* triedToWrap indicates whether an error occurred, if it's false then the
* object doesn't actually support creating a wrapper through its WrapObject
* hook.
*/
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope) {
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
*triedToWrap = false;
return nsnull;
}

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

@ -129,18 +129,18 @@ WrapNativeParent(JSContext *cx, JSObject *scope, T *p)
JSObject *
NodeListBase::create(JSContext *cx, XPCWrappedNativeScope *scope,
nsINodeList *aNodeList)
nsINodeList *aNodeList, bool *triedToWrap)
{
return NodeList<nsINodeList>::create(cx, scope, aNodeList, aNodeList);
return NodeList<nsINodeList>::create(cx, scope, aNodeList, aNodeList, triedToWrap);
}
JSObject *
NodeListBase::create(JSContext *cx, XPCWrappedNativeScope *scope,
nsIHTMLCollection *aHTMLCollection,
nsWrapperCache *aWrapperCache)
nsWrapperCache *aWrapperCache, bool *triedToWrap)
{
return NodeList<nsIHTMLCollection>::create(cx, scope, aHTMLCollection,
aWrapperCache);
aWrapperCache, triedToWrap);
}
template<class T>
@ -222,9 +222,14 @@ Register(nsDOMClassInfoData *aData)
}
bool
DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine)
DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine, nsresult *aResult)
{
return !!aDefine(cx, XPCWrappedNativeScope::FindInJSObjectScope(cx, obj));
bool enabled;
bool defined = !!aDefine(cx, XPCWrappedNativeScope::FindInJSObjectScope(cx, obj), &enabled);
NS_ASSERTION(!defined || enabled,
"We defined a constructor but the new bindings are disabled?");
*aResult = defined ? NS_OK : NS_ERROR_FAILURE;
return enabled;
}
template<class T>
@ -436,8 +441,15 @@ interface_hasInstance(JSContext *cx, JSObject *obj, const js::Value *vp, JSBool
template<class T>
JSObject *
NodeList<T>::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope)
NodeList<T>::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope, bool *enabled)
{
if(!scope->NewDOMBindingsEnabled()) {
*enabled = false;
return NULL;
}
*enabled = true;
nsDataHashtable<nsDepCharHashKey, JSObject*> &cache =
scope->GetCachedDOMPrototypes();
@ -504,8 +516,10 @@ NodeList<T>::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope)
template<class T>
JSObject *
NodeList<T>::create(JSContext *cx, XPCWrappedNativeScope *scope, T *aNodeList,
nsWrapperCache* aWrapperCache)
nsWrapperCache* aWrapperCache, bool *triedToWrap)
{
*triedToWrap = true;
JSObject *parent = WrapNativeParent(cx, scope->GetGlobalJSObject(), aNodeList->GetParentObject());
if (!parent)
return NULL;
@ -518,7 +532,7 @@ NodeList<T>::create(JSContext *cx, XPCWrappedNativeScope *scope, T *aNodeList,
scope = XPCWrappedNativeScope::FindInJSObjectScope(cx, parent);
}
JSObject *proto = getPrototype(cx, scope);
JSObject *proto = getPrototype(cx, scope, triedToWrap);
if (!proto)
return NULL;
JSObject *obj = NewProxyObject(cx, &NodeList<T>::instance,

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

@ -84,10 +84,10 @@ public:
NodeListBase() : ProxyHandler() {}
static JSObject *create(JSContext *cx, XPCWrappedNativeScope *scope,
nsINodeList *aNodeList);
nsINodeList *aNodeList, bool *triedToWrap);
static JSObject *create(JSContext *cx, XPCWrappedNativeScope *scope,
nsIHTMLCollection *aHTMLCollection,
nsWrapperCache *aWrapperCache);
nsWrapperCache *aWrapperCache, bool *triedToWrap);
};
/**
@ -110,7 +110,7 @@ class NodeList : public NodeListBase {
static Methods sProtoMethods[];
static bool instanceIsNodeListObject(JSContext *cx, JSObject *obj, JSObject *callee);
static JSObject *getPrototype(JSContext *cx, XPCWrappedNativeScope *scope);
static JSObject *getPrototype(JSContext *cx, XPCWrappedNativeScope *scope, bool *enabled);
static T *getNodeList(JSObject *obj);
@ -163,7 +163,7 @@ class NodeList : public NodeListBase {
void finalize(JSContext *cx, JSObject *proxy);
static JSObject *create(JSContext *cx, XPCWrappedNativeScope *scope, T *,
nsWrapperCache* aWrapperCache);
nsWrapperCache* aWrapperCache, bool *enabled);
static bool objIsNodeList(JSObject *obj) {
return js::IsProxy(obj) && js::GetProxyHandler(obj) == &instance;

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

@ -1155,7 +1155,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
// implementing it doesn't want a wrapped native as its JS Object, but
// instead it provides its own proxy object. In that case, the object
// to use is found as cache->GetWrapper(). If that is null, then the
// object will create (and fill the cache) from its PreCreate call.
// object will create (and fill the cache) from its WrapObject call.
nsWrapperCache *cache = aHelper.GetWrapperCache();
bool tryConstructSlimWrapper = false;
@ -1170,16 +1170,22 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
return JS_FALSE;
if(!flat) {
flat = cache->WrapObject(lccx.GetJSContext(), xpcscope);
bool triedToWrap;
flat = cache->WrapObject(lccx.GetJSContext(), xpcscope,
&triedToWrap);
if(!flat && triedToWrap)
return JS_FALSE;
if (!flat) {
flat = ConstructProxyObject(ccx, aHelper, xpcscope);
}
}
if(!JS_WrapObject(ccx, &flat))
return JS_FALSE;
if(flat) {
if(!JS_WrapObject(ccx, &flat))
return JS_FALSE;
return CreateHolderIfNeeded(ccx, flat, d, dest);
return CreateHolderIfNeeded(ccx, flat, d, dest);
}
}
if(!dest)

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

@ -52,6 +52,7 @@
#include "nsPrintfCString.h"
#include "mozilla/FunctionTimer.h"
#include "prsystem.h"
#include "mozilla/Preferences.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
@ -2018,6 +2019,8 @@ DiagnosticMemoryCallback(void *ptr, size_t size)
}
#endif
bool XPCJSRuntime::gNewDOMBindingsEnabled;
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
: mXPConnect(aXPConnect),
mJSRuntime(nsnull),
@ -2053,6 +2056,9 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
NS_TIME_FUNCTION;
DOM_InitInterfaces();
Preferences::AddBoolVarCache(&gNewDOMBindingsEnabled, "dom.new_bindings",
JS_FALSE);
// these jsids filled in later when we have a JSContext to work with.
mStrIDs[0] = JSID_VOID;

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

@ -793,6 +793,11 @@ public:
static void ActivityCallback(void *arg, JSBool active);
bool NewDOMBindingsEnabled()
{
return gNewDOMBindingsEnabled;
}
private:
XPCJSRuntime(); // no implementation
XPCJSRuntime(nsXPConnect* aXPConnect);
@ -802,6 +807,8 @@ private:
static void WatchdogMain(void *arg);
static bool gNewDOMBindingsEnabled;
static const char* mStrings[IDX_TOTAL_COUNT];
jsid mStrIDs[IDX_TOTAL_COUNT];
jsval mStrJSVals[IDX_TOTAL_COUNT];
@ -1616,6 +1623,11 @@ public:
}
void TraceDOMPrototypes(JSTracer *trc);
JSBool NewDOMBindingsEnabled()
{
return mNewDOMBindingsEnabled;
}
protected:
XPCWrappedNativeScope(XPCCallContext& ccx, JSObject* aGlobal);
virtual ~XPCWrappedNativeScope();
@ -1657,6 +1669,8 @@ private:
nsIScriptObjectPrincipal* mScriptObjectPrincipal;
nsDataHashtable<nsDepCharHashKey, JSObject*> mCachedDOMPrototypes;
JSBool mNewDOMBindingsEnabled;
};
JSObject* xpc_CloneJSFunction(XPCCallContext &ccx, JSObject *funobj,

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

@ -286,12 +286,13 @@ enum {
};
typedef JSObject*
(*DefineInterface)(JSContext *cx, XPCWrappedNativeScope *scope);
(*DefineInterface)(JSContext *cx, XPCWrappedNativeScope *scope, bool *enabled);
void
Register(nsDOMClassInfoData *aData);
extern bool
DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine);
DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine,
nsresult *aResult);
}
}

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

@ -148,7 +148,8 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(XPCCallContext& ccx,
mPrototypeJSObject(nsnull),
mPrototypeJSFunction(nsnull),
mPrototypeNoHelper(nsnull),
mScriptObjectPrincipal(nsnull)
mScriptObjectPrincipal(nsnull),
mNewDOMBindingsEnabled(ccx.GetRuntime()->NewDOMBindingsEnabled())
{
// add ourselves to the scopes list
{ // scoped lock

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

@ -599,6 +599,10 @@ pref("dom.min_timeout_value", 4);
// And for background windows
pref("dom.min_background_timeout_value", 1000);
// Use the new DOM bindings (only affects any scopes created after the pref is
// changed)
pref("dom.new_bindings", false);
// Parsing perf prefs. For now just mimic what the old code did.
#ifndef XP_WIN
pref("content.sink.pending_event_mode", 0);