Merge inbound to m-c a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Thu, 19 Mar 2015 19:15:11 -0700
changeset 251843 3257d9c4b257ee422629ca7d94fb83ee7883d523
parent 251830 988afda9eac4989e7a3aa5192c678a8f41ba69e8 (current diff)
parent 251809 b3fcbf6497653ca51fc762c2444470fba7270021 (diff)
child 251844 02ca416c13a5d084f20b10147635bdc6c4f3932a
push id1156
push userpbrosset@mozilla.com
push dateFri, 20 Mar 2015 16:00:24 +0000
reviewersmerge
milestone39.0a1
Merge inbound to m-c a=merge CLOSED TREE
browser/components/sessionstore/test/browser.ini
modules/brotli/dec/README
--- a/accessible/base/MarkupMap.h
+++ b/accessible/base/MarkupMap.h
@@ -200,32 +200,32 @@ MARKUPMAP(munderover_,
           AttrFromDOM(accentunder_, accentunder_),
           AttrFromDOM(align, align))
 
 MARKUPMAP(mmultiscripts_,
           New_HyperText,
           roles::MATHML_MULTISCRIPTS)
 
 MARKUPMAP(mtable_,
-          New_HyperText,
+          New_HTMLTableAccessible,
           roles::MATHML_TABLE,
           AttrFromDOM(align, align),
           AttrFromDOM(columnlines_, columnlines_),
           AttrFromDOM(rowlines_, rowlines_))
 
 MARKUPMAP(mlabeledtr_,
-          New_HyperText,
+          New_HTMLTableRowAccessible,
           roles::MATHML_LABELED_ROW)
 
 MARKUPMAP(mtr_,
-          New_HyperText,
+          New_HTMLTableRowAccessible,
           roles::MATHML_TABLE_ROW)
 
 MARKUPMAP(mtd_,
-          New_HyperText,
+          New_HTMLTableCellAccessible,
           roles::MATHML_CELL)
 
 MARKUPMAP(maction_,
           New_HyperText,
           roles::MATHML_ACTION,
           AttrFromDOM(actiontype_, actiontype_),
           AttrFromDOM(selection_, selection_))
 
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -196,16 +196,28 @@ static Accessible* New_HTMLLabel(nsICont
 
 static Accessible* New_HTMLOutput(nsIContent* aContent, Accessible* aContext)
   { return new HTMLOutputAccessible(aContent, aContext->Document()); }
 
 static Accessible* New_HTMLProgress(nsIContent* aContent, Accessible* aContext)
   { return new HTMLProgressMeterAccessible(aContent, aContext->Document()); }
 
 static Accessible*
+New_HTMLTableAccessible(nsIContent* aContent, Accessible* aContext)
+  { return new HTMLTableAccessible(aContent, aContext->Document()); }
+
+static Accessible*
+New_HTMLTableRowAccessible(nsIContent* aContent, Accessible* aContext)
+  { return new HTMLTableRowAccessible(aContent, aContext->Document()); }
+
+static Accessible*
+New_HTMLTableCellAccessible(nsIContent* aContent, Accessible* aContext)
+  { return new HTMLTableCellAccessible(aContent, aContext->Document()); }
+
+static Accessible*
 New_HTMLTableHeaderCell(nsIContent* aContent, Accessible* aContext)
 {
   if (aContext->IsTableRow() && aContext->GetContent() == aContent->GetParent())
     return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
   return nullptr;
 }
 
 static Accessible*
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -55,16 +55,19 @@ HTMLTableCellAccessible::
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableCellAccessible, HyperTextAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: Accessible implementation
 
 role
 HTMLTableCellAccessible::NativeRole()
 {
+  if (mContent->IsMathMLElement(nsGkAtoms::mtd_)) {
+    return roles::MATHML_CELL;
+  }
   return roles::CELL;
 }
 
 uint64_t
 HTMLTableCellAccessible::NativeState()
 {
   uint64_t state = HyperTextAccessibleWrap::NativeState();
 
@@ -143,18 +146,17 @@ HTMLTableCellAccessible::NativeAttribute
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: TableCellAccessible implementation
 
 TableAccessible*
 HTMLTableCellAccessible::Table() const
 {
   Accessible* parent = const_cast<HTMLTableCellAccessible*>(this);
   while ((parent = parent->Parent())) {
-    roles::Role role = parent->Role();
-    if (role == roles::TABLE || role == roles::TREE_TABLE)
+    if (parent->IsTable())
       return parent->AsTable();
   }
 
   return nullptr;
 }
 
 uint32_t
 HTMLTableCellAccessible::ColIdx() const
@@ -344,16 +346,21 @@ HTMLTableHeaderCellAccessible::NativeRol
 // HTMLTableRowAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableRowAccessible, Accessible)
 
 role
 HTMLTableRowAccessible::NativeRole()
 {
+  if (mContent->IsMathMLElement(nsGkAtoms::mtr_)) {
+    return roles::MATHML_TABLE_ROW;
+  } else if (mContent->IsMathMLElement(nsGkAtoms::mlabeledtr_)) {
+    return roles::MATHML_LABELED_ROW;
+  }
   return roles::ROW;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableAccessible, Accessible)
@@ -379,16 +386,19 @@ HTMLTableAccessible::CacheChildren()
     }
     AppendChild(child);
   }
 }
 
 role
 HTMLTableAccessible::NativeRole()
 {
+  if (mContent->IsMathMLElement(nsGkAtoms::mtable_)) {
+    return roles::MATHML_TABLE;
+  }
   return roles::TABLE;
 }
 
 uint64_t
 HTMLTableAccessible::NativeState()
 {
   return Accessible::NativeState() | states::READONLY;
 }
@@ -416,16 +426,21 @@ HTMLTableAccessible::NativeName(nsString
   return eNameOK;
 }
 
 already_AddRefed<nsIPersistentProperties>
 HTMLTableAccessible::NativeAttributes()
 {
   nsCOMPtr<nsIPersistentProperties> attributes =
     AccessibleWrap::NativeAttributes();
+
+  if (mContent->IsMathMLElement(nsGkAtoms::mtable_)) {
+    GetAccService()->MarkupAttributes(mContent, attributes);
+  }
+
   if (IsProbablyLayoutTable()) {
     nsAutoString unused;
     attributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
                                   NS_LITERAL_STRING("true"), unused);
   }
 
   return attributes.forget();
 }
--- a/accessible/tests/mochitest/table.js
+++ b/accessible/tests/mochitest/table.js
@@ -23,43 +23,61 @@ const kSpanned = kRowSpanned | kColSpann
 /**
  * Constants to define column header type.
  */
 const kNoColumnHeader = 0;
 const kListboxColumnHeader = 1;
 const kTreeColumnHeader = 2;
 
 /**
+ * Constants to define table type.
+ */
+const kTable = 0;
+const kTreeTable = 1;
+const kMathTable = 2;
+
+/**
  * Test table structure and related methods.
  *
  * @param  aIdentifier     [in] table accessible identifier
  * @param  aCellsArray     [in] two dimensional array (row X columns) of
  *                          cell types (see constants defined above).
  * @param  aColHeaderType  [in] specifies wether column header cells are
  *                          arranged into the list.
  * @param  aCaption        [in] caption text if any
  * @param  aSummary        [in] summary text if any
- * @param  aIsTreeTable    [in] specifies whether given table is tree table
+ * @param  aTableType      [in] specifies the table type.
+ * @param  aRowRoles       [in] array of row roles.
  */
 function testTableStruct(aIdentifier, aCellsArray, aColHeaderType,
-                         aCaption, aSummary, aIsTreeTable)
+                         aCaption, aSummary, aTableType, aRowRoles)
 {
   var tableNode = getNode(aIdentifier);
   var isGrid = tableNode.getAttribute("role") == "grid" ||
     tableNode.getAttribute("role") == "treegrid" ||
     tableNode.localName == "tree";
 
   var rowCount = aCellsArray.length;
   var colsCount = aCellsArray[0] ? aCellsArray[0].length : 0;
 
   // Test table accessible tree.
   var tableObj = {
-    role: aIsTreeTable ? ROLE_TREE_TABLE : ROLE_TABLE,
     children: []
   };
+  switch (aTableType) {
+    case kTable:
+      tableObj.role = ROLE_TABLE;
+      break;
+    case kTreeTable:
+      tableObj.role = ROLE_TREE_TABLE;
+      break;
+    case kMathTable:
+      tableObj.role = ROLE_MATHML_TABLE;
+      break;
+  }
 
   // caption accessible handling
   if (aCaption) {
     var captionObj = {
       role: ROLE_CAPTION,
       children: [
         {
           role: ROLE_TEXT_LEAF,
@@ -94,27 +112,28 @@ function testTableStruct(aIdentifier, aC
     }
 
     tableObj.children.push(headersObj);
   }
 
   // rows and cells accessibles
   for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     var rowObj = {
-      role: ROLE_ROW,
+      role: aRowRoles ? aRowRoles[rowIdx] : ROLE_ROW,
       children: []
     };
 
     for (var colIdx = 0; colIdx < colsCount; colIdx++) {
       var celltype = aCellsArray[rowIdx][colIdx];
 
       var role = ROLE_NOTHING;
       switch (celltype) {
         case kDataCell:
-          role = (isGrid ? ROLE_GRID_CELL : ROLE_CELL);
+          role = (aTableType == kMathTable ? ROLE_MATHML_CELL :
+                  (isGrid ? ROLE_GRID_CELL : ROLE_CELL));
           break;
         case kRowHeaderCell:
           role = ROLE_ROWHEADER;
           break;
         case kColHeaderCell:
           role = ROLE_COLUMNHEADER;
           break;
       }
--- a/accessible/tests/mochitest/table/a11y.ini
+++ b/accessible/tests/mochitest/table/a11y.ini
@@ -4,16 +4,17 @@
 [test_headers_listbox.xul]
 [test_headers_table.html]
 [test_headers_tree.xul]
 [test_indexes_ariagrid.html]
 [test_indexes_listbox.xul]
 [test_indexes_table.html]
 [test_indexes_tree.xul]
 [test_layoutguess.html]
+[test_mtable.html]
 [test_sels_ariagrid.html]
 [test_sels_listbox.xul]
 [test_sels_table.html]
 [test_sels_tree.xul]
 [test_struct_ariagrid.html]
 [test_struct_ariatreegrid.html]
 [test_struct_listbox.xul]
 [test_struct_table.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/table/test_mtable.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>MathML table tests</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../table.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      // 'Simple' table
+      var idxes = [
+        [0, 1],
+        [2, 3]
+      ];
+      testTableIndexes("simple", idxes);
+      var cellsArray = [
+        [kDataCell, kDataCell],
+        [kDataCell, kDataCell]
+      ];
+      var rowsArray = [ROLE_MATHML_TABLE_ROW, ROLE_MATHML_TABLE_ROW];
+      testTableStruct("simple", cellsArray, kNoColumnHeader,
+                      "", "", kMathTable, rowsArray);
+
+      // 'Complex' table
+      idxes = [
+        [0, 0, 0],
+        [1, 1, 2],
+        [1, 1, 3]
+      ];
+      testTableIndexes("complex", idxes);
+      cellsArray = [
+        [kDataCell,   kColSpanned, kColSpanned],
+        [kDataCell,   kColSpanned, kDataCell],
+        [kRowSpanned, kSpanned,    kDataCell],
+      ];
+      rowsArray = [
+        ROLE_MATHML_TABLE_ROW,
+        ROLE_MATHML_TABLE_ROW,
+        ROLE_MATHML_TABLE_ROW
+      ];
+      testTableStruct("complex", cellsArray, kNoColumnHeader,
+                      "", "", kMathTable, rowsArray);
+
+      // 'Simple' table with mlabeledtr
+      // At the moment we do not implement mlabeledtr but just hide the label
+      // with display: none. Thus we just test the role for now. See bug 689641.
+      var idxes = [[0]];
+      testTableIndexes("simple_label", idxes);
+      var cellsArray = [[kDataCell]];
+      rowsArray = [ROLE_MATHML_LABELED_ROW];
+      testTableStruct("simple_label", cellsArray, kNoColumnHeader,
+                      "", "", kMathTable, rowsArray);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <math>
+    <mtable id="simple">
+      <mtr>
+        <mtd>
+          <mn>1</mn>
+        </mtd>
+        <mtd>
+          <mn>0</mn>
+        </mtd>
+      </mtr>
+      <mtr>
+        <mtd>
+          <mn>0</mn>
+        </mtd>
+        <mtd>
+          <mn>1</mn>
+        </mtd>
+      </mtr>
+    </mtable>
+
+    <mtable id="complex">
+      <mtr>
+        <mtd columnspan="3">
+          <mtext>1 x 3</mtext>
+        </mtd>
+      </mtr>
+      <mtr>
+        <mtd rowspan="2" columnspan="2">
+          <mtext>2 x 2</mtext>
+        </mtd>
+        <mtd>
+          <mtext>1 x 1</mtext>
+        </mtd>
+      </mtr>
+      <mtr>
+        <mtd>
+          <mtext>1 x 1</mtext>
+        </mtd>
+      </mtr>
+    </mtable>
+
+    <mtable id="simple_label">
+      <mlabeledtr>
+        <mtd><mtext>1</mtext></mtd>
+        <mtd><mtext>label</mtext></mtd>
+      </mlabeledtr>
+    </mtable>
+  </math>
+
+</body>
+</html>
--- a/accessible/tests/mochitest/table/test_struct_ariatreegrid.html
+++ b/accessible/tests/mochitest/table/test_struct_ariatreegrid.html
@@ -23,17 +23,18 @@
       // HTML based ARIA tree grid
 
       var cellsArray = [
         [kColHeaderCell, kColHeaderCell, kColHeaderCell],
         [kDataCell,      kDataCell,      kDataCell],
         [kDataCell,      kDataCell,      kDataCell]
       ];
 
-      testTableStruct("treegrid", cellsArray, kNoColumnHeader, "", "", true);
+      testTableStruct("treegrid", cellsArray, kNoColumnHeader, "", "",
+                      kTreeTable);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
--- a/b2g/components/Frames.jsm
+++ b/b2g/components/Frames.jsm
@@ -20,32 +20,32 @@ const Observer = {
   _frames: new Map(),
 
   // Also save current number of iframes opened by app
   _apps: new Map(),
 
   start: function () {
     Services.obs.addObserver(this, 'remote-browser-shown', false);
     Services.obs.addObserver(this, 'inprocess-browser-shown', false);
-    Services.obs.addObserver(this, 'message-manager-disconnect', false);
+    Services.obs.addObserver(this, 'message-manager-close', false);
 
     SystemAppProxy.getFrames().forEach(frame => {
       let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
       this._frames.set(mm, frame);
       let mozapp = frame.getAttribute('mozapp');
       if (mozapp) {
         this._apps.set(mozapp, (this._apps.get(mozapp) || 0) + 1);
       }
     });
   },
 
   stop: function () {
     Services.obs.removeObserver(this, 'remote-browser-shown');
     Services.obs.removeObserver(this, 'inprocess-browser-shown');
-    Services.obs.removeObserver(this, 'message-manager-disconnect');
+    Services.obs.removeObserver(this, 'message-manager-close');
     this._frames.clear();
     this._apps.clear();
   },
 
   observe: function (subject, topic, data) {
     switch(topic) {
 
       // Listen for frame creation in OOP (device) as well as in parent process (b2g desktop)
@@ -56,17 +56,17 @@ const Observer = {
         // get a ref to the app <iframe>
         frameLoader.QueryInterface(Ci.nsIFrameLoader);
         let frame = frameLoader.ownerElement;
         let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
         this.onMessageManagerCreated(mm, frame);
         break;
 
       // Every time an iframe is destroyed, its message manager also is
-      case 'message-manager-disconnect':
+      case 'message-manager-close':
         this.onMessageManagerDestroyed(subject);
         break;
     }
   },
 
   onMessageManagerCreated: function (mm, frame) {
     this._frames.set(mm, frame);
 
--- a/browser/components/sessionstore/content/content-sessionStore.js
+++ b/browser/components/sessionstore/content/content-sessionStore.js
@@ -749,17 +749,17 @@ function handleRevivedTab() {
 
     removeEventListener("pagehide", handleRevivedTab);
 
     // We can't send a message using the frame message manager because by
     // the time we reach the unload event handler, it's "too late", and messages
     // won't be sent or received. The child-process message manager works though,
     // despite the fact that we're really running in the parent process.
     let browser = docShell.chromeEventHandler;
-    cpmm.sendSyncMessage("SessionStore:RemoteTabRevived", null, {browser: browser});
+    cpmm.sendAsyncMessage("SessionStore:RemoteTabRevived", null, {browser: browser});
   }
 }
 
 // If we're browsing from the tab crashed UI to a blacklisted URI that keeps
 // this browser non-remote, we'll handle that in a pagehide event.
 addEventListener("pagehide", handleRevivedTab);
 
 addEventListener("unload", () => {
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -67,17 +67,17 @@ support-files =
 [browser_aboutSessionRestore.js]
 [browser_attributes.js]
 [browser_backup_recovery.js]
 [browser_broadcast.js]
 [browser_capabilities.js]
 [browser_cleaner.js]
 [browser_cookies.js]
 [browser_crashedTabs.js]
-skip-if = !e10s || os == "linux" # Waiting on OMTC enabled by default on Linux (Bug 994541)
+skip-if = !e10s || !crashreporter
 [browser_dying_cache.js]
 [browser_dynamic_frames.js]
 [browser_form_restore_events.js]
 [browser_formdata.js]
 skip-if = buildapp == 'mulet'
 [browser_formdata_format.js]
 [browser_formdata_xpath.js]
 [browser_frametree.js]
--- a/browser/components/sessionstore/test/browser_crashedTabs.js
+++ b/browser/components/sessionstore/test/browser_crashedTabs.js
@@ -10,16 +10,19 @@ const PAGE_2 = "data:text/html,<html><bo
 Services.prefs.setBoolPref("browser.tabs.animate", false);
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref("browser.tabs.animate");
 });
 
 // Allow tabs to restore on demand so we can test pending states
 Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
 
+// Running this test in ASAN is slow.
+requestLongerTimeout(2);
+
 /**
  * Returns a Promise that resolves once a remote <xul:browser> has experienced
  * a crash. Also does the job of cleaning up the minidump of the crash.
  *
  * @param browser
  *        The <xul:browser> that will crash
  * @return Promise
  */
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -679,17 +679,17 @@ this.UITour = {
       }
     }
 
     if (!this.tourBrowsersByWindow.has(window)) {
       this.tourBrowsersByWindow.set(window, new Set());
     }
     this.tourBrowsersByWindow.get(window).add(browser);
 
-    Services.obs.addObserver(this, "message-manager-disconnect", false);
+    Services.obs.addObserver(this, "message-manager-close", false);
 
     window.addEventListener("SSWindowClosing", this);
 
     return true;
   },
 
   handleEvent: function(aEvent) {
     log.debug("handleEvent: type =", aEvent.type, "event =", aEvent);
@@ -731,17 +731,17 @@ this.UITour = {
     }
   },
 
   observe: function(aSubject, aTopic, aData) {
     log.debug("observe: aTopic =", aTopic);
     switch (aTopic) {
       // The browser message manager is disconnected when the <browser> is
       // destroyed and we want to teardown at that point.
-      case "message-manager-disconnect": {
+      case "message-manager-close": {
         let winEnum = Services.wm.getEnumerator("navigator:browser");
         while (winEnum.hasMoreElements()) {
           let window = winEnum.getNext();
           if (window.closed)
             continue;
 
           let tourBrowsers = this.tourBrowsersByWindow.get(window);
           if (!tourBrowsers)
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -45,44 +45,45 @@ let consoleOpened = Task.async(function*
 
   popup._panel.addEventListener("popupshown", function onShown() {
     popup._panel.removeEventListener("popupshown", onShown, false);
 
     ok(popup.isOpen, "popup is open");
 
     // 4 values, and the following properties:
     // __defineGetter__  __defineSetter__ __lookupGetter__ __lookupSetter__
-    // hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString
-    // toSource unwatch valueOf watch constructor.
-    is(popup.itemCount, 18, "popup.itemCount is correct");
+    // __proto__ hasOwnProperty isPrototypeOf propertyIsEnumerable
+    // toLocaleString toString toSource unwatch valueOf watch constructor.
+    is(popup.itemCount, 19, "popup.itemCount is correct");
 
     let sameItems = popup.getItems().reverse().map(function(e) {return e.label;});
     ok(sameItems.every(function(prop, index) {
       return [
         "__defineGetter__",
         "__defineSetter__",
         "__lookupGetter__",
         "__lookupSetter__",
+        "__proto__",
         "constructor",
         "hasOwnProperty",
         "isPrototypeOf",
         "item0",
         "item1",
         "item2",
         "item3",
         "propertyIsEnumerable",
         "toLocaleString",
         "toSource",
         "toString",
         "unwatch",
         "valueOf",
         "watch",
       ][index] === prop}), "getItems returns the items we expect");
 
-    is(popup.selectedIndex, 17,
+    is(popup.selectedIndex, 18,
        "Index of the first item from bottom is selected.");
     EventUtils.synthesizeKey("VK_DOWN", {});
 
     let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
 
     is(popup.selectedIndex, 0, "index 0 is selected");
     is(popup.selectedItem.label, "watch", "watch is selected");
     is(completeNode.value, prefix + "watch",
@@ -110,17 +111,17 @@ let consoleOpened = Task.async(function*
       "Index is greater after PGDN");
 
     currentSelectionIndex = popup.selectedIndex;
     EventUtils.synthesizeKey("VK_PAGE_UP", {});
 
     ok(popup.selectedIndex < currentSelectionIndex, "Index is less after Page UP");
 
     EventUtils.synthesizeKey("VK_END", {});
-    is(popup.selectedIndex, 17, "index is last after End");
+    is(popup.selectedIndex, 18, "index is last after End");
 
     EventUtils.synthesizeKey("VK_HOME", {});
     is(popup.selectedIndex, 0, "index is first after Home");
 
     info("press Tab and wait for popup to hide");
     popup._panel.addEventListener("popuphidden", function popupHidden() {
       popup._panel.removeEventListener("popuphidden", popupHidden, false);
       deferred.resolve();
@@ -147,19 +148,19 @@ function popupHideAfterTab()
 
   ok(!completeNode.value, "completeNode is empty");
 
   popup._panel.addEventListener("popupshown", function onShown() {
     popup._panel.removeEventListener("popupshown", onShown, false);
 
     ok(popup.isOpen, "popup is open");
 
-    is(popup.itemCount, 18, "popup.itemCount is correct");
+    is(popup.itemCount, 19, "popup.itemCount is correct");
 
-    is(popup.selectedIndex, 17, "First index from bottom is selected");
+    is(popup.selectedIndex, 18, "First index from bottom is selected");
     EventUtils.synthesizeKey("VK_DOWN", {});
 
     let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
 
     is(popup.selectedIndex, 0, "index 0 is selected");
     is(popup.selectedItem.label, "watch", "watch is selected");
     is(completeNode.value, prefix + "watch",
         "completeNode.value holds watch");
@@ -196,19 +197,19 @@ function testReturnKey()
 {
   let deferred = promise.defer();
 
   popup._panel.addEventListener("popupshown", function onShown() {
     popup._panel.removeEventListener("popupshown", onShown, false);
 
     ok(popup.isOpen, "popup is open");
 
-    is(popup.itemCount, 18, "popup.itemCount is correct");
+    is(popup.itemCount, 19, "popup.itemCount is correct");
 
-    is(popup.selectedIndex, 17, "First index from bottom is selected");
+    is(popup.selectedIndex, 18, "First index from bottom is selected");
     EventUtils.synthesizeKey("VK_DOWN", {});
 
     let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
 
     is(popup.selectedIndex, 0, "index 0 is selected");
     is(popup.selectedItem.label, "watch", "watch is selected");
     is(completeNode.value, prefix + "watch",
         "completeNode.value holds watch");
--- a/build/autoconf/toolchain.m4
+++ b/build/autoconf/toolchain.m4
@@ -96,19 +96,19 @@ if test "$GNU_CC"; then
         GCC_USE_GNU_LD=1
     fi
 fi
 
 AC_SUBST(CLANG_CXX)
 AC_SUBST(CLANG_CL)
 
 if test -n "$GNU_CC" -a -z "$CLANG_CC" ; then
-    if test "$GCC_MAJOR_VERSION" -eq 4 -a "$GCC_MINOR_VERSION" -lt 6 ||
+    if test "$GCC_MAJOR_VERSION" -eq 4 -a "$GCC_MINOR_VERSION" -lt 7 ||
        test "$GCC_MAJOR_VERSION" -lt 4; then
-        AC_MSG_ERROR([Only GCC 4.6 or newer supported])
+        AC_MSG_ERROR([Only GCC 4.7 or newer supported])
     fi
 fi
 ])
 
 AC_DEFUN([MOZ_CROSS_COMPILER],
 [
 echo "cross compiling from $host to $target"
 
--- a/dom/activities/Activity.cpp
+++ b/dom/activities/Activity.cpp
@@ -20,19 +20,19 @@ NS_IMPL_RELEASE_INHERITED(Activity, DOMR
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(Activity, DOMRequest,
                                    mProxy)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(Activity, DOMRequest)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 /* virtual */ JSObject*
-Activity::WrapObject(JSContext* aCx)
+Activity::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozActivityBinding::Wrap(aCx, this);
+  return MozActivityBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 Activity::Initialize(nsPIDOMWindow* aWindow,
                      JSContext* aCx,
                      const ActivityOptions& aOptions)
 {
   MOZ_ASSERT(aWindow);
--- a/dom/activities/Activity.h
+++ b/dom/activities/Activity.h
@@ -16,17 +16,17 @@ namespace mozilla {
 namespace dom {
 
 class Activity : public DOMRequest
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(Activity, DOMRequest)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<Activity>
   Constructor(const GlobalObject& aOwner,
               const ActivityOptions& aOptions,
               ErrorResult& aRv)
   {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aOwner.GetAsSupports());
     if (!window) {
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -61,19 +61,19 @@ const double ComputedTiming::kNullTimeFr
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Animation, mDocument, mTarget)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Animation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Animation, Release)
 
 JSObject*
-Animation::WrapObject(JSContext* aCx)
+Animation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AnimationBinding::Wrap(aCx, this);
+  return AnimationBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<AnimationEffect>
 Animation::GetEffect()
 {
   nsRefPtr<AnimationEffect> effect = new AnimationEffect(this);
   return effect.forget();
 }
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -184,17 +184,17 @@ public:
   {
     MOZ_ASSERT(aTarget, "null animation target is not yet supported");
   }
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Animation)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(Animation)
 
   nsIDocument* GetParentObject() const { return mDocument; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // FIXME: If we succeed in moving transition-specific code to a type of
   // AnimationEffect (as per the Web Animations API) we should remove these
   // virtual methods.
   virtual ElementPropertyTransition* AsTransition() { return nullptr; }
   virtual const ElementPropertyTransition* AsTransition() const {
     return nullptr;
   }
--- a/dom/animation/AnimationEffect.cpp
+++ b/dom/animation/AnimationEffect.cpp
@@ -10,15 +10,15 @@ namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffect, mAnimation)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationEffect, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationEffect, Release)
 
 JSObject*
-AnimationEffect::WrapObject(JSContext* aCx)
+AnimationEffect::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AnimationEffectBinding::Wrap(aCx, this);
+  return AnimationEffectBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/AnimationEffect.h
+++ b/dom/animation/AnimationEffect.h
@@ -22,17 +22,17 @@ public:
     : mAnimation(aAnimation)
   {
   }
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationEffect)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationEffect)
 
   Animation* GetParentObject() const { return mAnimation; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // AnimationEffect interface
   void GetName(nsString& aRetVal) const {
     aRetVal = mAnimation->Name();
   }
 
 private:
   ~AnimationEffect() { }
--- a/dom/animation/AnimationPlayer.cpp
+++ b/dom/animation/AnimationPlayer.cpp
@@ -21,19 +21,19 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(An
 NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationPlayer)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationPlayer)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationPlayer)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-AnimationPlayer::WrapObject(JSContext* aCx)
+AnimationPlayer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return dom::AnimationPlayerBinding::Wrap(aCx, this);
+  return dom::AnimationPlayerBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 AnimationPlayer::SetStartTime(const Nullable<TimeDuration>& aNewStartTime)
 {
 #if 1
   // Bug 1096776: once we support inactive/missing timelines we'll want to take
   // the disabled branch.
--- a/dom/animation/AnimationPlayer.h
+++ b/dom/animation/AnimationPlayer.h
@@ -59,17 +59,17 @@ public:
     , mIsRelevant(false)
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AnimationPlayer)
 
   AnimationTimeline* GetParentObject() const { return mTimeline; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual CSSAnimationPlayer* AsCSSAnimationPlayer() { return nullptr; }
   virtual CSSTransitionPlayer* AsCSSTransitionPlayer() { return nullptr; }
 
   // AnimationPlayer methods
   Animation* GetSource() const { return mSource; }
   AnimationTimeline* Timeline() const { return mTimeline; }
   Nullable<TimeDuration> GetStartTime() const { return mStartTime; }
--- a/dom/animation/AnimationTimeline.cpp
+++ b/dom/animation/AnimationTimeline.cpp
@@ -16,19 +16,19 @@ namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationTimeline, mDocument, mWindow)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationTimeline, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationTimeline, Release)
 
 JSObject*
-AnimationTimeline::WrapObject(JSContext* aCx)
+AnimationTimeline::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AnimationTimelineBinding::Wrap(aCx, this);
+  return AnimationTimelineBinding::Wrap(aCx, this, aGivenProto);
 }
 
 Nullable<TimeDuration>
 AnimationTimeline::GetCurrentTime() const
 {
   return ToTimelineTime(GetCurrentTimeStamp());
 }
 
--- a/dom/animation/AnimationTimeline.h
+++ b/dom/animation/AnimationTimeline.h
@@ -36,17 +36,17 @@ protected:
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationTimeline)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationTimeline)
 
   nsIGlobalObject* GetParentObject() const
   {
     return mWindow;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // AnimationTimeline methods
   Nullable<TimeDuration> GetCurrentTime() const;
 
   // Wrapper functions for AnimationTimeline DOM methods when called from
   // script.
   Nullable<double> GetCurrentTimeAsDouble() const;
 
--- a/dom/archivereader/ArchiveReader.cpp
+++ b/dom/archivereader/ArchiveReader.cpp
@@ -56,19 +56,19 @@ ArchiveReader::ArchiveReader(File& aBlob
   MOZ_ASSERT(aWindow);
 }
 
 ArchiveReader::~ArchiveReader()
 {
 }
 
 /* virtual */ JSObject*
-ArchiveReader::WrapObject(JSContext* aCx)
+ArchiveReader::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ArchiveReaderBinding::Wrap(aCx, this);
+  return ArchiveReaderBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 ArchiveReader::RegisterRequest(ArchiveRequest* aRequest)
 {
   switch (mStatus) {
     // Append to the list and let's start to work:
     case NOT_STARTED:
--- a/dom/archivereader/ArchiveReader.h
+++ b/dom/archivereader/ArchiveReader.h
@@ -46,17 +46,17 @@ public:
   ArchiveReader(File& aBlob, nsPIDOMWindow* aWindow,
                 const nsACString& aEncoding);
 
   nsIDOMWindow* GetParentObject() const
   {
     return mWindow;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   already_AddRefed<ArchiveRequest> GetFilenames();
   already_AddRefed<ArchiveRequest> GetFile(const nsAString& filename);
   already_AddRefed<ArchiveRequest> GetFiles();
 
   nsresult GetInputStream(nsIInputStream** aInputStream);
   nsresult GetSize(uint64_t* aSize);
 
--- a/dom/archivereader/ArchiveRequest.cpp
+++ b/dom/archivereader/ArchiveRequest.cpp
@@ -72,19 +72,19 @@ nsresult
 ArchiveRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
   aVisitor.mParentTarget = nullptr;
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-ArchiveRequest::WrapObject(JSContext* aCx)
+ArchiveRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ArchiveRequestBinding::Wrap(aCx, this);
+  return ArchiveRequestBinding::Wrap(aCx, this, aGivenProto);
 }
 
 ArchiveReader*
 ArchiveRequest::Reader() const
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return mArchiveReader;
--- a/dom/archivereader/ArchiveRequest.h
+++ b/dom/archivereader/ArchiveRequest.h
@@ -21,17 +21,17 @@ BEGIN_ARCHIVEREADER_NAMESPACE
 
 /**
  * This is the ArchiveRequest that handles any operation
  * related to ArchiveReader
  */
 class ArchiveRequest : public mozilla::dom::DOMRequest
 {
 public:
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   ArchiveReader* Reader() const;
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ArchiveRequest, DOMRequest)
 
   ArchiveRequest(nsPIDOMWindow* aWindow,
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -126,15 +126,16 @@ AnonymousContent::GetElementById(const n
       return kid->AsElement();
     }
   }
   return nullptr;
 }
 
 bool
 AnonymousContent::WrapObject(JSContext* aCx,
+                             JS::Handle<JSObject*> aGivenProto,
                              JS::MutableHandle<JSObject*> aReflector)
 {
-  return AnonymousContentBinding::Wrap(aCx, this, aReflector);
+  return AnonymousContentBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/base/AnonymousContent.h
+++ b/dom/base/AnonymousContent.h
@@ -22,17 +22,17 @@ class AnonymousContent MOZ_FINAL
 public:
   // Ref counting and cycle collection
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnonymousContent)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnonymousContent)
 
   explicit AnonymousContent(Element* aContentNode);
   nsCOMPtr<Element> GetContentNode();
   void SetContentNode(Element* aContentNode);
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
   // WebIDL methods
   void SetTextContentForElement(const nsAString& aElementId,
                                 const nsAString& aText,
                                 ErrorResult& aRv);
 
   void GetTextContentForElement(const nsAString& aElementId,
                                 DOMString& aText,
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -379,15 +379,15 @@ Attr::Initialize()
 
 void
 Attr::Shutdown()
 {
   sInitialized = false;
 }
 
 JSObject*
-Attr::WrapNode(JSContext* aCx)
+Attr::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AttrBinding::Wrap(aCx, this);
+  return AttrBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Attr.h
+++ b/dom/base/Attr.h
@@ -77,17 +77,17 @@ public:
   static void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Attr,
                                                                    nsIAttribute)
 
   virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // WebIDL
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // XPCOM GetName() is OK
   // XPCOM GetValue() is OK
 
   void SetValue(const nsAString& aValue, ErrorResult& aRv);
 
   bool Specified() const;
 
--- a/dom/base/BarProps.cpp
+++ b/dom/base/BarProps.cpp
@@ -29,19 +29,19 @@ BarProp::~BarProp()
 
 nsPIDOMWindow*
 BarProp::GetParentObject() const
 {
   return mDOMWindow;
 }
 
 JSObject*
-BarProp::WrapObject(JSContext* aCx)
+BarProp::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BarPropBinding::Wrap(aCx, this);
+  return BarPropBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BarProp, mDOMWindow)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(BarProp)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(BarProp)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BarProp)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
--- a/dom/base/BarProps.h
+++ b/dom/base/BarProps.h
@@ -35,17 +35,17 @@ public:
   explicit BarProp(nsGlobalWindow *aWindow);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BarProp)
 
   nsPIDOMWindow* GetParentObject() const;
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual bool GetVisible(ErrorResult& aRv) = 0;
   virtual void SetVisible(bool aVisible, ErrorResult& aRv) = 0;
 
 protected:
   virtual ~BarProp();
 
   bool GetVisibleByFlag(uint32_t aChromeFlag, ErrorResult& aRv);
--- a/dom/base/Comment.cpp
+++ b/dom/base/Comment.cpp
@@ -69,15 +69,15 @@ Comment::Constructor(const GlobalObject&
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   return window->GetDoc()->CreateComment(aData);
 }
 
 JSObject*
-Comment::WrapNode(JSContext *aCx)
+Comment::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CommentBinding::Wrap(aCx, this);
+  return CommentBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Comment.h
+++ b/dom/base/Comment.h
@@ -67,15 +67,15 @@ public:
   }
 #endif
 
   static already_AddRefed<Comment>
   Constructor(const GlobalObject& aGlobal, const nsAString& aData,
               ErrorResult& aRv);
 
 protected:
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_Comment_h
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -717,19 +717,19 @@ Console::Observe(nsISupports* aSubject, 
 
     mTimerRegistry.Clear();
   }
 
   return NS_OK;
 }
 
 JSObject*
-Console::WrapObject(JSContext* aCx)
+Console::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ConsoleBinding::Wrap(aCx, this);
+  return ConsoleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define METHOD(name, string)                                          \
   void                                                                \
   Console::name(JSContext* aCx, const Sequence<JS::Value>& aData)     \
   {                                                                   \
     Method(aCx, Method##name, NS_LITERAL_STRING(string), aData);      \
   }
--- a/dom/base/Console.h
+++ b/dom/base/Console.h
@@ -39,17 +39,17 @@ public:
 
   // WebIDL methods
   nsISupports* GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void
   Log(JSContext* aCx, const Sequence<JS::Value>& aData);
 
   void
   Info(JSContext* aCx, const Sequence<JS::Value>& aData);
 
   void
--- a/dom/base/Crypto.cpp
+++ b/dom/base/Crypto.cpp
@@ -41,19 +41,19 @@ Crypto::~Crypto()
 void
 Crypto::Init(nsIGlobalObject* aParent)
 {
   mParent = do_QueryInterface(aParent);
   MOZ_ASSERT(mParent);
 }
 
 /* virtual */ JSObject*
-Crypto::WrapObject(JSContext* aCx)
+Crypto::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CryptoBinding::Wrap(aCx, this);
+  return CryptoBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
                         JS::MutableHandle<JSObject*> aRetval,
                         ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Called on the wrong thread");
--- a/dom/base/Crypto.h
+++ b/dom/base/Crypto.h
@@ -45,17 +45,17 @@ public:
 
   nsIGlobalObject*
   GetParentObject() const
   {
     return mParent;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static uint8_t*
   GetRandomValues(uint32_t aLength);
 
 private:
   nsCOMPtr<nsIGlobalObject> mParent;
   nsRefPtr<SubtleCrypto> mSubtle;
 };
--- a/dom/base/DOMCursor.cpp
+++ b/dom/base/DOMCursor.cpp
@@ -71,15 +71,15 @@ DOMCursor::Continue(ErrorResult& aRv)
     return;
   }
 
   Reset();
   mCallback->HandleContinue();
 }
 
 /* virtual */ JSObject*
-DOMCursor::WrapObject(JSContext* aCx)
+DOMCursor::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMCursorBinding::Wrap(aCx, this);
+  return DOMCursorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/DOMCursor.h
+++ b/dom/base/DOMCursor.h
@@ -22,17 +22,17 @@ class DOMCursor : public DOMRequest
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMCURSOR
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMCursor,
                                            DOMRequest)
 
   DOMCursor(nsPIDOMWindow* aWindow, nsICursorContinueCallback *aCallback);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   bool Done() const
   {
     return mFinished;
   }
   virtual void Continue(ErrorResult& aRv);
 
   void Reset();
--- a/dom/base/DOMError.cpp
+++ b/dom/base/DOMError.cpp
@@ -50,19 +50,19 @@ DOMError::DOMError(nsPIDOMWindow* aWindo
 {
 }
 
 DOMError::~DOMError()
 {
 }
 
 JSObject*
-DOMError::WrapObject(JSContext* aCx)
+DOMError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMErrorBinding::Wrap(aCx, this);
+  return DOMErrorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<DOMError>
 DOMError::Constructor(const GlobalObject& aGlobal,
                       const nsAString& aName, const nsAString& aMessage,
                       ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
--- a/dom/base/DOMError.h
+++ b/dom/base/DOMError.h
@@ -54,17 +54,17 @@ public:
            const nsAString& aMessage);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<DOMError>
   Constructor(const GlobalObject& global, const nsAString& name,
               const nsAString& message, ErrorResult& aRv);
 
   void GetName(nsString& aRetval) const
   {
     aRetval = mName;
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -485,19 +485,19 @@ Exception::Initialize(const nsACString& 
   mData = aData;
   mInner = aInner;
 
   mInitialized = true;
   return NS_OK;
 }
 
 JSObject*
-Exception::WrapObject(JSContext* cx)
+Exception::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ExceptionBinding::Wrap(cx, this);
+  return ExceptionBinding::Wrap(cx, this, aGivenProto);
 }
 
 void
 Exception::GetMessageMoz(nsString& retval)
 {
   nsCString str;
 #ifdef DEBUG
   DebugOnly<nsresult> rv =
@@ -701,19 +701,19 @@ DOMException::Constructor(GlobalObject& 
     new DOMException(exceptionResult,
                      NS_ConvertUTF16toUTF8(aMessage),
                      name,
                      exceptionCode);
   return retval.forget();
 }
 
 JSObject*
-DOMException::WrapObject(JSContext* aCx)
+DOMException::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMExceptionBinding::Wrap(aCx, this);
+  return DOMExceptionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */already_AddRefed<DOMException>
 DOMException::Create(nsresult aRv)
 {
   nsCString name;
   nsCString message;
   uint16_t code;
--- a/dom/base/DOMException.h
+++ b/dom/base/DOMException.h
@@ -58,17 +58,17 @@ public:
   NS_DECL_NSIXPCEXCEPTION
 
   // Cruft used by XPConnect for exceptions originating in JS implemented
   // components.
   bool StealJSVal(JS::Value* aVp);
   void StowJSVal(JS::Value& aVp);
 
   // WebIDL API
-  virtual JSObject* WrapObject(JSContext* cx)
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE;
 
   nsISupports* GetParentObject() const { return nullptr; }
 
   void GetMessageMoz(nsString& retval);
 
   uint32_t Result() const;
 
@@ -131,17 +131,17 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMEXCEPTION
 
   // nsIException overrides
   NS_IMETHOD ToString(nsACString& aReturn) MOZ_OVERRIDE;
 
   // nsWrapperCache overrides
-  virtual JSObject* WrapObject(JSContext* aCx)
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE;
 
   static already_AddRefed<DOMException>
   Constructor(GlobalObject& /* unused */,
               const nsAString& aMessage,
               const Optional<nsAString>& aName,
               ErrorResult& aError);
 
--- a/dom/base/DOMImplementation.cpp
+++ b/dom/base/DOMImplementation.cpp
@@ -24,19 +24,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMImplementation, mOwner)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMImplementation)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMImplementation)
 
 JSObject*
-DOMImplementation::WrapObject(JSContext* aCx)
+DOMImplementation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMImplementationBinding::Wrap(aCx, this);
+  return DOMImplementationBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 DOMImplementation::HasFeature(const nsAString& aFeature,
                               const nsAString& aVersion)
 {
   return nsContentUtils::InternalIsSupported(
            static_cast<nsIDOMDOMImplementation*>(this),
--- a/dom/base/DOMImplementation.h
+++ b/dom/base/DOMImplementation.h
@@ -47,17 +47,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMImplementation)
 
   nsIDocument* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIDOMDOMImplementation
   NS_DECL_NSIDOMDOMIMPLEMENTATION
 
   bool HasFeature(const nsAString& aFeature, const nsAString& aVersion);
 
   already_AddRefed<DocumentType>
   CreateDocumentType(const nsAString& aQualifiedName,
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -653,15 +653,15 @@ DOMMatrix::SetMatrixValue(const nsAStrin
     SetE(result._31);
     SetF(result._32);
   }
 
   return this;
 }
 
 JSObject*
-DOMMatrix::WrapObject(JSContext* aCx)
+DOMMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMMatrixBinding::Wrap(aCx, this);
+  return DOMMatrixBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/DOMMatrix.h
+++ b/dom/base/DOMMatrix.h
@@ -161,17 +161,17 @@ public:
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Sequence<double>& aNumberSequence, ErrorResult& aRv);
 
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #define Set2DMatrixMember(entry2D, entry3D) \
 { \
   if (mMatrix3D) { \
     mMatrix3D->entry3D = v; \
   } else { \
     mMatrix2D->entry2D = v; \
   } \
--- a/dom/base/DOMParser.h
+++ b/dom/base/DOMParser.h
@@ -70,19 +70,19 @@ public:
   void Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI,
             nsIURI* aBaseURI, mozilla::ErrorResult& rv);
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::DOMParserBinding::Wrap(aCx, this);
+    return mozilla::dom::DOMParserBinding::Wrap(aCx, this, aGivenProto);
   }
 
 private:
   explicit DOMParser(nsISupports* aOwner) : mOwner(aOwner), mAttemptedInit(false)
   {
     MOZ_ASSERT(aOwner);
   }
 
--- a/dom/base/DOMPoint.cpp
+++ b/dom/base/DOMPoint.cpp
@@ -32,12 +32,12 @@ DOMPoint::Constructor(const GlobalObject
                       double aZ, double aW, ErrorResult& aRV)
 {
   nsRefPtr<DOMPoint> obj =
     new DOMPoint(aGlobal.GetAsSupports(), aX, aY, aZ, aW);
   return obj.forget();
 }
 
 JSObject*
-DOMPoint::WrapObject(JSContext* aCx)
+DOMPoint::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMPointBinding::Wrap(aCx, this);
+  return DOMPointBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/DOMPoint.h
+++ b/dom/base/DOMPoint.h
@@ -59,17 +59,17 @@ public:
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
               ErrorResult& aRV);
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, double aX, double aY,
               double aZ, double aW, ErrorResult& aRV);
 
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void SetX(double aX) { mX = aX; }
   void SetY(double aY) { mY = aY; }
   void SetZ(double aZ) { mZ = aZ; }
   void SetW(double aW) { mW = aW; }
 };
 
 }
--- a/dom/base/DOMQuad.cpp
+++ b/dom/base/DOMQuad.cpp
@@ -33,19 +33,19 @@ DOMQuad::DOMQuad(nsISupports* aParent)
 {
 }
 
 DOMQuad::~DOMQuad()
 {
 }
 
 JSObject*
-DOMQuad::WrapObject(JSContext* aCx)
+DOMQuad::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMQuadBinding::Wrap(aCx, this);
+  return DOMQuadBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DOMQuad>
 DOMQuad::Constructor(const GlobalObject& aGlobal,
                      const DOMPointInit& aP1,
                      const DOMPointInit& aP2,
                      const DOMPointInit& aP3,
                      const DOMPointInit& aP4,
--- a/dom/base/DOMQuad.h
+++ b/dom/base/DOMQuad.h
@@ -30,17 +30,17 @@ class DOMQuad MOZ_FINAL : public nsWrapp
 public:
   DOMQuad(nsISupports* aParent, CSSPoint aPoints[4]);
   explicit DOMQuad(nsISupports* aParent);
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMQuad)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMQuad)
 
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<DOMQuad>
   Constructor(const GlobalObject& aGlobal,
               const DOMPointInit& aP1,
               const DOMPointInit& aP2,
               const DOMPointInit& aP3,
               const DOMPointInit& aP4,
               ErrorResult& aRV);
--- a/dom/base/DOMRect.cpp
+++ b/dom/base/DOMRect.cpp
@@ -16,20 +16,20 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DO
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectReadOnly)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectReadOnly)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRectReadOnly)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-DOMRectReadOnly::WrapObject(JSContext* aCx)
+DOMRectReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   MOZ_ASSERT(mParent);
-  return DOMRectReadOnlyBinding::Wrap(aCx, this);
+  return DOMRectReadOnlyBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // -----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS_INHERITED(DOMRect, DOMRectReadOnly, nsIDOMClientRect)
 
 #define FORWARD_GETTER(_name)                                                   \
   NS_IMETHODIMP                                                                 \
@@ -42,20 +42,20 @@ NS_IMPL_ISUPPORTS_INHERITED(DOMRect, DOM
 FORWARD_GETTER(Left)
 FORWARD_GETTER(Top)
 FORWARD_GETTER(Right)
 FORWARD_GETTER(Bottom)
 FORWARD_GETTER(Width)
 FORWARD_GETTER(Height)
 
 JSObject*
-DOMRect::WrapObject(JSContext* aCx)
+DOMRect::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   MOZ_ASSERT(mParent);
-  return DOMRectBinding::Wrap(aCx, this);
+  return DOMRectBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DOMRect>
 DOMRect::Constructor(const GlobalObject& aGlobal, ErrorResult& aRV)
 {
   nsRefPtr<DOMRect> obj =
     new DOMRect(aGlobal.GetAsSupports(), 0.0, 0.0, 0.0, 0.0);
   return obj.forget();
@@ -94,19 +94,19 @@ DOMRectList::GetLength(uint32_t* aLength
 NS_IMETHODIMP    
 DOMRectList::Item(uint32_t aIndex, nsIDOMClientRect** aReturn)
 {
   NS_IF_ADDREF(*aReturn = Item(aIndex));
   return NS_OK;
 }
 
 JSObject*
-DOMRectList::WrapObject(JSContext *cx)
+DOMRectList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::DOMRectListBinding::Wrap(cx, this);
+  return mozilla::dom::DOMRectListBinding::Wrap(cx, this, aGivenProto);
 }
 
 static double
 RoundFloat(double aValue)
 {
   return floor(aValue + 0.5);
 }
 
--- a/dom/base/DOMRect.h
+++ b/dom/base/DOMRect.h
@@ -38,17 +38,17 @@ public:
   {
   }
 
   nsISupports* GetParentObject() const
   {
     MOZ_ASSERT(mParent);
     return mParent;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual double X() const = 0;
   virtual double Y() const = 0;
   virtual double Width() const = 0;
   virtual double Height() const = 0;
 
   double Left() const
   {
@@ -93,17 +93,17 @@ public:
   NS_DECL_NSIDOMCLIENTRECT
 
   static already_AddRefed<DOMRect>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRV);
   static already_AddRefed<DOMRect>
   Constructor(const GlobalObject& aGlobal, double aX, double aY,
               double aWidth, double aHeight, ErrorResult& aRV);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void SetRect(float aX, float aY, float aWidth, float aHeight) {
     mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight;
   }
   void SetLayoutRect(const nsRect& aLayoutRect);
 
   virtual double X() const MOZ_OVERRIDE
   {
@@ -156,17 +156,17 @@ public:
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectList)
 
   NS_DECL_NSIDOMCLIENTRECTLIST
   
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Append(DOMRect* aElement) { mArray.AppendElement(aElement); }
 
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -61,19 +61,19 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMRequest)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMRequest)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(DOMRequest, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(DOMRequest, DOMEventTargetHelper)
 
 /* virtual */ JSObject*
-DOMRequest::WrapObject(JSContext* aCx)
+DOMRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMRequestBinding::Wrap(aCx, this);
+  return DOMRequestBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_EVENT_HANDLER(DOMRequest, success)
 NS_IMPL_EVENT_HANDLER(DOMRequest, error)
 
 NS_IMETHODIMP
 DOMRequest::GetReadyState(nsAString& aReadyState)
 {
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -42,17 +42,17 @@ public:
                                                          DOMEventTargetHelper)
 
   // WrapperCache
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL Interface
   DOMRequestReadyState ReadyState() const
   {
     return mDone ? DOMRequestReadyState::Done
                  : DOMRequestReadyState::Pending;
   }
 
--- a/dom/base/DOMStringList.cpp
+++ b/dom/base/DOMStringList.cpp
@@ -19,15 +19,15 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 DOMStringList::~DOMStringList()
 {
 }
 
 JSObject*
-DOMStringList::WrapObject(JSContext* aCx)
+DOMStringList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMStringListBinding::Wrap(aCx, this);
+  return DOMStringListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/DOMStringList.h
+++ b/dom/base/DOMStringList.h
@@ -19,17 +19,17 @@ class DOMStringList : public nsISupports
 {
 protected:
   virtual ~DOMStringList();
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMStringList)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return nullptr;
   }
 
   void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult)
   {
     EnsureFresh();
--- a/dom/base/DocumentFragment.cpp
+++ b/dom/base/DocumentFragment.cpp
@@ -19,19 +19,19 @@
 #include "nsPIDOMWindow.h"
 #include "nsIDocument.h"
 #include "mozilla/IntegerPrintfMacros.h"
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
-DocumentFragment::WrapNode(JSContext *aCx)
+DocumentFragment::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DocumentFragmentBinding::Wrap(aCx, this);
+  return DocumentFragmentBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 DocumentFragment::IsNodeOfType(uint32_t aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eDOCUMENT_FRAGMENT));
 }
 
--- a/dom/base/DocumentFragment.h
+++ b/dom/base/DocumentFragment.h
@@ -60,17 +60,17 @@ public:
                                             nsGkAtoms::documentFragmentNodeName,
                                             nullptr, kNameSpaceID_None,
                                             nsIDOMNode::DOCUMENT_FRAGMENT_NODE)),
       mHost(nullptr)
   {
     Init();
   }
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIContent
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
--- a/dom/base/DocumentType.cpp
+++ b/dom/base/DocumentType.cpp
@@ -55,19 +55,19 @@ NS_NewDOMDocumentType(nsNodeInfoManager*
     new mozilla::dom::DocumentType(ni, aPublicId, aSystemId, aInternalSubset);
   return docType.forget();
 }
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
-DocumentType::WrapNode(JSContext *cx)
+DocumentType::WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DocumentTypeBinding::Wrap(cx, this);
+  return DocumentTypeBinding::Wrap(cx, this, aGivenProto);
 }
 
 DocumentType::DocumentType(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                            const nsAString& aPublicId,
                            const nsAString& aSystemId,
                            const nsAString& aInternalSubset) :
   DocumentTypeForward(aNodeInfo),
   mPublicId(aPublicId),
