Bug 788369. Allow passing strings to the XHR constructor, since CoffeeScript seems to want to do it. r=peterv, a=lsblakk
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 07 Sep 2012 11:07:12 -0400
changeset 106812 41696b70b514b97941f82e2fd8e5b8ac95b0c642
parent 106811 4dcae7cb73909c48ad8dc09a98cc52691b849450
child 106813 b0d065b8572ab6259d2767990fc259971e0a4635
push idunknown
push userunknown
push dateunknown
reviewerspeterv, lsblakk
bugs788369
milestone17.0a2
Bug 788369. Allow passing strings to the XHR constructor, since CoffeeScript seems to want to do it. r=peterv, a=lsblakk
content/base/src/nsXMLHttpRequest.h
content/base/test/test_XHR_parameters.html
dom/bindings/test/Makefile.in
dom/bindings/test/test_bug788369.html
dom/webidl/XMLHttpRequest.webidl
dom/workers/XMLHttpRequest.h
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -171,17 +171,17 @@ public:
   {
     return mozilla::dom::XMLHttpRequestBinding::Wrap(cx, scope, this, triedToWrap);
   }
   nsISupports* GetParentObject()
   {
     return GetOwner();
   }
 
-  // The WebIDL constructor.
+  // The WebIDL constructors.
   static already_AddRefed<nsXMLHttpRequest>
   Constructor(JSContext* aCx,
               nsISupports* aGlobal,
               const mozilla::dom::MozXMLHttpRequestParameters& aParams,
               ErrorResult& aRv)
   {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
     nsCOMPtr<nsIScriptObjectPrincipal> principal = do_QueryInterface(aGlobal);
@@ -191,16 +191,32 @@ public:
     }
 
     nsRefPtr<nsXMLHttpRequest> req = new nsXMLHttpRequest();
     req->Construct(principal->GetPrincipal(), window);
     req->InitParameters(aParams.mozAnon, aParams.mozSystem);
     return req.forget();
   }
 
+  static already_AddRefed<nsXMLHttpRequest>
+  Constructor(JSContext* aCx,
+              nsISupports* aGlobal,
+              const nsAString& ignored,
+              ErrorResult& aRv)
+  {
+    // Pretend like someone passed null, so we can pick up the default values
+    mozilla::dom::MozXMLHttpRequestParameters params;
+    if (!params.Init(aCx, JS::NullValue())) {
+      aRv.Throw(NS_ERROR_UNEXPECTED);
+      return nullptr;
+    }
+
+    return Constructor(aCx, aGlobal, params, aRv);
+  }
+
   void Construct(nsIPrincipal* aPrincipal,
                  nsPIDOMWindow* aOwnerWindow,
                  nsIURI* aBaseURI = NULL)
   {
     MOZ_ASSERT(aPrincipal);
     MOZ_ASSERT_IF(aOwnerWindow, aOwnerWindow->IsInnerWindow());
     mPrincipal = aPrincipal;
     BindToOwner(aOwnerWindow);
--- a/content/base/test/test_XHR_parameters.html
+++ b/content/base/test/test_XHR_parameters.html
@@ -24,25 +24,25 @@ function runTests() {
     undefined,
     null,
     {},
     {mozSystem: ""},
     {mozSystem: 0},
     {mozAnon: 1},
     {mozAnon: []},
     {get mozAnon() { return true; }},
-  ];
-
-  let invalidParameters = [
     0,
     7,
     Math.PI,
     "string",
     true,
     false,
+  ];
+
+  let invalidParameters = [
     {get mozSystem() { throw "Bla"; } },
   ];
 
   let havePrivileges = false;
 
   function testValidParameter(value) {
     let xhr;
     try {
--- a/dom/bindings/test/Makefile.in
+++ b/dom/bindings/test/Makefile.in
@@ -56,16 +56,17 @@ MOCHITEST_FILES := \
   test_interfaceToString.html \
   test_lookupGetter.html \
   test_InstanceOf.html \
   test_traceProtos.html \
   test_forOf.html \
   forOf_iframe.html \
   test_sequence_wrapping.html \
   file_bug775543.html \
+  test_bug788369.html \
   $(NULL)
 
 MOCHITEST_CHROME_FILES = \
   test_bug775543.html \
   $(NULL)
 
 # Include rules.mk before any of our targets so our first target is coming from
 # rules.mk and running make with no target in this dir does the right thing.
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/test_bug788369.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=788369
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 788369</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=788369">Mozilla Bug 788369</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 788369 **/
+try {
+  var xhr = new(window.ActiveXObject || XMLHttpRequest)("Microsoft.XMLHTTP");
+  ok(xhr instanceof XMLHttpRequest, "Should have an XHR object");
+} catch (e) {
+  ok(false, "Should not throw exception when constructing: " + e);
+}
+</script>
+</pre>
+</body>
+</html>
--- a/dom/webidl/XMLHttpRequest.webidl
+++ b/dom/webidl/XMLHttpRequest.webidl
@@ -46,17 +46,22 @@ dictionary MozXMLHttpRequestParameters
   boolean mozAnon = false;
 
   /**
    * If true, the same origin policy will not be enforced on the request.
    */
   boolean mozSystem = false;
 };
 
-[Constructor(optional MozXMLHttpRequestParameters params)]
+[Constructor(optional MozXMLHttpRequestParameters params),
+ // There are apparently callers, specifically CoffeeScript, who do
+ // things like this:
+ //   c = new(window.ActiveXObject || XMLHttpRequest)("Microsoft.XMLHTTP")
+ // To handle that, we need a constructor that takes a string.
+ Constructor(DOMString ignored)]
 interface XMLHttpRequest : XMLHttpRequestEventTarget {
   // event handler
   [TreatNonCallableAsNull, GetterInfallible=MainThread]
   attribute Function? onreadystatechange;
 
   // states
   const unsigned short UNSENT = 0;
   const unsigned short OPENED = 1;
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -69,16 +69,31 @@ public:
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   static XMLHttpRequest*
   Constructor(JSContext* aCx, JSObject* aGlobal,
               const MozXMLHttpRequestParametersWorkers& aParams,
               ErrorResult& aRv);
+
+  static XMLHttpRequest*
+  Constructor(JSContext* aCx, JSObject* aGlobal,
+              const nsAString& ignored, ErrorResult& aRv)
+  {
+    // Pretend like someone passed null, so we can pick up the default values
+    MozXMLHttpRequestParametersWorkers params;
+    if (!params.Init(aCx, JS::NullValue())) {
+      aRv.Throw(NS_ERROR_UNEXPECTED);
+      return nullptr;
+    }
+
+    return Constructor(aCx, aGlobal, params, aRv);
+  }
+
   void
   Unpin();
 
   bool
   Notify(JSContext* aCx, Status aStatus) MOZ_OVERRIDE;
 
 #define IMPL_GETTER_AND_SETTER(_type)                                          \
   JSObject*                                                                    \