Fix for bug 820657 (Implement the NamedGetter functionality on HTMLDocument) - refactor code to support document.all. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Wed, 27 Mar 2013 18:15:37 +0100
changeset 126556 1d97c190fe249a918977b8fd02f4a353955651bf
parent 126555 a2e02690e9bd42fa9ff09c176ac3bfb985753175
child 126557 85bcef2ac1fdba2e8340c0898c91f8ffb4fecbf7
push id24488
push userryanvm@gmail.com
push dateFri, 29 Mar 2013 00:54:52 +0000
treeherdermozilla-central@8aeabe064932 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs820657
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Fix for bug 820657 (Implement the NamedGetter functionality on HTMLDocument) - refactor code to support document.all. r=bz.
dom/base/nsDOMClassInfo.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -7115,16 +7115,86 @@ nsHTMLDocumentSH::DocumentAllTagsNewReso
       objp.set(obj);
     }
   }
 
   return JS_TRUE;
 }
 
 
+static nsresult
+ResolveAll(JSContext* cx, nsIDocument* doc, JSObject* obj)
+{
+  JSObject *proto;
+  if (!::JS_GetPrototype(cx, obj, &proto)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSObject *helper;
+  if (!GetDocumentAllHelper(cx, proto, &helper)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (!::JS_GetPrototype(cx, helper ? helper : obj, &proto)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // Check if the property all is defined on obj's (or helper's
+  // if obj doesn't exist) prototype, if it is, don't expose our
+  // document.all helper.
+
+  JSBool hasAll = JS_FALSE;
+  if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  if (hasAll && helper) {
+    // Our helper's prototype now has an "all" property, remove
+    // the helper out of the prototype chain to prevent
+    // shadowing of the now defined "all" property.
+    JSObject *tmp = obj, *tmpProto = tmp;
+
+    do {
+      tmp = tmpProto;
+      if (!::JS_GetPrototype(cx, tmp, &tmpProto)) {
+        return NS_ERROR_UNEXPECTED;
+      }
+    } while (tmpProto != helper);
+
+    ::JS_SetPrototype(cx, tmp, proto);
+  }
+
+  // If we don't already have a helper and "all" isn't already defined on
+  // our prototype, create a helper.
+  if (!helper && !hasAll) {
+    // Print a warning so developers can stop using document.all
+    PrintWarningOnConsole(cx, "DocumentAllUsed");
+
+    if (!::JS_GetPrototype(cx, obj, &proto)) {
+      return NS_ERROR_UNEXPECTED;
+    }
+    helper = ::JS_NewObject(cx, &sHTMLDocumentAllHelperClass,
+                            proto,
+                            ::JS_GetGlobalForObject(cx, obj));
+
+    if (!helper) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    // Insert the helper into our prototype chain. helper's prototype
+    // is already obj's current prototype.
+    if (!::JS_SetPrototype(cx, obj, helper)) {
+      xpc::Throw(cx, NS_ERROR_UNEXPECTED);
+      return NS_ERROR_UNEXPECTED;
+    }
+  }
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                              JSObject *obj, jsid id, uint32_t flags,
                              JSObject **objp, bool *_retval)
 {
   // nsDocumentSH::NewResolve() does a security check that we'd kinda
   // want to do here too before doing anything else. But given that we
   // only define dynamic properties here before the call to
@@ -7153,79 +7223,17 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec
       }
     }
 
     if (id == sAll_id && !sDisableDocumentAllSupport &&
         !ObjectIsNativeWrapper(cx, obj)) {
       nsIDocument *doc = static_cast<nsIDocument*>(wrapper->Native());
 
       if (doc->GetCompatibilityMode() == eCompatibility_NavQuirks) {
-        JSObject *proto;
-        if (!::JS_GetPrototype(cx, obj, &proto)) {
-          return NS_ERROR_FAILURE;
-        }
-
-        JSObject *helper;
-        if (!GetDocumentAllHelper(cx, proto, &helper)) {
-          return NS_ERROR_FAILURE;
-        }
-
-        if (!::JS_GetPrototype(cx, helper ? helper : obj, &proto)) {
-          return NS_ERROR_FAILURE;
-        }
-
-        // Check if the property all is defined on obj's (or helper's
-        // if obj doesn't exist) prototype, if it is, don't expose our
-        // document.all helper.
-
-        JSBool hasAll = JS_FALSE;
-        if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) {
-          return NS_ERROR_UNEXPECTED;
-        }
-
-        if (hasAll && helper) {
-          // Our helper's prototype now has an "all" property, remove
-          // the helper out of the prototype chain to prevent
-          // shadowing of the now defined "all" property.
-          JSObject *tmp = obj, *tmpProto = tmp;
-
-          do {
-            tmp = tmpProto;
-            if (!::JS_GetPrototype(cx, tmp, &tmpProto)) {
-              return NS_ERROR_UNEXPECTED;
-            }
-          } while (tmpProto != helper);
-
-          ::JS_SetPrototype(cx, tmp, proto);
-        }
-
-        // If we don't already have a helper and "all" isn't already defined on
-        // our prototype, create a helper.
-        if (!helper && !hasAll) {
-          // Print a warning so developers can stop using document.all
-          PrintWarningOnConsole(cx, "DocumentAllUsed");
-
-          if (!::JS_GetPrototype(cx, obj, &proto)) {
-            return NS_ERROR_UNEXPECTED;
-          }
-          helper = ::JS_NewObject(cx, &sHTMLDocumentAllHelperClass,
-                                  proto,
-                                  ::JS_GetGlobalForObject(cx, obj));
-
-          if (!helper) {
-            return NS_ERROR_OUT_OF_MEMORY;
-          }
-
-          // Insert the helper into our prototype chain. helper's prototype
-          // is already obj's current prototype.
-          if (!::JS_SetPrototype(cx, obj, helper)) {
-            xpc::Throw(cx, NS_ERROR_UNEXPECTED);
-            return NS_ERROR_UNEXPECTED;
-          }
-        }
+        return ResolveAll(cx, doc, obj);
       }
 
       return NS_OK;
     }
   }
 
   return nsDocumentSH::NewResolve(wrapper, cx, obj, id, flags, objp, _retval);
 }