--- a/dom/base/DocumentType.h
+++ b/dom/base/DocumentType.h
@@ -72,17 +72,17 @@ public:
   virtual nsGenericDOMDataNode* CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
                                               bool aCloneText) const MOZ_OVERRIDE;
 
   virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
 protected:
   virtual ~DocumentType();
 
-  virtual JSObject* WrapNode(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsString mPublicId;
   nsString mSystemId;
   nsString mInternalSubset;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -401,19 +401,19 @@ Element::GetBindingURL(nsIDocument *aDoc
   NS_ENSURE_TRUE(sc, false);
 
   *aResult = sc->StyleDisplay()->mBinding;
 
   return true;
 }
 
 JSObject*
-Element::WrapObject(JSContext *aCx)
+Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx));
+  JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aGivenProto));
   if (!obj) {
     return nullptr;
   }
 
   // Custom element prototype swizzling.
   CustomElementData* data = GetCustomElementData();
   if (obj && data) {
     // If this is a registered custom element then fix the prototype.
@@ -1103,19 +1103,19 @@ DestinationInsertionPointList::GetLength
 
 int32_t
 DestinationInsertionPointList::IndexOf(nsIContent* aContent)
 {
   return mDestinationPoints.IndexOf(aContent);
 }
 
 JSObject*
-DestinationInsertionPointList::WrapObject(JSContext* aCx)
+DestinationInsertionPointList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(aCx, this);
+  return NodeListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DestinationInsertionPointList>
 Element::GetDestinationInsertionPoints()
 {
   nsRefPtr<DestinationInsertionPointList> list =
     new DestinationInsertionPointList(this);
   return list.forget();
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -955,17 +955,17 @@ public:
     GetElementsByTagNameNS(const nsAString& aNamespaceURI,
                            const nsAString& aLocalName,
                            nsIDOMHTMLCollection** aResult);
   nsresult
     GetElementsByClassName(const nsAString& aClassNames,
                            nsIDOMHTMLCollection** aResult);
   void GetClassList(nsISupports** aClassList);
 
-  virtual JSObject* WrapObject(JSContext *aCx) MOZ_FINAL MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_FINAL MOZ_OVERRIDE;
 
   nsINode* GetScopeChainParent() const MOZ_OVERRIDE;
 
   /**
    * Locate an nsIEditor rooted at this content node, if there is one.
    */
   nsIEditor* GetEditorInternal();
 
@@ -1310,17 +1310,17 @@ public:
   // nsIDOMNodeList
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList
   virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
   virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
   virtual nsINode* GetParentObject() MOZ_OVERRIDE { return mParent; }
   virtual uint32_t Length() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~DestinationInsertionPointList();
 
   nsRefPtr<Element> mParent;
   nsCOMArray<nsIContent> mDestinationPoints;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -260,19 +260,19 @@ EventSource::Init(nsISupports* aOwner,
   // url parameter, so we don't care about the InitChannelAndRequestEventSource
   // result.
   InitChannelAndRequestEventSource();
 
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-EventSource::WrapObject(JSContext* aCx)
+EventSource::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return EventSourceBinding::Wrap(aCx, this);
+  return EventSourceBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<EventSource>
 EventSource::Constructor(const GlobalObject& aGlobal,
                          const nsAString& aURL,
                          const EventSourceInit& aEventSourceInitDict,
                          ErrorResult& aRv)
 {
--- a/dom/base/EventSource.h
+++ b/dom/base/EventSource.h
@@ -53,17 +53,17 @@ public:
 
   NS_DECL_NSIOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
     return GetOwner();
   }
   static already_AddRefed<EventSource>
--- a/dom/base/File.cpp
+++ b/dom/base/File.cpp
@@ -554,20 +554,20 @@ File::SetMutable(bool aMutable)
 
 NS_IMETHODIMP_(bool)
 File::IsMemoryFile()
 {
   return mImpl->IsMemoryFile();
 }
 
 JSObject*
-File::WrapObject(JSContext* aCx)
+File::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return IsFile() ? FileBinding::Wrap(aCx, this)
-                  : BlobBinding::Wrap(aCx, this);
+  return IsFile() ? FileBinding::Wrap(aCx, this, aGivenProto)
+                  : BlobBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<File>
 File::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<MultipartFileImpl> impl = new MultipartFileImpl();
 
   impl->InitializeBlob();
@@ -1230,19 +1230,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
   NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(FileList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(FileList)
 
 JSObject*
-FileList::WrapObject(JSContext *cx)
+FileList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::FileListBinding::Wrap(cx, this);
+  return mozilla::dom::FileListBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 FileList::GetLength(uint32_t* aLength)
 {
   *aLength = Length();
 
   return NS_OK;
--- a/dom/base/File.h
+++ b/dom/base/File.h
@@ -184,17 +184,17 @@ public:
 
   // File constructor - ChromeOnly
   static already_AddRefed<File>
   Constructor(const GlobalObject& aGlobal,
               nsIFile* aData,
               const ChromeFilePropertyBag& aBag,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint64_t GetSize(ErrorResult& aRv);
 
   // XPCOM GetType is OK
 
   // XPCOM GetName is OK
 
   int64_t GetLastModified(ErrorResult& aRv);
@@ -823,17 +823,17 @@ public:
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FileList)
 
   NS_DECL_NSIDOMFILELIST
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Disconnect()
   {
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -396,19 +396,19 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_E
 
 NS_INTERFACE_TABLE_HEAD(nsChildContentList)
   NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
   NS_INTERFACE_TABLE(nsChildContentList, nsINodeList, nsIDOMNodeList)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsChildContentList)
 NS_INTERFACE_MAP_END
 
 JSObject*
-nsChildContentList::WrapObject(JSContext *cx)
+nsChildContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(cx, this);
+  return NodeListBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 nsChildContentList::GetLength(uint32_t* aLength)
 {
   *aLength = mNode ? mNode->GetChildCount() : 0;
 
   return NS_OK;
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -51,17 +51,17 @@ public:
     : mNode(aNode)
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIDOMNodeList interface
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList interface
   virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
   virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
 
--- a/dom/base/MessageChannel.cpp
+++ b/dom/base/MessageChannel.cpp
@@ -76,19 +76,19 @@ MessageChannel::MessageChannel(nsPIDOMWi
 }
 
 MessageChannel::~MessageChannel()
 {
   MOZ_COUNT_DTOR(MessageChannel);
 }
 
 JSObject*
-MessageChannel::WrapObject(JSContext* aCx)
+MessageChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MessageChannelBinding::Wrap(aCx, this);
+  return MessageChannelBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<MessageChannel>
 MessageChannel::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
   if (!window) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
--- a/dom/base/MessageChannel.h
+++ b/dom/base/MessageChannel.h
@@ -35,17 +35,17 @@ public:
 
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<MessageChannel>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
   MessagePort*
   Port1() const
   {
     return mPort1;
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -218,17 +218,17 @@ PostMessageReadTransferStructuredClone(J
   StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(aClosure);
   NS_ASSERTION(scInfo, "Must have scInfo!");
 
   if (tag == SCTAG_DOM_MAP_MESSAGEPORT) {
     MessagePort* port = static_cast<MessagePort*>(data);
     port->BindToOwner(scInfo->mPort->GetOwner());
     scInfo->mPorts.Put(port, nullptr);
 
-    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx));
+    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx, JS::NullPtr()));
     if (!obj || !JS_WrapObject(aCx, &obj)) {
       return false;
     }
 
     MOZ_ASSERT(port->GetOwner() == scInfo->mPort->GetOwner());
     returnObject.set(obj);
     return true;
   }
@@ -409,19 +409,19 @@ MessagePort::MessagePort(nsPIDOMWindow* 
 }
 
 MessagePort::~MessagePort()
 {
   Close();
 }
 
 JSObject*
-MessagePort::WrapObject(JSContext* aCx)
+MessagePort::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MessagePortBinding::Wrap(aCx, this);
+  return MessagePortBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 MessagePort::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                             const Optional<Sequence<JS::Value>>& aTransferable,
                             ErrorResult& aRv)
 {
   nsRefPtr<PostMessageRunnable> event = new PostMessageRunnable();
--- a/dom/base/MessagePort.h
+++ b/dom/base/MessagePort.h
@@ -59,17 +59,17 @@ class MessagePort MOZ_FINAL : public Mes
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessagePort,
                                            DOMEventTargetHelper)
 
   explicit MessagePort(nsPIDOMWindow* aWindow);
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void
   PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                  const Optional<Sequence<JS::Value>>& aTransferable,
                  ErrorResult& aRv) MOZ_OVERRIDE;
 
   virtual void
   Start() MOZ_OVERRIDE;
--- a/dom/base/MessagePortList.cpp
+++ b/dom/base/MessagePortList.cpp
@@ -15,15 +15,15 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Me
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MessagePortList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MessagePortList)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessagePortList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-MessagePortList::WrapObject(JSContext* aCx)
+MessagePortList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MessagePortListBinding::Wrap(aCx, this);
+  return MessagePortListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/MessagePortList.h
+++ b/dom/base/MessagePortList.h
@@ -36,17 +36,17 @@ public:
 
   nsISupports*
   GetParentObject() const
   {
     return mOwner;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t
   Length() const
   {
     return mPorts.Length();
   }
 
   MessagePortBase*
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -2229,19 +2229,19 @@ Navigator::GetOwnPropertyNames(JSContext
     return;
   }
 
   NavigatorNameEnumeratorClosure closure(aCx, GetWrapper(), aNames);
   nameSpaceManager->EnumerateNavigatorNames(SaveNavigatorName, &closure);
 }
 
 JSObject*
-Navigator::WrapObject(JSContext* cx)
+Navigator::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NavigatorBinding::Wrap(cx, this);
+  return NavigatorBinding::Wrap(cx, this, aGivenProto);
 }
 
 /* static */
 bool
 Navigator::HasWakeLockSupport(JSContext* /* unused*/, JSObject* /*unused */)
 {
   nsCOMPtr<nsIPowerManagerService> pmService =
     do_GetService(POWERMANAGERSERVICE_CONTRACTID);
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -319,17 +319,17 @@ public:
 
   static bool IsE10sEnabled(JSContext* aCx, JSObject* aGlobal);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetWindow();
   }
 
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // GetWindowFromGlobal returns the inner window for this global, if
   // any, else null.
   static already_AddRefed<nsPIDOMWindow> GetWindowFromGlobal(JSObject* aGlobal);
 
 #ifdef MOZ_EME
   already_AddRefed<Promise>
   RequestMediaKeySystemAccess(const nsAString& aKeySystem,
--- a/dom/base/NodeIterator.cpp
+++ b/dom/base/NodeIterator.cpp
@@ -284,15 +284,15 @@ void NodeIterator::ContentRemoved(nsIDoc
 {
     nsINode *container = NODE_FROM(aContainer, aDocument);
 
     mPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
     mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
 }
 
 bool
-NodeIterator::WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector)
+NodeIterator::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-    return NodeIteratorBinding::Wrap(cx, this, aReflector);
+    return NodeIteratorBinding::Wrap(cx, this, aGivenProto, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/NodeIterator.h
+++ b/dom/base/NodeIterator.h
@@ -64,17 +64,17 @@ public:
         return NextOrPrevNode(&NodePointer::MoveToNext, aResult);
     }
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult)
     {
         return NextOrPrevNode(&NodePointer::MoveToPrevious, aResult);
     }
     // The XPCOM Detach() is fine for our purposes
 
-    bool WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector);
+    bool WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
 private:
     virtual ~NodeIterator();
 
     struct NodePointer {
         NodePointer() : mNode(nullptr) {}
         NodePointer(nsINode *aNode, bool aBeforeNode);
 
--- a/dom/base/PerformanceEntry.cpp
+++ b/dom/base/PerformanceEntry.cpp
@@ -29,12 +29,12 @@ PerformanceEntry::PerformanceEntry(nsPer
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
 }
 
 PerformanceEntry::~PerformanceEntry()
 {
 }
 
 JSObject*
-PerformanceEntry::WrapObject(JSContext* aCx)
+PerformanceEntry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::PerformanceEntryBinding::Wrap(aCx, this);
+  return mozilla::dom::PerformanceEntryBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceEntry.h
+++ b/dom/base/PerformanceEntry.h
@@ -22,17 +22,17 @@ protected:
 public:
   PerformanceEntry(nsPerformance* aPerformance,
                    const nsAString& aName,
                    const nsAString& aEntryType);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PerformanceEntry)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsPerformance* GetParentObject() const
   {
     return mPerformance;
   }
 
   void GetName(nsAString& aName) const
   {
--- a/dom/base/PerformanceMark.cpp
+++ b/dom/base/PerformanceMark.cpp
@@ -16,12 +16,12 @@ PerformanceMark::PerformanceMark(nsPerfo
   mStartTime = aPerformance->GetDOMTiming()->TimeStampToDOMHighRes(mozilla::TimeStamp::Now());
 }
 
 PerformanceMark::~PerformanceMark()
 {
 }
 
 JSObject*
-PerformanceMark::WrapObject(JSContext* aCx)
+PerformanceMark::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceMarkBinding::Wrap(aCx, this);
+  return PerformanceMarkBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceMark.h
+++ b/dom/base/PerformanceMark.h
@@ -13,17 +13,17 @@ namespace dom {
 
 // http://www.w3.org/TR/user-timing/#performancemark
 class PerformanceMark MOZ_FINAL : public PerformanceEntry
 {
 public:
   PerformanceMark(nsPerformance* aPerformance,
                   const nsAString& aName);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual DOMHighResTimeStamp StartTime() const MOZ_OVERRIDE
   {
     return mStartTime;
   }
 
 protected:
   virtual ~PerformanceMark();
--- a/dom/base/PerformanceMeasure.cpp
+++ b/dom/base/PerformanceMeasure.cpp
@@ -19,12 +19,12 @@ PerformanceMeasure::PerformanceMeasure(n
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
 }
 
 PerformanceMeasure::~PerformanceMeasure()
 {
 }
 
 JSObject*
-PerformanceMeasure::WrapObject(JSContext* aCx)
+PerformanceMeasure::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceMeasureBinding::Wrap(aCx, this);
+  return PerformanceMeasureBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceMeasure.h
+++ b/dom/base/PerformanceMeasure.h
@@ -15,17 +15,17 @@ namespace dom {
 class PerformanceMeasure MOZ_FINAL : public PerformanceEntry
 {
 public:
   PerformanceMeasure(nsPerformance* aPerformance,
                      const nsAString& aName,
                      DOMHighResTimeStamp aStartTime,
                      DOMHighResTimeStamp aEndTime);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual DOMHighResTimeStamp StartTime() const MOZ_OVERRIDE
   {
     return mStartTime;
   }
 
   virtual DOMHighResTimeStamp Duration() const MOZ_OVERRIDE
   {
--- a/dom/base/PerformanceResourceTiming.cpp
+++ b/dom/base/PerformanceResourceTiming.cpp
@@ -38,12 +38,12 @@ PerformanceResourceTiming::~PerformanceR
 DOMHighResTimeStamp
 PerformanceResourceTiming::StartTime() const
 {
   DOMHighResTimeStamp startTime = mTiming->RedirectStartHighRes();
   return startTime ? startTime : mTiming->FetchStartHighRes();
 }
 
 JSObject*
-PerformanceResourceTiming::WrapObject(JSContext* aCx)
+PerformanceResourceTiming::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceResourceTimingBinding::Wrap(aCx, this);
+  return PerformanceResourceTimingBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceResourceTiming.h
+++ b/dom/base/PerformanceResourceTiming.h
@@ -26,17 +26,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
       PerformanceResourceTiming,
       PerformanceEntry)
 
   PerformanceResourceTiming(nsPerformanceTiming* aPerformanceTiming,
                             nsPerformance* aPerformance,
                             const nsAString& aName);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 
   virtual DOMHighResTimeStamp StartTime() const MOZ_OVERRIDE;
 
   virtual DOMHighResTimeStamp Duration() const MOZ_OVERRIDE
   {
     return ResponseEnd() - StartTime();
   }
--- a/dom/base/ProcessGlobal.h
+++ b/dom/base/ProcessGlobal.h
@@ -53,17 +53,17 @@ public:
     if (!mGlobal) {
       return nullptr;
     }
 
     return mGlobal->GetJSObject();
   }
   virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE { return mPrincipal; }
 
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
     MOZ_CRASH("ProcessGlobal doesn't use DOM bindings!");
   }
 
 protected:
   virtual ~ProcessGlobal();
 
 private:
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -99,19 +99,19 @@ ShadowRoot::~ShadowRoot()
 
   // nsINode destructor expects mSubtreeRoot == this.
   SetSubtreeRootPointer(this);
 
   SetHost(nullptr);
 }
 
 JSObject*
-ShadowRoot::WrapObject(JSContext* aCx)
+ShadowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::ShadowRootBinding::Wrap(aCx, this);
+  return mozilla::dom::ShadowRootBinding::Wrap(aCx, this, aGivenProto);
 }
 
 ShadowRoot*
 ShadowRoot::FromNode(nsINode* aNode)
 {
   if (aNode->IsInShadowTree() && !aNode->GetParentNode()) {
     MOZ_ASSERT(aNode->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
                "ShadowRoot is a document fragment.");
--- a/dom/base/ShadowRoot.h
+++ b/dom/base/ShadowRoot.h
@@ -98,17 +98,17 @@ public:
 
   void SetAssociatedBinding(nsXBLBinding* aBinding) { mAssociatedBinding = aBinding; }
 
   nsISupports* GetParentObject() const { return mPoolHost; }
 
   nsIContent* GetPoolHost() { return mPoolHost; }
   nsTArray<HTMLShadowElement*>& ShadowDescendants() { return mShadowDescendants; }
 
-  JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static bool IsPooledNode(nsIContent* aChild, nsIContent* aContainer,
                            nsIContent* aHost);
   static ShadowRoot* FromNode(nsINode* aNode);
   static bool IsShadowInsertionPoint(nsIContent* aContent);
 
   static void RemoveDestInsertionPoint(nsIContent* aInsertionPoint,
                                        nsTArray<nsIContent*>& aDestInsertionPoints);
--- a/dom/base/StyleSheetList.cpp
+++ b/dom/base/StyleSheetList.cpp
@@ -18,19 +18,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsIDOMStyleSheetList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(StyleSheetList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(StyleSheetList)
 
 /* virtual */ JSObject*
-StyleSheetList::WrapObject(JSContext* aCx)
+StyleSheetList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return StyleSheetListBinding::Wrap(aCx, this);
+  return StyleSheetListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 StyleSheetList::GetLength(uint32_t* aLength)
 {
   *aLength = Length();
   return NS_OK;
 }
--- a/dom/base/StyleSheetList.h
+++ b/dom/base/StyleSheetList.h
@@ -19,17 +19,17 @@ namespace dom {
 class StyleSheetList : public nsIDOMStyleSheetList
                      , public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheetList)
   NS_DECL_NSIDOMSTYLESHEETLIST
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE MOZ_FINAL;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE MOZ_FINAL;
 
   virtual nsINode* GetParentObject() const = 0;
 
   virtual uint32_t Length() = 0;
   virtual CSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) = 0;
   CSSStyleSheet* Item(uint32_t aIndex)
   {
     bool dummy = false;
--- a/dom/base/SubtleCrypto.cpp
+++ b/dom/base/SubtleCrypto.cpp
@@ -24,19 +24,19 @@ NS_INTERFACE_MAP_END
 
 
 SubtleCrypto::SubtleCrypto(nsIGlobalObject* aParent)
   : mParent(aParent)
 {
 }
 
 JSObject*
-SubtleCrypto::WrapObject(JSContext* aCx)
+SubtleCrypto::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return SubtleCryptoBinding::Wrap(aCx, this);
+  return SubtleCryptoBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define SUBTLECRYPTO_METHOD_BODY(Operation, aRv, ...)                   \
   MOZ_ASSERT(mParent);                                                  \
   nsRefPtr<Promise> p = Promise::Create(mParent, aRv);                  \
   if (aRv.Failed()) {                                                   \
     return nullptr;                                                     \
   }                                                                     \
--- a/dom/base/SubtleCrypto.h
+++ b/dom/base/SubtleCrypto.h
@@ -33,17 +33,17 @@ public:
 public:
   explicit SubtleCrypto(nsIGlobalObject* aParent);
 
   nsIGlobalObject* GetParentObject() const
   {
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   already_AddRefed<Promise> Encrypt(JSContext* cx,
                                     const ObjectOrString& algorithm,
                                     CryptoKey& key,
                                     const CryptoOperationData& data,
                                     ErrorResult& aRv);
 
   already_AddRefed<Promise> Decrypt(JSContext* cx,
--- a/dom/base/TreeWalker.cpp
+++ b/dom/base/TreeWalker.cpp
@@ -446,15 +446,15 @@ TreeWalker::NextSiblingInternal(bool aRe
         }
         if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
             return nullptr;
         }
     }
 }
 
 bool
-TreeWalker::WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector)
+TreeWalker::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-    return TreeWalkerBinding::Wrap(aCx, this, aReflector);
+    return TreeWalkerBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/TreeWalker.h
+++ b/dom/base/TreeWalker.h
@@ -60,17 +60,17 @@ public:
     already_AddRefed<nsINode> ParentNode(ErrorResult& aResult);
     already_AddRefed<nsINode> FirstChild(ErrorResult& aResult);
     already_AddRefed<nsINode> LastChild(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> NextSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult);
     already_AddRefed<nsINode> NextNode(ErrorResult& aResult);
 
-    bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
+    bool WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
 private:
     nsCOMPtr<nsINode> mCurrentNode;
 
     /*
      * Implements FirstChild and LastChild which only vary in which direction
      * they search.
      * @param aReversed Controls whether we search forwards or backwards
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -42,19 +42,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 URL::URL(nsIURI* aURI)
   : mURI(aURI)
 {
 }
 
 bool
-URL::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-  return URLBinding::Wrap(aCx, this, aReflector);
+  return URLBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 /* static */ already_AddRefed<URL>
 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
                  URL& aBase, ErrorResult& aRv)
 {
   nsresult rv;
   nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -39,17 +39,17 @@ class URL MOZ_FINAL : public URLSearchPa
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(URL)
 
   explicit URL(nsIURI* aURI);
 
   // WebIDL methods
   bool
-  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               URL& aBase, ErrorResult& aRv);
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               const nsAString& aBase, ErrorResult& aRv);
 
--- a/dom/base/URLSearchParams.cpp
+++ b/dom/base/URLSearchParams.cpp
@@ -25,19 +25,19 @@ URLSearchParams::URLSearchParams()
 }
 
 URLSearchParams::~URLSearchParams()
 {
   DeleteAll();
 }
 
 JSObject*
-URLSearchParams::WrapObject(JSContext* aCx)
+URLSearchParams::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return URLSearchParamsBinding::Wrap(aCx, this);
+  return URLSearchParamsBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<URLSearchParams>
 URLSearchParams::Constructor(const GlobalObject& aGlobal,
                              const nsAString& aInit,
                              ErrorResult& aRv)
 {
   nsRefPtr<URLSearchParams> sp = new URLSearchParams();
--- a/dom/base/URLSearchParams.h
+++ b/dom/base/URLSearchParams.h
@@ -39,17 +39,17 @@ public:
 
   // WebIDL methods
   nsISupports* GetParentObject() const
   {
     return nullptr;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<URLSearchParams>
   Constructor(const GlobalObject& aGlobal, const nsAString& aInit,
               ErrorResult& aRv);
 
   static already_AddRefed<URLSearchParams>
   Constructor(const GlobalObject& aGlobal, URLSearchParams& aInit,
               ErrorResult& aRv);
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -904,19 +904,19 @@ WebSocket::WebSocket(nsPIDOMWindow* aOwn
   mIsMainThread = mImpl->mIsMainThread;
 }
 
 WebSocket::~WebSocket()
 {
 }
 
 JSObject*
-WebSocket::WrapObject(JSContext* cx)
+WebSocket::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return WebSocketBinding::Wrap(cx, this);
+  return WebSocketBinding::Wrap(cx, this, aGivenProto);
 }
 
 //---------------------------------------------------------------------------
 // WebIDL
 //---------------------------------------------------------------------------
 
 // Constructor:
 already_AddRefed<WebSocket>
--- a/dom/base/WebSocket.h
+++ b/dom/base/WebSocket.h
@@ -57,17 +57,17 @@ public:
   virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
   virtual void EventListenerRemoved(nsIAtom* aType) MOZ_OVERRIDE;
 
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   // nsWrapperCache
   nsPIDOMWindow* GetParentObject() { return GetOwner(); }
 
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 public: // static helpers:
 
   // Determine if preferences allow WebSocket
   static bool PrefEnabled(JSContext* aCx = nullptr, JSObject* aGlobal = nullptr);
 
 public: // WebIDL interface:
 
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -142,19 +142,19 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(nsSim
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsSimpleContentList)
 NS_INTERFACE_MAP_END_INHERITING(nsBaseContentList)
 
 
 NS_IMPL_ADDREF_INHERITED(nsSimpleContentList, nsBaseContentList)
 NS_IMPL_RELEASE_INHERITED(nsSimpleContentList, nsBaseContentList)
 
 JSObject*
-nsSimpleContentList::WrapObject(JSContext *cx)
+nsSimpleContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(cx, this);
+  return NodeListBinding::Wrap(cx, this, aGivenProto);
 }
 
 // Hashtable for storing nsContentLists
 static PLDHashTable gContentListHashTable;
 
 #define RECENTLY_USED_CONTENT_LIST_CACHE_SIZE 31
 static nsContentList*
   sRecentlyUsedContentLists[RECENTLY_USED_CONTENT_LIST_CACHE_SIZE] = {};
