From ad471c7e2b0ba8546ec9235fcb3493259bcb8ac3 Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Tue, 31 May 2011 23:47:18 +0200 Subject: [PATCH] Bug 648801 (new DOM list bindings) - Make HTMLCollection['string'] work. r=bz/jst/mrbkap. --HG-- extra : rebase_source : 7f61b1f61526c265c70de518086aeef8f20347bd --- js/src/xpconnect/src/dombindings.cpp | 58 +++++++++++++++++++++------- js/src/xpconnect/src/dombindings.h | 3 ++ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/js/src/xpconnect/src/dombindings.cpp b/js/src/xpconnect/src/dombindings.cpp index 263f5279832..38a59d5aa5f 100644 --- a/js/src/xpconnect/src/dombindings.cpp +++ b/js/src/xpconnect/src/dombindings.cpp @@ -96,10 +96,6 @@ Class NodeList::sProtoClass = { JS_ConvertStub }; -template<> -JSBool -NodeList::namedItem(JSContext *cx, uintN argc, jsval *vp); - template<> NodeList::Methods NodeList::sProtoMethods[] = { { nsDOMClassInfo::sItem_id, &item, 1 } @@ -219,6 +215,26 @@ NodeList::item(JSContext *cx, uintN argc, jsval *vp) return WrapObject(cx, obj, result, result, vp); } + +template<> +JSBool +NodeList::namedItem(JSContext *cx, JSObject *obj, jsval *name, jsval *vp) +{ + xpc_qsDOMString nameString(cx, *name, name, + xpc_qsDOMString::eDefaultNullBehavior, + xpc_qsDOMString::eDefaultUndefinedBehavior); + if (!nameString.IsValid()) + return JS_FALSE; + nsIHTMLCollection *collection = getNodeList(obj); + nsWrapperCache *cache; + nsISupports *result = collection->GetNamedItem(nameString, &cache); + if (!result) { + *vp = JSVAL_NULL; + return JS_TRUE; + } + return WrapObject(cx, obj, result, cache, vp); +} + template<> JSBool NodeList::namedItem(JSContext *cx, uintN argc, jsval *vp) @@ -230,15 +246,7 @@ NodeList::namedItem(JSContext *cx, uintN argc, jsval *vp) if (argc < 1) return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS); jsval *argv = JS_ARGV(cx, vp); - xpc_qsDOMString name(cx, argv[0], &argv[0], - xpc_qsDOMString::eDefaultNullBehavior, - xpc_qsDOMString::eDefaultUndefinedBehavior); - if (!name.IsValid()) - return JS_FALSE; - nsIHTMLCollection *htmlCollection = getNodeList(obj); - nsWrapperCache *cache; - nsISupports *result = htmlCollection->GetNamedItem(name, &cache); - return WrapObject(cx, obj, result, cache, vp); + return namedItem(cx, obj, &argv[0], vp); } template @@ -575,6 +583,26 @@ NodeList::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, Property return true; } +template<> +inline bool +NodeList::namedItem(JSContext *cx, JSObject *proxy, jsid id, Value *vp, bool *result) +{ + return false; +} +template<> +inline bool +NodeList::namedItem(JSContext *cx, JSObject *proxy, jsid id, Value *vp, bool *result) +{ + if (!JSID_IS_STRING(id)) + return false; + + jsval v = STRING_TO_JSVAL(JSID_TO_STRING(id)); + *result = namedItem(cx, proxy, &v, vp); + + // We treat failure as having handled the get. + return !*result || !vp->isNull(); +} + template bool NodeList::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp) @@ -597,6 +625,10 @@ NodeList::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Va return WrapObject(cx, proxy, result, result, vp); } + bool ok; + if (namedItem(cx, proxy, id, vp, &ok)) + return ok; + JSObject *proto = js::GetObjectProto(proxy); bool hit; if (!checkForCacheHit(cx, proxy, receiver, proto, id, vp, &hit)) diff --git a/js/src/xpconnect/src/dombindings.h b/js/src/xpconnect/src/dombindings.h index a2fb8b2a740..799299b5782 100644 --- a/js/src/xpconnect/src/dombindings.h +++ b/js/src/xpconnect/src/dombindings.h @@ -92,6 +92,9 @@ class NodeList : public NodeListBase { static JSBool item(JSContext *cx, uintN argc, jsval *vp); static JSBool namedItem(JSContext *cx, uintN argc, jsval *vp); + static JSBool namedItem(JSContext *cx, JSObject *obj, jsval *name, jsval *vp); + static bool namedItem(JSContext *cx, JSObject *proxy, jsid id, js::Value *vp, bool *result); + static bool cacheProtoShape(JSContext *cx, JSObject *proxy, JSObject *proto); static bool checkForCacheHit(JSContext *cx, JSObject *proxy, JSObject *receiver, JSObject *proto, jsid id, js::Value *vp, bool *hitp);