@@ -254,26 +254,26 @@ NS_GetContentList(nsINode* aRootNode,
 #ifdef DEBUG
 const nsCacheableFuncStringContentList::ContentListType
   nsCacheableFuncStringNodeList::sType = nsCacheableFuncStringContentList::eNodeList;
 const nsCacheableFuncStringContentList::ContentListType
   nsCacheableFuncStringHTMLCollection::sType = nsCacheableFuncStringContentList::eHTMLCollection;
 #endif
 
 JSObject*
-nsCacheableFuncStringNodeList::WrapObject(JSContext *cx)
+nsCacheableFuncStringNodeList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(cx, this);
+  return NodeListBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 JSObject*
-nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx)
+nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLCollectionBinding::Wrap(cx, this);
+  return HTMLCollectionBinding::Wrap(cx, this, aGivenProto);
 }
 
 // Hashtable for storing nsCacheableFuncStringContentList
 static PLDHashTable gFuncStringContentListHashTable;
 
 struct FuncStringContentListHashEntry : public PLDHashEntryHdr
 {
   nsCacheableFuncStringContentList* mContentList;
@@ -464,19 +464,19 @@ nsContentList::~nsContentList()
 
   if (mDestroyFunc) {
     // Clean up mData
     (*mDestroyFunc)(mData);
   }
 }
 
 JSObject*
-nsContentList::WrapObject(JSContext *cx)
+nsContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLCollectionBinding::Wrap(cx, this);
+  return HTMLCollectionBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsContentList, nsBaseContentList,
                             nsIHTMLCollection, nsIDOMHTMLCollection,
                             nsIMutationObserver)
 
 uint32_t
 nsContentList::Length(bool aDoFlush)
--- a/dom/base/nsContentList.h
+++ b/dom/base/nsContentList.h
@@ -82,17 +82,17 @@ public:
   }
 
   void Reset() {
     mElements.Clear();
   }
 
   virtual int32_t IndexOf(nsIContent *aContent, bool aDoFlush);
 
-  virtual JSObject* WrapObject(JSContext *cx)
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE = 0;
 
   void SetCapacity(uint32_t aCapacity)
   {
     mElements.SetCapacity(aCapacity);
   }
 protected:
   virtual ~nsBaseContentList();
@@ -120,17 +120,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSimpleContentList,
                                            nsBaseContentList)
 
   virtual nsINode* GetParentObject() MOZ_OVERRIDE
   {
     return mRoot;
   }
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 protected:
   virtual ~nsSimpleContentList() {}
 
 private:
   // This has to be a strong reference, the root might go away before the list.
   nsCOMPtr<nsINode> mRoot;
 };
@@ -246,17 +246,17 @@ public:
                 void* aData,
                 bool aDeep = true,
                 nsIAtom* aMatchAtom = nullptr,
                 int32_t aMatchNameSpaceId = kNameSpaceID_None,
                 bool aFuncMayDependOnAttr = true);
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~nsContentList();
 
   virtual JSObject* GetWrapperPreserveColorInternal() MOZ_OVERRIDE
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
 public:
@@ -531,17 +531,17 @@ public:
     : nsCacheableFuncStringContentList(aRootNode, aFunc, aDestroyFunc,
                                        aDataAllocator, aString)
   {
 #ifdef DEBUG
     mType = eNodeList;
 #endif
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #ifdef DEBUG
   static const ContentListType sType;
 #endif
 };
 
 class nsCacheableFuncStringHTMLCollection
   : public nsCacheableFuncStringContentList
@@ -555,16 +555,16 @@ public:
     : nsCacheableFuncStringContentList(aRootNode, aFunc, aDestroyFunc,
                                        aDataAllocator, aString)
   {
 #ifdef DEBUG
     mType = eHTMLCollection;
 #endif
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #ifdef DEBUG
   static const ContentListType sType;
 #endif
 };
 
 #endif // nsContentList_h___
--- a/dom/base/nsDOMAttributeMap.cpp
+++ b/dom/base/nsDOMAttributeMap.cpp
@@ -582,12 +582,12 @@ nsDOMAttributeMap::SizeOfIncludingThis(M
                                             aMallocSizeOf)
      : 0;
 
   // NB: mContent is non-owning and thus not counted.
   return n;
 }
 
 /* virtual */ JSObject*
-nsDOMAttributeMap::WrapObject(JSContext* aCx)
+nsDOMAttributeMap::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NamedNodeMapBinding::Wrap(aCx, this);
+  return NamedNodeMapBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/nsDOMAttributeMap.h
+++ b/dom/base/nsDOMAttributeMap.h
@@ -135,17 +135,17 @@ public:
    * @return The number of attribute nodes that aFunc was called for.
    */
   uint32_t Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const;
 
   Element* GetParentObject() const
   {
     return mContent;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   Attr* GetNamedItem(const nsAString& aAttrName);
   Attr* NamedGetter(const nsAString& aAttrName, bool& aFound);
   bool NameIsEnumerable(const nsAString& aName);
   already_AddRefed<Attr>
   SetNamedItem(Attr& aAttr, ErrorResult& aError)
   {
--- a/dom/base/nsDOMCaretPosition.cpp
+++ b/dom/base/nsDOMCaretPosition.cpp
@@ -51,19 +51,19 @@ nsDOMCaretPosition::GetClientRect() cons
   NS_ASSERTION(domRange, "unable to retrieve valid dom range from CaretPosition");
 
   rect = domRange->GetBoundingClientRect(false);
 
   return rect.forget();
 }
 
 JSObject*
-nsDOMCaretPosition::WrapObject(JSContext *aCx)
+nsDOMCaretPosition::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::CaretPositionBinding::Wrap(aCx, this);
+  return mozilla::dom::CaretPositionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMCaretPosition,
                                       mOffsetNode, mAnonymousContentNode)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCaretPosition)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCaretPosition)
 
--- a/dom/base/nsDOMCaretPosition.h
+++ b/dom/base/nsDOMCaretPosition.h
@@ -80,17 +80,17 @@ public:
     mAnonymousContentNode = aNode;
   }
 
   nsISupports* GetParentObject() const
   {
     return GetOffsetNode();
   }
 
-  virtual JSObject* WrapObject(JSContext *aCx)
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE MOZ_FINAL;
 
 protected:
   virtual ~nsDOMCaretPosition();
 
   uint32_t mOffset;
   nsCOMPtr<nsINode> mOffsetNode;
   nsCOMPtr<nsINode> mAnonymousContentNode;
--- a/dom/base/nsDOMDataChannel.cpp
+++ b/dom/base/nsDOMDataChannel.cpp
@@ -48,19 +48,19 @@ nsDOMDataChannel::~nsDOMDataChannel()
   // one) once we block GC until all the (appropriate) onXxxx handlers
   // are dropped. (See WebRTC spec)
   LOG(("Close()ing %p", mDataChannel.get()));
   mDataChannel->SetListener(nullptr, nullptr);
   mDataChannel->Close();
 }
 
 /* virtual */ JSObject*
-nsDOMDataChannel::WrapObject(JSContext* aCx)
+nsDOMDataChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DataChannelBinding::Wrap(aCx, this);
+  return DataChannelBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataChannel)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataChannel,
                                                   DOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
--- a/dom/base/nsDOMDataChannel.h
+++ b/dom/base/nsDOMDataChannel.h
@@ -37,17 +37,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDATACHANNEL
 
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(mozilla::DOMEventTargetHelper)
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDataChannel,
                                            mozilla::DOMEventTargetHelper)
 
-  virtual JSObject* WrapObject(JSContext* aCx)
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE;
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
   // WebIDL
   // Uses XPIDL GetLabel.
--- a/dom/base/nsDOMFileReader.cpp
+++ b/dom/base/nsDOMFileReader.cpp
@@ -525,12 +525,12 @@ nsDOMFileReader::GetAsDataURL(nsIDOMBlob
   if (!AppendASCIItoUTF16(encodedData, aResult, fallible)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-nsDOMFileReader::WrapObject(JSContext* aCx)
+nsDOMFileReader::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return FileReaderBinding::Wrap(aCx, this);
+  return FileReaderBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/nsDOMFileReader.h
+++ b/dom/base/nsDOMFileReader.h
@@ -57,17 +57,17 @@ public:
 
   virtual nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent,
                                nsAString& aTerminationEvent) MOZ_OVERRIDE;
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   static already_AddRefed<nsDOMFileReader>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
   void ReadAsArrayBuffer(JSContext* aCx, File& aBlob, ErrorResult& aRv)
   {
     ReadFileContent(aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
   }
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -43,19 +43,19 @@ public:
   {
   }
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::MutationRecordBinding::Wrap(aCx, this);
+    return mozilla::dom::MutationRecordBinding::Wrap(aCx, this, aGivenProto);
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationRecord)
 
   void GetType(mozilla::dom::DOMString& aRetVal) const
   {
     aRetVal.SetOwnedAtom(mType, mozilla::dom::DOMString::eNullNotExpected);
@@ -456,19 +456,19 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationObserver)
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_MUTATION_OBSERVER_IID)
 
   static already_AddRefed<nsDOMMutationObserver>
   Constructor(const mozilla::dom::GlobalObject& aGlobal,
               mozilla::dom::MutationCallback& aCb,
               mozilla::ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::MutationObserverBinding::Wrap(aCx, this);
+    return mozilla::dom::MutationObserverBinding::Wrap(aCx, this, aGivenProto);
   }
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
   void Observe(nsINode& aTarget,
--- a/dom/base/nsDOMSerializer.h
+++ b/dom/base/nsDOMSerializer.h
@@ -43,19 +43,19 @@ public:
   SerializeToStream(nsINode& aRoot, nsIOutputStream* aStream,
                     const nsAString& aCharset, mozilla::ErrorResult& rv);
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::XMLSerializerBinding::Wrap(aCx, this);
+    return mozilla::dom::XMLSerializerBinding::Wrap(aCx, this, aGivenProto);
   }
 
 private:
   virtual ~nsDOMSerializer();
 
   explicit nsDOMSerializer(nsISupports* aOwner) : mOwner(aOwner)
   {
     MOZ_ASSERT(aOwner);
--- a/dom/base/nsDOMSettableTokenList.cpp
+++ b/dom/base/nsDOMSettableTokenList.cpp
@@ -16,12 +16,12 @@ nsDOMSettableTokenList::SetValue(const n
   if (!mElement) {
     return;
   }
 
   rv = mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
 }
 
 JSObject*
-nsDOMSettableTokenList::WrapObject(JSContext *cx)
+nsDOMSettableTokenList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::DOMSettableTokenListBinding::Wrap(cx, this);
+  return mozilla::dom::DOMSettableTokenListBinding::Wrap(cx, this, aGivenProto);
 }
--- a/dom/base/nsDOMSettableTokenList.h
+++ b/dom/base/nsDOMSettableTokenList.h
@@ -17,17 +17,17 @@ class nsIAtom;
 // because nsDOMSettableTokenList is traversed by Element.
 class nsDOMSettableTokenList MOZ_FINAL : public nsDOMTokenList
 {
 public:
 
   nsDOMSettableTokenList(mozilla::dom::Element* aElement, nsIAtom* aAttrAtom)
     : nsDOMTokenList(aElement, aAttrAtom) {}
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   void GetValue(nsAString& aResult) { Stringify(aResult); }
   void SetValue(const nsAString& aValue, mozilla::ErrorResult& rv);
 };
 
 #endif // nsDOMSettableTokenList_h___
 
--- a/dom/base/nsDOMTokenList.cpp
+++ b/dom/base/nsDOMTokenList.cpp
@@ -304,13 +304,13 @@ nsDOMTokenList::Stringify(nsAString& aRe
     aResult.Truncate();
     return;
   }
 
   mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
 }
 
 JSObject*
-nsDOMTokenList::WrapObject(JSContext *cx)
+nsDOMTokenList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMTokenListBinding::Wrap(cx, this);
+  return DOMTokenListBinding::Wrap(cx, this, aGivenProto);
 }
 
--- a/dom/base/nsDOMTokenList.h
+++ b/dom/base/nsDOMTokenList.h
@@ -32,17 +32,17 @@ protected:
   typedef mozilla::dom::Element Element;
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTokenList)
 
   nsDOMTokenList(Element* aElement, nsIAtom* aAttrAtom);
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   Element* GetParentObject()
   {
     return mElement;
   }
 
   uint32_t Length();
   void Item(uint32_t aIndex, nsAString& aResult)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2885,29 +2885,16 @@ nsDOMWindowUtils::LeafLayersPartitionWin
   if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
     *aResult = false;
   }
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
-{
-  MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
-
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
-  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-
-  nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
-  *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -7355,24 +7355,24 @@ nsDocument::InitializeFrameLoader(nsFram
       NS_NewRunnableMethod(this, &nsDocument::MaybeInitializeFinalizeFrameLoaders);
     NS_ENSURE_TRUE(mFrameLoaderRunner, NS_ERROR_OUT_OF_MEMORY);
     nsContentUtils::AddScriptRunner(mFrameLoaderRunner);
   }
   return NS_OK;
 }
 
 nsresult
-nsDocument::FinalizeFrameLoader(nsFrameLoader* aLoader)
+nsDocument::FinalizeFrameLoader(nsFrameLoader* aLoader, nsIRunnable* aFinalizer)
 {
   mInitializableFrameLoaders.RemoveElement(aLoader);
   if (mInDestructor) {
     return NS_ERROR_FAILURE;
   }
 
-  mFinalizableFrameLoaders.AppendElement(aLoader);
+  mFrameLoaderFinalizers.AppendElement(aFinalizer);
   if (!mFrameLoaderRunner) {
     mFrameLoaderRunner =
       NS_NewRunnableMethod(this, &nsDocument::MaybeInitializeFinalizeFrameLoaders);
     NS_ENSURE_TRUE(mFrameLoaderRunner, NS_ERROR_OUT_OF_MEMORY);
     nsContentUtils::AddScriptRunner(mFrameLoaderRunner);
   }
   return NS_OK;
 }
@@ -7387,17 +7387,17 @@ nsDocument::MaybeInitializeFinalizeFrame
     return;
   }
 
   // We're not in an update, but it is not safe to run scripts, so
   // postpone frameloader initialization and finalization.
   if (!nsContentUtils::IsSafeToRunScript()) {
     if (!mInDestructor && !mFrameLoaderRunner &&
         (mInitializableFrameLoaders.Length() ||
-         mFinalizableFrameLoaders.Length())) {
+         mFrameLoaderFinalizers.Length())) {
       mFrameLoaderRunner =
         NS_NewRunnableMethod(this, &nsDocument::MaybeInitializeFinalizeFrameLoaders);
       nsContentUtils::AddScriptRunner(mFrameLoaderRunner);
     }
     return;
   }
   mFrameLoaderRunner = nullptr;
 
@@ -7406,52 +7406,38 @@ nsDocument::MaybeInitializeFinalizeFrame
   // array. But be careful to keep the loader alive when starting the load!
   while (mInitializableFrameLoaders.Length()) {
     nsRefPtr<nsFrameLoader> loader = mInitializableFrameLoaders[0];
     mInitializableFrameLoaders.RemoveElementAt(0);
     NS_ASSERTION(loader, "null frameloader in the array?");
     loader->ReallyStartLoading();
   }
 
-  uint32_t length = mFinalizableFrameLoaders.Length();
+  uint32_t length = mFrameLoaderFinalizers.Length();
   if (length > 0) {
-    nsTArray<nsRefPtr<nsFrameLoader> > loaders;
-    mFinalizableFrameLoaders.SwapElements(loaders);
+    nsTArray<nsCOMPtr<nsIRunnable> > finalizers;
+    mFrameLoaderFinalizers.SwapElements(finalizers);
     for (uint32_t i = 0; i < length; ++i) {
-      loaders[i]->Finalize();
+      finalizers[i]->Run();
     }
   }
 }
 
 void
 nsDocument::TryCancelFrameLoaderInitialization(nsIDocShell* aShell)
 {
   uint32_t length = mInitializableFrameLoaders.Length();
   for (uint32_t i = 0; i < length; ++i) {
     if (mInitializableFrameLoaders[i]->GetExistingDocShell() == aShell) {
       mInitializableFrameLoaders.RemoveElementAt(i);
       return;
     }
   }
 }
 
-bool
-nsDocument::FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell)
-{
-  if (aShell) {
-    uint32_t length = mFinalizableFrameLoaders.Length();
-    for (uint32_t i = 0; i < length; ++i) {
-      if (mFinalizableFrameLoaders[i]->GetExistingDocShell() == aShell) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 nsIDocument*
 nsDocument::RequestExternalResource(nsIURI* aURI,
                                     nsINode* aRequestingNode,
                                     ExternalResourceLoad** aPendingLoad)
 {
   NS_PRECONDITION(aURI, "Must have a URI");
   NS_PRECONDITION(aRequestingNode, "Must have a node");
   if (mDisplayDocument) {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1030,19 +1030,18 @@ public:
                                                    float aBottomSize, float aLeftSize,
                                                    bool aIgnoreRootScrollFrame,
                                                    bool aFlushLayout,
                                                    nsIDOMNodeList** aReturn) MOZ_OVERRIDE;
 
   virtual void FlushSkinBindings() MOZ_OVERRIDE;
 
   virtual nsresult InitializeFrameLoader(nsFrameLoader* aLoader) MOZ_OVERRIDE;
-  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader) MOZ_OVERRIDE;
+  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader, nsIRunnable* aFinalizer) MOZ_OVERRIDE;
   virtual void TryCancelFrameLoaderInitialization(nsIDocShell* aShell) MOZ_OVERRIDE;
-  virtual bool FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell) MOZ_OVERRIDE;
   virtual nsIDocument*
     RequestExternalResource(nsIURI* aURI,
                             nsINode* aRequestingNode,
                             ExternalResourceLoad** aPendingLoad) MOZ_OVERRIDE;
   virtual void
     EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData) MOZ_OVERRIDE;
 
   nsTArray<nsCString> mHostObjectURIs;
@@ -1765,17 +1764,17 @@ private:
   // AddStyleRelevantLink.
   bool mStyledLinksCleared;
 #endif
 
   // Member to store out last-selected stylesheet set.
   nsString mLastStyleSheetSet;
 
   nsTArray<nsRefPtr<nsFrameLoader> > mInitializableFrameLoaders;
-  nsTArray<nsRefPtr<nsFrameLoader> > mFinalizableFrameLoaders;
+  nsTArray<nsCOMPtr<nsIRunnable> > mFrameLoaderFinalizers;
   nsRefPtr<nsRunnableMethod<nsDocument> > mFrameLoaderRunner;
 
   nsRevocableEventPtr<nsRunnableMethod<nsDocument, void, false> >
     mPendingTitleChangeEvent;
 
   nsExternalResourceMap mExternalResourceMap;
 
   // All images in process of being preloaded.  This is a hashtable so
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1805,20 +1805,16 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
   }
 #endif
 
   if (aIsNewDocument) {
     // if this is a new document, update the parent chain of frames so that
     // focus can be traversed from the top level down to the newly focused
     // window.
     AdjustWindowFocus(aWindow, false);
-
-    // Update the window touch registration to reflect the state of
-    // the new document that got focus
-    aWindow->UpdateTouchState();
   }
 
   // indicate that the window has taken focus.
   if (aWindow->TakeFocus(true, focusMethod))
     aIsNewDocument = true;
 
   SetFocusedWindowInternal(aWindow);
 
--- a/dom/base/nsFormData.cpp
+++ b/dom/base/nsFormData.cpp
@@ -259,19 +259,19 @@ nsFormData::Append(const nsAString& aNam
   nsString valAsString;
   valAsString.Adopt(stringData, stringLen);
 
   Append(aName, valAsString);
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-nsFormData::WrapObject(JSContext* aCx)
+nsFormData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return FormDataBinding::Wrap(aCx, this);
+  return FormDataBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<nsFormData>
 nsFormData::Constructor(const GlobalObject& aGlobal,
                         const Optional<NonNull<HTMLFormElement> >& aFormElement,
                         ErrorResult& aRv)
 {
   nsRefPtr<nsFormData> formData = new nsFormData(aGlobal.GetAsSupports());
--- a/dom/base/nsFormData.h
+++ b/dom/base/nsFormData.h
@@ -75,17 +75,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFormData,
                                                          nsIDOMFormData)
 
   NS_DECL_NSIDOMFORMDATA
   NS_DECL_NSIXHRSENDABLE
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   nsISupports*
   GetParentObject() const
   {
     return mOwner;
   }
   static already_AddRefed<nsFormData>
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -102,35 +102,16 @@
 using namespace mozilla;
 using namespace mozilla::hal;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 typedef FrameMetrics::ViewID ViewID;
 
-class nsAsyncDocShellDestroyer : public nsRunnable
-{
-public:
-  explicit nsAsyncDocShellDestroyer(nsIDocShell* aDocShell)
-    : mDocShell(aDocShell)
-  {
-  }
-
-  NS_IMETHOD Run()
-  {
-    nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
-    if (base_win) {
-      base_win->Destroy();
-    }
-    return NS_OK;
-  }
-  nsRefPtr<nsIDocShell> mDocShell;
-};
-
 // Bug 136580: Limit to the number of nested content frames that can have the
 //             same URL. This is to stop content that is recursively loading
 //             itself.  Note that "#foo" on the end of URL doesn't affect
 //             whether it's considered identical, but "?foo" or ";foo" are
 //             considered and compared.
 // Bug 228829: Limit this to 1, like IE does.
 #define MAX_SAME_URL_CONTENT_FRAMES 1
 
@@ -176,17 +157,16 @@ nsFrameLoader::nsFrameLoader(Element* aO
   , mChildID(0)
   , mEventMode(EVENT_MODE_NORMAL_DISPATCH)
 {
   ResetPermissionManagerStatus();
 }
 
 nsFrameLoader::~nsFrameLoader()
 {
-  mNeedsAsyncDestroy = true;
   if (mMessageManager) {
     mMessageManager->Disconnect();
   }
   MOZ_RELEASE_ASSERT(mDestroyCalled);
 }
 
 nsFrameLoader*
 nsFrameLoader::Create(Element* aOwner, bool aNetworkCreated)
@@ -518,26 +498,16 @@ nsFrameLoader::GetDocShell(nsIDocShell *
   }
 
   *aDocShell = mDocShell;
   NS_IF_ADDREF(*aDocShell);
 
   return rv;
 }
 
-void
-nsFrameLoader::Finalize()
-{
-  nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
-  if (base_win) {
-    base_win->Destroy();
-  }
-  mDocShell = nullptr;
-}
-
 static void
 FirePageHideEvent(nsIDocShellTreeItem* aItem,
                   EventTarget* aChromeEventHandler)
 {
   nsCOMPtr<nsIDocument> doc = aItem->GetDocument();
   NS_ASSERTION(doc, "What happened here?");
   doc->OnPageHide(true, aChromeEventHandler);
 
@@ -1353,51 +1323,80 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
 
   FirePageShowEvent(ourDocshell, ourEventTarget, true);
   FirePageShowEvent(otherDocshell, otherEventTarget, true);
 
   mInSwap = aOther->mInSwap = false;
   return NS_OK;
 }
 
-void
-nsFrameLoader::DestroyChild()
-{
-  if (mRemoteBrowser) {
-    mRemoteBrowser->SetOwnerElement(nullptr);
-    mRemoteBrowser->Destroy();
-    mRemoteBrowser = nullptr;
-  }
-}
-
 NS_IMETHODIMP
 nsFrameLoader::Destroy()
 {
+  StartDestroy();
+  return NS_OK;
+}
+
+class nsFrameLoaderDestroyRunnable : public nsRunnable
+{
+  enum DestroyPhase
+  {
+    // See the implementation of Run for an explanation of these phases.
+    eDestroyDocShell,
+    eWaitForUnloadMessage,
+    eDestroyComplete
+  };
+
+  nsRefPtr<nsFrameLoader> mFrameLoader;
+  DestroyPhase mPhase;
+
+public:
+  explicit nsFrameLoaderDestroyRunnable(nsFrameLoader* aFrameLoader)
+   : mFrameLoader(aFrameLoader), mPhase(eDestroyDocShell) {}
+
+  NS_IMETHODIMP Run() MOZ_OVERRIDE;
+};
+
+void
+nsFrameLoader::StartDestroy()
+{
+  // nsFrameLoader::StartDestroy is called just before the frameloader is
+  // detached from the <browser> element. Destruction continues in phases via
+  // the nsFrameLoaderDestroyRunnable.
+
   if (mDestroyCalled) {
-    return NS_OK;
+    return;
   }
   mDestroyCalled = true;
 
+  // After this point, we return an error when trying to send a message using
+  // the message manager on the frame.
   if (mMessageManager) {
-    mMessageManager->Disconnect();
+    mMessageManager->Close();
   }
-  if (mChildMessageManager) {
-    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->Disconnect();
+
+  // Retain references to the <browser> element and the frameloader in case we
+  // receive any messages from the message manager on the frame. These
+  // references are dropped in DestroyComplete.
+  if (mChildMessageManager || mRemoteBrowser) {
+    mOwnerContentStrong = mOwnerContent;
+    if (mRemoteBrowser) {
+      mRemoteBrowser->CacheFrameLoader(this);
+    }
   }
 
   nsCOMPtr<nsIDocument> doc;
   bool dynamicSubframeRemoval = false;
   if (mOwnerContent) {
     doc = mOwnerContent->OwnerDoc();
     dynamicSubframeRemoval = !mIsTopLevelContent && !doc->InUnlinkOrDeletion();
     doc->SetSubDocumentFor(mOwnerContent, nullptr);
 
     SetOwnerContent(nullptr);
   }
-  DestroyChild();
 
   // Seems like this is a dynamic frame removal.
   if (dynamicSubframeRemoval) {
     if (mDocShell) {
       mDocShell->RemoveFromSessionHistory();
     }
   }
 
@@ -1407,42 +1406,141 @@ nsFrameLoader::Destroy()
       nsCOMPtr<nsIDocShellTreeItem> parentItem;
       mDocShell->GetParent(getter_AddRefs(parentItem));
       nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
       if (owner) {
         owner->ContentShellRemoved(mDocShell);
       }
     }
   }
-  
+
   // Let our window know that we are gone
   if (mDocShell) {
     nsCOMPtr<nsPIDOMWindow> win_private(mDocShell->GetWindow());
     if (win_private) {
       win_private->SetFrameElementInternal(nullptr);
     }
   }
 
-  if ((mNeedsAsyncDestroy || !doc ||
-       NS_FAILED(doc->FinalizeFrameLoader(this))) && mDocShell) {
-    nsCOMPtr<nsIRunnable> event = new nsAsyncDocShellDestroyer(mDocShell);
-    NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
-    NS_DispatchToCurrentThread(event);
-
-    // Let go of our docshell now that the async destroyer holds on to
-    // the docshell.
-
-    mDocShell = nullptr;
+  nsCOMPtr<nsIRunnable> destroyRunnable = new nsFrameLoaderDestroyRunnable(this);
+  if (mNeedsAsyncDestroy || !doc ||
+      NS_FAILED(doc->FinalizeFrameLoader(this, destroyRunnable))) {
+    NS_DispatchToCurrentThread(destroyRunnable);
   }
-
-  // NOTE: 'this' may very well be gone by now.
+}
+
+nsresult
+nsFrameLoaderDestroyRunnable::Run()
+{
+  switch (mPhase) {
+  case eDestroyDocShell:
+    mFrameLoader->DestroyDocShell();
+
+    // In the out-of-process case, TabParent will eventually call
+    // DestroyComplete once it receives a __delete__ message from the child. In
+    // the in-process case, we dispatch a series of runnables to ensure that
+    // DestroyComplete gets called at the right time. The frame loader is kept
+    // alive by mFrameLoader during this time.
+    if (mFrameLoader->mChildMessageManager) {
+      // When the docshell is destroyed, NotifyWindowIDDestroyed is called to
+      // asynchronously notify {outer,inner}-window-destroyed via a runnable. We
+      // don't want DestroyComplete to run until after those runnables have
+      // run. Since we're enqueueing ourselves after the window-destroyed
+      // runnables are enqueued, we're guaranteed to run after.
+      mPhase = eWaitForUnloadMessage;
+      NS_DispatchToCurrentThread(this);
+    }
+    break;
+
+   case eWaitForUnloadMessage:
+     // The *-window-destroyed observers have finished running at this
+     // point. However, it's possible that a *-window-destroyed observer might
+     // have sent a message using the message manager. These messages might not
+     // have been processed yet. So we enqueue ourselves again to ensure that
+     // DestroyComplete runs after all messages sent by *-window-destroyed
+     // observers have been processed.
+     mPhase = eDestroyComplete;
+     NS_DispatchToCurrentThread(this);
+     break;
+
+   case eDestroyComplete:
+     // Now that all messages sent by unload listeners and window destroyed
+     // observers have been processed, we disconnect the message manager and
+     // finish destruction.
+     mFrameLoader->DestroyComplete();
+     break;
+  }
 
   return NS_OK;
 }
 
+void
+nsFrameLoader::DestroyDocShell()
+{
+  // This code runs after the frameloader has been detached from the <browser>
+  // element. We postpone this work because we may not be allowed to run
+  // script at that time.
+
+  // Ask the TabChild to fire the frame script "unload" event, destroy its
+  // docshell, and finally destroy the PBrowser actor. This eventually leads to
+  // nsFrameLoader::DestroyComplete being called.
+  if (mRemoteBrowser) {
+    mRemoteBrowser->Destroy();
+  }
+
+  // Fire the "unload" event if we're in-process.
+  if (mChildMessageManager) {
+    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->FireUnloadEvent();
+  }
+
+  // Destroy the docshell.
+  nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
+  if (base_win) {
+    base_win->Destroy();
+  }
+  mDocShell = nullptr;
+
+  if (mChildMessageManager) {
+    // Stop handling events in the in-process frame script.
+    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->DisconnectEventListeners();
+  }
+}
+
+void
+nsFrameLoader::DestroyComplete()
+{
+  // We get here, as part of StartDestroy, after the docshell has been destroyed
+  // and all message manager messages sent during docshell destruction have been
+  // dispatched.  We also get here if the child process crashes. In the latter
+  // case, StartDestroy might not have been called.
+
+  // Drop the strong references created in StartDestroy.
+  if (mChildMessageManager || mRemoteBrowser) {
+    mOwnerContentStrong = nullptr;
+    if (mRemoteBrowser) {
+      mRemoteBrowser->CacheFrameLoader(nullptr);
+    }
+  }
+
+  // Call TabParent::Destroy if we haven't already (in case of a crash).
+  if (mRemoteBrowser) {
+    mRemoteBrowser->SetOwnerElement(nullptr);
+    mRemoteBrowser->Destroy();
+    mRemoteBrowser = nullptr;
+  }
+
+  if (mMessageManager) {
+    mMessageManager->Disconnect();
+  }
+
+  if (mChildMessageManager) {
+    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->Disconnect();
+  }
+}
+
 NS_IMETHODIMP
 nsFrameLoader::GetDepthTooGreat(bool* aDepthTooGreat)
 {
   *aDepthTooGreat = mDepthTooGreat;
   return NS_OK;
 }
 
 void
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -73,17 +73,19 @@ public:
                                bool aNetworkCreated);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader)
   NS_DECL_NSIFRAMELOADER
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   nsresult CheckForRecursiveLoad(nsIURI* aURI);
   nsresult ReallyStartLoading();
-  void Finalize();
+  void StartDestroy();
+  void DestroyDocShell();
+  void DestroyComplete();
   nsIDocShell* GetExistingDocShell() { return mDocShell; }
   mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget();
   nsresult CreateStaticClone(nsIFrameLoader* aDest);
 
   /**
    * MessageManagerCallback methods that we override.
    */
   virtual bool DoLoadMessageManagerScript(const nsAString& aURL,
@@ -314,16 +316,21 @@ private:
   void ResetPermissionManagerStatus();
 
   void InitializeBrowserAPI();
 
   nsCOMPtr<nsIDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURIToLoad;
   mozilla::dom::Element* mOwnerContent; // WEAK
 
+  // After the frameloader has been removed from the DOM but before all of the
+  // messages from the frame have been received, we keep a strong reference to
+  // our <browser> element.
+  nsRefPtr<mozilla::dom::Element> mOwnerContentStrong;
+
   // Note: this variable must be modified only by ResetPermissionManagerStatus()
   uint32_t mAppIdSentToPermissionManager;
 
 public:
   // public because a callback needs these.
   nsRefPtr<nsFrameMessageManager> mMessageManager;
   nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
 private:
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -296,17 +296,18 @@ SameProcessCpowHolder::ToObject(JSContex
   aObjp.set(mObj);
   return JS_WrapObject(aCx, aObjp);
 }
 
 // nsIMessageListenerManager
 
 NS_IMETHODIMP
 nsFrameMessageManager::AddMessageListener(const nsAString& aMessage,
-                                          nsIMessageListener* aListener)
+                                          nsIMessageListener* aListener,
+                                          bool aListenWhenClosed)
 {
   nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
     mListeners.Get(aMessage);
   if (!listeners) {
     listeners = new nsAutoTObserverArray<nsMessageListenerInfo, 1>();
     mListeners.Put(aMessage, listeners);
   } else {
     uint32_t len = listeners->Length();
@@ -315,16 +316,17 @@ nsFrameMessageManager::AddMessageListene
         return NS_OK;
       }
     }
   }
 
   nsMessageListenerInfo* entry = listeners->AppendElement();
   NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
   entry->mStrongListener = aListener;
+  entry->mListenWhenClosed = aListenWhenClosed;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::RemoveMessageListener(const nsAString& aMessage,
                                              nsIMessageListener* aListener)
 {
   nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
@@ -402,16 +404,17 @@ nsFrameMessageManager::AddWeakMessageLis
       if (listeners->ElementAt(i).mWeakListener == weak) {
         return NS_OK;
       }
     }
   }
 
   nsMessageListenerInfo* entry = listeners->AppendElement();
   entry->mWeakListener = weak;
+  entry->mListenWhenClosed = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::RemoveWeakMessageListener(const nsAString& aMessage,
                                                  nsIMessageListener* aListener)
 {
   nsWeakPtr weak = do_GetWeakReference(aListener);
@@ -979,16 +982,30 @@ nsresult
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
                                       const nsAString& aMessage,
                                       bool aIsSync,
                                       const StructuredCloneData* aCloneData,
                                       mozilla::jsipc::CpowHolder* aCpows,
                                       nsIPrincipal* aPrincipal,
                                       InfallibleTArray<nsString>* aJSONRetVal)
 {
+  return ReceiveMessage(aTarget, mClosed, aMessage, aIsSync,
+                        aCloneData, aCpows, aPrincipal, aJSONRetVal);
+}
+
+nsresult
+nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
+                                      bool aTargetClosed,
+                                      const nsAString& aMessage,
+                                      bool aIsSync,
+                                      const StructuredCloneData* aCloneData,
+                                      mozilla::jsipc::CpowHolder* aCpows,
+                                      nsIPrincipal* aPrincipal,
+                                      InfallibleTArray<nsString>* aJSONRetVal)
+{
   nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
     mListeners.Get(aMessage);
   if (listeners) {
 
     MMListenerRemover lr(this);
 
     nsAutoTObserverArray<nsMessageListenerInfo, 1>::EndLimitedIterator
       iter(*listeners);
@@ -999,16 +1016,20 @@ nsFrameMessageManager::ReceiveMessage(ns
       if (listener.mWeakListener) {
         weakListener = do_QueryReferent(listener.mWeakListener);
         if (!weakListener) {
           listeners->RemoveElement(listener);
           continue;
         }
       }
 
+      if (!listener.mListenWhenClosed && aTargetClosed) {
+        continue;
+      }
+
       nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS;
       if (weakListener) {
         wrappedJS = do_QueryInterface(weakListener);
       } else {
         wrappedJS = do_QueryInterface(listener.mStrongListener);
       }
 
       if (!wrappedJS) {
@@ -1149,17 +1170,17 @@ nsFrameMessageManager::ReceiveMessage(ns
             continue;
           }
           aJSONRetVal->AppendElement(json);
         }
       }
     }
   }
   nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
-  return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
+  return mParentManager ? mParentManager->ReceiveMessage(aTarget, aTargetClosed, aMessage,
                                                          aIsSync, aCloneData,
                                                          aCpows, aPrincipal,
                                                          aJSONRetVal) : NS_OK;
 }
 
 void
 nsFrameMessageManager::AddChildManager(nsFrameMessageManager* aManager)
 {
@@ -1230,32 +1251,48 @@ nsFrameMessageManager::RemoveFromParent(
     mParentManager->RemoveChildManager(this);
   }
   mParentManager = nullptr;
   mCallback = nullptr;
   mOwnedCallback = nullptr;
 }
 
 void
+nsFrameMessageManager::Close()
+{
+  if (!mClosed) {
+    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+    if (obs) {
+      obs->NotifyObservers(NS_ISUPPORTS_CAST(nsIContentFrameMessageManager*, this),
+                            "message-manager-close", nullptr);
+    }
+  }
+  mClosed = true;
+  mCallback = nullptr;
+  mOwnedCallback = nullptr;
+}
+
+void
 nsFrameMessageManager::Disconnect(bool aRemoveFromParent)
 {
+  // Notify message-manager-close if we haven't already.
+  Close();
+
   if (!mDisconnected) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
        obs->NotifyObservers(NS_ISUPPORTS_CAST(nsIContentFrameMessageManager*, this),
                             "message-manager-disconnect", nullptr);
     }
   }
   if (mParentManager && aRemoveFromParent) {
     mParentManager->RemoveChildManager(this);
   }
   mDisconnected = true;
   mParentManager = nullptr;
-  mCallback = nullptr;
-  mOwnedCallback = nullptr;
   if (!mHandlingMessage) {
     mListeners.Clear();
   }
 }
 
 namespace {
 
 struct MessageManagerReferentCount
@@ -1598,23 +1635,23 @@ nsMessageManagerScriptExecutor::TryCache
 
     JSAutoCompartment ac(cx, global);
     JS::CompileOptions options(cx, JSVERSION_LATEST);
     options.setFileAndLine(url.get(), 1);
     options.setNoScriptRval(true);
     JS::Rooted<JSScript*> script(cx);
 
     if (aRunInGlobalScope) {
-      if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
+      if (!JS::Compile(cx, options, srcBuf, &script)) {
         return;
       }
     } else {
       // We can't clone compile-and-go scripts.
       options.setCompileAndGo(false);
-      if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
+      if (!JS::Compile(cx, options, srcBuf, &script)) {
         return;
       }
     }
 
     aScriptp.set(script);
 
     nsAutoCString scheme;
     uri->GetScheme(scheme);
--- a/dom/base/nsFrameMessageManager.h
+++ b/dom/base/nsFrameMessageManager.h
@@ -128,16 +128,17 @@ struct nsMessageListenerInfo
   bool operator==(const nsMessageListenerInfo& aOther) const
   {
     return &aOther == this;
   }
 
   // Exactly one of mStrongListener and mWeakListener must be non-null.
   nsCOMPtr<nsIMessageListener> mStrongListener;
   nsWeakPtr mWeakListener;
+  bool mListenWhenClosed;
 };
 
 
 class MOZ_STACK_CLASS SameProcessCpowHolder : public mozilla::jsipc::CpowHolder
 {
 public:
   SameProcessCpowHolder(JSRuntime *aRuntime, JS::Handle<JSObject*> aObj)
     : mObj(aRuntime, aObj)
@@ -164,16 +165,17 @@ public:
                         nsFrameMessageManager* aParentManager,
                         /* mozilla::dom::ipc::MessageManagerFlags */ uint32_t aFlags)
   : mChrome(!!(aFlags & mozilla::dom::ipc::MM_CHROME)),
     mGlobal(!!(aFlags & mozilla::dom::ipc::MM_GLOBAL)),
     mIsProcessManager(!!(aFlags & mozilla::dom::ipc::MM_PROCESSMANAGER)),
     mIsBroadcaster(!!(aFlags & mozilla::dom::ipc::MM_BROADCASTER)),
     mOwnsCallback(!!(aFlags & mozilla::dom::ipc::MM_OWNSCALLBACK)),
     mHandlingMessage(false),
+    mClosed(false),
     mDisconnected(false),
     mCallback(aCallback),
     mParentManager(aParentManager)
   {
     NS_ASSERTION(mChrome || !aParentManager, "Should not set parent manager!");
     NS_ASSERTION(!mIsBroadcaster || !mCallback,
                  "Broadcasters cannot have callbacks!");
     // This is a bit hackish. When parent manager is global, we want
@@ -233,16 +235,17 @@ public:
                           InfallibleTArray<nsString>* aJSONRetVal);
 
   void AddChildManager(nsFrameMessageManager* aManager);
   void RemoveChildManager(nsFrameMessageManager* aManager)
   {
     mChildManagers.RemoveObject(aManager);
   }
   void Disconnect(bool aRemoveFromParent = true);
+  void Close();
 
   void InitWithCallback(mozilla::dom::ipc::MessageManagerCallback* aCallback);
   void SetCallback(mozilla::dom::ipc::MessageManagerCallback* aCallback);
   mozilla::dom::ipc::MessageManagerCallback* GetCallback()
   {
     return mCallback;
   }
 
@@ -285,16 +288,21 @@ private:
                        JS::Handle<JS::Value> aJSON,
                        JS::Handle<JS::Value> aObjects,
                        nsIPrincipal* aPrincipal,
                        JSContext* aCx,
                        uint8_t aArgc,
                        JS::MutableHandle<JS::Value> aRetval,
                        bool aIsSync);
 
+  nsresult ReceiveMessage(nsISupports* aTarget, bool aTargetClosed, const nsAString& aMessage,
+                          bool aIsSync, const StructuredCloneData* aCloneData,
+                          mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
+                          InfallibleTArray<nsString>* aJSONRetVal);
+
   NS_IMETHOD LoadScript(const nsAString& aURL,
                         bool aAllowDelayedLoad,
                         bool aRunInGlobalScope);
   NS_IMETHOD RemoveDelayedScript(const nsAString& aURL);
   NS_IMETHOD GetDelayedScripts(JSContext* aCx, JS::MutableHandle<JS::Value> aList);
 
 protected:
   friend class MMListenerRemover;
@@ -304,16 +312,17 @@ protected:
                    nsAutoTObserverArray<nsMessageListenerInfo, 1>> mListeners;
   nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
   bool mChrome;     // true if we're in the chrome process
   bool mGlobal;     // true if we're the global frame message manager
   bool mIsProcessManager; // true if the message manager belongs to the process realm
   bool mIsBroadcaster; // true if the message manager is a broadcaster
   bool mOwnsCallback;
   bool mHandlingMessage;
+  bool mClosed;    // true if we can no longer send messages
   bool mDisconnected;
   mozilla::dom::ipc::MessageManagerCallback* mCallback;
   nsAutoPtr<mozilla::dom::ipc::MessageManagerCallback> mOwnedCallback;
   nsFrameMessageManager* mParentManager;
   nsTArray<nsString> mPendingScripts;
   nsTArray<bool> mPendingScriptsGlobalStates;
 
   void LoadPendingScripts(nsFrameMessageManager* aManager,
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -569,17 +569,17 @@ extern uint64_t
 NextWindowID();
 }
 }
 
 nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
 : mFrameElement(nullptr), mDocShell(nullptr), mModalStateDepth(0),
   mRunningTimeout(nullptr), mMutationBits(0), mIsDocumentLoaded(false),
   mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
-  mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
+  mMayHavePaintEventListener(false),
   mMayHaveMouseEnterLeaveEventListener(false),
   mMayHavePointerEnterLeaveEventListener(false),
   mIsModalContentWindow(false),
   mIsActive(false), mIsBackground(false),
   mAudioMuted(false), mAudioVolume(1.0),
   mDesktopModeViewport(false), mInnerWindow(nullptr),
   mOuterWindow(aOuterWindow),
   // Make sure no actual window ends up with mWindowID == 0
@@ -8012,17 +8012,17 @@ PostMessageReadTransferStructuredClone(J
   StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(aClosure);
   NS_ASSERTION(scInfo, "Must have scInfo!");
 
   if (tag == SCTAG_DOM_MAP_MESSAGEPORT) {
     MessagePort* port = static_cast<MessagePort*>(aData);
     port->BindToOwner(scInfo->window);
     scInfo->ports.Put(port, nullptr);
 
-    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx));
+    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx, JS::NullPtr()));
     if (JS_WrapObject(aCx, &obj)) {
       MOZ_ASSERT(port->GetOwner() == scInfo->window);
       returnObject.set(obj);
     }
 
     return true;
   }
 
@@ -9839,57 +9839,16 @@ void nsGlobalWindow::SetIsBackground(boo
     nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
     if (inner) {
       inner->SyncGamepadState();
     }
   }
 #endif
 }
 
-void nsGlobalWindow::MaybeUpdateTouchState()
-{
-  FORWARD_TO_INNER_VOID(MaybeUpdateTouchState, ());
-
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-
-  nsCOMPtr<nsIDOMWindow> focusedWindow;
-  fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
-
-  if(this == focusedWindow) {
-    UpdateTouchState();
-  }
-
-  if (mMayHaveTouchEventListener) {
-    nsCOMPtr<nsIObserverService> observerService =
-      services::GetObserverService();
-
-    if (observerService) {
-      observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
-                                       DOM_TOUCH_LISTENER_ADDED,
-                                       nullptr);
-    }
-  }
-}
-
-void nsGlobalWindow::UpdateTouchState()
-{
-  FORWARD_TO_INNER_VOID(UpdateTouchState, ());
-
-  nsCOMPtr<nsIWidget> mainWidget = GetMainWidget();
-  if (!mainWidget) {
-    return;
-  }
-
-  if (mMayHaveTouchEventListener) {
-    mainWidget->RegisterTouchWindow();
-  } else {
-    mainWidget->UnregisterTouchWindow();
-  }
-}
-
 void
 nsGlobalWindow::EnableGamepadUpdates()
 {
   MOZ_ASSERT(IsInnerWindow());
 
   if (mHasGamepad) {
 #ifdef MOZ_GAMEPAD
     nsRefPtr<GamepadService> gamepadsvc(GamepadService::GetService());
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -350,17 +350,17 @@ public:
 
   // callback for close event
   void ReallyCloseWindow();
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsWrapperCache
-  virtual JSObject *WrapObject(JSContext *cx) MOZ_OVERRIDE
+  virtual JSObject *WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
     return IsInnerWindow() || EnsureInnerWindow() ? GetWrapper() : nullptr;
   }
 
   // nsIGlobalJSObjectHolder
   virtual JSObject* GetGlobalJSObject() MOZ_OVERRIDE;
 
   // nsIScriptGlobalObject
@@ -463,19 +463,16 @@ public:
 
   virtual void EnterModalState() MOZ_OVERRIDE;
   virtual void LeaveModalState() MOZ_OVERRIDE;
 
   // Outer windows only.
   virtual bool CanClose() MOZ_OVERRIDE;
   virtual void ForceClose() MOZ_OVERRIDE;
 
-  virtual void MaybeUpdateTouchState() MOZ_OVERRIDE;
-  virtual void UpdateTouchState() MOZ_OVERRIDE;
-
   // Outer windows only.
   virtual bool DispatchCustomEvent(const nsAString& aEventName) MOZ_OVERRIDE;
   bool DispatchResizeEvent(const mozilla::CSSIntSize& aSize);
 
   // Inner windows only.
   virtual void RefreshCompartmentPrincipal() MOZ_OVERRIDE;
 
   // Outer windows only.
--- a/dom/base/nsHistory.cpp
+++ b/dom/base/nsHistory.cpp
@@ -55,19 +55,19 @@ nsHistory::~nsHistory()
 nsPIDOMWindow*
 nsHistory::GetParentObject() const
 {
   nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
   return win;
 }
 
 JSObject*
-nsHistory::WrapObject(JSContext* aCx)
+nsHistory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HistoryBinding::Wrap(aCx, this);
+  return HistoryBinding::Wrap(aCx, this, aGivenProto);
 }
 
 uint32_t
 nsHistory::GetLength(ErrorResult& aRv) const
 {
   nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
   if (!win || !win->HasActiveDocument()) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
--- a/dom/base/nsHistory.h
+++ b/dom/base/nsHistory.h
@@ -28,17 +28,17 @@ class nsHistory MOZ_FINAL : public nsIDO
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsHistory)
 
 public:
   explicit nsHistory(nsPIDOMWindow* aInnerWindow);
 
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t GetLength(mozilla::ErrorResult& aRv) const;
   void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
                 mozilla::ErrorResult& aRv) const;
   void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
   void Back(mozilla::ErrorResult& aRv);
   void Forward(mozilla::ErrorResult& aRv);
   void PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -58,16 +58,17 @@ class nsIDOMNodeList;
 class nsIHTMLCollection;
 class nsILayoutHistoryState;
 class nsILoadContext;
 class nsIObjectLoadingContent;
 class nsIObserver;
 class nsIPresShell;
 class nsIPrincipal;
 class nsIRequest;
+class nsIRunnable;
 class nsIStreamListener;
 class nsIStructuredCloneContainer;
 class nsIStyleRule;
 class nsIStyleSheet;
 class nsIURI;
 class nsIVariant;
 class nsLocation;
 class nsViewManager;
@@ -1659,21 +1660,19 @@ public:
   already_AddRefed<nsIDocumentEncoder> GetCachedEncoder();
 
   void SetCachedEncoder(already_AddRefed<nsIDocumentEncoder> aEncoder);
 
   // In case of failure, the document really can't initialize the frame loader.
   virtual nsresult InitializeFrameLoader(nsFrameLoader* aLoader) = 0;
   // In case of failure, the caller must handle the error, for example by
   // finalizing frame loader asynchronously.
-  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader) = 0;
+  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader, nsIRunnable* aFinalizer) = 0;
   // Removes the frame loader of aShell from the initialization list.
   virtual void TryCancelFrameLoaderInitialization(nsIDocShell* aShell) = 0;
-  //  Returns true if the frame loader of aShell is in the finalization list.
-  virtual bool FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell) = 0;
 
   /**
    * Check whether this document is a root document that is not an
    * external resource.
    */
   bool IsRootDisplayDocument() const
   {
     return !mParentDocument && !mDisplayDocument;
--- a/dom/base/nsIMessageManager.idl
+++ b/dom/base/nsIMessageManager.idl
@@ -196,31 +196,38 @@ interface nsIMessageListener : nsISuppor
    * returned as JSON (will be changed to use structured clones).
    * When there are multiple listeners to sync messages, each
    * listener's return value is sent back as an array.  |undefined|
    * return values show up as undefined values in the array.
    */
   void receiveMessage();
 };
 
-[scriptable, builtinclass, uuid(aae827bd-acf1-45fe-a556-ea545d4c0804)]
+[scriptable, builtinclass, uuid(b949bfec-bb7d-47bc-b387-ac6a9b655072)]
 interface nsIMessageListenerManager : nsISupports
 {
   /**
    * Register |listener| to receive |messageName|.  All listener
    * callbacks for a particular message are invoked when that message
    * is received.
    *
    * The message manager holds a strong ref to |listener|.
    *
    * If the same listener registers twice for the same message, the
    * second registration is ignored.
+   *
+   * Pass true for listenWhenClosed if you want to receive messages
+   * during the short period after a frame has been removed from the
+   * DOM and before its frame script has finished unloading. This
+   * parameter only has an effect for frame message managers in
+   * the main process. Default is false.
    */
   void addMessageListener(in AString messageName,
-                          in nsIMessageListener listener);
+                          in nsIMessageListener listener,
+                          [optional] in boolean listenWhenClosed);
 
   /**
    * Undo an |addMessageListener| call -- that is, calling this causes us to no
    * longer invoke |listener| when |messageName| is received.
    *
    * removeMessageListener does not remove a message listener added via
    * addWeakMessageListener; use removeWeakMessageListener for that.
    */
@@ -247,17 +254,17 @@ interface nsIMessageListenerManager : ns
 };
 
 /**
  * Message "senders" have a single "other side" to which messages are
  * sent.  For example, a child-process message manager will send
  * messages that are only delivered to its one parent-process message
  * manager.
  */
-[scriptable, builtinclass, uuid(d6b0d851-43e6-426d-9f13-054bc0198175)]
+[scriptable, builtinclass, uuid(bb5d79e4-e73c-45e7-9651-4d718f4b994c)]
 interface nsIMessageSender : nsIMessageListenerManager
 {
   /**
    * Send |messageName| and |obj| to the "other side" of this message
    * manager.  This invokes listeners who registered for
    * |messageName|.
    *
    * See nsIMessageListener::receiveMessage() for the format of the
@@ -279,17 +286,17 @@ interface nsIMessageSender : nsIMessageL
 
 /**
  * Message "broadcasters" don't have a single "other side" that they
  * send messages to, but rather a set of subordinate message managers.
  * For example, broadcasting a message through a window message
  * manager will broadcast the message to all frame message managers
  * within its window.
  */
-[scriptable, builtinclass, uuid(d36346b9-5d3b-497d-9c28-ffbc3e4f6d0d)]
+[scriptable, builtinclass, uuid(4d7d62ad-4725-4f39-86cf-8fb22bf9c1d8)]
 interface nsIMessageBroadcaster : nsIMessageListenerManager
 {
   /**
    * Like |sendAsyncMessage()|, but also broadcasts this message to
    * all "child" message managers of this message manager.  See long
    * comment above for details.
    *
    * WARNING: broadcasting messages can be very expensive and leak
@@ -306,17 +313,17 @@ interface nsIMessageBroadcaster : nsIMes
   readonly attribute unsigned long childCount;
 
   /**
    * Return a single subordinate message manager.
    */
   nsIMessageListenerManager getChildAt(in unsigned long aIndex);
 };
 
-[scriptable, builtinclass, uuid(7fda0941-9dcc-448b-bd39-16373c5b4003)]
+[scriptable, builtinclass, uuid(0e602c9e-1977-422a-a8e4-fe0d4a4f78d0)]
 interface nsISyncMessageSender : nsIMessageSender
 {
   /**
    * Like |sendAsyncMessage()|, except blocks the sender until all
    * listeners of the message have been invoked.  Returns an array
    * containing return values from each listener invoked.
    */
   [implicit_jscontext, optional_argc]
@@ -336,17 +343,17 @@ interface nsISyncMessageSender : nsIMess
    */
   [implicit_jscontext, optional_argc]
   jsval sendRpcMessage([optional] in AString messageName,
                        [optional] in jsval obj,
                        [optional] in jsval objects,
                        [optional] in nsIPrincipal principal);
 };
 
-[scriptable, builtinclass, uuid(e04a7ade-c61a-46ec-9f13-efeabedd9d3d)]
+[scriptable, builtinclass, uuid(13f3555f-769e-44ea-b607-5239230c3162)]
 interface nsIMessageManagerGlobal : nsISyncMessageSender
 {
   /**
    * Print a string to stdout.
    */
   void dump(in DOMString aStr);
 
   /**
@@ -371,23 +378,23 @@ interface nsIContentFrameMessageManager 
   readonly attribute nsIDOMWindow content;
 
   /**
    * The top level docshell or null.
    */
   readonly attribute nsIDocShell docShell;
 };
 
-[uuid(a2325927-9c0c-437d-9215-749c79235031)]
+[uuid(a9e07e89-7125-48e3-bf73-2cbae7fc5b1c)]
 interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
 {
   [notxpcom] nsIContent getOwnerContent();
 };
 
-[scriptable, builtinclass, uuid(9ca95410-b253-11e4-ab27-0800200c9a66)]
+[scriptable, builtinclass, uuid(d0c799a2-d5ff-4a75-acbb-b8c8347944a6)]
 interface nsIContentProcessMessageManager : nsIMessageManagerGlobal
 {
 };
 
 [scriptable, builtinclass, uuid(6fb78110-45ae-11e3-8f96-0800200c9a66)]
 interface nsIFrameScriptLoader : nsISupports
 {
   /**
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -2659,17 +2659,17 @@ nsINode::GetElementById(const nsAString&
     if (id && id->Equals(aId)) {
       return kid->AsElement();
     }
   }
   return nullptr;
 }
 
 JSObject*
-nsINode::WrapObject(JSContext *aCx)
+nsINode::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   // Make sure one of these is true
   // (1) our owner document has a script handling object,
   // (2) Our owner document has had a script handling object, or has been marked
   //     to have had one,
   // (3) we are running a privileged script.
   // Event handling is possible only if (1). If (2) event handling is
   // prevented.
@@ -2678,17 +2678,17 @@ nsINode::WrapObject(JSContext *aCx)
   bool hasHadScriptHandlingObject = false;
   if (!OwnerDoc()->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
       !hasHadScriptHandlingObject &&
       !nsContentUtils::IsCallerChrome()) {
     Throw(aCx, NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
-  JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx));
+  JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx, aGivenProto));
   MOZ_ASSERT_IF(ChromeOnlyAccess(),
                 xpc::IsInContentXBLScope(obj) || !xpc::UseContentXBLScope(js::GetObjectCompartment(obj)));
   return obj;
 }
 
 already_AddRefed<nsINode>
 nsINode::CloneNode(bool aDeep, ErrorResult& aError)
 {
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -362,31 +362,35 @@ public:
    * type, such as Text, Document, Comment ...  Use this when you can instead of
    * checking the tag.
    *
    * @param aFlags what types you want to test for (see above)
    * @return whether the content matches ALL flags passed in
    */
   virtual bool IsNodeOfType(uint32_t aFlags) const = 0;
 
-  virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   /**
    * returns true if we are in priviliged code or
    * layout.css.getBoxQuads.enabled == true.
    */
   static bool HasBoxQuadsSupport(JSContext* aCx, JSObject* /* unused */);
 
 protected:
   /**
    * WrapNode is called from WrapObject to actually wrap this node, WrapObject
    * does some additional checks and fix-up that's common to all nodes. WrapNode
    * should just call the DOM binding's Wrap function.
+   *
+   * aGivenProto is the prototype to use (or null if the default one should be
+   * used) and should just be passed directly on to the DOM binding's Wrap
+   * function.
    */
-  virtual JSObject* WrapNode(JSContext *aCx) = 0;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) = 0;
 
 public:
   mozilla::dom::ParentObject GetParentObject() const; // Implemented in nsIDocument.h
 
   /**
    * Return the scope chain parent for this node, for use in things
    * like event handler compilation.  Returning null means to use the
    * global object as the scope chain parent.
--- a/dom/base/nsInProcessTabChildGlobal.cpp
+++ b/dom/base/nsInProcessTabChildGlobal.cpp
@@ -96,16 +96,17 @@ nsInProcessTabChildGlobal::DoSendAsyncMe
   NS_DispatchToCurrentThread(ev);
   return true;
 }
 
 nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
                                                      nsIContent* aOwner,
                                                      nsFrameMessageManager* aChrome)
 : mDocShell(aShell), mInitialized(false), mLoadingScript(false),
+  mPreventEventsEscaping(false),
   mOwner(aOwner), mChromeMessageManager(aChrome)
 {
   SetIsNotDOMBinding();
   mozilla::HoldJSObjects(this);
 
   // If owner corresponds to an <iframe mozbrowser> or <iframe mozapp>, we'll
   // have to tweak our PreHandleEvent implementation.
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwner);
@@ -202,89 +203,100 @@ nsInProcessTabChildGlobal::GetContent(ns
 NS_IMETHODIMP
 nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
 {
   NS_IF_ADDREF(*aDocShell = mDocShell);
   return NS_OK;
 }
 
 void
-nsInProcessTabChildGlobal::Disconnect()
+nsInProcessTabChildGlobal::FireUnloadEvent()
 {
-  // Let the frame scripts know the child is being closed. We do any other
-  // cleanup after the event has been fired. See DelayedDisconnect
-  nsContentUtils::AddScriptRunner(
-     NS_NewRunnableMethod(this, &nsInProcessTabChildGlobal::DelayedDisconnect)
-  );
+  // We're called from nsDocument::MaybeInitializeFinalizeFrameLoaders, so it
+  // should be safe to run script.
+  MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
+
+  // Don't let the unload event propagate to chrome event handlers.
+  mPreventEventsEscaping = true;
+  DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
+
+  // Allow events fired during docshell destruction (pagehide, unload) to
+  // propagate to the <browser> element since chrome code depends on this.
+  mPreventEventsEscaping = false;
 }
 
 void
-nsInProcessTabChildGlobal::DelayedDisconnect()
+nsInProcessTabChildGlobal::DisconnectEventListeners()
 {
-  // Don't let the event escape
-  mOwner = nullptr;
-
-  // Fire the "unload" event
-  DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
-
-  // Continue with the Disconnect cleanup
   if (mDocShell) {
     nsCOMPtr<nsPIDOMWindow> win = mDocShell->GetWindow();
     if (win) {
       MOZ_ASSERT(win->IsOuterWindow());
       win->SetChromeEventHandler(win->GetChromeEventHandler());
     }
   }
+  if (mListenerManager) {
+    mListenerManager->Disconnect();
+  }
+
   mDocShell = nullptr;
+}
+
+void
+nsInProcessTabChildGlobal::Disconnect()
+{
   mChromeMessageManager = nullptr;
+  mOwner = nullptr;
   if (mMessageManager) {
     static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
     mMessageManager = nullptr;
   }
-  if (mListenerManager) {
-    mListenerManager->Disconnect();
-  }
 }
 
 NS_IMETHODIMP_(nsIContent *)
 nsInProcessTabChildGlobal::GetOwnerContent()
 {
   return mOwner;
 }
 
 nsresult
 nsInProcessTabChildGlobal::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
 
-  if (mIsBrowserOrAppFrame &&
-      (!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
-    if (mOwner) {
-      nsPIDOMWindow* innerWindow = mOwner->OwnerDoc()->GetInnerWindow();
-      if (innerWindow) {
-        aVisitor.mParentTarget = innerWindow->GetParentTarget();
-      }
-    }
-  } else {
-    aVisitor.mParentTarget = mOwner;
-  }
-
 #ifdef DEBUG
   if (mOwner) {
     nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
     nsRefPtr<nsFrameLoader> fl = owner->GetFrameLoader();
     if (fl) {
       NS_ASSERTION(this == fl->GetTabChildGlobalAsEventTarget(),
                    "Wrong event target!");
       NS_ASSERTION(fl->mMessageManager == mChromeMessageManager,
                    "Wrong message manager!");
     }
   }
 #endif
 
+  if (mPreventEventsEscaping) {
+    aVisitor.mParentTarget = nullptr;
+    return NS_OK;
+  }
+
+  if (mIsBrowserOrAppFrame &&
+      (!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
+    if (mOwner) {
+      nsPIDOMWindow* innerWindow = mOwner->OwnerDoc()->GetInnerWindow();
+      if (innerWindow) {
+        aVisitor.mParentTarget = innerWindow->GetParentTarget();
+      }
+    }
+  } else {
+    aVisitor.mParentTarget = mOwner;
+  }
+
   return NS_OK;
 }
 
 nsresult
 nsInProcessTabChildGlobal::InitTabChildGlobal()
 {
   // If you change this, please change GetCompartmentName() in XPCJSRuntime.cpp
   // accordingly.
--- a/dom/base/nsInProcessTabChildGlobal.h
+++ b/dom/base/nsInProcessTabChildGlobal.h
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
 /* vim: set sw=4 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsInProcessTabChildGlobal_h
 #define nsInProcessTabChildGlobal_h
 
@@ -113,16 +113,18 @@ public:
                                                            aWantsUntrusted,
                                                            optional_argc);
   }
   using mozilla::DOMEventTargetHelper::AddEventListener;
 
   virtual JSContext* GetJSContextForEventHandlers() MOZ_OVERRIDE { return nsContentUtils::GetSafeJSContext(); }
   virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE { return mPrincipal; }
   void LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope);
+  void FireUnloadEvent();
+  void DisconnectEventListeners();
   void Disconnect();
   void SendMessageToParent(const nsString& aMessage, bool aSync,
                            const nsString& aJSON,
                            nsTArray<nsString>* aJSONRetVal);
   nsFrameMessageManager* GetInnerManager()
   {
     return static_cast<nsFrameMessageManager*>(mMessageManager.get());
   }
@@ -132,26 +134,24 @@ public:
   {
     return mChromeMessageManager;
   }
   void SetChromeMessageManager(nsFrameMessageManager* aParent)
   {
     mChromeMessageManager = aParent;
   }
 
-  void DelayedDisconnect();
-
   virtual JSObject* GetGlobalJSObject() MOZ_OVERRIDE {
     if (!mGlobal) {
       return nullptr;
     }
 
     return mGlobal->GetJSObject();
   }
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
     MOZ_CRASH("nsInProcessTabChildGlobal doesn't use DOM bindings!");
   }
 protected:
   virtual ~nsInProcessTabChildGlobal();
 
   nsresult Init();
   nsresult InitTabChildGlobal();
@@ -159,15 +159,16 @@ protected:
   nsCOMPtr<nsIDocShell> mDocShell;
   bool mInitialized;
   bool mLoadingScript;
 
   // Is this the message manager for an in-process <iframe mozbrowser> or
   // <iframe mozapp>?  This affects where events get sent, so it affects
   // PreHandleEvent.
   bool mIsBrowserOrAppFrame;
+  bool mPreventEventsEscaping;
 public:
   nsIContent* mOwner;
   nsFrameMessageManager* mChromeMessageManager;
   nsTArray<nsCOMPtr<nsIRunnable> > mASyncMessages;
 };
 
 #endif
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2468,17 +2468,17 @@ NS_DOMReadStructuredClone(JSContext* cx,
 
     // Prevent the return value from being trashed by a GC during ~nsRefPtr.
     JS::Rooted<JSObject*> result(cx);
     {
       nsRefPtr<CryptoKey> key = new CryptoKey(global);
       if (!key->ReadStructuredClone(reader)) {
         result = nullptr;
       } else {
-        result = key->WrapObject(cx);
+        result = key->WrapObject(cx, JS::NullPtr());
       }
     }
     return result;
   } else if (tag == SCTAG_DOM_NULL_PRINCIPAL ||
              tag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
              tag == SCTAG_DOM_CONTENT_PRINCIPAL) {
     mozilla::ipc::PrincipalInfo info;
     if (tag == SCTAG_DOM_SYSTEM_PRINCIPAL) {
@@ -2524,17 +2524,17 @@ NS_DOMReadStructuredClone(JSContext* cx,
       return nullptr;
     }
 
     // Prevent the return value from being trashed by a GC during ~nsRefPtr.
     JS::Rooted<JSObject*> result(cx);
     {
       nsRefPtr<MozNDEFRecord> ndefRecord = new MozNDEFRecord(global);
       result = ndefRecord->ReadStructuredClone(cx, reader) ?
-               ndefRecord->WrapObject(cx) : nullptr;
+               ndefRecord->WrapObject(cx, JS::NullPtr()) : nullptr;
     }
     return result;
 #else
     return nullptr;
 #endif
   }
 
   // Don't know what this is. Bail.
--- a/dom/base/nsLocation.cpp
+++ b/dom/base/nsLocation.cpp
@@ -1048,19 +1048,19 @@ nsLocation::CallerSubsumes()
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(outer);
   bool subsumes = false;
   nsresult rv = nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(sop->GetPrincipal(), &subsumes);
   NS_ENSURE_SUCCESS(rv, false);
   return subsumes;
 }
 
 JSObject*
-nsLocation::WrapObject(JSContext* aCx)
+nsLocation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return LocationBinding::Wrap(aCx, this);
+  return LocationBinding::Wrap(aCx, this, aGivenProto);
 }
 
 URLSearchParams*
 nsLocation::GetDocShellSearchParams()
 {
   nsCOMPtr<nsIDocShell> docShell = GetDocShell();
   if (!docShell) {
     return nullptr;
--- a/dom/base/nsLocation.h
+++ b/dom/base/nsLocation.h
@@ -137,17 +137,17 @@ public:
   void Stringify(nsAString& aRetval, ErrorResult& aError)
   {
     GetHref(aRetval, aError);
   }
   nsPIDOMWindow* GetParentObject() const
   {
     return mInnerWindow;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // URLSearchParamsObserver
   void URLSearchParamsUpdated(mozilla::dom::URLSearchParams* aSearchParams) MOZ_OVERRIDE;
 
 protected:
   virtual ~nsLocation();
 
   nsresult SetSearchInternal(const nsAString& aSearch);
--- a/dom/base/nsMimeTypeArray.cpp
+++ b/dom/base/nsMimeTypeArray.cpp
@@ -35,19 +35,19 @@ nsMimeTypeArray::nsMimeTypeArray(nsPIDOM
 {
 }
 
 nsMimeTypeArray::~nsMimeTypeArray()
 {
 }
 
 JSObject*
-nsMimeTypeArray::WrapObject(JSContext* aCx)
+nsMimeTypeArray::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MimeTypeArrayBinding::Wrap(aCx, this);
+  return MimeTypeArrayBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 nsMimeTypeArray::Refresh()
 {
   mMimeTypes.Clear();
   mHiddenMimeTypes.Clear();
 }
@@ -249,19 +249,19 @@ nsMimeType::~nsMimeType()
 nsPIDOMWindow*
 nsMimeType::GetParentObject() const
 {
   MOZ_ASSERT(mWindow);
   return mWindow;
 }
 
 JSObject*
-nsMimeType::WrapObject(JSContext* aCx)
+nsMimeType::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MimeTypeBinding::Wrap(aCx, this);
+  return MimeTypeBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 nsMimeType::GetDescription(nsString& retval) const
 {
   retval.Truncate();
 
   if (mPluginElement) {
--- a/dom/base/nsMimeTypeArray.h
+++ b/dom/base/nsMimeTypeArray.h
@@ -21,17 +21,17 @@ class nsMimeTypeArray MOZ_FINAL : public
 {
 public:
   explicit nsMimeTypeArray(nsPIDOMWindow* aWindow);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsMimeTypeArray)
 
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void Refresh();
 
   // MimeTypeArray WebIDL methods
   nsMimeType* Item(uint32_t index);
   nsMimeType* NamedItem(const nsAString& name);
   nsMimeType* IndexedGetter(uint32_t index, bool &found);
   nsMimeType* NamedGetter(const nsAString& name, bool &found);
@@ -64,17 +64,17 @@ class nsMimeType MOZ_FINAL : public nsWr
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsMimeType)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsMimeType)
 
   nsMimeType(nsPIDOMWindow* aWindow, nsPluginElement* aPluginElement,
              uint32_t aPluginTagMimeIndex, const nsAString& aMimeType);
   nsMimeType(nsPIDOMWindow* aWindow, const nsAString& aMimeType);
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   const nsString& Type() const
   {
     return mType;
   }
 
   // MimeType WebIDL methods
   void GetDescription(nsString& retval) const;
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -514,19 +514,16 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       nsPIDOMWindow* window = newDoc->GetInnerWindow();
       if (window) {
         EventListenerManager* elm = aNode->GetExistingListenerManager();
         if (elm) {
           window->SetMutationListeners(elm->MutationListenerBits());
           if (elm->MayHavePaintEventListener()) {
             window->SetHasPaintEventListeners();
           }
-          if (elm->MayHaveTouchEventListener()) {
-            window->SetHasTouchEventListeners();
-          }
           if (elm->MayHaveMouseEnterLeaveEventListener()) {
             window->SetHasMouseEnterLeaveEventListeners();
           }
           if (elm->MayHavePointerEnterLeaveEventListener()) {
             window->SetHasPointerEnterLeaveEventListeners();
           }
         }
       }
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -58,18 +58,18 @@ enum PopupControlState {
 enum UIStateChangeType
 {
   UIStateChangeType_NoChange,
   UIStateChangeType_Set,
   UIStateChangeType_Clear
 };
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x19fb3019, 0x7b5d, 0x4235, \
-  { 0xa9, 0x59, 0xa2, 0x31, 0xa2, 0xe7, 0x94, 0x79 } }
+{ 0x4178bd68, 0xa3f7, 0x4ff7, \
+  { 0xa6, 0x27, 0x4a, 0x99, 0xa1, 0xe0, 0x42, 0x37 } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -155,19 +155,16 @@ public:
       NS_ERROR("HasMutationListeners() called on orphan inner window!");
 
       return;
     }
 
     mMutationBits |= aType;
   }
 
-  virtual void MaybeUpdateTouchState() {}
-  virtual void UpdateTouchState() {}
-
   nsIDocument* GetExtantDoc() const
   {
     return mDoc;
   }
   nsIURI* GetDocumentURI() const;
   nsIURI* GetDocBaseURI() const;
 
   nsIDocument* GetDoc()
@@ -435,31 +432,16 @@ public:
    * or content in that document) has a paint event listener.
    */
   bool HasPaintEventListeners()
   {
     return mMayHavePaintEventListener;
   }
   
   /**
-   * Call this to indicate that some node (this window, its document,
-   * or content in that document) has a touch event listener.
-   */
-  void SetHasTouchEventListeners()
-  {
-    mMayHaveTouchEventListener = true;
-    MaybeUpdateTouchState();
-  }
-
-  bool HasTouchEventListeners()
-  {
-    return mMayHaveTouchEventListener;
-  }
-
-  /**
    * Moves the top-level window into fullscreen mode if aIsFullScreen is true,
    * otherwise exits fullscreen. If aRequireTrust is true, this method only
    * changes window state in a context trusted for write.
    *
    * If aHMD is not null, the window is made full screen on the given VR HMD
    * device instead of its currrent display.
    *
    * Outer windows only.
@@ -769,17 +751,16 @@ protected:
   nsTimeout             *mRunningTimeout;
 
   uint32_t               mMutationBits;
 
   bool                   mIsDocumentLoaded;
   bool                   mIsHandlingResizeEvent;
   bool                   mIsInnerWindow;
   bool                   mMayHavePaintEventListener;
-  bool                   mMayHaveTouchEventListener;
   bool                   mMayHaveMouseEnterLeaveEventListener;
   bool                   mMayHavePointerEnterLeaveEventListener;
 
   // This variable is used on both inner and outer windows (and they
   // should match).
   bool                   mIsModalContentWindow;
 
   // Tracks activation state that's used for :-moz-window-inactive.
--- a/dom/base/nsPerformance.cpp
+++ b/dom/base/nsPerformance.cpp
@@ -356,19 +356,19 @@ nsPerformanceTiming::ResponseEnd()
 
 bool
 nsPerformanceTiming::IsInitialized() const
 {
   return mInitialized;
 }
 
 JSObject*
-nsPerformanceTiming::WrapObject(JSContext *cx)
+nsPerformanceTiming::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceTimingBinding::Wrap(cx, this);
+  return PerformanceTimingBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsPerformanceNavigation, mPerformance)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsPerformanceNavigation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsPerformanceNavigation, Release)
 
@@ -378,19 +378,19 @@ nsPerformanceNavigation::nsPerformanceNa
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
 }
 
 nsPerformanceNavigation::~nsPerformanceNavigation()
 {
 }
 
 JSObject*
-nsPerformanceNavigation::WrapObject(JSContext *cx)
+nsPerformanceNavigation::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceNavigationBinding::Wrap(cx, this);
+  return PerformanceNavigationBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(nsPerformance, DOMEventTargetHelper,
                                    mWindow, mTiming,
                                    mNavigation, mEntries,
                                    mParentPerformance)
 NS_IMPL_ADDREF_INHERITED(nsPerformance, DOMEventTargetHelper)
@@ -461,19 +461,19 @@ nsPerformance::Navigation()
 
 DOMHighResTimeStamp
 nsPerformance::Now()
 {
   return GetDOMTiming()->TimeStampToDOMHighRes(TimeStamp::Now());
 }
 
 JSObject*
-nsPerformance::WrapObject(JSContext *cx)
+nsPerformance::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceBinding::Wrap(cx, this);
+  return PerformanceBinding::Wrap(cx, this, aGivenProto);
 }
 
 void
 nsPerformance::GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   retval = mEntries;
--- a/dom/base/nsPerformance.h
+++ b/dom/base/nsPerformance.h
@@ -112,17 +112,17 @@ public:
   inline DOMHighResTimeStamp TimeStampToDOMHighRes(TimeStamp aStamp) const
   {
     MOZ_ASSERT(!aStamp.IsNull());
     mozilla::TimeDuration duration =
         aStamp - GetDOMTiming()->GetNavigationStartTimeStamp();
     return duration.ToMilliseconds() + mZeroTime;
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // PerformanceNavigation WebIDL methods
   DOMTimeMilliSec NavigationStart() const {
     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
       return 0;
     }
     return GetDOMTiming()->GetNavigationStart();
   }
@@ -266,17 +266,17 @@ public:
   nsDOMNavigationTiming* GetDOMTiming() const;
   nsPerformanceTiming* GetPerformanceTiming() const;
 
   nsPerformance* GetParentObject() const
   {
     return mPerformance;
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // PerformanceNavigation WebIDL methods
   uint16_t Type() const {
     return GetDOMTiming()->GetType();
   }
   uint16_t RedirectCount() const {
     return GetPerformanceTiming()->GetRedirectCount();
   }
@@ -314,17 +314,17 @@ public:
     return mParentPerformance;
   }
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mWindow.get();
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // Performance WebIDL methods
   DOMHighResTimeStamp Now();
   nsPerformanceTiming* Timing();
   nsPerformanceNavigation* Navigation();
 
   void GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval);
   void GetEntriesByType(const nsAString& entryType,
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -46,19 +46,19 @@ nsPluginArray::~nsPluginArray()
 nsPIDOMWindow*
 nsPluginArray::GetParentObject() const
 {
   MOZ_ASSERT(mWindow);
   return mWindow;
 }
 
 JSObject*
-nsPluginArray::WrapObject(JSContext* aCx)
+nsPluginArray::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PluginArrayBinding::Wrap(aCx, this);
+  return PluginArrayBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginArray)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginArray)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginArray)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
@@ -394,19 +394,19 @@ nsPluginElement::~nsPluginElement()
 nsPIDOMWindow*
 nsPluginElement::GetParentObject() const
 {
   MOZ_ASSERT(mWindow);
   return mWindow;
 }
 
 JSObject*
-nsPluginElement::WrapObject(JSContext* aCx)
+nsPluginElement::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PluginBinding::Wrap(aCx, this);
+  return PluginBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 nsPluginElement::GetDescription(nsString& retval) const
 {
   CopyUTF8toUTF16(mPluginTag->mDescription, retval);
 }
 
--- a/dom/base/nsPluginArray.h
+++ b/dom/base/nsPluginArray.h
@@ -26,17 +26,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsPluginArray,
                                                          nsIObserver)
 
   // nsIObserver
   NS_DECL_NSIOBSERVER
 
   explicit nsPluginArray(nsPIDOMWindow* aWindow);
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsPluginArray registers itself as an observer with a weak reference.
   // This can't be done in the constructor, because at that point its
   // refcount is 0 (and it gets destroyed upon registration). So, Init()
   // must be called after construction.
   void Init();
   void Invalidate();
 
@@ -80,17 +80,17 @@ class nsPluginElement MOZ_FINAL : public
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPluginElement)
 
   nsPluginElement(nsPIDOMWindow* aWindow, nsPluginTag* aPluginTag);
 
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsPluginTag* PluginTag() const
   {
     return mPluginTag;
   }
 
   // Plugin WebIDL methods
 
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -33,19 +33,19 @@
 #include "mozilla/Telemetry.h"
 #include "mozilla/Likely.h"
 #include "nsCSSFrameConstructor.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 JSObject*
-nsRange::WrapObject(JSContext* aCx)
+nsRange::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return RangeBinding::Wrap(aCx, this);
+  return RangeBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /******************************************************
  * stack based utilty class for managing monitor
  ******************************************************/
 
 static void InvalidateAllFrames(nsINode* aNode)
 {
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -239,17 +239,17 @@ public:
   void SetStartBefore(nsINode& aNode, ErrorResult& aErr);
   void SurroundContents(nsINode& aNode, ErrorResult& aErr);
   already_AddRefed<DOMRect> GetBoundingClientRect(bool aClampToEdge = true,
                                                   bool aFlushLayout = true);
   already_AddRefed<DOMRectList> GetClientRects(bool aClampToEdge = true,
                                                bool aFlushLayout = true);
 
   nsINode* GetParentObject() const { return mOwner; }
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE MOZ_FINAL;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE MOZ_FINAL;
 
 private:
   // no copy's or assigns
   nsRange(const nsRange&);
   nsRange& operator=(const nsRange&);
 
   /**
    * Cut or delete the range's contents.
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -330,19 +330,19 @@ nsScreen::IsDeviceSizePageSize()
       return docShell->GetDeviceSizeIsPageSize();
     }
   }
   return false;
 }
 
 /* virtual */
 JSObject*
-nsScreen::WrapObject(JSContext* aCx)
+nsScreen::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ScreenBinding::Wrap(aCx, this);
+  return ScreenBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS(nsScreen::FullScreenEventListener, nsIDOMEventListener)
 
 NS_IMETHODIMP
 nsScreen::FullScreenEventListener::HandleEvent(nsIDOMEvent* aEvent)
 {
 #ifdef DEBUG
--- a/dom/base/nsScreen.h
+++ b/dom/base/nsScreen.h
@@ -117,17 +117,17 @@ public:
   void GetMozOrientation(nsString& aOrientation);
 
   IMPL_EVENT_HANDLER(mozorientationchange)
 
   bool MozLockOrientation(const nsAString& aOrientation, ErrorResult& aRv);
   bool MozLockOrientation(const mozilla::dom::Sequence<nsString>& aOrientations, ErrorResult& aRv);
   void MozUnlockOrientation();
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) MOZ_OVERRIDE;
 
 protected:
   nsDeviceContext* GetDeviceContext();
   nsresult GetRect(nsRect& aRect);
   nsresult GetAvailRect(nsRect& aRect);
 
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -95,19 +95,19 @@ private:
 nsTextNode::~nsTextNode()
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsTextNode, nsGenericDOMDataNode, nsIDOMNode,
                             nsIDOMText, nsIDOMCharacterData)
 
 JSObject*
-nsTextNode::WrapNode(JSContext *aCx)
+nsTextNode::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return TextBinding::Wrap(aCx, this);
+  return TextBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 nsTextNode::IsNodeOfType(uint32_t aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eTEXT | eDATA_NODE));
 }
 
--- a/dom/base/nsTextNode.h
+++ b/dom/base/nsTextNode.h
@@ -76,12 +76,12 @@ public:
 #ifdef DEBUG
   virtual void List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE;
   virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const MOZ_OVERRIDE;
 #endif
 
 protected:
   virtual ~nsTextNode();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 #endif // nsTextNode_h
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -365,19 +365,19 @@ nsWindowRoot::SetPopupNode(nsIDOMNode* a
 
 nsIGlobalObject*
 nsWindowRoot::GetParentObject()
 {
   return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
 }
 
 JSObject*
-nsWindowRoot::WrapObject(JSContext* aCx)
+nsWindowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::WindowRootBinding::Wrap(aCx, this);
+  return mozilla::dom::WindowRootBinding::Wrap(aCx, this, aGivenProto);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
 
 already_AddRefed<EventTarget>
 NS_NewWindowRoot(nsPIDOMWindow* aWindow)
 {
   nsCOMPtr<EventTarget> result = new nsWindowRoot(aWindow);
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -64,17 +64,17 @@ public:
   {
     mParent = aTarget;
   }
   virtual mozilla::dom::EventTarget* GetParentTarget() MOZ_OVERRIDE { return mParent; }
   virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE;
 
   nsIGlobalObject* GetParentObject();
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot,
                                                          nsIDOMEventTarget)
 
 protected:
   virtual ~nsWindowRoot();
 
   void GetEnabledDisabledCommandsForControllers(nsIControllers* aControllers,
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -147,17 +147,17 @@ public:
   {
     return !HasWrapperFlag(WRAPPER_IS_NOT_DOM_BINDING);
   }
 
   /**
    * Wrap the object corresponding to this wrapper cache. If non-null is
    * returned, the object has already been stored in the wrapper cache.
    */
-  virtual JSObject* WrapObject(JSContext* cx) = 0;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) = 0;
 
   /**
    * Returns true if the object has a non-gray wrapper.
    */
   bool IsBlack();
 
   /**
    * Returns true if the object has a black wrapper,
--- a/dom/base/nsXMLHttpRequest.cpp
+++ b/dom/base/nsXMLHttpRequest.cpp
@@ -270,19 +270,19 @@ nsXHREventTarget::DisconnectFromOwner()
 NS_INTERFACE_MAP_BEGIN(nsXMLHttpRequestUpload)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUpload)
 NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
 
 NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
 NS_IMPL_RELEASE_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
 
 /* virtual */ JSObject*
-nsXMLHttpRequestUpload::WrapObject(JSContext* aCx)
+nsXMLHttpRequestUpload::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return XMLHttpRequestUploadBinding::Wrap(aCx, this);
+  return XMLHttpRequestUploadBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /////////////////////////////////////////////
 //
 //
 /////////////////////////////////////////////
 
 bool
--- a/dom/base/nsXMLHttpRequest.h
+++ b/dom/base/nsXMLHttpRequest.h
@@ -155,17 +155,17 @@ public:
   {
   }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget)
   NS_DECL_NSIXMLHTTPREQUESTUPLOAD
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return GetOwner();
   }
 
   bool HasListeners()
   {
     return mListenerManager && mListenerManager->HasListeners();
@@ -191,19 +191,19 @@ class nsXMLHttpRequest MOZ_FINAL : publi
                                    public nsISizeOfEventTarget
 {
   friend class nsXHRParseEndListener;
   friend class nsXMLHttpRequestXPCOMifier;
 
 public:
   nsXMLHttpRequest();
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::XMLHttpRequestBinding::Wrap(cx, this);
+    return mozilla::dom::XMLHttpRequestBinding::Wrap(cx, this, aGivenProto);
   }
   nsISupports* GetParentObject()
   {
     return GetOwner();
   }
 
   // The WebIDL constructors.
   static already_AddRefed<nsXMLHttpRequest>
--- a/dom/base/test/browser.ini
+++ b/dom/base/test/browser.ini
@@ -1,12 +1,17 @@
 [DEFAULT]
+support-files =
+  file_messagemanager_unload.html
 
 [browser_bug593387.js]
 skip-if = e10s # Bug ?????? - test directly touches content (contentWindow.iframe.addEventListener)
 [browser_bug902350.js]
 skip-if = e10s # Bug ?????? - test e10s utils don't support load events from iframe etc, which this test relies on.
 [browser_messagemanager_loadprocessscript.js]
+[browser_pagehide_on_tab_close.js]
+skip-if = e10s # this tests non-e10s behavior. it's not expected to work in e10s.
+[browser_messagemanager_unload.js]
 [browser_state_notifications.js]
 # skip-if = e10s # Bug ?????? - content-document-* notifications come while document's URI is still about:blank, but test expects real URL.
 skip-if = true # Intermittent failures - bug 987493. Restore the skip-if above once fixed
 [browser_bug1058164.js]
 skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.
new file mode 100644
--- /dev/null
+++ b/dom/base/test/browser_messagemanager_unload.js
@@ -0,0 +1,98 @@
+function frameScript()
+{
+  Components.utils.import("resource://gre/modules/Services.jsm");
+
+  function eventHandler(e) {
+    if (!docShell) {
+      sendAsyncMessage("Test:Fail", "docShell is null");
+    }
+
+    sendAsyncMessage("Test:Event", [e.type, e.target === content.document, e.eventPhase]);
+  }
+
+  let outerID = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+        getInterface(Components.interfaces.nsIDOMWindowUtils).outerWindowID;
+  function onOuterWindowDestroyed(subject, topic, data) {
+    if (docShell) {
+      sendAsyncMessage("Test:Fail", "docShell is non-null");
+    }
+
+    let id = subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data;
+    sendAsyncMessage("Test:Event", ["outer-window-destroyed", id == outerID]);
+    if (id == outerID) {
+      Services.obs.removeObserver(onOuterWindowDestroyed, "outer-window-destroyed");
+    }
+  }
+
+  let url = "https://example.com/browser/dom/base/test/file_messagemanager_unload.html";
+
+  content.location = url;
+  addEventListener("load", (e) => {
+    if (e.target.location != url) {
+      return;
+    }
+
+    addEventListener("unload", eventHandler, false);
+    addEventListener("unload", eventHandler, true);
+    addEventListener("pagehide", eventHandler, false);
+    addEventListener("pagehide", eventHandler, true);
+    Services.obs.addObserver(onOuterWindowDestroyed, "outer-window-destroyed", false);
+
+    sendAsyncMessage("Test:Ready");
+  }, true);
+}
+
+const EXPECTED = [
+  // Unload events on the TabChildGlobal. These come first so that the
+  // docshell is available.
+  ["unload", false, 2],
+  ["unload", false, 2],
+
+  // pagehide and unload events for the top-level page.
+  ["pagehide", true, 1],
+  ["pagehide", true, 3],
+  ["unload", true, 1],
+
+  // pagehide and unload events for the iframe.
+  ["pagehide", false, 1],
+  ["pagehide", false, 3],
+  ["unload", false, 1],
+
+  // outer-window-destroyed for both pages.
+  ["outer-window-destroyed", false],
+  ["outer-window-destroyed", true],
+];
+
+function test() {
+  waitForExplicitFinish();
+
+  var newTab = gBrowser.addTab("about:blank");
+  gBrowser.selectedTab = newTab;
+
+  let browser = newTab.linkedBrowser;
+
+  browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false);
+
+  browser.messageManager.addMessageListener("Test:Fail", (msg) => {
+    ok(false, msg.data);
+  }, true);
+
+  let index = 0;
+  browser.messageManager.addMessageListener("Test:Event", (msg) => {
+    ok(msg.target === browser, "<browser> is correct");
+
+    info(JSON.stringify(msg.data));
+
+    is(JSON.stringify(msg.data), JSON.stringify(EXPECTED[index]), "results match");
+    index++;
+
+    if (index == EXPECTED.length) {
+      finish();
+    }
+  }, true);
+
+  browser.messageManager.addMessageListener("Test:Ready", () => {
+    info("Got ready message");
+    gBrowser.removeCurrentTab();
+  });
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/test/browser_pagehide_on_tab_close.js
@@ -0,0 +1,17 @@
+function test() {
+  waitForExplicitFinish();
+
+  var tab = gBrowser.addTab();
+  gBrowser.selectedTab = tab;
+
+  tab.linkedBrowser.addEventListener("load", function onload() {
+    tab.linkedBrowser.removeEventListener("load", onload);
+
+    tab.linkedBrowser.addEventListener("pagehide", function() {
+      ok(true, "got page hide event");
+      finish();
+    });
+
+    executeSoon(() => { gBrowser.removeTab(tab); });
+  }, true);
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_messagemanager_unload.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <iframe id="frame" src="about:robots"></iframe>
+  </body>
+</html>
--- a/dom/battery/BatteryManager.cpp
+++ b/dom/battery/BatteryManager.cpp
@@ -45,19 +45,19 @@ BatteryManager::Init()
 
 void
 BatteryManager::Shutdown()
 {
   hal::UnregisterBatteryObserver(this);
 }
 
 JSObject*
-BatteryManager::WrapObject(JSContext* aCx)
+BatteryManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BatteryManagerBinding::Wrap(aCx, this);
+  return BatteryManagerBinding::Wrap(aCx, this, aGivenProto);
 }
 
 double
 BatteryManager::DischargingTime() const
 {
   if (mCharging || mRemainingTime == kUnknownRemainingTime) {
     return std::numeric_limits<double>::infinity();
   }
--- a/dom/battery/BatteryManager.h
+++ b/dom/battery/BatteryManager.h
@@ -39,17 +39,17 @@ public:
    * WebIDL Interface
    */
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   bool Charging() const
   {
     return mCharging;
   }
 
   double ChargingTime() const;
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -747,17 +747,17 @@ NativeInterface2JSObjectAndThrowIfFailed
   nsresult rv;
   // Inline some logic from XPCConvert::NativeInterfaceToJSObject that we need
   // on all threads.
   nsWrapperCache *cache = aHelper.GetWrapperCache();
 
   if (cache && cache->IsDOMBinding()) {
       JS::Rooted<JSObject*> obj(aCx, cache->GetWrapper());
       if (!obj) {
-          obj = cache->WrapObject(aCx);
+        obj = cache->WrapObject(aCx, JS::NullPtr());
       }
 
       if (obj && aAllowNativeWrapper && !JS_WrapObject(aCx, &obj)) {
         return false;
       }
 
       if (obj) {
         aRetval.setObject(*obj);
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -925,17 +925,17 @@ DoGetOrCreateDOMReflector(JSContext* cx,
   if (obj) {
     JS::ExposeObjectToActiveJS(obj);
   } else {
     // Inline this here while we have non-dom objects in wrapper caches.
     if (!couldBeDOMBinding) {
       return false;
     }
 
-    obj = value->WrapObject(cx);
+    obj = value->WrapObject(cx, JS::NullPtr());
     if (!obj) {
       // At this point, obj is null, so just return false.
       // Callers seem to be testing JS_IsExceptionPending(cx) to
       // figure out whether WrapObject() threw.
       return false;
     }
   }
 
@@ -1033,17 +1033,17 @@ WrapNewBindingNonWrapperCachedObject(JSC
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    if (!value->WrapObject(cx, &obj)) {
+    if (!value->WrapObject(cx, JS::NullPtr(), &obj)) {
       return false;
     }
   }
 
   // We can end up here in all sorts of compartments, per above.  Make
   // sure to JS_WrapValue!
   rval.set(JS::ObjectValue(*obj));
   return JS_WrapValue(cx, rval);
@@ -1079,17 +1079,17 @@ WrapNewBindingNonWrapperCachedObject(JSC
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    if (!value->WrapObject(cx, &obj)) {
+    if (!value->WrapObject(cx, JS::NullPtr(), &obj)) {
       return false;
     }
 
     value.forget();
   }
 
   // We can end up here in all sorts of compartments, per above.  Make
   // sure to JS_WrapValue!
@@ -1515,17 +1515,17 @@ struct WrapNativeParentHelper
     if ((obj = cache->GetWrapper())) {
       return obj;
     }
 
     // Inline this here while we have non-dom objects in wrapper caches.
     if (!CouldBeDOMBinding(parent)) {
       obj = WrapNativeParentFallback<T>::Wrap(cx, parent, cache);
     } else {
-      obj = parent->WrapObject(cx);
+      obj = parent->WrapObject(cx, JS::NullPtr());
     }
 
     return obj;
   }
 };
 
 // Wrapping of our native parent, for cases when it's not a WebIDL object.  In
 // this case it must be nsISupports.
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3177,21 +3177,18 @@ def CopyUnforgeablePropertiesToInstance(
     # unforgeable holder for those with the right JSClass.  Luckily, there
     # aren't too many globals being created.
     if descriptor.isGlobal():
         copyFunc = "JS_CopyPropertiesFrom"
     else:
         copyFunc = "JS_InitializePropertiesFromCompatibleNativeObject"
     copyCode.append(CGGeneric(fill(
         """
-        // XXXbz Once we allow subclassing, we'll want to make sure that
-        // this uses the canonical proto, not whatever random passed-in
-        // proto we end up using for the object.
         JS::Rooted<JSObject*> unforgeableHolder(aCx,
-          &js::GetReservedSlot(proto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
+          &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
         if (!${copyFunc}(aCx, ${obj}, unforgeableHolder)) {
           $*{cleanup}
           return false;
         }
         """,
         copyFunc=copyFunc,
         obj=obj,
         cleanup=cleanup)))
@@ -3238,124 +3235,150 @@ def InitMemberSlots(descriptor, wrapperC
         if (!UpdateMemberSlots(aCx, aReflector, aObject)) {
           $*{clearWrapper}
           return false;
         }
         """,
         clearWrapper=clearWrapper)
 
 
+def DeclareProto():
+    """
+    Declare the canonicalProto and proto we have for our wrapping operation.
+    """
+    return dedent(
+        """
+        JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx, global);
+        if (!canonicalProto) {
+          return false;
+        }
+        JS::Rooted<JSObject*> proto(aCx);
+        if (aGivenProto) {
+          proto = aGivenProto;
+          if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
+            if (!JS_WrapObject(aCx, &proto)) {
+              return false;
+            }
+          }
+        } else {
+          proto = canonicalProto;
+        }
+        """)
+
+
 class CGWrapWithCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that implements nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
                 Argument('nsWrapperCache*', 'aCache'),
+                Argument('JS::Handle<JSObject*>', 'aGivenProto'),
                 Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
-            $*{assertion}
+            $*{assertInheritance}
+            MOZ_ASSERT_IF(aGivenProto, !aCache->GetWrapper());
 
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
                        "nsISupports must be on our primary inheritance chain");
 
             JS::Rooted<JSObject*> parent(aCx, WrapNativeParent(aCx, aObject->GetParentObject()));
             if (!parent) {
               return false;
             }
 
             // That might have ended up wrapping us already, due to the wonders
             // of XBL.  Check for that, and bail out as needed.
             aReflector.set(aCache->GetWrapper());
             if (aReflector) {
+              MOZ_ASSERT(!aGivenProto,
+                         "How are we supposed to change the proto now?");
               return true;
             }
 
             JSAutoCompartment ac(aCx, parent);
             JS::Rooted<JSObject*> global(aCx, js::GetGlobalForObjectCrossCompartment(parent));
-            JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
-            if (!proto) {
-              return false;
-            }
+            $*{declareProto}
 
             $*{createObject}
 
             aCache->SetWrapper(aReflector);
             $*{unforgeable}
             $*{slots}
             creator.InitializationSucceeded();
             return true;
             """,
-            assertion=AssertInheritanceChain(self.descriptor),
+            assertInheritance=AssertInheritanceChain(self.descriptor),
+            declareProto=DeclareProto(),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, True),
             slots=InitMemberSlots(self.descriptor, True))
 
 
 class CGWrapMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
-                Argument('T*', 'aObject')]
+                Argument('T*', 'aObject'),
+                Argument('JS::Handle<JSObject*>', 'aGivenProto')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args,
                                   inline=True, templateArgs=["class T"])
 
     def definition_body(self):
         return dedent("""
             JS::Rooted<JSObject*> reflector(aCx);
-            return Wrap(aCx, aObject, aObject, &reflector) ? reflector.get() : nullptr;
+            return Wrap(aCx, aObject, aObject, aGivenProto, &reflector) ? reflector.get() : nullptr;
             """)
 
 
 class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that does not implement
     nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
+                Argument('JS::Handle<JSObject*>', 'aGivenProto'),
                 Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
             $*{assertions}
 
             JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
-            JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
-            if (!proto) {
-              return false;
-            }
+            $*{declareProto}
 
             $*{createObject}
 
             $*{unforgeable}
 
             $*{slots}
             creator.InitializationSucceeded();
             return true;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
+            declareProto=DeclareProto(),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, False),
             slots=InitMemberSlots(self.descriptor, False))
 
 
 class CGWrapGlobalMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a global.  The global must implement
@@ -3389,20 +3412,20 @@ class CGWrapGlobalMethod(CGAbstractMetho
         if self.descriptor.workers:
             fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
 // JS_FireOnNewGlobalObject(aCx, aReflector);
 """
         else:
             fireOnNewGlobal = ""
 
         if self.descriptor.hasUnforgeableMembers:
-            declareProto = "JS::Handle<JSObject*> proto =\n"
+            declareProto = "JS::Handle<JSObject*> canonicalProto =\n"
             assertProto = (
-                "MOZ_ASSERT(proto &&\n"
-                "           IsDOMIfaceAndProtoClass(js::GetObjectClass(proto)));\n")
+                "MOZ_ASSERT(canonicalProto &&\n"
+                "           IsDOMIfaceAndProtoClass(js::GetObjectClass(canonicalProto)));\n")
         else:
             declareProto = ""
             assertProto = ""
 
         return fill(
             """
             $*{assertions}
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
@@ -13078,17 +13101,18 @@ class CGBindingImplClass(CGClass):
                     descriptor, FakeMember(),
                     "NameIsEnumerable",
                     (BuiltinTypes[IDLBuiltinType.Types.boolean],
                      [FakeArgument(BuiltinTypes[IDLBuiltinType.Types.domstring],
                                    FakeMember(),
                                    name="aName")]),
                     { "infallible": True }))
 
-        wrapArgs = [Argument('JSContext*', 'aCx')]
+        wrapArgs = [Argument('JSContext*', 'aCx'),
+                    Argument('JS::Handle<JSObject*>', 'aGivenProto')]
         self.methodDecls.insert(0,
                                 ClassMethod(wrapMethodName, "JSObject*",
                                             wrapArgs, virtual=descriptor.wrapperCache,
                                             breakAfterReturnDecl=" ",
                                             override=descriptor.wrapperCache,
                                             body=self.getWrapObjectBody()))
         if wantGetParent:
             self.methodDecls.insert(0,
@@ -13198,19 +13222,19 @@ class CGExampleClass(CGBindingImplClass)
                   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
                   NS_INTERFACE_MAP_ENTRY(nsISupports)
                 NS_INTERFACE_MAP_END
 
                 """)
 
         classImpl = ccImpl + ctordtor + "\n" + dedent("""
             JSObject*
-            ${nativeType}::WrapObject(JSContext* aCx)
+            ${nativeType}::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
             {
-              return ${ifaceName}Binding::Wrap(aCx, this);
+              return ${ifaceName}Binding::Wrap(aCx, this, aGivenProto);
             }
 
             """)
         return string.Template(classImpl).substitute(
             ifaceName=self.descriptor.name,
             nativeType=self.nativeLeafName(self.descriptor),
             parentType=self.nativeLeafName(self.parentDesc) if self.parentIface else "")
 
@@ -13568,17 +13592,17 @@ class CGJSImplClass(CGBindingImplClass):
                          methods=self.methodDecls,
                          decorators=decorators,
                          extradeclarations=extradeclarations,
                          extradefinitions=extradefinitions)
 
     def getWrapObjectBody(self):
         return fill(
             """
-            JS::Rooted<JSObject*> obj(aCx, ${name}Binding::Wrap(aCx, this));
+            JS::Rooted<JSObject*> obj(aCx, ${name}Binding::Wrap(aCx, this, aGivenProto));
             if (!obj) {
               return nullptr;
             }
 
             // Now define it on our chrome object
             JSAutoCompartment ac(aCx, mImpl->Callback());
             if (!JS_WrapObject(aCx, &obj)) {
               return nullptr;
@@ -14961,17 +14985,17 @@ class CGEventClass(CGBindingImplClass):
 
         CGClass.__init__(self, className,
                          bases=[ClassBase(self.parentType)],
                          methods=[asConcreteTypeMethod]+self.methodDecls,
                          members=members,
                          extradeclarations=baseDeclarations)
 
     def getWrapObjectBody(self):
-        return "return %sBinding::Wrap(aCx, this);\n" % self.descriptor.name
+        return "return %sBinding::Wrap(aCx, this, aGivenProto);\n" % self.descriptor.name
 
     def implTraverse(self):
         retVal = ""
         for m in self.descriptor.interface.members:
             # Unroll the type so we pick up sequences of interfaces too.
             if m.isAttr() and idlTypeNeedsCycleCollection(m.type):
                 retVal += ("  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(" +
                            CGDictionary.makeMemberName(m.identifier.name) +
--- a/dom/bindings/StructuredClone.cpp
+++ b/dom/bindings/StructuredClone.cpp
@@ -27,17 +27,17 @@ ReadStructuredCloneImageData(JSContext* 
 
   // Protect the result from a moving GC in ~nsRefPtr.
   JS::Rooted<JSObject*> result(aCx);
   {
     // Construct the ImageData.
     nsRefPtr<ImageData> imageData = new ImageData(width, height,
                                                   dataArray.toObject());
     // Wrap it in a JS::Value.
-    if (!imageData->WrapObject(aCx, &result)) {
+    if (!imageData->WrapObject(aCx, JS::NullPtr(), &result)) {
       return nullptr;
     }
   }
   return result;
 }
 
 bool
 WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter,
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -85,17 +85,17 @@ public:
 
 NS_DEFINE_STATIC_IID_ACCESSOR(TestExternalInterface, NS_TEST_EXTERNAL_INTERFACE_IID)
 
 class TestNonWrapperCacheInterface : public nsISupports
 {
 public:
   NS_DECL_ISUPPORTS
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 };
 
 class OnlyForUseInConstructor : public nsISupports,
                                 public nsWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS
   // We need a GetParentObject to make binding codegen happy
--- a/dom/bindings/test/test_Object.prototype_props.html
+++ b/dom/bindings/test/test_Object.prototype_props.html
@@ -2,19 +2,16 @@
 <meta charset=utf-8>
 <title>Test for bug 987110</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 test(function() {
   var props = Object.getOwnPropertyNames(Object.prototype);
-  // getOwnPropertyNames intentionally filters out the non-standard
-  // "__proto__" property.
-  props.push("__proto__");
   // If you change this list, make sure it continues to match the list in
   // Codegen.py's CGDictionary.getMemberDefinition method.
   var expected = [
       "constructor", "toSource", "toString", "toLocaleString", "valueOf",
       "watch", "unwatch", "hasOwnProperty", "isPrototypeOf",
       "propertyIsEnumerable", "__defineGetter__", "__defineSetter__",
       "__lookupGetter__", "__lookupSetter__", "__proto__"
     ];
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -1062,12 +1062,12 @@ BluetoothAdapter::SendMediaPlayStatus(co
                      aMediaPlayStatus.mPosition,
                      aMediaPlayStatus.mPlayStatus,
                      results);
 
   return request.forget();
 }
 
 JSObject*
-BluetoothAdapter::WrapObject(JSContext* aCx)
+BluetoothAdapter::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothAdapterBinding::Wrap(aCx, this);
+  return BluetoothAdapterBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth/BluetoothAdapter.h
+++ b/dom/bluetooth/BluetoothAdapter.h
@@ -164,17 +164,17 @@ public:
   IMPL_EVENT_HANDLER(scostatuschanged);
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
   virtual JSObject*
-    WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+    WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
   ~BluetoothAdapter();
 
   void Root();
 
   already_AddRefed<mozilla::dom::DOMRequest>
--- a/dom/bluetooth/BluetoothDevice.cpp
+++ b/dom/bluetooth/BluetoothDevice.cpp
@@ -229,12 +229,12 @@ BluetoothDevice::GetServices(JSContext* 
     return;
   }
 
   JS::ExposeObjectToActiveJS(mJsServices);
   aServices.setObject(*mJsServices);
 }
 
 JSObject*
-BluetoothDevice::WrapObject(JSContext* aContext)
+BluetoothDevice::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothDeviceBinding::Wrap(aContext, this);
+  return BluetoothDeviceBinding::Wrap(aContext, this, aGivenProto);
 }
--- a/dom/bluetooth/BluetoothDevice.h
+++ b/dom/bluetooth/BluetoothDevice.h
@@ -82,17 +82,17 @@ public:
   void Unroot();
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
   virtual JSObject*
-    WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+    WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
 private:
   BluetoothDevice(nsPIDOMWindow* aOwner, const nsAString& aAdapterPath,
                   const BluetoothValue& aValue);
   ~BluetoothDevice();
   void Root();
--- a/dom/bluetooth/BluetoothManager.cpp
+++ b/dom/bluetooth/BluetoothManager.cpp
@@ -205,12 +205,12 @@ BluetoothManager::Notify(const Bluetooth
     warningMsg.AssignLiteral("Not handling manager signal: ");
     warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
     BT_WARNING(warningMsg.get());
 #endif
   }
 }
 
 JSObject*
-BluetoothManager::WrapObject(JSContext* aCx)
+BluetoothManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothManagerBinding::Wrap(aCx, this);
+  return BluetoothManagerBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth/BluetoothManager.h
+++ b/dom/bluetooth/BluetoothManager.h
@@ -47,17 +47,17 @@ public:
   IMPL_EVENT_HANDLER(adapteradded);
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
   virtual JSObject*
-    WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+    WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
 private:
   BluetoothManager(nsPIDOMWindow* aWindow);
   ~BluetoothManager();
 };
 
--- a/dom/bluetooth2/BluetoothAdapter.cpp
+++ b/dom/bluetooth2/BluetoothAdapter.cpp
@@ -1317,12 +1317,12 @@ BluetoothAdapter::SendMediaPlayStatus(co
                      aMediaPlayStatus.mPosition,
                      aMediaPlayStatus.mPlayStatus,
                      results);
 
   return request.forget();
 }
 
 JSObject*
-BluetoothAdapter::WrapObject(JSContext* aCx)
+BluetoothAdapter::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothAdapterBinding::Wrap(aCx, this);
+  return BluetoothAdapterBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothAdapter.h
+++ b/dom/bluetooth2/BluetoothAdapter.h
@@ -159,17 +159,17 @@ public:
     Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
 
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   /**
    * Set this adapter's discovery handle in use (mDiscoveryHandleInUse).
    *
    * |mDiscoveryHandleInUse| is set to the latest discovery handle when adapter
    * just starts discovery, and is reset to nullptr when discovery is stopped
    * by some adapter.
--- a/dom/bluetooth2/BluetoothClassOfDevice.cpp
+++ b/dom/bluetooth2/BluetoothClassOfDevice.cpp
@@ -90,12 +90,12 @@ BluetoothClassOfDevice::Create(nsPIDOMWi
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aOwner);
 
   nsRefPtr<BluetoothClassOfDevice> cod = new BluetoothClassOfDevice(aOwner);
   return cod.forget();
 }
 
 JSObject*
-BluetoothClassOfDevice::WrapObject(JSContext* aCx)
+BluetoothClassOfDevice::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothClassOfDeviceBinding::Wrap(aCx, this);
+  return BluetoothClassOfDeviceBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothClassOfDevice.h
+++ b/dom/bluetooth2/BluetoothClassOfDevice.h
@@ -64,17 +64,17 @@ public:
    * @param aValue [in] CoD value to update
    */
   void Update(const uint32_t aValue);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mOwnerWindow;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   BluetoothClassOfDevice(nsPIDOMWindow* aOwner);
   ~BluetoothClassOfDevice();
 
   /**
    * Reset CoD to default value.
    */
--- a/dom/bluetooth2/BluetoothDevice.cpp
+++ b/dom/bluetooth2/BluetoothDevice.cpp
@@ -315,12 +315,12 @@ BluetoothDevice::GetGatt()
   if (!mGatt) {
     mGatt = new BluetoothGatt(GetOwner(), mAddress);
   }
 
   return mGatt;
 }
 
 JSObject*
-BluetoothDevice::WrapObject(JSContext* aContext)
+BluetoothDevice::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothDeviceBinding::Wrap(aContext, this);
+  return BluetoothDeviceBinding::Wrap(aContext, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothDevice.h
+++ b/dom/bluetooth2/BluetoothDevice.h
@@ -89,17 +89,17 @@ public:
     Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
 
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
 private:
   BluetoothDevice(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
   ~BluetoothDevice();
 
   /**
    * Set device properties according to properties array
--- a/dom/bluetooth2/BluetoothDiscoveryHandle.cpp
+++ b/dom/bluetooth2/BluetoothDiscoveryHandle.cpp
@@ -53,12 +53,12 @@ BluetoothDiscoveryHandle::DispatchDevice
   nsRefPtr<BluetoothDeviceEvent> event =
     BluetoothDeviceEvent::Constructor(this,
                                       NS_LITERAL_STRING("devicefound"),
                                       init);
   DispatchTrustedEvent(event);
 }
 
 JSObject*
-BluetoothDiscoveryHandle::WrapObject(JSContext* aCx)
+BluetoothDiscoveryHandle::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothDiscoveryHandleBinding::Wrap(aCx, this);
+  return BluetoothDiscoveryHandleBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothDiscoveryHandle.h
+++ b/dom/bluetooth2/BluetoothDiscoveryHandle.h
@@ -25,17 +25,17 @@ public:
 
   static already_AddRefed<BluetoothDiscoveryHandle>
     Create(nsPIDOMWindow* aWindow);
 
   void DispatchDeviceEvent(BluetoothDevice* aDevice);
 
   IMPL_EVENT_HANDLER(devicefound);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   BluetoothDiscoveryHandle(nsPIDOMWindow* aWindow);
   ~BluetoothDiscoveryHandle();
 };
 
 END_BLUETOOTH_NAMESPACE
 
--- a/dom/bluetooth2/BluetoothGatt.cpp
+++ b/dom/bluetooth2/BluetoothGatt.cpp
@@ -255,12 +255,12 @@ BluetoothGatt::Notify(const BluetoothSig
     UpdateConnectionState(state);
   } else {
     BT_WARNING("Not handling GATT signal: %s",
                NS_ConvertUTF16toUTF8(aData.name()).get());
   }
 }
 
 JSObject*
-BluetoothGatt::WrapObject(JSContext* aContext)
+BluetoothGatt::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothGattBinding::Wrap(aContext, this);
+  return BluetoothGattBinding::Wrap(aContext, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothGatt.h
+++ b/dom/bluetooth2/BluetoothGatt.h
@@ -58,17 +58,17 @@ public:
    ***************************************************************************/
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   BluetoothGatt(nsPIDOMWindow* aOwner,
                 const nsAString& aDeviceAddr);
 
 private:
   ~BluetoothGatt();
 
--- a/dom/bluetooth2/BluetoothManager.cpp
+++ b/dom/bluetooth2/BluetoothManager.cpp
@@ -282,12 +282,12 @@ BluetoothManager::Notify(const Bluetooth
     HandleAdapterRemoved(aData.value());
   } else {
     BT_WARNING("Not handling manager signal: %s",
                NS_ConvertUTF16toUTF8(aData.name()).get());
   }
 }
 
 JSObject*
-BluetoothManager::WrapObject(JSContext* aCx)
+BluetoothManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothManagerBinding::Wrap(aCx, this);
+  return BluetoothManagerBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothManager.h
+++ b/dom/bluetooth2/BluetoothManager.h
@@ -58,17 +58,17 @@ public:
   static bool CheckPermission(nsPIDOMWindow* aWindow);
 
   void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   /**
    * Create a BluetoothAdapter object based on properties array
    * and append it into adapters array.
    *
    * @param aValue [in] Properties array to create BluetoothAdapter object
    */
--- a/dom/bluetooth2/BluetoothPairingHandle.cpp
+++ b/dom/bluetooth2/BluetoothPairingHandle.cpp
@@ -116,12 +116,12 @@ BluetoothPairingHandle::SetPairingConfir
 
   bs->SetPairingConfirmationInternal(mDeviceAddress,
                                      aConfirm,
                                      result);
   return promise.forget();
 }
 
 JSObject*
-BluetoothPairingHandle::WrapObject(JSContext* aCx)
+BluetoothPairingHandle::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothPairingHandleBinding::Wrap(aCx, this);
+  return BluetoothPairingHandleBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothPairingHandle.h
+++ b/dom/bluetooth2/BluetoothPairingHandle.h
@@ -34,17 +34,17 @@ public:
            const nsAString& aType,
            const nsAString& aPasskey);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetPasskey(nsString& aPasskey) const
   {
     aPasskey = mPasskey;
   }
 
   already_AddRefed<Promise>
     SetPinCode(const nsAString& aPinCode, ErrorResult& aRv);
--- a/dom/bluetooth2/BluetoothPairingListener.cpp
+++ b/dom/bluetooth2/BluetoothPairingListener.cpp
@@ -103,19 +103,19 @@ BluetoothPairingListener::Notify(const B
     DispatchPairingEvent(name, address, passkey, type);
   } else {
     BT_WARNING("Not handling pairing listener signal: %s",
                NS_ConvertUTF16toUTF8(aData.name()).get());
   }
 }
 
 JSObject*
-BluetoothPairingListener::WrapObject(JSContext* aCx)
+BluetoothPairingListener::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothPairingListenerBinding::Wrap(aCx, this);
+  return BluetoothPairingListenerBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 BluetoothPairingListener::DisconnectFromOwner()
 {
   DOMEventTargetHelper::DisconnectFromOwner();
 
   BluetoothService* bs = BluetoothService::Get();
--- a/dom/bluetooth2/BluetoothPairingListener.h
+++ b/dom/bluetooth2/BluetoothPairingListener.h
@@ -32,17 +32,17 @@ public:
 
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
   virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
 
   IMPL_EVENT_HANDLER(displaypasskeyreq);
   IMPL_EVENT_HANDLER(enterpincodereq);
   IMPL_EVENT_HANDLER(pairingconfirmationreq);
   IMPL_EVENT_HANDLER(pairingconsentreq);
 
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -411,19 +411,19 @@ BroadcastChannel::BroadcastChannel(nsPID
 
 BroadcastChannel::~BroadcastChannel()
 {
   Shutdown();
   MOZ_ASSERT(!mWorkerFeature);
 }
 
 JSObject*
-BroadcastChannel::WrapObject(JSContext* aCx)
+BroadcastChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BroadcastChannelBinding::Wrap(aCx, this);
+  return BroadcastChannelBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<BroadcastChannel>
 BroadcastChannel::Constructor(const GlobalObject& aGlobal,
                               const nsAString& aChannel,
                               ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
--- a/dom/broadcastchannel/BroadcastChannel.h
+++ b/dom/broadcastchannel/BroadcastChannel.h
@@ -44,17 +44,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BroadcastChannel,
                                            DOMEventTargetHelper)
 
   static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<BroadcastChannel>
   Constructor(const GlobalObject& aGlobal, const nsAString& aChannel,
               ErrorResult& aRv);
 
   void GetName(nsAString& aName) const
   {
     aName = mChannel;
--- a/dom/cache/Cache.cpp
+++ b/dom/cache/Cache.cpp
@@ -370,19 +370,19 @@ Cache::PrefEnabled(JSContext* aCx, JSObj
 
 nsISupports*
 Cache::GetParentObject() const
 {
   return mGlobal;
 }
 
 JSObject*
-Cache::WrapObject(JSContext* aContext)
+Cache::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return CacheBinding::Wrap(aContext, this);
+  return CacheBinding::Wrap(aContext, this, aGivenProto);
 }
 
 void
 Cache::DestroyInternal(CacheChild* aActor)
 {
   MOZ_ASSERT(mActor);
   MOZ_ASSERT(mActor == aActor);
   mActor->ClearListener();
--- a/dom/cache/Cache.h
+++ b/dom/cache/Cache.h
@@ -66,17 +66,17 @@ public:
   already_AddRefed<Promise>
   Keys(const Optional<RequestOrUSVString>& aRequest,
        const CacheQueryOptions& aParams, ErrorResult& aRv);
 
   // binding methods
   static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
 
   nsISupports* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aContext) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // Called when CacheChild actor is being destroyed
   void DestroyInternal(CacheChild* aActor);
 
   // methods forwarded from CacheChild
   void RecvMatchResponse(RequestId aRequestId, nsresult aRv,
                          const PCacheResponseOrVoid& aResponse);
   void RecvMatchAllResponse(RequestId aRequestId, nsresult aRv,
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -309,19 +309,19 @@ CacheStorage::PrefEnabled(JSContext* aCx
 
 nsISupports*
 CacheStorage::GetParentObject() const
 {
   return mGlobal;
 }
 
 JSObject*
-CacheStorage::WrapObject(JSContext* aContext)
+CacheStorage::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::CacheStorageBinding::Wrap(aContext, this);
+  return mozilla::dom::CacheStorageBinding::Wrap(aContext, this, aGivenProto);
 }
 
 void
 CacheStorage::ActorCreated(PBackgroundChild* aActor)
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
   MOZ_ASSERT(aActor);
 
--- a/dom/cache/CacheStorage.h
+++ b/dom/cache/CacheStorage.h
@@ -67,17 +67,17 @@ public:
   already_AddRefed<Promise> Open(const nsAString& aKey, ErrorResult& aRv);
   already_AddRefed<Promise> Delete(const nsAString& aKey, ErrorResult& aRv);
   already_AddRefed<Promise> Keys(ErrorResult& aRv);
 
   // binding methods
   static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
 
   nsISupports* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aContext) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIIPCbackgroundChildCreateCallback methods
   virtual void ActorCreated(PBackgroundChild* aActor) MOZ_OVERRIDE;
   virtual void ActorFailed() MOZ_OVERRIDE;
 
   // Called when CacheStorageChild actor is being destroyed
   void DestroyInternal(CacheStorageChild* aActor);
 
--- a/dom/cache/Manager.cpp
+++ b/dom/cache/Manager.cpp
@@ -92,21 +92,18 @@ public:
   }
 
   virtual void
   RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo) MOZ_OVERRIDE
   {
     MOZ_ASSERT(aResolver);
     MOZ_ASSERT(aQuotaInfo.mDir);
 
-    if (IsCanceled()) {
-      // TODO: handle orphaned files (bug 1110446)
-      aResolver->Resolve(NS_ERROR_ABORT);
-      return;
-    }
+    // Note that since DeleteOrphanedBodyAction isn't used while the context is
+    // being initialized, we don't need to check for cancellation here.
 
     nsCOMPtr<nsIFile> dbDir;
     nsresult rv = aQuotaInfo.mDir->Clone(getter_AddRefs(dbDir));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       aResolver->Resolve(rv);
       return;
     }
 
--- a/dom/cache/test/mochitest/test_cache_matchAll_request.js
+++ b/dom/cache/test/mochitest/test_cache_matchAll_request.js
@@ -70,16 +70,36 @@ function testRequest(request1, request2,
         })
     );
   }).then(function() {
     return c.matchAll(request1);
   }).then(function(r) {
     is(r.length, 1, "Should only find 1 item");
     return checkResponse(r[0], response1, response1Text);
   }).then(function() {
+    return c.matchAll(new Request(request1, {method: "HEAD"}));
+  }).then(function(r) {
+    is(r.length, 1, "Should only find 1 item");
+    return checkResponse(r[0], response1, response1Text);
+  }).then(function() {
+    return Promise.all(
+      ["POST", "PUT", "DELETE", "OPTIONS"]
+        .map(function(method) {
+          var req = new Request(request1, {method: method});
+          return c.matchAll(req)
+            .then(function(r) {
+              is(r.length, 0, "Searching for a request with a non-GET/HEAD method should not succeed");
+              return c.matchAll(req, {ignoreMethod: true});
+            }).then(function(r) {
+              is(r.length, 1, "Should only find 1 item");
+              return checkResponse(r[0], response1, response1Text);
+            });
+        })
+    );
+  }).then(function() {
     return c.matchAll(requestWithDifferentFragment);
   }).then(function(r) {
     is(r.length, 1, "Should only find 1 item");
     return checkResponse(r[0], response1, response1Text);
   }).then(function() {
     return c.matchAll(requestWithAlternateQueryString,
                       {ignoreSearch: true, cacheName: name});
   }).then(function(r) {
--- a/dom/cache/test/mochitest/test_cache_match_request.js
+++ b/dom/cache/test/mochitest/test_cache_match_request.js
@@ -56,16 +56,34 @@ function testRequest(request, unknownReq
             });
         })
     );
   }).then(function() {
     return c.match(request);
   }).then(function(r) {
     return checkResponse(r);
   }).then(function() {
+    return c.match(new Request(request, {method: "HEAD"}));
+  }).then(function(r) {
+    return checkResponse(r);
+  }).then(function() {
+    return Promise.all(
+      ["POST", "PUT", "DELETE", "OPTIONS"]
+        .map(function(method) {
+          var req = new Request(request, {method: method});
+          return c.match(req)
+            .then(function(r) {
+              is(typeof r, "undefined", "Searching for a request with a non-GET/HEAD method should not succeed");
+              return c.match(req, {ignoreMethod: true});
+            }).then(function(r) {
+              return checkResponse(r);
+            });
+        })
+    );
+  }).then(function() {
     return caches.match(request);
   }).then(function(r) {
     return checkResponse(r);
   }).then(function() {
     return caches.match(requestWithDifferentFragment);
   }).then(function(r) {
     return checkResponse(r);
   }).then(function() {
--- a/dom/camera/DOMCameraCapabilities.cpp
+++ b/dom/camera/DOMCameraCapabilities.cpp
@@ -89,19 +89,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderVideoProfile)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderVideoProfile)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderVideoProfile::WrapObject(JSContext* aCx)
+CameraRecorderVideoProfile::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderVideoProfileBinding::Wrap(aCx, this);
+  return CameraRecorderVideoProfileBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderVideoProfile::CameraRecorderVideoProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Video& aProfile)
   : mParent(aParent)
   , mCodec(aProfile.GetCodec())
   , mBitrate(aProfile.GetBitsPerSecond())
   , mFramerate(aProfile.GetFramesPerSecond())
@@ -129,19 +129,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderAudioProfile)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderAudioProfile)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderAudioProfile::WrapObject(JSContext* aCx)
+CameraRecorderAudioProfile::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderAudioProfileBinding::Wrap(aCx, this);
+  return CameraRecorderAudioProfileBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderAudioProfile::CameraRecorderAudioProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Audio& aProfile)
   : mParent(aParent)
   , mCodec(aProfile.GetCodec())
   , mBitrate(aProfile.GetBitsPerSecond())
   , mSamplerate(aProfile.GetSamplesPerSecond())
@@ -169,19 +169,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderProfile)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderProfile)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderProfile::WrapObject(JSContext* aCx)
+CameraRecorderProfile::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderProfileBinding::Wrap(aCx, this);
+  return CameraRecorderProfileBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderProfile::CameraRecorderProfile(nsISupports* aParent,
                                              const ICameraControl::RecorderProfile& aProfile)
   : mParent(aParent)
   , mName(aProfile.GetName())
   , mContainerFormat(aProfile.GetContainer())
   , mMimeType(aProfile.GetMimeType())
@@ -211,19 +211,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderProfiles)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderProfiles)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderProfiles::WrapObject(JSContext* aCx)
+CameraRecorderProfiles::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderProfilesBinding::Wrap(aCx, this);
+  return CameraRecorderProfilesBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderProfiles::CameraRecorderProfiles(nsISupports* aParent,
                                                ICameraControl* aCameraControl)
   : mParent(aParent)
   , mCameraControl(aCameraControl)
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
@@ -344,19 +344,19 @@ CameraCapabilities::OnHardwareClosed()
   if (mCameraControl) {
     mCameraControl->RemoveListener(mListener);
     mCameraControl = nullptr;
   }
   mListener = nullptr;
 }
 
 JSObject*
-CameraCapabilities::WrapObject(JSContext* aCx)
+CameraCapabilities::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraCapabilitiesBinding::Wrap(aCx, this);
+  return CameraCapabilitiesBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define LOG_IF_ERROR(rv, param)                               \
   do {                                                        \
     if (NS_FAILED(rv)) {                                      \
       DOM_CAMERA_LOGW("Error %x trying to get " #param "\n",  \
         (rv));                                                \
     }                                                         \
--- a/dom/camera/DOMCameraCapabilities.h
+++ b/dom/camera/DOMCameraCapabilities.h
@@ -34,17 +34,17 @@ class CameraRecorderVideoProfile MOZ_FIN
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderVideoProfile)
 
   explicit CameraRecorderVideoProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Video& aProfile);
   nsISupports* GetParentObject() const        { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t BitsPerSecond() const              { return mBitrate; }
   uint32_t FramesPerSecond() const            { return mFramerate; }
   void GetCodec(nsAString& aCodec) const      { aCodec = mCodec; }
 
   void GetSize(dom::CameraSize& aSize) const  { aSize = mSize; }
 
   // XXXmikeh - legacy, remove these when the Camera app is updated
@@ -73,17 +73,17 @@ class CameraRecorderAudioProfile MOZ_FIN
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderAudioProfile)
 
   explicit CameraRecorderAudioProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Audio& aProfile);
   nsISupports* GetParentObject() const    { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t BitsPerSecond() const          { return mBitrate; }
   uint32_t SamplesPerSecond() const       { return mSamplerate; }
   uint32_t Channels() const               { return mChannels; }
   void GetCodec(nsAString& aCodec) const  { aCodec = mCodec; }
 
 protected:
   virtual ~CameraRecorderAudioProfile();
@@ -107,17 +107,17 @@ class CameraRecorderProfile MOZ_FINAL : 
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderProfile)
 
   explicit CameraRecorderProfile(nsISupports* aParent,
                                  const ICameraControl::RecorderProfile& aProfile);
   nsISupports* GetParentObject() const          { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetMimeType(nsAString& aMimeType) const  { aMimeType = mMimeType; }
 
   CameraRecorderVideoProfile* Video()           { return mVideo; }
   CameraRecorderAudioProfile* Audio()           { return mAudio; }
 
   void GetName(nsAString& aName) const          { aName = mName; }
 
@@ -153,17 +153,17 @@ class CameraRecorderProfiles MOZ_FINAL :
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderProfiles)
 
   explicit CameraRecorderProfiles(nsISupports* aParent,
                                   ICameraControl* aCameraControl);
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   CameraRecorderProfile* NamedGetter(const nsAString& aName, bool& aFound);
   bool NameIsEnumerable(const nsAString& aName);
   void GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames);
 
   virtual void OnHardwareClosed();
 
 protected:
@@ -195,17 +195,17 @@ public:
   // Great Renaming proposed in bug 983177.
   static bool HasSupport(JSContext* aCx, JSObject* aGlobal);
 
   explicit CameraCapabilities(nsPIDOMWindow* aWindow,
                               ICameraControl* aCameraControl);
 
   nsPIDOMWindow* GetParentObject() const { return mWindow; }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetPreviewSizes(nsTArray<CameraSize>& aRetVal);
   void GetPictureSizes(nsTArray<CameraSize>& aRetVal);
   void GetThumbnailSizes(nsTArray<CameraSize>& aRetVal);
   void GetVideoSizes(nsTArray<CameraSize>& aRetVal);
   void GetFileFormats(nsTArray<nsString>& aRetVal);
   void GetWhiteBalanceModes(nsTArray<nsString>& aRetVal);
   void GetSceneModes(nsTArray<nsString>& aRetVal);
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -306,19 +306,19 @@ nsDOMCameraControl::nsDOMCameraControl(u
 nsDOMCameraControl::~nsDOMCameraControl()
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
   /*invoke DOMMdediastream destroy*/
   Destroy();
 }
 
 JSObject*
-nsDOMCameraControl::WrapObject(JSContext* aCx)
+nsDOMCameraControl::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraControlBinding::Wrap(aCx, this);
+  return CameraControlBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 nsDOMCameraControl::IsWindowStillActive()
 {
   return nsDOMCameraManager::IsWindowStillActive(mWindow->WindowID());
 }
 
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -118,17 +118,17 @@ public:
                                                 nsDOMDeviceStorage& storageArea,
                                                 const nsAString& filename,
                                                 ErrorResult& aRv);
   void StopRecording(ErrorResult& aRv);
   void ResumePreview(ErrorResult& aRv);
   already_AddRefed<dom::Promise> ReleaseHardware(ErrorResult& aRv);
   void ResumeContinuousFocus(ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   operator nsISupports*() { return static_cast<DOMMediaStream*>(this); }
 
 #ifdef MOZ_WIDGET_GONK
   static void PreinitCameraHardware();
   static void DiscardCachedCameraInstance(nsITimer* aTimer, void* aClosure);
 #endif
 
--- a/dom/camera/DOMCameraDetectedFace.cpp
+++ b/dom/camera/DOMCameraDetectedFace.cpp
@@ -21,19 +21,19 @@ NS_INTERFACE_MAP_END
 /* static */
 bool
 DOMCameraDetectedFace::HasSupport(JSContext* aCx, JSObject* aGlobal)
 {
   return Navigator::HasCameraSupport(aCx, aGlobal);
 }
 
 JSObject*
-DOMCameraDetectedFace::WrapObject(JSContext* aCx)
+DOMCameraDetectedFace::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraDetectedFaceBinding::Wrap(aCx, this);
+  return CameraDetectedFaceBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */
 already_AddRefed<DOMCameraDetectedFace>
 DOMCameraDetectedFace::Constructor(const GlobalObject& aGlobal,
                                    const dom::CameraDetectedFaceInit& aFace,
                                    ErrorResult& aRv)
 {
--- a/dom/camera/DOMCameraDetectedFace.h
+++ b/dom/camera/DOMCameraDetectedFace.h
@@ -50,17 +50,17 @@ public:
 
   nsISupports*
   GetParentObject() const
   {
     MOZ_ASSERT(mParent);
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 protected:
   DOMCameraDetectedFace(nsISupports* aParent, const dom::CameraDetectedFaceInit& aFace);
   virtual ~DOMCameraDetectedFace() { }
 
   nsCOMPtr<nsISupports> mParent;
 
   uint32_t mId;
--- a/dom/camera/DOMCameraManager.cpp
+++ b/dom/camera/DOMCameraManager.cpp
@@ -431,12 +431,12 @@ nsDOMCameraManager::IsWindowStillActive(
   if (!sActiveWindows) {
     return false;
   }
 
   return !!sActiveWindows->Get(aWindowId);
 }
 
 JSObject*
-nsDOMCameraManager::WrapObject(JSContext* aCx)
+nsDOMCameraManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraManagerBinding::Wrap(aCx, this);
+  return CameraManagerBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/camera/DOMCameraManager.h
+++ b/dom/camera/DOMCameraManager.h
@@ -69,17 +69,17 @@ public:
   // WebIDL
   already_AddRefed<mozilla::dom::Promise>
   GetCamera(const nsAString& aCamera,
             const mozilla::dom::CameraConfiguration& aOptions,
             mozilla::ErrorResult& aRv);
   void GetListOfCameras(nsTArray<nsString>& aList, mozilla::ErrorResult& aRv);
 
   nsPIDOMWindow* GetParentObject() const { return mWindow; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #ifdef MOZ_WIDGET_GONK
   static void PreinitCameraHardware();
 #endif
 
 protected:
   void XpComShutdown();
   void Shutdown(uint64_t aWindowId);
--- a/dom/canvas/CanvasGradient.h
+++ b/dom/canvas/CanvasGradient.h
@@ -46,19 +46,19 @@ public:
                                                       gfx::ExtendMode::CLAMP);
 
     return mStops;
   }
 
   // WebIDL
   void AddColorStop(float offset, const nsAString& colorstr, ErrorResult& rv);
 
-  JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CanvasGradientBinding::Wrap(aCx, this);
+    return CanvasGradientBinding::Wrap(aCx, this, aGivenProto);
   }
 
   CanvasRenderingContext2D* GetParentObject()
   {
     return mContext;
   }
 
 protected:
--- a/dom/canvas/CanvasPath.h
+++ b/dom/canvas/CanvasPath.h
@@ -22,17 +22,17 @@ class CanvasPath MOZ_FINAL :
   public nsWrapperCache
 {
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
 
   nsCOMPtr<nsISupports> GetParentObject() { return mParent; }
 
-  JSObject* WrapObject(JSContext* aCx);
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
                                                   ErrorResult& rv);
   static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
                                                   CanvasPath& aCanvasPath,
                                                   ErrorResult& rv);
   static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
                                                   const nsAString& aPathString,
--- a/dom/canvas/CanvasPattern.h
+++ b/dom/canvas/CanvasPattern.h
@@ -47,19 +47,19 @@ public:
     , mPrincipal(principalForSecurityCheck)
     , mTransform()
     , mForceWriteOnly(forceWriteOnly)
     , mCORSUsed(CORSUsed)
     , mRepeat(aRepeat)
   {
   }
 
-  JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CanvasPatternBinding::Wrap(aCx, this);
+    return CanvasPatternBinding::Wrap(aCx, this, aGivenProto);
   }
 
   CanvasRenderingContext2D* GetParentObject()
   {
     return mContext;
   }
 
   // WebIDL
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -974,19 +974,19 @@ CanvasRenderingContext2D::~CanvasRenderi
     gfxPlatform::GetPlatform()->GetSkiaGLGlue()->GetGLContext()->fDeleteTextures(1, &mVideoTexture);
   }
 #endif
 
   RemoveDemotableContext(this);
 }
 
 JSObject*
-CanvasRenderingContext2D::WrapObject(JSContext *cx)
+CanvasRenderingContext2D::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CanvasRenderingContext2DBinding::Wrap(cx, this);
+  return CanvasRenderingContext2DBinding::Wrap(cx, this, aGivenProto);
 }
 
 bool
 CanvasRenderingContext2D::ParseColor(const nsAString& aString,
                                      nscolor* aColor)
 {
   nsIDocument* document = mCanvasElement
                           ? mCanvasElement->OwnerDoc()
@@ -5388,19 +5388,19 @@ CanvasPath::CanvasPath(nsISupports* aPar
   : mParent(aParent), mPathBuilder(aPathBuilder)
 {
   if (!mPathBuilder) {
     mPathBuilder = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget()->CreatePathBuilder();
   }
 }
 
 JSObject*
-CanvasPath::WrapObject(JSContext* aCx)
+CanvasPath::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return Path2DBinding::Wrap(aCx, this);
+  return Path2DBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<CanvasPath>
 CanvasPath::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<CanvasPath> path = new CanvasPath(aGlobal.GetAsSupports());
   return path.forget();
 }
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -64,17 +64,17 @@ class CanvasRenderingContext2D MOZ_FINAL
 typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
   HTMLImageOrCanvasOrVideoElement;
 
   virtual ~CanvasRenderingContext2D();
 
 public:
   CanvasRenderingContext2D();
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   HTMLCanvasElement* GetCanvas() const
   {
     // corresponds to changes to the old bindings made in bug 745025
     return mCanvasElement->GetOriginalCanvas();
   }
 
   void Save();
--- a/dom/canvas/ImageData.cpp
+++ b/dom/canvas/ImageData.cpp
@@ -104,15 +104,15 @@ ImageData::DropData()
 {
   if (mData) {
     mData = nullptr;
     mozilla::DropJSObjects(this);
   }
 }
 
 bool
-ImageData::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+ImageData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-  return ImageDataBinding::Wrap(aCx, this, aReflector);
+  return ImageDataBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/ImageData.h
+++ b/dom/canvas/ImageData.h
@@ -68,17 +68,17 @@ public:
     aData.set(GetDataObject());
   }
   JSObject* GetDataObject() const
   {
     JS::ExposeObjectToActiveJS(mData);
     return mData;
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
 private:
   void HoldData();
   void DropData();
 
   ImageData() = delete;
 
   uint32_t mWidth, mHeight;
--- a/dom/canvas/TextMetrics.h
+++ b/dom/canvas/TextMetrics.h
@@ -25,19 +25,19 @@ public:
     MOZ_COUNT_DTOR(TextMetrics);
   }
 
   float Width() const
   {
     return width;
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextMetricsBinding::Wrap(aCx, this, aReflector);
+    return TextMetricsBinding::Wrap(aCx, this, aGivenProto, aReflector);
   }
 
 private:
   float width;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/WebGL1Context.cpp
+++ b/dom/canvas/WebGL1Context.cpp
@@ -21,19 +21,19 @@ WebGL1Context::WebGL1Context()
 {
 }
 
 WebGL1Context::~WebGL1Context()
 {
 }
 
 JSObject*
-WebGL1Context::WrapObject(JSContext* cx)
+WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLRenderingContextBinding::Wrap(cx, this);
+    return dom::WebGLRenderingContextBinding::Wrap(cx, this, aGivenProto);
 }
 
 } // namespace mozilla
 
 nsresult
 NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** out_result)
 {
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::CANVAS_WEBGL_USED, 1);
--- a/dom/canvas/WebGL1Context.h
+++ b/dom/canvas/WebGL1Context.h
@@ -22,17 +22,17 @@ private:
 public:
     virtual ~WebGL1Context();
 
     virtual bool IsWebGL2() const MOZ_OVERRIDE {
         return false;
     }
 
     // nsWrapperCache
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
     virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) MOZ_OVERRIDE;
     virtual bool ValidateBufferTarget(GLenum target, const char* info) MOZ_OVERRIDE;
     virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) MOZ_OVERRIDE;
     virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) MOZ_OVERRIDE;
 };
 
--- a/dom/canvas/WebGL2Context.cpp
+++ b/dom/canvas/WebGL2Context.cpp
@@ -35,19 +35,19 @@ WebGL2Context::IsSupported()
 
 /*static*/ WebGL2Context*
 WebGL2Context::Create()
 {
     return new WebGL2Context();
 }
 
 JSObject*
-WebGL2Context::WrapObject(JSContext* cx)
+WebGL2Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGL2RenderingContextBinding::Wrap(cx, this);
+    return dom::WebGL2RenderingContextBinding::Wrap(cx, this, aGivenProto);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // WebGL 2 initialisation
 
 // These WebGL 1 extensions are natively supported by WebGL 2.
 static const WebGLExtensionID kNativelySupportedExtensions[] = {
     WebGLExtensionID::ANGLE_instanced_arrays,
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -32,17 +32,17 @@ public:
     virtual bool IsWebGL2() const MOZ_OVERRIDE
     {
         return true;
     }
 
     // -------------------------------------------------------------------------
     // IMPLEMENT nsWrapperCache
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     // -------------------------------------------------------------------------
     // Buffer objects - WebGL2ContextBuffers.cpp
 
     void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
                            GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
     void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBuffer& returnedData);
     void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBufferView& returnedData);
--- a/dom/canvas/WebGLActiveInfo.cpp
+++ b/dom/canvas/WebGLActiveInfo.cpp
@@ -82,19 +82,19 @@ WebGLActiveInfo::WebGLActiveInfo(WebGLCo
     , mIsArray(isArray)
     , mElemSize(ElemSizeFromType(elemType))
     , mBaseMappedName(baseMappedName)
 { }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 JSObject*
-WebGLActiveInfo::WrapObject(JSContext* js)
+WebGLActiveInfo::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLActiveInfoBinding::Wrap(js, this);
+    return dom::WebGLActiveInfoBinding::Wrap(js, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLActiveInfo)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLActiveInfo, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLActiveInfo, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLActiveInfo.h
+++ b/dom/canvas/WebGLActiveInfo.h
@@ -20,17 +20,17 @@ class WebGLContext;
 
 class WebGLActiveInfo MOZ_FINAL
     : public nsWrapperCache
 {
 public:
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLActiveInfo)
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLActiveInfo)
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     WebGLContext* GetParentObject() const {
         return mWebGL;
     }
 
 
     WebGLContext* const mWebGL;
 
--- a/dom/canvas/WebGLBuffer.cpp
+++ b/dom/canvas/WebGLBuffer.cpp
@@ -77,19 +77,19 @@ WebGLBuffer::Validate(GLenum type, uint3
 
 bool
 WebGLBuffer::IsElementArrayUsedWithMultipleTypes() const
 {
     return mCache->BeenUsedWithMultipleTypes();
 }
 
 JSObject*
-WebGLBuffer::WrapObject(JSContext* cx)
+WebGLBuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLBufferBinding::Wrap(cx, this);
+    return dom::WebGLBufferBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLBuffer)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLBuffer, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLBuffer, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLBuffer.h
+++ b/dom/canvas/WebGLBuffer.h
@@ -45,17 +45,17 @@ public:
                   uint32_t* const out_upperBound);
 
     bool IsElementArrayUsedWithMultipleTypes() const;
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer)
 
 protected:
     ~WebGLBuffer();
 
     virtual void OnTargetChanged() MOZ_OVERRIDE;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -192,17 +192,17 @@ public:
 
     MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLContext)
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
                                                            nsIDOMWebGLRenderingContext)
 
-    virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE = 0;
+    virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE = 0;
 
     NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
 
     // nsICanvasRenderingContextInternal
 #ifdef DEBUG
     virtual int32_t GetWidth() const MOZ_OVERRIDE;
     virtual int32_t GetHeight() const MOZ_OVERRIDE;
 #endif
--- a/dom/canvas/WebGLExtensions.h
+++ b/dom/canvas/WebGLExtensions.h
@@ -36,22 +36,22 @@ public:
 
 protected:
     virtual ~WebGLExtensionBase();
 
     bool mIsLost;
 };
 
 #define DECL_WEBGL_EXTENSION_GOOP \
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType)            \
     JSObject*                                                    \
-    WebGLExtensionType::WrapObject(JSContext* cx) {              \
-        return dom::WebGLExtensionType##Binding::Wrap(cx, this); \
+    WebGLExtensionType::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) {              \
+        return dom::WebGLExtensionType##Binding::Wrap(cx, this, aGivenProto); \
     }
 
 class WebGLExtensionCompressedTextureATC
     : public WebGLExtensionBase
 {
 public:
     explicit WebGLExtensionCompressedTextureATC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureATC();
--- a/dom/canvas/WebGLFramebuffer.cpp
+++ b/dom/canvas/WebGLFramebuffer.cpp
@@ -11,19 +11,19 @@
 #include "WebGLContextUtils.h"
 #include "WebGLExtensions.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLTexture.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLFramebuffer::WrapObject(JSContext* cx)
+WebGLFramebuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLFramebufferBinding::Wrap(cx, this);
+    return dom::WebGLFramebufferBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
     : WebGLBindableName<FBTarget>(fbo)
     , WebGLContextBoundObject(webgl)
     , mStatus(0)
     , mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
     , mStencilAttachment(LOCAL_GL_STENCIL_ATTACHMENT)
--- a/dom/canvas/WebGLFramebuffer.h
+++ b/dom/canvas/WebGLFramebuffer.h
@@ -152,17 +152,17 @@ public:
     const WebGLRectangleObject& RectangleObject() const;
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
     void FinalizeAttachments() const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
 
     // mask mirrors glClear.
     bool HasCompletePlanes(GLbitfield mask);
 
     bool CheckAndInitializeAttachments();
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -705,19 +705,19 @@ WebGLProgram::FindUniformByMappedName(co
         return true;
 
     return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 JSObject*
-WebGLProgram::WrapObject(JSContext* js)
+WebGLProgram::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLProgramBinding::Wrap(js, this);
+    return dom::WebGLProgramBinding::Wrap(js, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLProgram, mVertShader, mFragShader)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLProgram, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLProgram, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLProgram.h
+++ b/dom/canvas/WebGLProgram.h
@@ -133,17 +133,17 @@ public:
     const webgl::LinkedProgramInfo* LinkInfo() const {
         return mMostRecentLinkInfo.get();
     }
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
     ~WebGLProgram() {
         DeleteOnce();
     }
 
     bool LinkAndUpdate();
 
--- a/dom/canvas/WebGLQuery.cpp
+++ b/dom/canvas/WebGLQuery.cpp
@@ -8,19 +8,19 @@
 #include "GLContext.h"
 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
 #include "nsContentUtils.h"
 #include "WebGLContext.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLQuery::WrapObject(JSContext* cx)
+WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLQueryBinding::Wrap(cx, this);
+    return dom::WebGLQueryBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLQuery::WebGLQuery(WebGLContext* webgl)
     : WebGLContextBoundObject(webgl)
     , mGLName(0)
     , mType(0)
 {
     mContext->mQueries.insertBack(this);
--- a/dom/canvas/WebGLQuery.h
+++ b/dom/canvas/WebGLQuery.h
@@ -31,17 +31,17 @@ public:
     void Delete();
 
     // nsWrapperCache
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
     // NS
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
 
 
 private:
     ~WebGLQuery() {
         DeleteOnce();
--- a/dom/canvas/WebGLRenderbuffer.cpp
+++ b/dom/canvas/WebGLRenderbuffer.cpp
@@ -36,19 +36,19 @@ NeedsDepthStencilEmu(gl::GLContext* gl, 
     MOZ_ASSERT(internalFormat != LOCAL_GL_DEPTH_STENCIL);
     if (internalFormat != LOCAL_GL_DEPTH24_STENCIL8)
         return false;
 
     return !SupportsDepthStencil(gl);
 }
 
 JSObject*
-WebGLRenderbuffer::WrapObject(JSContext* cx)
+WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLRenderbufferBinding::Wrap(cx, this);
+    return dom::WebGLRenderbufferBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
     : WebGLBindable<RBTarget>()
     , WebGLContextBoundObject(webgl)
     , mPrimaryRB(0)
     , mSecondaryRB(0)
     , mInternalFormat(0)
--- a/dom/canvas/WebGLRenderbuffer.h
+++ b/dom/canvas/WebGLRenderbuffer.h
@@ -59,17 +59,17 @@ public:
 
     void BindRenderbuffer() const;
     void RenderbufferStorage(GLsizei samples, GLenum internalFormat,
                              GLsizei width, GLsizei height) const;
     void FramebufferRenderbuffer(FBAttachment attachment) const;
     // Only handles a subset of `pname`s.
     GLint GetRenderbufferParameter(RBTarget target, RBParam pname) const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLRenderbuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLRenderbuffer)
 
 protected:
     ~WebGLRenderbuffer() {
         DeleteOnce();
     }
--- a/dom/canvas/WebGLSampler.cpp
+++ b/dom/canvas/WebGLSampler.cpp
@@ -34,19 +34,19 @@ WebGLSampler::Delete()
 
 WebGLContext*
 WebGLSampler::GetParentObject() const
 {
     return Context();
 }
 
 JSObject*
-WebGLSampler::WrapObject(JSContext* cx)
+WebGLSampler::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLSamplerBinding::Wrap(cx, this);
+    return dom::WebGLSamplerBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSampler)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSampler, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSampler, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLSampler.h
+++ b/dom/canvas/WebGLSampler.h
@@ -23,17 +23,17 @@ class WebGLSampler MOZ_FINAL
     friend class WebGLContext2;
 
 public:
     explicit WebGLSampler(WebGLContext* webgl, GLuint sampler);
 
     void Delete();
     WebGLContext* GetParentObject() const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
 
 private:
     ~WebGLSampler();
--- a/dom/canvas/WebGLShader.cpp
+++ b/dom/canvas/WebGLShader.cpp
@@ -344,19 +344,19 @@ WebGLShader::FindUniformByMappedName(con
     *out_userName = userNameStr.c_str();
     return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Boilerplate
 
 JSObject*
-WebGLShader::WrapObject(JSContext* js)
+WebGLShader::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLShaderBinding::Wrap(js, this);
+    return dom::WebGLShaderBinding::Wrap(js, this, aGivenProto);
 }
 
 size_t
 WebGLShader::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
 {
     size_t validatorSize = mValidator ? mallocSizeOf(mValidator.get())
                                       : 0;
     return mallocSizeOf(this) +
--- a/dom/canvas/WebGLShader.h
+++ b/dom/canvas/WebGLShader.h
@@ -57,17 +57,17 @@ public:
     }
 
     // Other funcs
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     void Delete();
 
     WebGLContext* GetParentObject() const { return Context(); }
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLShader)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLShader)
 
 public:
     const GLuint mGLName;
     const GLenum mType;
 protected:
--- a/dom/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/dom/canvas/WebGLShaderPrecisionFormat.cpp
@@ -7,14 +7,15 @@
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 
 namespace mozilla {
 
 bool
 WebGLShaderPrecisionFormat::WrapObject(JSContext* aCx,
+                                       JS::Handle<JSObject*> aGivenProto,
                                        JS::MutableHandle<JSObject*> aReflector)
 {
-    return dom::WebGLShaderPrecisionFormatBinding::Wrap(aCx, this, aReflector);
+    return dom::WebGLShaderPrecisionFormatBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // namespace mozilla
--- a/dom/canvas/WebGLShaderPrecisionFormat.h
+++ b/dom/canvas/WebGLShaderPrecisionFormat.h
@@ -19,17 +19,17 @@ public:
     WebGLShaderPrecisionFormat(WebGLContext* context, GLint rangeMin,
                                GLint rangeMax, GLint precision)
         : WebGLContextBoundObject(context)
         , mRangeMin(rangeMin)
         , mRangeMax(rangeMax)
         , mPrecision(precision)
     { }
 
-    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+    bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
     // WebIDL WebGLShaderPrecisionFormat API
     GLint RangeMin() const {
         return mRangeMin;
     }
 
     GLint RangeMax() const {
         return mRangeMax;
--- a/dom/canvas/WebGLSync.cpp
+++ b/dom/canvas/WebGLSync.cpp
@@ -29,18 +29,18 @@ WebGLSync::GetParentObject() const
 {
     MOZ_CRASH("Not Implemented.");
     return nullptr;
 }
 
 // -------------------------------------------------------------------------
 // IMPLEMENT NS
 JSObject*
-WebGLSync::WrapObject(JSContext* cx)
+WebGLSync::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLSyncBinding::Wrap(cx, this);
+    return dom::WebGLSyncBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSync)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSync, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSync, Release);
 
 } // namespace mozilla
--- a/dom/canvas/WebGLSync.h
+++ b/dom/canvas/WebGLSync.h
@@ -21,17 +21,17 @@ class WebGLSync MOZ_FINAL
     friend class WebGL2Context;
 
 public:
     explicit WebGLSync(WebGLContext* webgl);
 
     void Delete();
     WebGLContext* GetParentObject() const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSync)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSync)
 
 private:
     ~WebGLSync();
 };
 
--- a/dom/canvas/WebGLTexture.cpp
+++ b/dom/canvas/WebGLTexture.cpp
@@ -13,18 +13,18 @@
 #include "ScopedGLHelpers.h"
 #include "WebGLContext.h"
 #include "WebGLContextUtils.h"
 #include "WebGLTexelConversions.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLTexture::WrapObject(JSContext* cx) {
-    return dom::WebGLTextureBinding::Wrap(cx, this);
+WebGLTexture::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) {
+    return dom::WebGLTextureBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
     : WebGLBindableName<TexTarget>(tex)
     , WebGLContextBoundObject(webgl)
     , mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
     , mMagFilter(LOCAL_GL_LINEAR)
     , mWrapS(LOCAL_GL_REPEAT)
--- a/dom/canvas/WebGLTexture.h
+++ b/dom/canvas/WebGLTexture.h
@@ -41,17 +41,17 @@ public:
     explicit WebGLTexture(WebGLContext* webgl, GLuint tex);
 
     void Delete();
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTexture)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTexture)
 
 protected:
     ~WebGLTexture() {
         DeleteOnce();
     }
--- a/dom/canvas/WebGLTransformFeedback.cpp
+++ b/dom/canvas/WebGLTransformFeedback.cpp
@@ -40,19 +40,19 @@ WebGLTransformFeedback::Delete()
 
 WebGLContext*
 WebGLTransformFeedback::GetParentObject() const
 {
     return Context();
 }
 
 JSObject*
-WebGLTransformFeedback::WrapObject(JSContext* cx)
+WebGLTransformFeedback::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLTransformFeedbackBinding::Wrap(cx, this);
+    return dom::WebGLTransformFeedbackBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTransformFeedback)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTransformFeedback, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTransformFeedback, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLTransformFeedback.h
+++ b/dom/canvas/WebGLTransformFeedback.h
@@ -23,17 +23,17 @@ class WebGLTransformFeedback MOZ_FINAL
     friend class WebGLContext;
     friend class WebGL2Context;
 
 public:
     explicit WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
 
     void Delete();
     WebGLContext* GetParentObject() const;
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTransformFeedback)
 
 private:
     ~WebGLTransformFeedback();
     GLenum mMode;
     bool mIsActive;
--- a/dom/canvas/WebGLUniformLocation.cpp
+++ b/dom/canvas/WebGLUniformLocation.cpp
@@ -260,19 +260,19 @@ WebGLUniformLocation::GetUniform(JSConte
     default:
         MOZ_CRASH("Invalid elemType.");
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 JSObject*
-WebGLUniformLocation::WrapObject(JSContext* js)
+WebGLUniformLocation::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLUniformLocationBinding::Wrap(js, this);
+    return dom::WebGLUniformLocationBinding::Wrap(js, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLUniformLocation)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLUniformLocation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLUniformLocation, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLUniformLocation.h
+++ b/dom/canvas/WebGLUniformLocation.h
@@ -27,17 +27,17 @@ struct LinkedProgramInfo;
 class WebGLUniformLocation MOZ_FINAL
     : public nsWrapperCache
     , public WebGLContextBoundObject
 {
 public:
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLUniformLocation)
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLUniformLocation)
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     WebGLContext* GetParentObject() const {
         return mContext;
     }
 
 
     const WeakPtr<const webgl::LinkedProgramInfo> mLinkInfo;
     const GLuint mLoc;
--- a/dom/canvas/WebGLVertexArray.cpp
+++ b/dom/canvas/WebGLVertexArray.cpp
@@ -10,19 +10,19 @@
 #include "WebGLBuffer.h"
 #include "WebGLContext.h"
 #include "WebGLVertexArrayGL.h"
 #include "WebGLVertexArrayFake.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLVertexArray::WrapObject(JSContext* cx)
+WebGLVertexArray::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLVertexArrayBinding::Wrap(cx, this);
+    return dom::WebGLVertexArrayBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
     : WebGLBindable<VAOBinding>()
     , WebGLContextBoundObject(webgl)
     , mGLName(0)
 {
     mContext->mVertexArrays.insertBack(this);
--- a/dom/canvas/WebGLVertexArray.h
+++ b/dom/canvas/WebGLVertexArray.h
@@ -49,17 +49,17 @@ public:
 
     // Implement parent classes:
     void Delete();
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray)
 
     GLuint GLName() const { return mGLName; }
 
 protected:
     explicit WebGLVertexArray(WebGLContext* webgl);
--- a/dom/cellbroadcast/CellBroadcast.cpp
+++ b/dom/cellbroadcast/CellBroadcast.cpp
@@ -97,19 +97,19 @@ CellBroadcast::~CellBroadcast()
   }
 
   mListener = nullptr;
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(CellBroadcast, DOMEventTargetHelper)
 
 JSObject*
-CellBroadcast::WrapObject(JSContext* aCx)
+CellBroadcast::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCellBroadcastBinding::Wrap(aCx, this);
+  return MozCellBroadcastBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // Forwarded nsICellBroadcastListener methods
 
 NS_IMETHODIMP
 CellBroadcast::NotifyMessageReceived(uint32_t aServiceId,
                                      uint32_t aGsmGeographicalScope,
                                      uint16_t aMessageCode,
--- a/dom/cellbroadcast/CellBroadcast.h
+++ b/dom/cellbroadcast/CellBroadcast.h
@@ -44,17 +44,17 @@ public:
   CellBroadcast() = delete;
   CellBroadcast(nsPIDOMWindow *aWindow,
                 nsICellBroadcastService* aService);
 
   nsPIDOMWindow*
   GetParentObject() const { return GetOwner(); }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   IMPL_EVENT_HANDLER(received)
 
 private:
   nsRefPtr<Listener> mListener;
 };
 
 } // namespace dom
--- a/dom/cellbroadcast/CellBroadcastMessage.cpp
+++ b/dom/cellbroadcast/CellBroadcastMessage.cpp
@@ -97,19 +97,19 @@ CellBroadcastMessage::CellBroadcastMessa
 
   // CdmaServiceCategory represents a 16bit unsigned value.
   if (aCdmaServiceCategory <= 0xFFFFU) {
     mCdmaServiceCategory.SetValue(static_cast<uint16_t>(aCdmaServiceCategory));
   }
 }
 
 JSObject*
-CellBroadcastMessage::WrapObject(JSContext* aCx)
+CellBroadcastMessage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCellBroadcastMessageBinding::Wrap(aCx, this);
+  return MozCellBroadcastMessageBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<CellBroadcastEtwsInfo>
 CellBroadcastMessage::GetEtws() const
 {
   nsRefPtr<CellBroadcastEtwsInfo> etwsInfo = mEtwsInfo;
   return etwsInfo.forget();
 }
@@ -139,15 +139,15 @@ CellBroadcastEtwsInfo::CellBroadcastEtws
   if (aWarningType <
       static_cast<uint32_t>(CellBroadcastEtwsWarningType::EndGuard_)) {
     mWarningType.SetValue(
       ToWebidlEnum<CellBroadcastEtwsWarningType>(aWarningType));
   }
 }
 
 JSObject*
-CellBroadcastEtwsInfo::WrapObject(JSContext* aCx)
+CellBroadcastEtwsInfo::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCellBroadcastEtwsInfoBinding::Wrap(aCx, this);
+  return MozCellBroadcastEtwsInfoBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/cellbroadcast/CellBroadcastMessage.h
+++ b/dom/cellbroadcast/CellBroadcastMessage.h
@@ -39,17 +39,17 @@ public:
                        bool aHasEtwsInfo,
                        uint32_t aEtwsWarningType,
                        bool aEtwsEmergencyUserAlert,
                        bool aEtwsPopup);
 
   nsPIDOMWindow*
   GetParentObject() const { return mWindow; }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL interface
 
   uint32_t ServiceId() const { return mServiceId; }
 
   const Nullable<CellBroadcastGsmGeographicalScope>&
   GetGsmGeographicalScope() { return mGsmGeographicalScope; }
 
@@ -101,17 +101,17 @@ public:
   CellBroadcastEtwsInfo(nsPIDOMWindow* aWindow,
                         uint32_t aWarningType,
                         bool aEmergencyUserAlert,
                         bool aPopup);
 
   nsPIDOMWindow*
   GetParentObject() const { return mWindow; }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL interface
 
   const Nullable<CellBroadcastEtwsWarningType>&
   GetWarningType()  { return mWarningType; }
 
   bool EmergencyUserAlert() const { return mEmergencyUserAlert; }
 
--- a/dom/crypto/CryptoKey.cpp
+++ b/dom/crypto/CryptoKey.cpp
@@ -78,19 +78,19 @@ CryptoKey::~CryptoKey()
   if (isAlreadyShutDown()) {
     return;
   }
   destructorSafeDestroyNSSReference();
   shutdown(calledFromObject);
 }
 
 JSObject*
-CryptoKey::WrapObject(JSContext* aCx)
+CryptoKey::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CryptoKeyBinding::Wrap(aCx, this);
+  return CryptoKeyBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 CryptoKey::GetType(nsString& aRetVal) const
 {
   uint32_t type = mAttributes & TYPE_MASK;
   switch (type) {
     case PUBLIC:  aRetVal.AssignLiteral(WEBCRYPTO_KEY_TYPE_PUBLIC); break;
--- a/dom/crypto/CryptoKey.h
+++ b/dom/crypto/CryptoKey.h
@@ -93,17 +93,17 @@ public:
 
   explicit CryptoKey(nsIGlobalObject* aWindow);
 
   nsIGlobalObject* GetParentObject() const
   {
     return mGlobal;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL methods
   void GetType(nsString& aRetVal) const;
   bool Extractable() const;
   void GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
                     ErrorResult& aRv) const;
   void GetUsages(nsTArray<nsString>& aRetVal) const;
 
--- a/dom/datastore/DataStore.cpp
+++ b/dom/datastore/DataStore.cpp
@@ -42,19 +42,19 @@ DataStore::Constructor(GlobalObject& aGl
     return nullptr;
   }
 
   nsRefPtr<DataStore> store = new DataStore(window);
   return store.forget();
 }
 
 JSObject*
-DataStore::WrapObject(JSContext* aCx)
+DataStore::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DataStoreBinding::Wrap(aCx, this);
+  return DataStoreBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /*static*/ bool
 DataStore::EnabledForScope(JSContext* aCx, JS::Handle<JSObject*> aObj)
 {
   // Only expose the interface when it is:
   // 1. enabled by the preference and
   // 2. accessed by the chrome codes in Gecko.
--- a/dom/datastore/DataStore.h
+++ b/dom/datastore/DataStore.h
@@ -28,17 +28,17 @@ public:
 
   explicit DataStore(nsPIDOMWindow* aWindow);
 
   // WebIDL (internal functions)
 
   static already_AddRefed<DataStore> Constructor(GlobalObject& aGlobal,
                                                  ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static bool EnabledForScope(JSContext* aCx, JS::Handle<JSObject*> aObj);
 
   // WebIDL (public APIs)
 
   void GetName(nsAString& aName, ErrorResult& aRv);
 
   void GetOwner(nsAString& aOwner, ErrorResult& aRv);
--- a/dom/datastore/DataStoreCursor.cpp
+++ b/dom/datastore/DataStoreCursor.cpp
@@ -26,19 +26,20 @@ already_AddRefed<DataStoreCursor>
 DataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<DataStoreCursor> cursor = new DataStoreCursor();
   return cursor.forget();
 }
 
 bool
 DataStoreCursor::WrapObject(JSContext* aCx,
+                            JS::Handle<JSObject*> aGivenProto,
                             JS::MutableHandle<JSObject*> aReflector)
 {
-  return DataStoreCursorBinding::Wrap(aCx, this, aReflector);
+  return DataStoreCursorBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 already_AddRefed<DataStore>
 DataStoreCursor::GetStore(ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mCursor);
 
--- a/dom/datastore/DataStoreCursor.h
+++ b/dom/datastore/DataStoreCursor.h
@@ -28,17 +28,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(DataStoreCursor)
 
   // WebIDL (internal functions)
 
   static already_AddRefed<DataStoreCursor> Constructor(GlobalObject& aGlobal,
                                                        ErrorResult& aRv);
 
-  bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
   // WebIDL (public APIs)
 
   already_AddRefed<DataStore> GetStore(ErrorResult& aRv);
 
   already_AddRefed<Promise> Next(ErrorResult& aRv);
 
   void Close(ErrorResult& aRv);
--- a/dom/datastore/DataStoreService.cpp
+++ b/dom/datastore/DataStoreService.cpp
@@ -1015,17 +1015,17 @@ DataStoreService::GetDataStoresResolve(n
     nsRefPtr<DataStore> exposedStore = new DataStore(aWindow);
 
     ErrorResult error;
     exposedStore->SetDataStoreImpl(*dataStoreObj, error);
     if (error.Failed()) {
       return;
     }
 
-    JS::Rooted<JSObject*> obj(cx, exposedStore->WrapObject(cx));
+    JS::Rooted<JSObject*> obj(cx, exposedStore->WrapObject(cx, JS::NullPtr()));
     MOZ_ASSERT(obj);
 
     JS::Rooted<JS::Value> exposedObject(cx, JS::ObjectValue(*obj));
     dataStore->SetExposedObject(exposedObject);
 
     counter->AppendDataStore(cx, exposedStore, dataStore);
   }
 }
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -210,17 +210,17 @@ public:
 
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
     return GetOwner();
   }
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   IMPL_EVENT_HANDLER(change)
 
   already_AddRefed<DOMRequest>
   Add(nsIDOMBlob* aBlob, ErrorResult& aRv);
   already_AddRefed<DOMRequest>
   AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, ErrorResult& aRv);
 
--- a/dom/devicestorage/DeviceStorageRequestChild.cpp
+++ b/dom/devicestorage/DeviceStorageRequestChild.cpp
@@ -103,17 +103,17 @@ DeviceStorageRequestChild::
     {
       BlobResponse r = aValue;
       BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
       nsRefPtr<FileImpl> bloblImpl = actor->GetBlobImpl();
       nsRefPtr<File> blob = new File(mRequest->GetParentObject(), bloblImpl);
 
       AutoJSContext cx;
 
-      JS::Rooted<JSObject*> obj(cx, blob->WrapObject(cx));
+      JS::Rooted<JSObject*> obj(cx, blob->WrapObject(cx, JS::NullPtr()));
       MOZ_ASSERT(obj);
 
       JS::Rooted<JS::Value> result(cx, JS::ObjectValue(*obj));
       mRequest->FireSuccess(result);
       break;
     }
 
     case DeviceStorageResponseValue::TFreeSpaceStorageResponse:
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -3341,19 +3341,19 @@ nsDOMDeviceStorage::nsDOMDeviceStorage(n
   , mIsShareable(false)
   , mIsRemovable(false)
   , mIsWatchingFile(false)
   , mAllowedToWatchFile(false)
 {
 }
 
 /* virtual */ JSObject*
-nsDOMDeviceStorage::WrapObject(JSContext* aCx)
+nsDOMDeviceStorage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DeviceStorageBinding::Wrap(aCx, this);
+  return DeviceStorageBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType,
                          const nsAString &aVolName)
 {
   DebugOnly<FileUpdateDispatcher*> observer
     = FileUpdateDispatcher::GetSingleton();
--- a/dom/encoding/TextDecoder.h
+++ b/dom/encoding/TextDecoder.h
@@ -44,19 +44,19 @@ public:
     MOZ_COUNT_CTOR(TextDecoder);
   }
 
   ~TextDecoder()
   {
     MOZ_COUNT_DTOR(TextDecoder);
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextDecoderBinding::Wrap(aCx, this, aReflector);
+    return TextDecoderBinding::Wrap(aCx, this, aGivenProto, aReflector);
   }
 
   /**
    * Validates provided label and throws an exception if invalid label.
    *
    * @param aLabel       The encoding label (case insensitive) provided.
    * @param aFatal       indicates whether to throw an 'EncodingError'
    *                     exception or not when decoding.
--- a/dom/encoding/TextEncoder.h
+++ b/dom/encoding/TextEncoder.h
@@ -37,19 +37,19 @@ public:
   TextEncoder()
   {
   }
 
   virtual
   ~TextEncoder()
   {}
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextEncoderBinding::Wrap(aCx, this, aReflector);
+    return TextEncoderBinding::Wrap(aCx, this, aGivenProto, aReflector);
   }
 
 protected:
 
   /**
    * Validates provided encoding and throws an exception if invalid encoding.
    * If no encoding is provided then mEncoding is default initialised to "utf-8".
    *
--- a/dom/events/AnimationEvent.h
+++ b/dom/events/AnimationEvent.h
@@ -28,19 +28,19 @@ public:
   NS_DECL_NSIDOMANIMATIONEVENT
 
   static already_AddRefed<AnimationEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const AnimationEventInit& aParam,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return AnimationEventBinding::Wrap(aCx, this);
+    return AnimationEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // xpidl implementation
   // GetAnimationName(nsAString& aAnimationName);
   // GetPseudoElement(nsAString& aPseudoElement);
 
   float ElapsedTime();
 
--- a/dom/events/BeforeAfterKeyboardEvent.h
+++ b/dom/events/BeforeAfterKeyboardEvent.h
@@ -14,19 +14,19 @@ namespace dom {
 
 class BeforeAfterKeyboardEvent : public KeyboardEvent
 {
 public:
   BeforeAfterKeyboardEvent(EventTarget* aOwner,
                            nsPresContext* aPresContext,
                            InternalBeforeAfterKeyboardEvent* aEvent);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return BeforeAfterKeyboardEventBinding::Wrap(aCx, this);
+    return BeforeAfterKeyboardEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   static already_AddRefed<BeforeAfterKeyboardEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const BeforeAfterKeyboardEventInit& aParam,
               ErrorResult& aRv);
 
--- a/dom/events/BeforeUnloadEvent.h
+++ b/dom/events/BeforeUnloadEvent.h
@@ -19,19 +19,19 @@ class BeforeUnloadEvent : public Event,
 public:
   BeforeUnloadEvent(EventTarget* aOwner,
                     nsPresContext* aPresContext,
                     WidgetEvent* aEvent)
     : Event(aOwner, aPresContext, aEvent)
   {
   }
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return BeforeUnloadEventBinding::Wrap(aCx, this);
+    return BeforeUnloadEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward to Event
   NS_FORWARD_TO_EVENT
 
   // nsIDOMBeforeUnloadEvent Interface
--- a/dom/events/ClipboardEvent.h
+++ b/dom/events/ClipboardEvent.h
@@ -25,19 +25,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMCLIPBOARDEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return ClipboardEventBinding::Wrap(aCx, this);
+    return ClipboardEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   static already_AddRefed<ClipboardEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const ClipboardEventInit& aParam,
               ErrorResult& aRv);
 
--- a/dom/events/CommandEvent.h
+++ b/dom/events/CommandEvent.h
@@ -24,19 +24,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMCOMMANDEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CommandEventBinding::Wrap(aCx, this);
+    return CommandEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void InitCommandEvent(const nsAString& aType,
                         bool aCanBubble,
                         bool aCancelable,
                         const nsAString& aCommand,
                         ErrorResult& aRv)
   {
--- a/dom/events/CompositionEvent.h
+++ b/dom/events/CompositionEvent.h
@@ -22,19 +22,19 @@ public:
   CompositionEvent(EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    WidgetCompositionEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_TO_UIEVENT
   NS_DECL_NSIDOMCOMPOSITIONEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CompositionEventBinding::Wrap(aCx, this);
+    return CompositionEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void InitCompositionEvent(const nsAString& aType,
                             bool aCanBubble,
                             bool aCancelable,
                             nsIDOMWindow* aView,
                             const nsAString& aData,
                             const nsAString& aLocale,
--- a/dom/events/CustomEvent.cpp
+++ b/dom/events/CustomEvent.cpp
@@ -48,19 +48,19 @@ CustomEvent::Constructor(const GlobalObj
   bool trusted = e->Init(t);
   JS::Rooted<JS::Value> detail(aGlobal.Context(), aParam.mDetail);
   e->InitCustomEvent(aGlobal.Context(), aType, aParam.mBubbles, aParam.mCancelable, detail, aRv);
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 JSObject*
-CustomEvent::WrapObjectInternal(JSContext* aCx)
+CustomEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::CustomEventBinding::Wrap(aCx, this);
+  return mozilla::dom::CustomEventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 CustomEvent::InitCustomEvent(const nsAString& aType,
                              bool aCanBubble,
                              bool aCancelable,
                              nsIVariant* aDetail)
 {
--- a/dom/events/CustomEvent.h
+++ b/dom/events/CustomEvent.h
@@ -33,17 +33,17 @@ public:
 
   static already_AddRefed<CustomEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const CustomEventInit& aParam,
               ErrorResult& aRv);
 
   virtual JSObject*
-  WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void
   GetDetail(JSContext* aCx,
             JS::MutableHandle<JS::Value> aRetval);
 
   void
   InitCustomEvent(JSContext* aCx,
                   const nsAString& aType,
--- a/dom/events/DataContainerEvent.h
+++ b/dom/events/DataContainerEvent.h
@@ -26,19 +26,19 @@ public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DataContainerEvent, Event)
 
   NS_FORWARD_TO_EVENT
 
   NS_DECL_NSIDOMDATACONTAINEREVENT
 
   virtual JSObject*
-  WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DataContainerEventBinding::Wrap(aCx, this);
+    return DataContainerEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   already_AddRefed<nsIVariant> GetData(const nsAString& aKey)
   {
     nsCOMPtr<nsIVariant> val;
     GetData(aKey, getter_AddRefs(val));
     return val.forget();
   }
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -162,19 +162,19 @@ DataTransfer::Constructor(const GlobalOb
   uint32_t eventType = nsContentUtils::GetEventId(eventTypeAtom);
   nsRefPtr<DataTransfer> transfer = new DataTransfer(aGlobal.GetAsSupports(),
                                                      eventType, aIsExternal,
                                                      -1);
   return transfer.forget();
 }
 
 JSObject*
-DataTransfer::WrapObject(JSContext* aCx)
+DataTransfer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DataTransferBinding::Wrap(aCx, this);
+  return DataTransferBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 DataTransfer::GetDropEffect(nsAString& aDropEffect)
 {
   nsString dropEffect;
   GetDropEffect(dropEffect);
   aDropEffect = dropEffect;
--- a/dom/events/DataTransfer.h
+++ b/dom/events/DataTransfer.h
@@ -99,17 +99,17 @@ public:
   // latter will occur when an external drag occurs, that is, a drag where the
   // source is another application, or a drag is started by calling the drag
   // service directly. For clipboard operations, aClipboardType indicates
   // which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations,
   // or if access to the system clipboard should not be allowed.
   DataTransfer(nsISupports* aParent, uint32_t aEventType, bool aIsExternal,
                int32_t aClipboardType);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void SetParentObject(nsISupports* aNewParent)
   {
     MOZ_ASSERT(aNewParent);
--- a/dom/events/DeviceMotionEvent.h
+++ b/dom/events/DeviceMotionEvent.h
@@ -22,19 +22,19 @@ public:
                      Nullable<double> aAlpha, Nullable<double> aBeta,
                      Nullable<double> aGamma);
 
   DeviceMotionEvent* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DeviceRotationRateBinding::Wrap(aCx, this);
+    return DeviceRotationRateBinding::Wrap(aCx, this, aGivenProto);
   }
 
   Nullable<double> GetAlpha() const { return mAlpha; }
   Nullable<double> GetBeta() const { return mBeta; }
   Nullable<double> GetGamma() const { return mGamma; }
 
 private:
   ~DeviceRotationRate();
@@ -54,19 +54,19 @@ public:
                      Nullable<double> aX, Nullable<double> aY,
                      Nullable<double> aZ);
 
   DeviceMotionEvent* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DeviceAccelerationBinding::Wrap(aCx, this);
+    return DeviceAccelerationBinding::Wrap(aCx, this, aGivenProto);
   }
 
   Nullable<double> GetX() const { return mX; }
   Nullable<double> GetY() const { return mY; }
   Nullable<double> GetZ() const { return mZ; }
 
 private:
   ~DeviceAcceleration();
@@ -89,19 +89,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward to Event
   NS_FORWARD_TO_EVENT
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeviceMotionEvent, Event)
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DeviceMotionEventBinding::Wrap(aCx, this);
+    return DeviceMotionEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   DeviceAcceleration* GetAcceleration() const
   {
     return mAcceleration;
   }
 
   DeviceAcceleration* GetAccelerationIncludingGravity() const
--- a/dom/events/DragEvent.h
+++ b/dom/events/DragEvent.h
@@ -25,19 +25,19 @@ public:
             WidgetDragEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMDRAGEVENT
 
   NS_FORWARD_TO_MOUSEEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DragEventBinding::Wrap(aCx, this);
+    return DragEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   DataTransfer* GetDataTransfer();
 
   void InitDragEvent(const nsAString& aType,
                      bool aCanBubble, bool aCancelable,
                      nsIDOMWindow* aView, int32_t aDetail,
                      int32_t aScreenX, int32_t aScreenY,
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -229,28 +229,28 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 JSObject*
-Event::WrapObject(JSContext* aCx)
+Event::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   if (mIsMainThreadEvent && !GetWrapperPreserveColor()) {
     nsJSContext::LikelyShortLivingObjectCreated();
   }
-  return WrapObjectInternal(aCx);
+  return WrapObjectInternal(aCx, aGivenProto);
 }
 
 JSObject*
-Event::WrapObjectInternal(JSContext* aCx)
+Event::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return EventBinding::Wrap(aCx, this);
+  return EventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 Event::IsChrome(JSContext* aCx) const
 {
   return mIsMainThreadEvent ?
     xpc::AccessCheck::isChrome(js::GetContextCompartment(aCx)) :
     mozilla::dom::workers::IsCurrentThreadRunningChromeWorker();
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -85,19 +85,19 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Event)
 
   nsIGlobalObject* GetParentObject()
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE MOZ_FINAL;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE MOZ_FINAL;
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx);
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto);
 
 #define GENERATED_EVENT(EventClass_) \
   virtual EventClass_* As##EventClass_()  \
   {                                       \
     return nullptr;                       \
   }
 #include "mozilla/dom/GeneratedEventList.h"
 #undef GENERATED_EVENT
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -92,17 +92,16 @@ MutationBitForEventType(uint32_t aEventT
 
 uint32_t EventListenerManager::sMainThreadCreatedCount = 0;
 
 EventListenerManager::EventListenerManager(EventTarget* aTarget)
   : mMayHavePaintEventListener(false)
   , mMayHaveMutationListeners(false)
   , mMayHaveCapturingListeners(false)
   , mMayHaveSystemGroupListeners(false)
-  , mMayHaveTouchEventListener(false)
   , mMayHaveMouseEnterLeaveEventListener(false)
   , mMayHavePointerEnterLeaveEventListener(false)
   , mClearingListeners(false)
   , mIsMainThreadELM(NS_IsMainThread())
   , mNoListenerForEvent(0)
   , mTarget(aTarget)
 {
   NS_ASSERTION(aTarget, "unexpected null pointer");
@@ -323,27 +322,16 @@ EventListenerManager::AddEventListenerIn
       window->EnableNetworkEvent(NS_NETWORK_UPLOAD_EVENT);
     }
   } else if (aTypeAtom == nsGkAtoms::onmoznetworkdownload) {
     nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
     if (window) {
       window->EnableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
     }
 #endif // MOZ_B2G
-  } else if (aTypeAtom == nsGkAtoms::ontouchstart ||
-             aTypeAtom == nsGkAtoms::ontouchend ||
-             aTypeAtom == nsGkAtoms::ontouchmove ||
-             aTypeAtom == nsGkAtoms::ontouchcancel) {
-    mMayHaveTouchEventListener = true;
-    nsPIDOMWindow* window = GetInnerWindowForTarget();
-    // we don't want touchevent listeners added by scrollbars to flip this flag
-    // so we ignore listeners created with system event flag
-    if (window && !aFlags.mInSystemGroup) {
-      window->SetHasTouchEventListeners();
-    }
   } else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) {
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (aTypeAtom == nsGkAtoms::onpointerenter ||
         aTypeAtom == nsGkAtoms::onpointerleave) {
       mMayHavePointerEnterLeaveEventListener = true;
       if (window) {
 #ifdef DEBUG
         nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -383,22 +383,16 @@ public:
   static void Shutdown();
 
   /**
    * Returns true if there may be a paint event listener registered,
    * false if there definitely isn't.
    */
   bool MayHavePaintEventListener() { return mMayHavePaintEventListener; }
 
-  /**
-   * Returns true if there may be a touch event listener registered,
-   * false if there definitely isn't.
-   */
-  bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; }
-
   bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
   bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
 
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
 
   uint32_t ListenerCount() const
   {
     return mListeners.Length();
@@ -538,17 +532,16 @@ protected:
 
   already_AddRefed<nsIScriptGlobalObject>
   GetScriptGlobalAndDocument(nsIDocument** aDoc);
 
   uint32_t mMayHavePaintEventListener : 1;
   uint32_t mMayHaveMutationListeners : 1;
   uint32_t mMayHaveCapturingListeners : 1;
   uint32_t mMayHaveSystemGroupListeners : 1;
-  uint32_t mMayHaveTouchEventListener : 1;
   uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
   uint32_t mMayHavePointerEnterLeaveEventListener : 1;
   uint32_t mClearingListeners : 1;
   uint32_t mIsMainThreadELM : 1;
   uint32_t mNoListenerForEvent : 23;
 
   nsAutoTObserverArray<Listener, 2> mListeners;
   dom::EventTarget* MOZ_NON_OWNING_REF mTarget;
--- a/dom/events/FocusEvent.h
+++ b/dom/events/FocusEvent.h
@@ -18,19 +18,19 @@ class FocusEvent : public UIEvent,
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMFOCUSEVENT
 
   // Forward to base class
   NS_FORWARD_TO_UIEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return FocusEventBinding::Wrap(aCx, this);
+    return FocusEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   FocusEvent(EventTarget* aOwner,
              nsPresContext* aPresContext,
              InternalFocusEvent* aEvent);
 
   EventTarget* GetRelatedTarget();
 
--- a/dom/events/ImageCaptureError.cpp
+++ b/dom/events/ImageCaptureError.cpp
@@ -32,19 +32,19 @@ ImageCaptureError::~ImageCaptureError()
 
 nsISupports*
 ImageCaptureError::GetParentObject() const
 {
   return mParent;
 }
 
 JSObject*
-ImageCaptureError::WrapObject(JSContext* aCx)
+ImageCaptureError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ImageCaptureErrorBinding::Wrap(aCx, this);
+  return ImageCaptureErrorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 uint16_t
 ImageCaptureError::Code() const
 {
   return mCode;
 }
 
--- a/dom/events/ImageCaptureError.h
+++ b/dom/events/ImageCaptureError.h
@@ -26,17 +26,17 @@ class ImageCaptureError MOZ_FINAL : publ
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageCaptureError)
 
   ImageCaptureError(nsISupports* aParent, uint16_t aCode, const nsAString& aMessage);
 
   nsISupports* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint16_t Code() const;
 
   enum {
     FRAME_GRAB_ERROR = 1,
     SETTINGS_ERROR = 2,
     PHOTO_ERROR = 3,
     ERROR_UNKNOWN = 4,
--- a/dom/events/InputEvent.h
+++ b/dom/events/InputEvent.h
@@ -26,19 +26,19 @@ public:
   NS_FORWARD_TO_UIEVENT
 
 
   static already_AddRefed<InputEvent> Constructor(const GlobalObject& aGlobal,
                                                   const nsAString& aType,
                                                   const InputEventInit& aParam,
                                                   ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return InputEventBinding::Wrap(aCx, this);
+    return InputEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   bool IsComposing();
 
 protected:
   ~InputEvent() {}
 };
 
--- a/dom/events/KeyboardEvent.h
+++ b/dom/events/KeyboardEvent.h
@@ -31,19 +31,19 @@ public:
   NS_FORWARD_TO_UIEVENT
 
   static already_AddRefed<KeyboardEvent> Constructor(
                                            const GlobalObject& aGlobal,
                                            const nsAString& aType,
                                            const KeyboardEventInit& aParam,
                                            ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return KeyboardEventBinding::Wrap(aCx, this);
+    return KeyboardEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   bool AltKey();
   bool CtrlKey();
   bool ShiftKey();
   bool MetaKey();
 
   bool GetModifierState(const nsAString& aKey)
--- a/dom/events/MessageEvent.cpp
+++ b/dom/events/MessageEvent.cpp
@@ -55,19 +55,19 @@ MessageEvent::MessageEvent(EventTarget* 
 
 MessageEvent::~MessageEvent()
 {
   mData.setUndefined();
   DropJSObjects(this);
 }
 
 JSObject*
-MessageEvent::WrapObjectInternal(JSContext* aCx)
+MessageEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::MessageEventBinding::Wrap(aCx, this);
+  return mozilla::dom::MessageEventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData)
 {
   ErrorResult rv;
   GetData(aCx, aData, rv);
   return rv.ErrorCode();
--- a/dom/events/MessageEvent.h
+++ b/dom/events/MessageEvent.h
@@ -44,17 +44,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MessageEvent, Event)
 
   NS_DECL_NSIDOMMESSAGEEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
                ErrorResult& aRv);
 
   void GetSource(Nullable<OwningWindowProxyOrMessagePortOrClient>& aValue) const;
 
   MessagePortList* GetPorts()
   {
--- a/dom/events/MouseEvent.h
+++ b/dom/events/MouseEvent.h
@@ -25,19 +25,19 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseEvent Interface
   NS_DECL_NSIDOMMOUSEEVENT
 
   // Forward to base class
   NS_FORWARD_TO_UIEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return MouseEventBinding::Wrap(aCx, this);
+    return MouseEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // Web IDL binding methods
   virtual uint32_t Which() MOZ_OVERRIDE
   {
     return Button() + 1;
   }
 
--- a/dom/events/MouseScrollEvent.h
+++ b/dom/events/MouseScrollEvent.h
@@ -24,19 +24,19 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseScrollEvent Interface
   NS_DECL_NSIDOMMOUSESCROLLEVENT
 
   // Forward to base class
   NS_FORWARD_TO_MOUSEEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return MouseScrollEventBinding::Wrap(aCx, this);
+    return MouseScrollEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   int32_t Axis();
 
   void InitMouseScrollEvent(const nsAString& aType, bool aCanBubble,
                             bool aCancelable, nsIDOMWindow* aView,
                             int32_t aDetail, int32_t aScreenX, int32_t aScreenY,
                             int32_t aClientX, int32_t aClientY,
--- a/dom/events/MutationEvent.h
+++ b/dom/events/MutationEvent.h
@@ -25,19 +25,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMMUTATIONEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return MutationEventBinding::Wrap(aCx, this);
+    return MutationEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // xpidl implementation
   // GetPrevValue(nsAString& aPrevValue);
   // GetNewValue(nsAString& aNewValue);
   // GetAttrName(nsAString& aAttrName);
 
   already_AddRefed<nsINode> GetRelatedNode();
--- a/dom/events/NotifyPaintEvent.h
+++ b/dom/events/NotifyPaintEvent.h
@@ -38,19 +38,19 @@ public:
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() MOZ_OVERRIDE
   {
     return Event::DuplicatePrivateData();
   }
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) MOZ_OVERRIDE;
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return NotifyPaintEventBinding::Wrap(aCx, this);
+    return NotifyPaintEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   already_AddRefed<DOMRectList> ClientRects();
 
   already_AddRefed<DOMRect> BoundingClientRect();
 
   already_AddRefed<PaintRequestList> PaintRequests();
 
--- a/dom/events/PaintRequest.cpp
+++ b/dom/events/PaintRequest.cpp
@@ -23,19 +23,19 @@ NS_INTERFACE_TABLE_HEAD(PaintRequest)
   NS_INTERFACE_TABLE(PaintRequest, nsIDOMPaintRequest)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(PaintRequest)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(PaintRequest)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(PaintRequest)
 
 /* virtual */ JSObject*
-PaintRequest::WrapObject(JSContext* aCx)
+PaintRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PaintRequestBinding::Wrap(aCx, this);
+  return PaintRequestBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DOMRect>
 PaintRequest::ClientRect()
 {
   nsRefPtr<DOMRect> clientRect = new DOMRect(this);
   clientRect->SetLayoutRect(mRequest.mRect);
   return clientRect.forget();
@@ -66,15 +66,15 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(PaintRequestList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(PaintRequestList)
 
 JSObject*
-PaintRequestList::WrapObject(JSContext* aCx)
+PaintRequestList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PaintRequestListBinding::Wrap(aCx, this);
+  return PaintRequestListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/events/PaintRequest.h
+++ b/dom/events/PaintRequest.h
@@ -26,17 +26,17 @@ public:
   {
     mRequest.mFlags = 0;
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PaintRequest)
   NS_DECL_NSIDOMPAINTREQUEST
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsIDOMEvent* GetParentObject() const
   {
     return mParent;
   }
 
   already_AddRefed<DOMRect> ClientRect();
   void GetReason(nsAString& aResult) const
@@ -60,17 +60,17 @@ class PaintRequestList MOZ_FINAL : publi
 public:
   explicit PaintRequestList(nsIDOMEvent *aParent) : mParent(aParent)
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PaintRequestList)
   
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Append(PaintRequest* aElement)
   {
     mArray.AppendElement(aElement);
--- a/dom/events/PointerEvent.h
+++ b/dom/events/PointerEvent.h
@@ -17,19 +17,19 @@ namespace dom {
 
 class PointerEvent : public MouseEvent
 {
 public:
   PointerEvent(EventTarget* aOwner,
                nsPresContext* aPresContext,
                WidgetPointerEvent* aEvent);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return PointerEventBinding::Wrap(aCx, this);
+    return PointerEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   static already_AddRefed<PointerEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const PointerEventInit& aParam,
               ErrorResult& aRv);
 
--- a/dom/events/ScrollAreaEvent.h
+++ b/dom/events/ScrollAreaEvent.h
@@ -33,19 +33,19 @@ public:
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() MOZ_OVERRIDE
   {
     return Event::DuplicatePrivateData();
   }
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) MOZ_OVERRIDE;
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return ScrollAreaEventBinding::Wrap(aCx, this);
+    return ScrollAreaEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   float X() const
   {
     return mClientArea->Left();
   }
 
   float Y() const
--- a/dom/events/SimpleGestureEvent.h
+++ b/dom/events/SimpleGestureEvent.h
@@ -25,19 +25,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMSIMPLEGESTUREEVENT
 
   // Forward to base class
   NS_FORWARD_TO_MOUSEEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return SimpleGestureEventBinding::Wrap(aCx, this);
+    return SimpleGestureEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   uint32_t AllowedDirections();
   uint32_t Direction();
   double Delta();
   uint32_t ClickCount();
 
   void InitSimpleGestureEvent(const nsAString& aType,
--- a/dom/events/SpeechRecognitionError.h
+++ b/dom/events/SpeechRecognitionError.h
@@ -21,19 +21,19 @@ public:
   virtual ~SpeechRecognitionError();
 
   static already_AddRefed<SpeechRecognitionError>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const SpeechRecognitionErrorInit& aParam,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::SpeechRecognitionErrorBinding::Wrap(aCx, this);
+    return mozilla::dom::SpeechRecognitionErrorBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void
   GetMessage(nsAString& aString)
   {
     aString = mMessage;
   }
 
--- a/dom/events/StorageEvent.cpp
+++ b/dom/events/StorageEvent.cpp
@@ -40,19 +40,19 @@ StorageEvent::~StorageEvent()
 
 StorageEvent*
 StorageEvent::AsStorageEvent()
 {
   return this;
 }
 
 JSObject*
-StorageEvent::WrapObjectInternal(JSContext* aCx)
+StorageEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return StorageEventBinding::Wrap(aCx, this);
+  return StorageEventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<StorageEvent>
 StorageEvent::Constructor(EventTarget* aOwner,
                           const nsAString& aType,
                           const StorageEventInit& aEventInitDict)
 {
   nsRefPtr<StorageEvent> e = new StorageEvent(aOwner);
--- a/dom/events/StorageEvent.h
+++ b/dom/events/StorageEvent.h
@@ -37,17 +37,17 @@ protected:
   nsString mOldValue;
   nsString mNewValue;
   nsString mUrl;
   nsRefPtr<DOMStorage> mStorageArea;
 
 public:
   virtual StorageEvent* AsStorageEvent();
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<StorageEvent>
   Constructor(EventTarget* aOwner, const nsAString& aType,
               const StorageEventInit& aEventInitDict);
 
   static already_AddRefed<StorageEvent>
   Constructor(const GlobalObject& aGlobal, const nsAString& aType,
               const StorageEventInit& aEventInitDict, ErrorResult& aRv);
--- a/dom/events/Touch.cpp
+++ b/dom/events/Touch.cpp
@@ -125,19 +125,19 @@ Touch::Equals(Touch* aTouch)
   return mRefPoint == aTouch->mRefPoint &&
          mForce == aTouch->Force() &&
          mRotationAngle == aTouch->RotationAngle() &&
          mRadius.x == aTouch->RadiusX() &&
          mRadius.y == aTouch->RadiusY();
 }
 
 JSObject*
-Touch::WrapObject(JSContext* aCx)
+Touch::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return TouchBinding::Wrap(aCx, this);
+  return TouchBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // Parent ourselves to the window of the target. This achieves the desirable
 // effects of parenting to the target, but avoids making the touch inaccessible
 // when the target happens to be NAC and therefore reflected into the XBL scope.
 EventTarget*
 Touch::GetParentObject()
 {
--- a/dom/events/Touch.h
+++ b/dom/events/Touch.h
@@ -49,17 +49,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Touch)
 
   void InitializePoints(nsPresContext* aPresContext, WidgetEvent* aEvent);
 
   void SetTarget(EventTarget* aTarget);
 
   bool Equals(Touch* aTouch);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   EventTarget* GetParentObject();
 
   // WebIDL
   int32_t Identifier() const { return mIdentifier; }
   EventTarget* GetTarget() const;
   int32_t ScreenX() const { return mScreenPoint.x; }
   int32_t ScreenY() const { return mScreenPoint.y; }
--- a/dom/events/TouchEvent.cpp
+++ b/dom/events/TouchEvent.cpp
@@ -31,19 +31,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TouchList, mParent, mPoints)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(TouchList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(TouchList)
 
 JSObject*
-TouchList::WrapObject(JSContext* aCx)
+TouchList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return TouchListBinding::Wrap(aCx, this);
+  return TouchListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // static
 bool
 TouchList::PrefEnabled(JSContext* aCx, JSObject* aGlobal)
 {
   return TouchEvent::PrefEnabled(aCx, aGlobal);
 }
--- a/dom/events/TouchEvent.h
+++ b/dom/events/TouchEvent.h
@@ -39,17 +39,17 @@ public:
     nsJSContext::LikelyShortLivingObjectCreated();
   }
 
   void Append(Touch* aPoint)
   {
     mPoints.AppendElement(aPoint);
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
   static bool PrefEnabled(JSContext* aCx = nullptr,
                           JSObject* aGlobal = nullptr);
@@ -84,19 +84,19 @@ class TouchEvent : public UIEvent
 public:
   TouchEvent(EventTarget* aOwner,
              nsPresContext* aPresContext,
              WidgetTouchEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TouchEvent, UIEvent)
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return TouchEventBinding::Wrap(aCx, this);
+    return TouchEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   TouchList* Touches();
   TouchList* TargetTouches();
   TouchList* ChangedTouches();
 
   bool AltKey();
   bool MetaKey();
--- a/dom/events/TransitionEvent.h
+++ b/dom/events/TransitionEvent.h
@@ -28,19 +28,19 @@ public:
   NS_DECL_NSIDOMTRANSITIONEVENT
 
   static already_AddRefed<TransitionEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const TransitionEventInit& aParam,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return TransitionEventBinding::Wrap(aCx, this);
+    return TransitionEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // xpidl implementation
   // GetPropertyName(nsAString& aPropertyName)
   // GetPseudoElement(nsAString& aPreudoElement)
 
   float ElapsedTime();
 
--- a/dom/events/UIEvent.h
+++ b/dom/events/UIEvent.h
@@ -96,19 +96,19 @@ public:
     return CSSIntPoint::FromAppUnitsRounded(pt);
   }
 
   static already_AddRefed<UIEvent> Constructor(const GlobalObject& aGlobal,
                                                const nsAString& aType,
                                                const UIEventInit& aParam,
                                                ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return UIEventBinding::Wrap(aCx, this);
+    return UIEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   nsIDOMWindow* GetView() const
   {
     return mView;
   }
 
   int32_t Detail() const
--- a/dom/events/WheelEvent.h
+++ b/dom/events/WheelEvent.h
@@ -32,19 +32,19 @@ public:
   NS_FORWARD_TO_MOUSEEVENT
 
   static
   already_AddRefed<WheelEvent> Constructor(const GlobalObject& aGlobal,
                                            const nsAString& aType,
                                            const WheelEventInit& aParam,
                                            ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return WheelEventBinding::Wrap(aCx, this);
+    return WheelEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // NOTE: DeltaX(), DeltaY() and DeltaZ() return CSS pixels when deltaMode is
   //       DOM_DELTA_PIXEL. (The internal event's delta values are device pixels
   //       if it's dispatched by widget)
   double DeltaX();
   double DeltaY();
   double DeltaZ();
--- a/dom/events/XULCommandEvent.h
+++ b/dom/events/XULCommandEvent.h
@@ -26,19 +26,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULCommandEvent, UIEvent)
   NS_DECL_NSIDOMXULCOMMANDEVENT
 
   // Forward our inherited virtual methods to the base class
   NS_FORWARD_TO_UIEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return XULCommandEventBinding::Wrap(aCx, this);
+    return XULCommandEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   bool AltKey();
   bool CtrlKey();
   bool ShiftKey();
   bool MetaKey();
 
   already_AddRefed<Event> GetSourceEvent()
--- a/dom/events/test/bug648573.html
+++ b/dom/events/test/bug648573.html
@@ -16,19 +16,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 648573 **/
 SimpleTest.waitForExplicitFinish();
 var utils = SpecialPowers.getDOMWindowUtils(window);
 
-ok(!utils.mayHaveTouchEventListeners,
-  "There shouldn't be any touch event listeners yet.");
-
 ok("createTouch" in document, "Should have createTouch function");
 ok("createTouchList" in document, "Should have createTouchList function");
 ok(document.createEvent("touchevent"), "Should be able to create TouchEvent objects");
 
 var t1 = document.createTouch(window, document, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
 is(t1.target, document, "Wrong target");
 is(t1.identifier, 1, "Wrong identifier");
 is(t1.pageX, 2, "Wrong pageX");
@@ -96,16 +93,14 @@ function runEventTest(type) {
   t.dispatchEvent(e);
   ok(t.didCall, "Should have called the listener(2)");
 }
 
 for (var i = 0; i < events.length; ++i) {
   runEventTest(events[i]);
 }
 
-ok(utils.mayHaveTouchEventListeners,
-  "There should be touch event listeners.");
 SimpleTest.finish();
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/fetch/Headers.cpp
+++ b/dom/fetch/Headers.cpp
@@ -70,18 +70,18 @@ Headers::Constructor(const GlobalObject&
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   return headers.forget();
 }
 
 JSObject*
-Headers::WrapObject(JSContext* aCx)
+Headers::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::HeadersBinding::Wrap(aCx, this);
+  return mozilla::dom::HeadersBinding::Wrap(aCx, this, aGivenProto);
 }
 
 Headers::~Headers()
 {
 }
 } // namespace dom
 } // namespace mozilla
--- a/dom/fetch/Headers.h
+++ b/dom/fetch/Headers.h
@@ -105,17 +105,17 @@ public:
     return mInternalHeaders->Guard();
   }
 
   void SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv)
   {
     mInternalHeaders->SetGuard(aGuard, aRv);
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject() const { return mOwner; }
 
 private:
   virtual ~Headers();
 
   InternalHeaders*
   GetInternalHeaders() const
   {
--- a/dom/fetch/Request.h
+++ b/dom/fetch/Request.h
@@ -32,19 +32,19 @@ class Request MOZ_FINAL : public nsISupp
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Request)
 
 public:
   Request(nsIGlobalObject* aOwner, InternalRequest* aRequest);
 
   JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return RequestBinding::Wrap(aCx, this);
+    return RequestBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void
   GetUrl(nsAString& aUrl) const
   {
     CopyUTF8toUTF16(mRequest->mURL, aUrl);
   }
 
--- a/dom/fetch/Response.h
+++ b/dom/fetch/Response.h
@@ -32,19 +32,19 @@ class Response MOZ_FINAL : public nsISup
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Response)
 
 public:
   Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse);
 
   Response(const Response& aOther) = delete;
 
   JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return ResponseBinding::Wrap(aCx, this);
+    return ResponseBinding::Wrap(aCx, this, aGivenProto);
   }
 
   ResponseType
   Type() const
   {
     return mInternalResponse->Type();
   }
 
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -70,19 +70,19 @@ Directory::~Directory()
 
 nsPIDOMWindow*
 Directory::GetParentObject() const
 {
   return mFileSystem->GetWindow();
 }
 
 JSObject*
-Directory::WrapObject(JSContext* aCx)
+Directory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DirectoryBinding::Wrap(aCx, this);
+  return DirectoryBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 Directory::GetName(nsString& aRetval) const
 {
   aRetval.Truncate();
 
   if (mPath.IsEmpty()) {
--- a/dom/filesystem/Directory.h
+++ b/dom/filesystem/Directory.h
@@ -51,17 +51,17 @@ public:
   Directory(FileSystemBase* aFileSystem, const nsAString& aPath);
 
   // ========= Begin WebIDL bindings. ===========
 
   nsPIDOMWindow*
   GetParentObject() const;
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void
   GetName(nsString& aRetval) const;
 
   already_AddRefed<Promise>
   CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
              ErrorResult& aRv);
 
--- a/dom/fmradio/FMRadio.cpp
+++ b/dom/fmradio/FMRadio.cpp
@@ -180,19 +180,19 @@ FMRadio::Shutdown()
   NS_ENSURE_TRUE_VOID(target);
   target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this,
                                     /* useCapture = */ true);
 
   mIsShutdown = true;
 }
 
 JSObject*
-FMRadio::WrapObject(JSContext* aCx)
+FMRadio::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return FMRadioBinding::Wrap(aCx, this);
+  return FMRadioBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 FMRadio::Notify(const SwitchEvent& aEvent)
 {
   MOZ_ASSERT(!mHasInternalAntenna);
 
   if (mHeadphoneState != aEvent.status()) {
--- a/dom/fmradio/FMRadio.h
+++ b/dom/fmradio/FMRadio.h
@@ -46,17 +46,17 @@ public:
   /* FMRadioEventObserver */
   virtual void Notify(const FMRadioEventType& aType) MOZ_OVERRIDE;
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static bool Enabled();
 
   bool RdsEnabled();
 
   bool AntennaAvailable() const;
 
   Nullable<double> GetFrequency() const;
--- a/dom/gamepad/Gamepad.cpp
+++ b/dom/gamepad/Gamepad.cpp
@@ -115,15 +115,15 @@ Gamepad::Clone(nsISupports* aParent)
   nsRefPtr<Gamepad> out =
     new Gamepad(aParent, mID, mIndex, mMapping,
                 mButtons.Length(), mAxes.Length());
   out->SyncState(this);
   return out.forget();
 }
 
 /* virtual */ JSObject*
-Gamepad::WrapObject(JSContext* aCx)
+Gamepad::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return GamepadBinding::Wrap(aCx, this);
+  return GamepadBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/gamepad/Gamepad.h
+++ b/dom/gamepad/Gamepad.h
@@ -54,17 +54,17 @@ public:
   // parented to aParent.
   already_AddRefed<Gamepad> Clone(nsISupports* aParent);
 
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetId(nsAString& aID) const
   {
     aID = mID;
   }
 
   DOMHighResTimeStamp Timestamp() const
   {
--- a/dom/gamepad/GamepadButton.cpp
+++ b/dom/gamepad/GamepadButton.cpp
@@ -14,15 +14,15 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(Gamepad
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GamepadButton)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GamepadButton, mParent)
 
 /* virtual */ JSObject*
-GamepadButton::WrapObject(JSContext* aCx)
+GamepadButton::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return GamepadButtonBinding::Wrap(aCx, this);
+  return GamepadButtonBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/gamepad/GamepadButton.h
+++ b/dom/gamepad/GamepadButton.h
@@ -25,17 +25,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GamepadButton)
 
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void SetPressed(bool aPressed)
   {
     mPressed = aPressed;
   }
 
   void SetValue(double aValue)
   {
--- a/dom/geolocation/nsGeoPosition.cpp
+++ b/dom/geolocation/nsGeoPosition.cpp
@@ -166,19 +166,19 @@ Position::~Position()
 
 nsISupports*
 Position::GetParentObject() const
 {
   return mParent;
 }
 
 JSObject*
-Position::WrapObject(JSContext* aCx)
+Position::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PositionBinding::Wrap(aCx, this);
+  return PositionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 Coordinates*
 Position::Coords()
 {
   if (!mCoordinates) {
     nsCOMPtr<nsIDOMGeoPositionCoords> coords;
     mGeoPosition->GetCoords(getter_AddRefs(coords));
@@ -219,19 +219,19 @@ Coordinates::~Coordinates()
 
 Position*
 Coordinates::GetParentObject() const
 {
   return mPosition;
 }
 
 JSObject*
-Coordinates::WrapObject(JSContext* aCx)
+Coordinates::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CoordinatesBinding::Wrap(aCx, this);
+  return CoordinatesBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define GENERATE_COORDS_WRAPPED_GETTER(name) \
 double                                       \
 Coordinates::name() const                    \
 {                                            \
   double rv;                                 \
   mCoords->Get##name(&rv);                   \
--- a/dom/geolocation/nsGeoPosition.h
+++ b/dom/geolocation/nsGeoPosition.h
@@ -85,17 +85,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Position)
 
 public:
   Position(nsISupports* aParent, nsIDOMGeoPosition* aGeoPosition);
 
   nsISupports* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   Coordinates* Coords();
 
   uint64_t Timestamp() const;
 
   nsIDOMGeoPosition* GetWrappedGeoPosition() { return mGeoPosition; }
 
 private:
@@ -113,17 +113,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Coordinates)
 
 public:
   Coordinates(Position* aPosition, nsIDOMGeoPositionCoords* aCoords);
 
   Position* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   double Latitude() const;
 
   double Longitude() const;
 
   Nullable<double> GetAltitude() const;
 
   double Accuracy() const;
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -310,19 +310,19 @@ PositionError::GetMessage(nsAString& aMe
 
 Geolocation*
 PositionError::GetParentObject() const
 {
   return mParent;
 }
 
 JSObject*
-PositionError::WrapObject(JSContext* aCx)
+PositionError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PositionErrorBinding::Wrap(aCx, this);
+  return PositionErrorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 PositionError::NotifyCallback(const GeoPositionErrorCallback& aCallback)
 {
   nsAutoMicroTask mt;
   if (aCallback.HasWebIDLCallback()) {
     PositionErrorCallback* callback = aCallback.GetWebIDLCallback();
@@ -1618,12 +1618,12 @@ Geolocation::RegisterRequestWithPrompt(n
   }
 
   nsCOMPtr<nsIRunnable> ev  = new RequestPromptEvent(request, mOwner);
   NS_DispatchToMainThread(ev);
   return true;
 }
 
 JSObject*
-Geolocation::WrapObject(JSContext *aCtx)
+Geolocation::WrapObject(JSContext *aCtx, JS::Handle<JSObject*> aGivenProto)
 {
-  return GeolocationBinding::Wrap(aCtx, this);
+  return GeolocationBinding::Wrap(aCtx, this, aGivenProto);
 }
--- a/dom/geolocation/nsGeolocation.h
+++ b/dom/geolocation/nsGeolocation.h
@@ -135,17 +135,17 @@ public:
   NS_DECL_NSIGEOLOCATIONUPDATE
   NS_DECL_NSIDOMGEOGEOLOCATION
 
   Geolocation();
 
   nsresult Init(nsIDOMWindow* contentDom=nullptr);
 
   nsIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext *aCtx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCtx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   int32_t WatchPosition(PositionCallback& aCallback, PositionErrorCallback* aErrorCallback, const PositionOptions& aOptions, ErrorResult& aRv);
   void GetCurrentPosition(PositionCallback& aCallback, PositionErrorCallback* aErrorCallback, const PositionOptions& aOptions, ErrorResult& aRv);
 
   // Returns true if any of the callbacks are repeating
   bool HasActiveCallbacks();
 
   // Register an allowed request
@@ -228,17 +228,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PositionError)
 
   NS_DECL_NSIDOMGEOPOSITIONERROR
 
   PositionError(Geolocation* aParent, int16_t aCode);
 
   Geolocation* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   int16_t Code() const {
     return mCode;
   }
 
   void NotifyCallback(const GeoPositionErrorCallback& callback);
 private:
   ~PositionError();
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -205,15 +205,15 @@ HTMLAllCollection::GetSupportedNames(uns
   aNames.SetCapacity(atoms.Length());
   for (uint32_t i = 0; i < atoms.Length(); ++i) {
     aNames.AppendElement(nsDependentAtomString(atoms[i]));
   }
 }
 
 
 JSObject*
-HTMLAllCollection::WrapObject(JSContext* aCx)
+HTMLAllCollection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAllCollectionBinding::Wrap(aCx, this);
+  return HTMLAllCollectionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAllCollection.h
+++ b/dom/html/HTMLAllCollection.h
@@ -35,17 +35,17 @@ class HTMLAllCollection MOZ_FINAL : publ
   ~HTMLAllCollection();
 
 public:
   explicit HTMLAllCollection(nsHTMLDocument* aDocument);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HTMLAllCollection)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsINode* GetParentObject() const;
 
   uint32_t Length();
   nsIContent* Item(uint32_t aIndex);
   void Item(const nsAString& aName, Nullable<OwningNodeOrHTMLCollection>& aResult)
   {
     NamedItem(aName, aResult);
   }
--- a/dom/html/HTMLAnchorElement.cpp
+++ b/dom/html/HTMLAnchorElement.cpp
@@ -64,19 +64,19 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
                                                 nsGenericHTMLElement)
   tmp->Link::Unlink();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLAnchorElement)
 
 JSObject*
-HTMLAnchorElement::WrapNode(JSContext *aCx)
+HTMLAnchorElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAnchorElementBinding::Wrap(aCx, this);
+  return HTMLAnchorElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Charset, charset)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Coords, coords)
 NS_IMPL_URI_ATTR(HTMLAnchorElement, Href, href)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Hreflang, hreflang)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Name, name)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Rel, rel)
--- a/dom/html/HTMLAnchorElement.h
+++ b/dom/html/HTMLAnchorElement.h
@@ -224,16 +224,16 @@ public:
     GetHref(aResult, aError);
   }
 
 protected:
   virtual ~HTMLAnchorElement();
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsRefPtr<nsDOMTokenList > mRelList;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLAnchorElement_h
--- a/dom/html/HTMLAreaElement.cpp
+++ b/dom/html/HTMLAreaElement.cpp
@@ -264,15 +264,15 @@ HTMLAreaElement::IntrinsicState() const
 size_t
 HTMLAreaElement::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
          Link::SizeOfExcludingThis(aMallocSizeOf);
 }
 
 JSObject*
-HTMLAreaElement::WrapNode(JSContext* aCx)
+HTMLAreaElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAreaElementBinding::Wrap(aCx, this);
+  return HTMLAreaElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAreaElement.h
+++ b/dom/html/HTMLAreaElement.h
@@ -173,17 +173,17 @@ public:
   void Stringify(nsAString& aResult, ErrorResult& aError)
   {
     GetHref(aResult, aError);
   }
 
 protected:
   virtual ~HTMLAreaElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
   nsRefPtr<nsDOMTokenList > mRelList;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAudioElement.cpp
+++ b/dom/html/HTMLAudioElement.cpp
@@ -91,15 +91,15 @@ nsresult HTMLAudioElement::SetAcceptHead
       "video/*;q=0.6,*/*;q=0.5");
 
     return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                       value,
                                       false);
 }
 
 JSObject*
-HTMLAudioElement::WrapNode(JSContext* aCx)
+HTMLAudioElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAudioElementBinding::Wrap(aCx, this);
+  return HTMLAudioElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAudioElement.h
+++ b/dom/html/HTMLAudioElement.h
@@ -38,15 +38,15 @@ public:
 
   static already_AddRefed<HTMLAudioElement>
   Audio(const GlobalObject& aGlobal,
         const Optional<nsAString>& aSrc, ErrorResult& aRv);
 
 protected:
   virtual ~HTMLAudioElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLAudioElement_h
--- a/dom/html/HTMLBRElement.cpp
+++ b/dom/html/HTMLBRElement.cpp
@@ -90,15 +90,15 @@ HTMLBRElement::IsAttributeMapped(const n
 
 nsMapRuleToAttributesFunc
 HTMLBRElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 JSObject*
-HTMLBRElement::WrapNode(JSContext *aCx)
+HTMLBRElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLBRElementBinding::Wrap(aCx, this);
+  return HTMLBRElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLBRElement.h
+++ b/dom/html/HTMLBRElement.h
@@ -38,17 +38,17 @@ public:
   {
     return GetBoolAttr(nsGkAtoms::clear);
   }
   void SetClear(const nsAString& aClear, ErrorResult& aError)
   {
     return SetHTMLAttr(nsGkAtoms::clear, aClear, aError);
   }
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   virtual ~HTMLBRElement();
 
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
--- a/dom/html/HTMLBodyElement.cpp
+++ b/dom/html/HTMLBodyElement.cpp
@@ -184,19 +184,19 @@ BodyRule::List(FILE* out, int32_t aInden
 HTMLBodyElement::~HTMLBodyElement()
 {
   if (mContentStyleRule) {
     mContentStyleRule->mPart = nullptr;
   }
 }
 
 JSObject*
-HTMLBodyElement::WrapNode(JSContext *aCx)
+HTMLBodyElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLBodyElementBinding::Wrap(aCx, this);
+  return HTMLBodyElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLBodyElement, nsGenericHTMLElement,
                             nsIDOMHTMLBodyElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLBodyElement)
 
 NS_IMETHODIMP 
--- a/dom/html/HTMLBodyElement.h
+++ b/dom/html/HTMLBodyElement.h
@@ -129,17 +129,17 @@ public:
   virtual already_AddRefed<nsIEditor> GetAssociatedEditor() MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLBodyElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsRefPtr<BodyRule> mContentStyleRule;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -574,15 +574,15 @@ HTMLButtonElement::IntrinsicState() cons
   if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
     state |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
   }
 
   return state;
 }
 
 JSObject*
-HTMLButtonElement::WrapNode(JSContext* aCx)
+HTMLButtonElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLButtonElementBinding::Wrap(aCx, this);
+  return HTMLButtonElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -57,17 +57,17 @@ public:
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult PostHandleEvent(
                      EventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
 
   // nsINode
   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   virtual void DoneCreatingElement() MOZ_OVERRIDE;
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -67,19 +67,19 @@ HTMLCanvasPrintState::HTMLCanvasPrintSta
 {
 }
 
 HTMLCanvasPrintState::~HTMLCanvasPrintState()
 {
 }
 
 /* virtual */ JSObject*
-HTMLCanvasPrintState::WrapObject(JSContext* aCx)
+HTMLCanvasPrintState::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCanvasPrintStateBinding::Wrap(aCx, this);
+  return MozCanvasPrintStateBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsISupports*
 HTMLCanvasPrintState::Context() const
 {
   return mContext;
 }
 
@@ -132,19 +132,19 @@ NS_IMPL_RELEASE_INHERITED(HTMLCanvasElem
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLCanvasElement)
   NS_INTERFACE_TABLE_INHERITED(HTMLCanvasElement, nsIDOMHTMLCanvasElement)
 NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLCanvasElement)
 
 /* virtual */ JSObject*
-HTMLCanvasElement::WrapNode(JSContext* aCx)
+HTMLCanvasElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLCanvasElementBinding::Wrap(aCx, this);
+  return HTMLCanvasElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsIntSize
 HTMLCanvasElement::GetWidthHeight()
 {
   nsIntSize size(DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT);
   const nsAttrValue* value;
 
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -210,17 +210,17 @@ public:
   // take a snapshot of the canvas that needs to be "live" (e.g. -moz-element).
   void MarkContextClean();
 
   nsresult GetContext(const nsAString& aContextId, nsISupports** aContext);
 
 protected:
   virtual ~HTMLCanvasElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsIntSize GetWidthHeight();
 
   nsresult UpdateContext(JSContext* aCx, JS::Handle<JS::Value> options);
   nsresult ParseParams(JSContext* aCx,
                        const nsAString& aType,
                        const JS::Value& aEncoderOptions,
                        nsAString& aParams,
@@ -274,17 +274,17 @@ public:
 
   void NotifyDone();
 
   bool mIsDone;
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(HTMLCanvasPrintState)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(HTMLCanvasPrintState)
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   HTMLCanvasElement* GetParentObject()
   {
     return mCanvas;
   }
 
 private:
   ~HTMLCanvasPrintState();
--- a/dom/html/HTMLContentElement.cpp
+++ b/dom/html/HTMLContentElement.cpp
@@ -38,19 +38,19 @@ NS_IMPL_ADDREF_INHERITED(HTMLContentElem
 NS_IMPL_RELEASE_INHERITED(HTMLContentElement, Element)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLContentElement)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLContentElement)
 
 JSObject*
-HTMLContentElement::WrapNode(JSContext *aCx)
+HTMLContentElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLContentElementBinding::Wrap(aCx, this);
+  return HTMLContentElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 HTMLContentElement::BindToTree(nsIDocument* aDocument,
                                nsIContent* aParent,
                                nsIContent* aBindingParent,
                                bool aCompileEventHandlers)
 {
@@ -357,13 +357,13 @@ DistributedContentList::GetLength(uint32
 
 int32_t
 DistributedContentList::IndexOf(nsIContent* aContent)
 {
   return mDistributedNodes.IndexOf(aContent);
 }
 
 JSObject*
-DistributedContentList::WrapObject(JSContext* aCx)
+DistributedContentList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(aCx, this);
+  return NodeListBinding::Wrap(aCx, this, aGivenProto);
 }
 
--- a/dom/html/HTMLContentElement.h
+++ b/dom/html/HTMLContentElement.h
@@ -68,17 +68,17 @@ public:
   void SetSelect(const nsAString& aSelect)
   {
     Element::SetAttr(kNameSpaceID_None, nsGkAtoms::select, aSelect, true);
   }
 
 protected:
   virtual ~HTMLContentElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   /**
    * Updates the destination insertion points of the fallback
    * content of this insertion point. If there are nodes matched
    * to this insertion point, then destination insertion points
    * of fallback are cleared, otherwise, this insertion point
    * is a destination insertion point.
    */
@@ -105,17 +105,17 @@ public:
 
   // nsIDOMNodeList
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList
   virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
   virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
   virtual nsINode* GetParentObject() MOZ_OVERRIDE { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~DistributedContentList();
   nsRefPtr<HTMLContentElement> mParent;
   nsCOMArray<nsIContent> mDistributedNodes;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLDataElement.cpp
+++ b/dom/html/HTMLDataElement.cpp
@@ -19,19 +19,19 @@ HTMLDataElement::HTMLDataElement(already
 
 HTMLDataElement::~HTMLDataElement()
 {
 }
 
 NS_IMPL_ELEMENT_CLONE(HTMLDataElement)
 
 JSObject*
-HTMLDataElement::WrapNode(JSContext* aCx)
+HTMLDataElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLDataElementBinding::Wrap(aCx, this);
+  return HTMLDataElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 HTMLDataElement::GetItemValueText(DOMString& text)
 {
   GetValue(text);
 }
 
--- a/dom/html/HTMLDataElement.h
+++ b/dom/html/HTMLDataElement.h
@@ -32,15 +32,15 @@ public:
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLDataElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLDataElement_h
--- a/dom/html/HTMLDataListElement.cpp
+++ b/dom/html/HTMLDataListElement.cpp
@@ -11,19 +11,19 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(DataList)
 namespace mozilla {
 namespace dom {
 
 HTMLDataListElement::~HTMLDataListElement()
 {
 }
 
 JSObject*
-HTMLDataListElement::WrapNode(JSContext *aCx)
+HTMLDataListElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLDataListElementBinding::Wrap(aCx, this);
+  return HTMLDataListElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLDataListElement, nsGenericHTMLElement,
                                    mOptions)
 
 NS_IMPL_ADDREF_INHERITED(HTMLDataListElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLDataListElement, Element)
 
--- a/dom/html/HTMLDataListElement.h
+++ b/dom/html/HTMLDataListElement.h
@@ -39,17 +39,17 @@ public:
   static bool MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
                              nsIAtom* aAtom, void* aData);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLDataListElement,
                                            nsGenericHTMLElement)
 protected:
   virtual ~HTMLDataListElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // <option>'s list inside the datalist element.
   nsRefPtr<nsContentList> mOptions;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/html/HTMLDivElement.cpp
+++ b/dom/html/HTMLDivElement.cpp
@@ -19,19 +19,19 @@ HTMLDivElement::~HTMLDivElement()
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLDivElement, nsGenericHTMLElement,
                             nsIDOMHTMLDivElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLDivElement)
 
 JSObject*
-HTMLDivElement::WrapNode(JSContext *aCx)
+HTMLDivElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return dom::HTMLDivElementBinding::Wrap(aCx, this);
+  return dom::HTMLDivElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 HTMLDivElement::ParseAttribute(int32_t aNamespaceID,
                                nsIAtom* aAttribute,
                                const nsAString& aValue,
                                nsAttrValue& aResult)
 {
--- a/dom/html/HTMLDivElement.h
+++ b/dom/html/HTMLDivElement.h
@@ -54,17 +54,17 @@ public:
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLDivElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLElement.cpp
+++ b/dom/html/HTMLElement.cpp
@@ -17,17 +17,17 @@ public:
   virtual ~HTMLElement();
 
   NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML) MOZ_OVERRIDE;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo,
                          nsINode** aResult) const MOZ_OVERRIDE;
 
 protected:
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 HTMLElement::HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLElement::~HTMLElement()
@@ -53,19 +53,19 @@ HTMLElement::GetInnerHTML(nsAString& aIn
     }
     return NS_OK;
   }
 
   return nsGenericHTMLElement::GetInnerHTML(aInnerHTML);
 }
 
 JSObject*
-HTMLElement::WrapNode(JSContext *aCx)
+HTMLElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return dom::HTMLElementBinding::Wrap(aCx, this);
+  return dom::HTMLElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
 
 // Here, we expand 'NS_IMPL_NS_NEW_HTML_ELEMENT()' by hand.
 // (Calling the macro directly (with no args) produces compiler warnings.)
 nsGenericHTMLElement*
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -365,15 +365,15 @@ HTMLFieldSetElement::IntrinsicState() co
   } else {
     state |= NS_EVENT_STATE_VALID;
   }
 
   return state;
 }
 
 JSObject*
-HTMLFieldSetElement::WrapNode(JSContext* aCx)
+HTMLFieldSetElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFieldSetElementBinding::Wrap(aCx, this);
+  return HTMLFieldSetElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -106,17 +106,17 @@ public:
    *
    * @param aElementValidityState the new validity state of the element
    */
   void UpdateValidity(bool aElementValidityState);
 
 protected:
   virtual ~HTMLFieldSetElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
 
   /**
    * Notify all elements (in mElements) that the first legend of the fieldset
    * has now changed.
    */
   void NotifyElementsForFirstLegendChange(bool aNotify);
--- a/dom/html/HTMLFontElement.cpp
+++ b/dom/html/HTMLFontElement.cpp
@@ -16,19 +16,19 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Font)
 namespace mozilla {
 namespace dom {
 
 HTMLFontElement::~HTMLFontElement()
 {
 }
 
 JSObject*
-HTMLFontElement::WrapNode(JSContext *aCx)
+HTMLFontElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFontElementBinding::Wrap(aCx, this);
+  return HTMLFontElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ELEMENT_CLONE(HTMLFontElement)
 
 bool
 HTMLFontElement::ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
--- a/dom/html/HTMLFontElement.h
+++ b/dom/html/HTMLFontElement.h
@@ -50,17 +50,17 @@ public:
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLFontElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFormControlsCollection.cpp
+++ b/dom/html/HTMLFormControlsCollection.cpp
@@ -406,15 +406,15 @@ HTMLFormControlsCollection::GetSupported
   FlushPendingNotifications();
   // Just enumerate mNameLookupTable.  This won't guarantee order, but
   // that's OK, because the HTML5 spec doesn't define an order for
   // this enumeration.
   mNameLookupTable.EnumerateRead(CollectNames, &aNames);
 }
 
 /* virtual */ JSObject*
-HTMLFormControlsCollection::WrapObject(JSContext* aCx)
+HTMLFormControlsCollection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFormControlsCollectionBinding::Wrap(aCx, this);
+  return HTMLFormControlsCollectionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFormControlsCollection.h
+++ b/dom/html/HTMLFormControlsCollection.h
@@ -75,17 +75,17 @@ public:
    *
    * @param aControls The list of sorted controls[out].
    * @return NS_OK or NS_ERROR_OUT_OF_MEMORY.
    */
   nsresult GetSortedControls(nsTArray<nsGenericHTMLFormElement*>& aControls) const;
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~HTMLFormControlsCollection();
   virtual JSObject* GetWrapperPreserveColorInternal() MOZ_OVERRIDE
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
 public:
 
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -2511,15 +2511,15 @@ HTMLFormElement::AddToPastNamesMap(const
   // previous entry with the same name, if any.
   nsCOMPtr<nsIContent> node = do_QueryInterface(aChild);
   if (node) {
     mPastNameLookupTable.Put(aName, aChild);
   }
 }
  
 JSObject*
-HTMLFormElement::WrapNode(JSContext* aCx)
+HTMLFormElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFormElementBinding::Wrap(aCx, this);
+  return HTMLFormElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFormElement.h
+++ b/dom/html/HTMLFormElement.h
@@ -405,17 +405,17 @@ public:
                       nsIContent* aForm);
 #endif
 
   js::ExpandoAndGeneration mExpandoAndGeneration;
 
   void RequestAutocomplete();
 
 protected:
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void PostPasswordEvent();
   void EventHandled() { mFormPasswordEventDispatcher = nullptr; }
 
   class FormPasswordEventDispatcher MOZ_FINAL : public AsyncEventDispatcher
   {
   public:
     FormPasswordEventDispatcher(HTMLFormElement* aEventNode,
--- a/dom/html/HTMLFrameElement.cpp
+++ b/dom/html/HTMLFrameElement.cpp
@@ -76,15 +76,15 @@ HTMLFrameElement::ParseAttribute(int32_t
     }
   }
 
   return nsGenericHTMLFrameElement::ParseAttribute(aNamespaceID, aAttribute,
                                                    aValue, aResult);
 }
 
 JSObject*
-HTMLFrameElement::WrapNode(JSContext* aCx)
+HTMLFrameElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFrameElementBinding::Wrap(aCx, this);
+  return HTMLFrameElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace mozilla
 } // namespace dom
--- a/dom/html/HTMLFrameElement.h
+++ b/dom/html/HTMLFrameElement.h
@@ -91,17 +91,17 @@ public:
   }
 
   using nsGenericHTMLFrameElement::GetContentDocument;
   using nsGenericHTMLFrameElement::GetContentWindow;
 
 protected:
   virtual ~HTMLFrameElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFrameSetElement.cpp
+++ b/dom/html/HTMLFrameSetElement.cpp
@@ -13,19 +13,19 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
 namespace mozilla {
 namespace dom {
 
 HTMLFrameSetElement::~HTMLFrameSetElement()
 {
 }
 
 JSObject*
-HTMLFrameSetElement::WrapNode(JSContext *aCx)
+HTMLFrameSetElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFrameSetElementBinding::Wrap(aCx, this);
+  return HTMLFrameSetElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLFrameSetElement, nsGenericHTMLElement,
                             nsIDOMHTMLFrameSetElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLFrameSetElement)
 
 NS_IMETHODIMP 
--- a/dom/html/HTMLFrameSetElement.h
+++ b/dom/html/HTMLFrameSetElement.h
@@ -134,17 +134,17 @@ public:
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               int32_t aModType) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLFrameSetElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   nsresult ParseRowCol(const nsAString& aValue,
                        int32_t&         aNumSpecs,
                        nsFramesetSpec** aSpecs);
 
   /**
    * The number of size specs in our "rows" attr
--- a/dom/html/HTMLHRElement.cpp
+++ b/dom/html/HTMLHRElement.cpp
@@ -252,15 +252,15 @@ HTMLHRElement::IsAttributeMapped(const n
 
 nsMapRuleToAttributesFunc
 HTMLHRElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 JSObject*
-HTMLHRElement::WrapNode(JSContext* aCx)
+HTMLHRElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLHRElementBinding::Wrap(aCx, this);
+  return HTMLHRElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace mozilla
 } // namespace dom
--- a/dom/html/HTMLHRElement.h
+++ b/dom/html/HTMLHRElement.h
@@ -67,17 +67,17 @@ public:
   void SetWidth(const nsAString& aWidth, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::width, aWidth, aError);
   }
 
 protected:
   virtual ~HTMLHRElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLHeadingElement.cpp
+++ b/dom/html/HTMLHeadingElement.cpp
@@ -22,19 +22,19 @@ HTMLHeadingElement::~HTMLHeadingElement(
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLHeadingElement, nsGenericHTMLElement,
                             nsIDOMHTMLHeadingElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLHeadingElement)
 
 JSObject*
-HTMLHeadingElement::WrapNode(JSContext *aCx)
+HTMLHeadingElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLHeadingElementBinding::Wrap(aCx, this);
+  return HTMLHeadingElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_STRING_ATTR(HTMLHeadingElement, Align, align)
 
 
 bool
 HTMLHeadingElement::ParseAttribute(int32_t aNamespaceID,
                                    nsIAtom* aAttribute,
--- a/dom/html/HTMLHeadingElement.h
+++ b/dom/html/HTMLHeadingElement.h
@@ -37,17 +37,17 @@ public:
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // The XPCOM versions of GetAlign and SetAlign are fine for us for
   // use from WebIDL.
 
 protected:
   virtual ~HTMLHeadingElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace mozilla
 } // namespace dom
--- a/dom/html/HTMLIFrameElement.cpp
+++ b/dom/html/HTMLIFrameElement.cpp
@@ -242,15 +242,15 @@ HTMLIFrameElement::UnsetAttr(int32_t aNa
 uint32_t
 HTMLIFrameElement::GetSandboxFlags()
 {
   const nsAttrValue* sandboxAttr = GetParsedAttr(nsGkAtoms::sandbox);
   return nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
 }
 
 JSObject*
-HTMLIFrameElement::WrapNode(JSContext* aCx)
+HTMLIFrameElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLIFrameElementBinding::Wrap(aCx, this);
+  return HTMLIFrameElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLIFrameElement.h
+++ b/dom/html/HTMLIFrameElement.h
@@ -175,17 +175,17 @@ public:
   // nsGenericHTMLFrameElement::GetAppManifestURL is fine
 
 protected:
   virtual ~HTMLIFrameElement();
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -797,19 +797,19 @@ HTMLImageElement::CopyInnerTo(Element* a
 
 CORSMode
 HTMLImageElement::GetCORSMode()
 {
   return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 }
 
 JSObject*
-HTMLImageElement::WrapNode(JSContext* aCx)
+HTMLImageElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLImageElementBinding::Wrap(aCx, this);
+  return HTMLImageElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #ifdef DEBUG
 nsIDOMHTMLFormElement*
 HTMLImageElement::GetForm() const
 {
   return mForm;
 }
--- a/dom/html/HTMLImageElement.h
+++ b/dom/html/HTMLImageElement.h
@@ -308,17 +308,17 @@ protected:
   // only that it is valid.
   bool TryCreateResponsiveSelector(nsIContent *aSourceNode,
                                    const nsAString *aSrcset = nullptr,
                                    const nsAString *aSizes = nullptr);
 
   CSSIntPoint GetXY();
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   void UpdateFormOwner();
 
   virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                  const nsAttrValueOrString* aValue,
                                  bool aNotify) MOZ_OVERRIDE;
 
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -7564,17 +7564,17 @@ HTMLInputElement::UpdateHasRange()
 
 void
 HTMLInputElement::PickerClosed()
 {
   mPickerRunning = false;
 }
 
 JSObject*
-HTMLInputElement::WrapNode(JSContext* aCx)
-{
-  return HTMLInputElementBinding::Wrap(aCx, this);
+HTMLInputElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return HTMLInputElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
 
 #undef NS_ORIGINAL_CHECKED_VALUE
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -757,17 +757,17 @@ public:
    * then this function will return the number parsed as a Decimal, otherwise
    * it will return a Decimal for which Decimal::isFinite() will return false.
    */
   static Decimal StringToDecimal(const nsAString& aValue);
 
 protected:
   vi