Bug 824589. Convert XULElement to WebIDL. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 29 Jan 2013 12:51:55 -0500
changeset 130123 22695cac389690829d6f9860c92a381b969c783c
parent 130122 6d36308422243e67ed5d406cc1841a694045aa57
child 130124 2a0424e177c19a871d287a50688ac71efcac8458
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs824589
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 824589. Convert XULElement to WebIDL. r=peterv The assertions in nsINode and nsWrapperCache are to eagerly catch failures to override those methods. The classinfo change for XULTreeBuilder is needed because one of those is returned via an nsIXULTemplateBuilder attribute on XULElement. Alternately, I could mark it notflattened in Bindings.conf, but Enn said he prefers this anyway. The change to the QI impl in BindingUtils is needed because when XPConnect converts an IID from C++ to JS it makes is an nsJSID, not an nsJSIID. We've run into this before, sadly. I removed "id" from nsIDOMXULElement because it's already on Element. I suppose I could have left it there, but this seems cleaner. The nsJSIID::HasInstance changes are needed to support XBL-implemented interfaces. Sadly, this does mean that if the underlying object QIs to something but we didn't put those props on the WebIDL we'll end up testing true for instanceof but not exposing the props. I don't see an obviously better way. We should work on killing off uses of "instanceof someinterface". The browser.js change is needed to avoid throwing exceptions during browser-chrome tests that are now getting reported because our swapFrameLoaders is no longer an XPConnect method.
browser/base/content/browser.js
content/base/public/nsINode.h
content/canvas/src/CanvasRenderingContext2D.cpp
content/canvas/src/CanvasRenderingContext2D.h
content/canvas/src/Makefile.in
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsWrapperCache.h
dom/bindings/BindingUtils.cpp
dom/bindings/Bindings.conf
dom/bindings/Makefile.in
dom/interfaces/xul/nsIDOMXULElement.idl
dom/webidl/CanvasRenderingContext2D.webidl
dom/webidl/HTMLElement.webidl
dom/webidl/SVGElement.webidl
dom/webidl/WebIDL.mk
dom/webidl/XULElement.webidl
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/dom_quickstubs.qsconf
xpfe/appshell/src/nsXULWindow.cpp
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1260,17 +1260,17 @@ var gBrowserInit = {
     IndexedDBPromptHelper.init();
     gFormSubmitObserver.init();
     SocialUI.init();
     AddonManager.addAddonListener(AddonsMgrListener);
     WebrtcIndicator.init();
 
     gBrowser.addEventListener("pageshow", function(event) {
       // Filter out events that are not about the document load we are interested in
-      if (event.target == content.document)
+      if (content && event.target == content.document)
         setTimeout(pageShowEventHandlers, 0, event);
     }, true);
 
     // Ensure login manager is up and running.
     Services.logins;
 
     if (mustLoadSidebar) {
       let sidebar = document.getElementById("sidebar");
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -383,16 +383,17 @@ 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.
    */
   virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
                              bool *aTriedToWrap)
   {
+    MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapNode");
     *aTriedToWrap = false;
     return nullptr;
   }
 
 public:
   nsIDocument* GetParentObject() const
   {
     // Make sure that we get the owner document of the content node, in case
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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/. */
 
 #include "base/basictypes.h"
 #include "CanvasRenderingContext2D.h"
 
-#include "nsIDOMXULElement.h"
+#include "nsXULElement.h"
 
 #include "prenv.h"
 
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
 
 #include "nsContentUtils.h"
 
@@ -3229,17 +3229,17 @@ CanvasRenderingContext2D::DrawWindow(nsI
 
   // note that x and y are coordinates in the document that
   // we're drawing; x and y are drawn to 0,0 in current user
   // space.
   RedrawUser(gfxRect(0, 0, w, h));
 }
 
 void
-CanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* elem,
+CanvasRenderingContext2D::AsyncDrawXULElement(nsXULElement& elem,
                                               double x, double y,
                                               double w, double h,
                                               const nsAString& bgColor,
                                               uint32_t flags,
                                               ErrorResult& error)
 {
   // We can't allow web apps to call this until we fix at least the
   // following potential security issues:
@@ -3250,17 +3250,17 @@ CanvasRenderingContext2D::AsyncDrawXULEl
   if (!nsContentUtils::IsCallerChrome()) {
     // not permitted to use DrawWindow
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
     error.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
 #if 0
-  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(elem);
+  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(&elem);
   if (!loaderOwner) {
     error.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
   if (!frameloader) {
     error.Throw(NS_ERROR_FAILURE);
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -19,17 +19,17 @@
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
     {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
 #define NS_CANVASPATTERNAZURE_PRIVATE_IID \
     {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
 
-class nsIDOMXULElement;
+class nsXULElement;
 
 namespace mozilla {
 namespace gfx {
 struct Rect;
 class SourceSurface;
 }
 
 namespace dom {
@@ -433,17 +433,17 @@ public:
     if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
       CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
     }
   }
 
   void DrawWindow(nsIDOMWindow* window, double x, double y, double w, double h,
                   const nsAString& bgColor, uint32_t flags,
                   mozilla::ErrorResult& error);
-  void AsyncDrawXULElement(nsIDOMXULElement* elem, double x, double y, double w,
+  void AsyncDrawXULElement(nsXULElement& elem, double x, double y, double w,
                            double h, const nsAString& bgColor, uint32_t flags,
                            mozilla::ErrorResult& error);
 
   nsresult Redraw();
 
   // nsICanvasRenderingContextInternal
   NS_IMETHOD SetDimensions(int32_t width, int32_t height);
   NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height);
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -63,16 +63,17 @@ CPPSRCS += \
 	WebGLShaderPrecisionFormat.cpp \
 	WebGLTexelConversions.cpp \
 	WebGLTexture.cpp \
 	WebGLUniformLocation.cpp \
 	$(NULL)
 
 LOCAL_INCLUDES += \
 	-I$(topsrcdir)/js/xpconnect/wrappers \
+	-I$(topsrcdir)/content/xul/content/src \
 	$(NULL)
 
 else
 
 CPPSRCS += WebGLContextNotSupported.cpp
 
 endif
 
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -99,18 +99,19 @@
 #include "nsNodeInfoManager.h"
 #include "nsXBLBinding.h"
 #include "nsEventDispatcher.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsICSSDeclaration.h"
 
-namespace css = mozilla::css;
-namespace dom = mozilla::dom;
+#include "mozilla/dom/XULElementBinding.h"
+
+using namespace mozilla;
 
 //----------------------------------------------------------------------
 
 static NS_DEFINE_CID(kXULPopupListenerCID,        NS_XULPOPUPLISTENER_CID);
 
 //----------------------------------------------------------------------
 
 #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
@@ -161,16 +162,18 @@ NS_INTERFACE_MAP_END_AGGREGATED(mElement
 //
 
 nsXULElement::nsXULElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsStyledElement(aNodeInfo),
       mBindingParent(nullptr)
 {
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumElements);
 
+    SetIsDOMBinding();
+
     // We may be READWRITE by default; check.
     if (IsReadWriteTextElement()) {
         AddStatesSilently(NS_EVENT_STATE_MOZ_READWRITE);
         RemoveStatesSilently(NS_EVENT_STATE_MOZ_READONLY);
     }
 }
 
 nsXULElement::nsXULSlots::nsXULSlots()
@@ -395,66 +398,78 @@ nsXULElement::Clone(nsINodeInfo *aNodeIn
 
 //----------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
                                      const nsAString& aValue,
                                      nsIDOMNodeList** aReturn)
 {
+    *aReturn = GetElementsByAttribute(aAttribute, aValue).get();
+    return NS_OK;
+}
+
+already_AddRefed<nsINodeList>
+nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
+                                     const nsAString& aValue)
+{
     nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
-    NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
     void* attrValue = new nsString(aValue);
-    NS_ENSURE_TRUE(attrValue, NS_ERROR_OUT_OF_MEMORY);
-    nsContentList *list = 
+    nsRefPtr<nsContentList> list =
         new nsContentList(this,
                           nsXULDocument::MatchAttribute,
                           nsContentUtils::DestroyMatchString,
                           attrValue,
                           true,
                           attrAtom,
                           kNameSpaceID_Unknown);
-    NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
-
-    NS_ADDREF(*aReturn = list);
-    return NS_OK;
+    return list.forget();
 }
 
 NS_IMETHODIMP
 nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
                                        const nsAString& aAttribute,
                                        const nsAString& aValue,
                                        nsIDOMNodeList** aReturn)
 {
+    ErrorResult rv;
+    *aReturn =
+        GetElementsByAttributeNS(aNamespaceURI, aAttribute, aValue, rv).get();
+    return rv.ErrorCode();
+}
+
+already_AddRefed<nsINodeList>
+nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
+                                       const nsAString& aAttribute,
+                                       const nsAString& aValue,
+                                       ErrorResult& rv)
+{
     nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
-    NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
 
     int32_t nameSpaceId = kNameSpaceID_Wildcard;
     if (!aNamespaceURI.EqualsLiteral("*")) {
-      nsresult rv =
+      rv =
         nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                               nameSpaceId);
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (rv.Failed()) {
+          return nullptr;
+      }
     }
 
     void* attrValue = new nsString(aValue);
-    NS_ENSURE_TRUE(attrValue, NS_ERROR_OUT_OF_MEMORY);
-    
-    nsContentList *list = 
+    nsRefPtr<nsContentList> list =
         new nsContentList(this,
                           nsXULDocument::MatchAttribute,
                           nsContentUtils::DestroyMatchString,
                           attrValue,
                           true,
                           attrAtom,
                           nameSpaceId);
-    NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
 
-    NS_ADDREF(*aReturn = list);
-    return NS_OK;
+    return list.forget();
 }
 
 nsEventListenerManager*
 nsXULElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer)
 {
     // XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc()
     // here, override BindToTree for those classes and munge event
     // listeners there?
@@ -1171,60 +1186,81 @@ nsXULElement::PreHandleEvent(nsEventChai
 
     return nsStyledElement::PreHandleEvent(aVisitor);
 }
 
 // XXX This _should_ be an implementation method, _not_ publicly exposed :-(
 NS_IMETHODIMP
 nsXULElement::GetResource(nsIRDFResource** aResource)
 {
+    ErrorResult rv;
+    *aResource = GetResource(rv).get();
+    return rv.ErrorCode();
+}
+
+already_AddRefed<nsIRDFResource>
+nsXULElement::GetResource(ErrorResult& rv)
+{
     nsAutoString id;
     GetAttr(kNameSpaceID_None, nsGkAtoms::ref, id);
     if (id.IsEmpty()) {
         GetAttr(kNameSpaceID_None, nsGkAtoms::id, id);
     }
 
-    if (!id.IsEmpty()) {
-        return nsXULContentUtils::RDFService()->
-            GetUnicodeResource(id, aResource);
+    if (id.IsEmpty()) {
+        return nullptr;
     }
-    *aResource = nullptr;
 
-    return NS_OK;
+    nsCOMPtr<nsIRDFResource> resource;
+    rv = nsXULContentUtils::RDFService()->
+        GetUnicodeResource(id, getter_AddRefs(resource));
+    return resource.forget();
 }
 
-
 NS_IMETHODIMP
 nsXULElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
 {
-    nsCOMPtr<nsIXULTemplateBuilder> builder;
-    GetBuilder(getter_AddRefs(builder));
+    *aDatabase = GetDatabase().get();
+    return NS_OK;
+}
 
-    if (builder)
-        builder->GetDatabase(aDatabase);
-    else
-        *aDatabase = nullptr;
+already_AddRefed<nsIRDFCompositeDataSource>
+nsXULElement::GetDatabase()
+{
+    nsCOMPtr<nsIXULTemplateBuilder> builder = GetBuilder();
+    if (!builder) {
+        return nullptr;
+    }
 
-    return NS_OK;
+    nsCOMPtr<nsIRDFCompositeDataSource> database;
+    builder->GetDatabase(getter_AddRefs(database));
+    return database.forget();
 }
 
 
 NS_IMETHODIMP
 nsXULElement::GetBuilder(nsIXULTemplateBuilder** aBuilder)
 {
-    *aBuilder = nullptr;
-
-    // XXX sXBL/XBL2 issue! Owner or current document?
-    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(GetCurrentDoc());
-    if (xuldoc)
-        xuldoc->GetTemplateBuilderFor(this, aBuilder);
-
+    *aBuilder = GetBuilder().get();
     return NS_OK;
 }
 
+already_AddRefed<nsIXULTemplateBuilder>
+nsXULElement::GetBuilder()
+{
+    // XXX sXBL/XBL2 issue! Owner or current document?
+    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(GetCurrentDoc());
+    if (!xuldoc) {
+        return nullptr;
+    }
+
+    nsCOMPtr<nsIXULTemplateBuilder> builder;
+    xuldoc->GetTemplateBuilderFor(this, getter_AddRefs(builder));
+    return builder.forget();
+}
 
 //----------------------------------------------------------------------
 // Implementation methods
 
 NS_IMETHODIMP
 nsXULElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
 {
     return NS_OK;
@@ -1264,39 +1300,55 @@ nsXULElement::IsAttributeMapped(const ns
 {
     return false;
 }
 
 // Controllers Methods
 NS_IMETHODIMP
 nsXULElement::GetControllers(nsIControllers** aResult)
 {
+    ErrorResult rv;
+    NS_IF_ADDREF(*aResult = GetControllers(rv));
+    return rv.ErrorCode();
+}
+
+nsIControllers*
+nsXULElement::GetControllers(ErrorResult& rv)
+{
     if (! Controllers()) {
         nsDOMSlots* slots = DOMSlots();
 
-        nsresult rv;
         rv = NS_NewXULControllers(nullptr, NS_GET_IID(nsIControllers),
                                   reinterpret_cast<void**>(&slots->mControllers));
 
-        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a controllers");
-        if (NS_FAILED(rv)) return rv;
+        NS_ASSERTION(NS_SUCCEEDED(rv.ErrorCode()),
+                     "unable to create a controllers");
+        if (rv.Failed()) {
+            return nullptr;
+        }
     }
 
-    *aResult = Controllers();
-    NS_IF_ADDREF(*aResult);
-    return NS_OK;
+    return Controllers();
 }
 
 NS_IMETHODIMP
 nsXULElement::GetBoxObject(nsIBoxObject** aResult)
 {
-  *aResult = nullptr;
+    ErrorResult rv;
+    *aResult = GetBoxObject(rv).get();
+    return rv.ErrorCode();
+}
 
-  // XXX sXBL/XBL2 issue! Owner or current document?
-  return OwnerDoc()->GetBoxObjectFor(this, aResult);
+already_AddRefed<nsIBoxObject>
+nsXULElement::GetBoxObject(ErrorResult& rv)
+{
+    nsCOMPtr<nsIBoxObject> boxObject;
+    // XXX sXBL/XBL2 issue! Owner or current document?
+    rv = OwnerDoc()->GetBoxObjectFor(this, getter_AddRefs(boxObject));
+    return boxObject.forget();
 }
 
 // Methods for setting/getting attributes from nsIDOMXULElement
 #define NS_IMPL_XUL_STRING_ATTR(_method, _atom)                     \
   NS_IMETHODIMP                                                     \
   nsXULElement::Get##_method(nsAString& aReturn)                    \
   {                                                                 \
     GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aReturn);         \
@@ -1306,36 +1358,29 @@ nsXULElement::GetBoxObject(nsIBoxObject*
   nsXULElement::Set##_method(const nsAString& aValue)               \
   {                                                                 \
     return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue,    \
                    true);                                        \
   }
 
 #define NS_IMPL_XUL_BOOL_ATTR(_method, _atom)                       \
   NS_IMETHODIMP                                                     \
-  nsXULElement::Get##_method(bool* aResult)                       \
+  nsXULElement::Get##_method(bool* aResult)                         \
   {                                                                 \
-    *aResult = BoolAttrIsTrue(nsGkAtoms::_atom);                   \
-                                                                    \
+    *aResult = _method();                                           \
     return NS_OK;                                                   \
   }                                                                 \
   NS_IMETHODIMP                                                     \
-  nsXULElement::Set##_method(bool aValue)                         \
+  nsXULElement::Set##_method(bool aValue)                           \
   {                                                                 \
-    if (aValue)                                                     \
-      SetAttr(kNameSpaceID_None, nsGkAtoms::_atom,                 \
-              NS_LITERAL_STRING("true"), true);                  \
-    else                                                            \
-      UnsetAttr(kNameSpaceID_None, nsGkAtoms::_atom, true);     \
-                                                                    \
-    return NS_OK;                                                   \
+      SetXULBoolAttr(nsGkAtoms::_atom, aValue);                     \
+      return NS_OK;                                                 \
   }
 
 
-NS_IMPL_XUL_STRING_ATTR(Id, id)
 NS_IMPL_XUL_STRING_ATTR(ClassName, _class)
 NS_IMPL_XUL_STRING_ATTR(Align, align)
 NS_IMPL_XUL_STRING_ATTR(Dir, dir)
 NS_IMPL_XUL_STRING_ATTR(Flex, flex)
 NS_IMPL_XUL_STRING_ATTR(FlexGroup, flexgroup)
 NS_IMPL_XUL_STRING_ATTR(Ordinal, ordinal)
 NS_IMPL_XUL_STRING_ATTR(Orient, orient)
 NS_IMPL_XUL_STRING_ATTR(Pack, pack)
@@ -1413,34 +1458,42 @@ nsresult
 nsXULElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
 {
     nsCOMPtr<nsIContent> otherContent(do_QueryInterface(aOtherOwner));
     NS_ENSURE_TRUE(otherContent, NS_ERROR_NOT_IMPLEMENTED);
 
     nsXULElement* otherEl = FromContent(otherContent);
     NS_ENSURE_TRUE(otherEl, NS_ERROR_NOT_IMPLEMENTED);
 
-    if (otherEl == this) {
+    ErrorResult rv;
+    SwapFrameLoaders(*otherEl, rv);
+    return rv.ErrorCode();
+}
+
+void
+nsXULElement::SwapFrameLoaders(nsXULElement& aOtherElement, ErrorResult& rv)
+{
+    if (&aOtherElement == this) {
         // nothing to do
-        return NS_OK;
+        return;
     }
 
     nsXULSlots *ourSlots = static_cast<nsXULSlots*>(GetExistingDOMSlots());
     nsXULSlots *otherSlots =
-        static_cast<nsXULSlots*>(otherEl->GetExistingDOMSlots());
+        static_cast<nsXULSlots*>(aOtherElement.GetExistingDOMSlots());
     if (!ourSlots || !ourSlots->mFrameLoader ||
         !otherSlots || !otherSlots->mFrameLoader) {
         // Can't handle swapping when there is nothing to swap... yet.
-        return NS_ERROR_NOT_IMPLEMENTED;
+        rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+        return;
     }
 
-    return
-        ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
-                                                    ourSlots->mFrameLoader,
-                                                    otherSlots->mFrameLoader);
+    rv = ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
+                                                     ourSlots->mFrameLoader,
+                                                     otherSlots->mFrameLoader);
 }
 
 NS_IMETHODIMP
 nsXULElement::GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement)
 {
     for (nsIContent* current = GetParent(); current;
          current = current->GetParent()) {
         if (current->NodeInfo()->Equals(nsGkAtoms::listbox,
@@ -1454,44 +1507,68 @@ nsXULElement::GetParentTree(nsIDOMXULMul
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULElement::Focus()
 {
+    ErrorResult rv;
+    Focus(rv);
+    return rv.ErrorCode();
+}
+
+void
+nsXULElement::Focus(ErrorResult& rv)
+{
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     nsCOMPtr<nsIDOMElement> elem = do_QueryObject(this);
-    return fm ? fm->SetFocus(this, 0) : NS_OK;
+    if (fm) {
+        rv = fm->SetFocus(this, 0);
+    }
 }
 
 NS_IMETHODIMP
 nsXULElement::Blur()
 {
+    ErrorResult rv;
+    Blur(rv);
+    return rv.ErrorCode();
+}
+
+void
+nsXULElement::Blur(ErrorResult& rv)
+{
     if (!ShouldBlur(this))
-      return NS_OK;
+      return;
 
     nsIDocument* doc = GetCurrentDoc();
     if (!doc)
-      return NS_OK;
+      return;
 
     nsIDOMWindow* win = doc->GetWindow();
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-    if (win && fm)
-      return fm->ClearFocus(win);
-    return NS_OK;
+    if (win && fm) {
+      rv = fm->ClearFocus(win);
+    }
 }
 
 NS_IMETHODIMP
 nsXULElement::Click()
 {
   return ClickWithInputSource(nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN);
 }
 
+void
+nsXULElement::Click(ErrorResult& rv)
+{
+  rv = Click();
+}
+
 nsresult
 nsXULElement::ClickWithInputSource(uint16_t aInputSource)
 {
     if (BoolAttrIsTrue(nsGkAtoms::disabled))
         return NS_OK;
 
     nsCOMPtr<nsIDocument> doc = GetCurrentDoc(); // Strong just in case
     if (doc) {
@@ -1787,17 +1864,17 @@ nsXULElement::ResetChromeMargins()
     nsIWidget* mainWidget = GetWindowWidget();
     if (!mainWidget)
         return;
     // See nsIWidget
     nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget));
 }
 
 bool
-nsXULElement::BoolAttrIsTrue(nsIAtom* aName)
+nsXULElement::BoolAttrIsTrue(nsIAtom* aName) const
 {
     const nsAttrValue* attr =
         GetAttrInfo(kNameSpaceID_None, aName).mValue;
 
     return attr && attr->Type() == nsAttrValue::eAtom &&
            attr->GetAtomValue() == nsGkAtoms::_true;
 }
 
@@ -1825,16 +1902,22 @@ nsXULElement::RecompileScriptEventListen
 }
 
 bool
 nsXULElement::IsEventAttributeName(nsIAtom *aName)
 {
   return nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL);
 }
 
+JSObject*
+nsXULElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+    return dom::XULElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULPrototypeNode)
     if (tmp->mType == nsXULPrototypeNode::eType_Element) {
         static_cast<nsXULPrototypeElement*>(tmp)->Unlink();
     }
     else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
         static_cast<nsXULPrototypeScript*>(tmp)->UnlinkJSObjects();
     }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -32,16 +32,18 @@
 #include "nsLayoutCID.h"
 #include "nsAttrAndChildArray.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsStyledElement.h"
 #include "nsDOMScriptObjectHolder.h"
 #include "nsIFrameLoader.h"
 #include "jspubtd.h"
+#include "nsGenericHTMLElement.h"
+#include "nsFrameLoader.h"
 
 class nsIDocument;
 class nsString;
 class nsIDocShell;
 
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class nsIScriptGlobalObjectOwner;
@@ -388,28 +390,30 @@ public:
      * template-generated element has already had its children generated.
      */
     void SetTemplateGenerated() { SetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     void ClearTemplateGenerated() { UnsetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     bool GetTemplateGenerated() { return HasFlag(XUL_ELEMENT_TEMPLATE_GENERATED); }
 
     // nsIDOMNode
     NS_FORWARD_NSIDOMNODE_TO_NSINODE
+    // And since that shadowed GetParentElement with the XPCOM
+    // signature, pull in the one we care about.
+    using nsStyledElement::GetParentElement;
 
     // nsIDOMElement
     NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
     // nsIDOMXULElement
     NS_DECL_NSIDOMXULELEMENT
 
     virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
     virtual nsEventStates IntrinsicState() const;
 
     nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
-    already_AddRefed<nsFrameLoader> GetFrameLoader();
     nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
 
     virtual void RecompileScriptEventListeners();
 
     // This function should ONLY be used by BindToTree implementations.
     // The function exists solely because XUL elements store the binding
     // parent as a member instead of in the slots, as Element does.
     void SetXULBindingParent(nsIContent* aBindingParent)
@@ -418,16 +422,179 @@ public:
     }
 
     virtual nsXPCClassInfo* GetClassInfo();
 
     virtual nsIDOMNode* AsDOMNode() { return this; }
 
     virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
+    void SetXULAttr(nsIAtom* aName, const nsAString& aValue,
+                    mozilla::ErrorResult& aError)
+    {
+        aError = SetAttr(kNameSpaceID_None, aName, aValue, true);
+    }
+    void SetXULBoolAttr(nsIAtom* aName, bool aValue)
+    {
+        if (aValue) {
+            SetAttr(kNameSpaceID_None, aName, NS_LITERAL_STRING("true"), true);
+        } else {
+            UnsetAttr(kNameSpaceID_None, aName, true);
+        }
+    }
+
+    // WebIDL API
+    // The XPCOM getter is fine for our string attributes.
+    // The XPCOM setter is fine for our bool attributes.
+    void SetClassName(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::_class, aValue, rv);
+    }
+    void SetAlign(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::align, aValue, rv);
+    }
+    void SetDir(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::dir, aValue, rv);
+    }
+    void SetFlex(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::flex, aValue, rv);
+    }
+    void SetFlexGroup(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::flexgroup, aValue, rv);
+    }
+    void SetOrdinal(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::ordinal, aValue, rv);
+    }
+    void SetOrient(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::orient, aValue, rv);
+    }
+    void SetPack(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::pack, aValue, rv);
+    }
+    bool Hidden() const
+    {
+        return BoolAttrIsTrue(nsGkAtoms::hidden);
+    }
+    bool Collapsed() const
+    {
+        return BoolAttrIsTrue(nsGkAtoms::collapsed);
+    }
+    void SetObserves(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::observes, aValue, rv);
+    }
+    void SetMenu(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::menu, aValue, rv);
+    }
+    void SetContextMenu(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::contextmenu, aValue, rv);
+    }
+    void SetTooltip(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::tooltip, aValue, rv);
+    }
+    void SetWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::width, aValue, rv);
+    }
+    void SetHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::height, aValue, rv);
+    }
+    void SetMinWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::minwidth, aValue, rv);
+    }
+    void SetMinHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::minheight, aValue, rv);
+    }
+    void SetMaxWidth(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::maxwidth, aValue, rv);
+    }
+    void SetMaxHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::maxheight, aValue, rv);
+    }
+    void SetPersist(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::persist, aValue, rv);
+    }
+    void SetLeft(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::left, aValue, rv);
+    }
+    void SetTop(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::top, aValue, rv);
+    }
+    void SetDatasources(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::datasources, aValue, rv);
+    }
+    void SetRef(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::ref, aValue, rv);
+    }
+    void SetTooltipText(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::tooltiptext, aValue, rv);
+    }
+    void SetStatusText(const nsAString& aValue, mozilla::ErrorResult& rv)
+    {
+        SetXULAttr(nsGkAtoms::statustext, aValue, rv);
+    }
+    bool AllowEvents() const
+    {
+        return BoolAttrIsTrue(nsGkAtoms::allowevents);
+    }
+    already_AddRefed<nsIRDFCompositeDataSource> GetDatabase();
+    already_AddRefed<nsIXULTemplateBuilder> GetBuilder();
+    already_AddRefed<nsIRDFResource> GetResource(mozilla::ErrorResult& rv);
+    nsIControllers* GetControllers(mozilla::ErrorResult& rv);
+    already_AddRefed<nsIBoxObject> GetBoxObject(mozilla::ErrorResult& rv);
+    void Focus(mozilla::ErrorResult& rv);
+    void Blur(mozilla::ErrorResult& rv);
+    void Click(mozilla::ErrorResult& rv);
+    // The XPCOM DoCommand never fails, so it's OK for us.
+    already_AddRefed<nsINodeList>
+      GetElementsByAttribute(const nsAString& aAttribute,
+                             const nsAString& aValue);
+    already_AddRefed<nsINodeList>
+      GetElementsByAttributeNS(const nsAString& aNamespaceURI,
+                               const nsAString& aAttribute,
+                               const nsAString& aValue,
+                               mozilla::ErrorResult& rv);
+    // Style() inherited from nsStyledElement
+    already_AddRefed<nsFrameLoader> GetFrameLoader();
+    void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& rv);
+
+    // For XUL, the parent is the parent element, if any
+    nsINode* GetParentObject() const
+    {
+        Element* parent = GetParentElement();
+        if (parent) {
+            return parent;
+        }
+        return nsStyledElement::GetParentObject();
+    }
+    static bool PrefEnabled()
+    {
+        return nsGenericHTMLElement::PrefEnabled();
+    }
 protected:
 
     // This can be removed if EnsureContentsGenerated dies.
     friend class nsNSElementTearoff;
 
     // Implementation methods
     nsresult EnsureContentsGenerated(void) const;
 
@@ -506,17 +673,17 @@ protected:
     // Internal accessor. This shadows the 'Slots', and returns
     // appropriate value.
     nsIControllers *Controllers() {
       nsDOMSlots* slots = GetExistingDOMSlots();
       return slots ? slots->mControllers : nullptr; 
     }
 
     void UnregisterAccessKey(const nsAString& aOldValue);
-    bool BoolAttrIsTrue(nsIAtom* aName);
+    bool BoolAttrIsTrue(nsIAtom* aName) const;
 
     friend nsresult
     NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
     friend void
     NS_TrustedNewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
 
     static already_AddRefed<nsXULElement>
     Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
@@ -525,11 +692,14 @@ protected:
     bool IsReadWriteTextElement() const
     {
         const nsIAtom* tag = Tag();
         return
             GetNameSpaceID() == kNameSpaceID_XUL &&
             (tag == nsGkAtoms::textbox || tag == nsGkAtoms::textarea) &&
             !HasAttr(kNameSpaceID_None, nsGkAtoms::readonly);
     }
+
+    virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                               bool *aTriedToWrap) MOZ_OVERRIDE;
 };
 
 #endif // nsXULElement_h__
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -2942,16 +2942,17 @@ nsDOMClassInfo::Init()
 
 #ifdef MOZ_XUL
   DOM_CLASSINFO_MAP_BEGIN(XULTemplateBuilder, nsIXULTemplateBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(XULTreeBuilder, nsIXULTreeBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTreeBuilder)
+    DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsITreeView)
   DOM_CLASSINFO_MAP_END
 #endif
 
   DOM_CLASSINFO_MAP_BEGIN(DOMStringList, nsIDOMDOMStringList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMStringList)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -2,16 +2,17 @@
 /* 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 nsWrapperCache_h___
 #define nsWrapperCache_h___
 
 #include "nsCycleCollectionParticipant.h"
+#include "mozilla/Assertions.h"
 
 class JSObject;
 struct JSContext;
 class XPCWrappedNativeScope;
 
 namespace mozilla {
 namespace dom {
 namespace workers {
@@ -156,16 +157,17 @@ public:
    * value set in triedToWrap is meaningless. If null is returned then
    * triedToWrap indicates whether an error occurred, if it's false then the
    * object doesn't actually support creating a wrapper through its WrapObject
    * hook.
    */
   virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
                                bool *triedToWrap)
   {
+    MOZ_ASSERT(!IsDOMBinding(), "Someone forgot to override WrapObject");
     *triedToWrap = false;
     return nullptr;
   }
 
   /**
    * Returns true if the object has a non-gray wrapper.
    */
   bool IsBlack();
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -570,19 +570,19 @@ QueryInterface(JSContext* cx, unsigned a
     return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
   }
 
   JS::Value* argv = JS_ARGV(cx, vp);
   if (!argv[0].isObject()) {
     return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
   }
 
-  nsIJSIID* iid;
+  nsIJSID* iid;
   xpc_qsSelfRef iidRef;
-  if (NS_FAILED(xpc_qsUnwrapArg<nsIJSIID>(cx, argv[0], &iid, &iidRef.ptr,
+  if (NS_FAILED(xpc_qsUnwrapArg<nsIJSID>(cx, argv[0], &iid, &iidRef.ptr,
                                           &argv[0]))) {
     return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
   }
   MOZ_ASSERT(iid);
 
   if (iid->GetID()->Equals(NS_GET_IID(nsIClassInfo))) {
     nsresult rv;
     nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(native, &rv);
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1008,16 +1008,22 @@ DOMInterfaces = {
 },
 
 'XPathEvaluator': {
     'nativeType': 'nsXPathEvaluator',
     'headerFile': 'nsXPathEvaluator.h',
     'wrapperCache': False
 },
 
+'XULElement': {
+    'nativeType': 'nsXULElement',
+    'resultNotAddRefed': [ 'controllers', 'style' ],
+    'hasInstanceInterface': 'nsIDOMXULElement',
+},
+
 ####################################
 # Test Interfaces of various sorts #
 ####################################
 
 'TestInterface' : {
         # Keep this in sync with TestExampleInterface
         'headerFile': 'TestBindingHeader.h',
         'register': False,
@@ -1211,16 +1217,23 @@ addExternalIface('DOMStringList')
 addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('HTMLHeadElement', nativeType='mozilla::dom::Element')
 addExternalIface('HTMLCanvasElement', nativeType='mozilla::dom::HTMLCanvasElement')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LockedFile')
 addExternalIface('MediaStream')
+addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
+addExternalIface('MozControllers', nativeType='nsIControllers')
+addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
+addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
+                 notflattened=True)
+addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
+addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
 addExternalIface('NamedNodeMap')
 addExternalIface('NodeIterator')
 addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
 addExternalIface('nsISupports', nativeType='nsISupports')
 addExternalIface('OutputStream', nativeType='nsIOutputStream',
                  notflattened=True)
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
@@ -1239,9 +1252,8 @@ addExternalIface('TouchList', headerFile
 addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
                  notflattened=True)
 addExternalIface('UserDataHandler')
 addExternalIface('Window')
 addExternalIface('WindowProxy', nativeType='nsIDOMWindow')
 addExternalIface('XPathResult', nativeType='nsISupports')
 addExternalIface('XPathExpression')
 addExternalIface('XPathNSResolver')
-addExternalIface('XULElement')
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -81,16 +81,17 @@ LOCAL_INCLUDES += -I$(topsrcdir)/js/xpco
   -I$(topsrcdir)/js/xpconnect/wrappers \
   -I$(topsrcdir)/content/canvas/src \
   -I$(topsrcdir)/content/html/content/src \
   -I$(topsrcdir)/media/webrtc/signaling/src/peerconnection \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/content/xslt/src/base \
   -I$(topsrcdir)/content/xslt/src/xpath \
   -I$(topsrcdir)/content/xml/content/src \
+  -I$(topsrcdir)/content/xul/content/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 # If you change bindinggen_dependencies here, change it in
 # dom/bindings/test/Makefile.in too.
 bindinggen_dependencies := \
   BindingGen.py \
--- a/dom/interfaces/xul/nsIDOMXULElement.idl
+++ b/dom/interfaces/xul/nsIDOMXULElement.idl
@@ -7,20 +7,19 @@
 
 interface nsIRDFCompositeDataSource;
 interface nsIXULTemplateBuilder;
 interface nsIRDFResource;
 interface nsIControllers;
 interface nsIBoxObject;
 
 
-[scriptable, uuid(3a07dead-39e5-4dad-bc68-6ef369994126)]
+[scriptable, uuid(bece5b0b-6e59-4de5-98d0-088adfd1cadc)]
 interface nsIDOMXULElement : nsIDOMElement
 {
-  attribute DOMString                 id;
   attribute DOMString                 className;
 
   // Layout properties
   attribute DOMString align;
   attribute DOMString dir;
   attribute DOMString flex;
   attribute DOMString flexGroup;
   attribute DOMString ordinal;
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -13,17 +13,16 @@
 
 interface CanvasGradient;
 interface CanvasPattern;
 interface HitRegionOptions;
 interface HTMLCanvasElement;
 interface HTMLVideoElement;
 interface TextMetrics;
 interface Window;
-interface XULElement;
 
 enum CanvasWindingRule { "nonzero", "evenodd" };
 
 interface CanvasRenderingContext2D {
 
   // back-reference to the canvas.  Might be null if we're not
   // associated with a canvas.
   readonly attribute HTMLCanvasElement? canvas;
--- a/dom/webidl/HTMLElement.webidl
+++ b/dom/webidl/HTMLElement.webidl
@@ -10,16 +10,17 @@
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 interface DOMStringMap;
 interface HTMLMenuElement;
 
+// Hack to make sure that we initialize the touch prefs properly
 [PrefControlled]
 interface HTMLElement : Element {
   // metadata attributes
            attribute DOMString title;
            attribute DOMString lang;
   //         attribute boolean translate;
   [SetterThrows]
            attribute DOMString dir;
@@ -75,29 +76,16 @@ interface HTMLElement : Element {
   // styling
   [Constant]
   readonly attribute CSSStyleDeclaration style;
 
   // Mozilla specific stuff
   // FIXME Bug 810677 Move className from HTMLElement to Element
            attribute DOMString className;
 
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchstart;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchend;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchmove;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchenter;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchleave;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchcancel;
-
   [SetterThrows]
            attribute EventHandler oncopy;
   [SetterThrows]
            attribute EventHandler oncut;
   [SetterThrows]
            attribute EventHandler onpaste;
 };
 
@@ -105,12 +93,29 @@ interface HTMLElement : Element {
 partial interface HTMLElement {
   readonly attribute Element? offsetParent;
   readonly attribute long offsetTop;
   readonly attribute long offsetLeft;
   readonly attribute long offsetWidth;
   readonly attribute long offsetHeight;
 };
 
+[NoInterfaceObject]
+interface TouchEventHandlers {
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchstart;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchend;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchmove;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchenter;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchleave;
+  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
+           attribute EventHandler ontouchcancel;
+};
+
 HTMLElement implements GlobalEventHandlers;
 HTMLElement implements NodeEventHandlers;
+HTMLElement implements TouchEventHandlers;
 
 interface HTMLUnknownElement : HTMLElement {};
--- a/dom/webidl/SVGElement.webidl
+++ b/dom/webidl/SVGElement.webidl
@@ -29,31 +29,19 @@ interface SVGElement : Element {
   attribute DOMString xmllang;
   [SetterThrows]
   attribute DOMString xmlspace;*/
 
   [Throws]
   readonly attribute SVGSVGElement? ownerSVGElement;
   readonly attribute SVGElement? viewportElement;
 
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchstart;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchend;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchmove;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchenter;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchleave;
-  [SetterThrows,Pref="dom.w3c_touch_events.expose"]
-           attribute EventHandler ontouchcancel;
-
   [SetterThrows]
            attribute EventHandler oncopy;
   [SetterThrows]
            attribute EventHandler oncut;
   [SetterThrows]
            attribute EventHandler onpaste;
 };
 
 SVGElement implements GlobalEventHandlers;
 SVGElement implements NodeEventHandlers;
+SVGElement implements TouchEventHandlers;
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -179,16 +179,17 @@ webidl_files = \
   WebSocket.webidl \
   UndoManager.webidl \
   USSDReceivedEvent.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
   XMLHttpRequestUpload.webidl \
   XMLSerializer.webidl \
   XPathEvaluator.webidl \
+  XULElement.webidl \
   $(NULL)
 
 ifdef MOZ_WEBGL
 webidl_files += \
   WebGLRenderingContext.webidl \
   $(NULL)
 endif
 
new file mode 100644
--- /dev/null
+++ b/dom/webidl/XULElement.webidl
@@ -0,0 +1,134 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+interface MozBoxObject;
+interface MozControllers;
+interface MozFrameLoader;
+interface MozRDFCompositeDataSource;
+interface MozRDFResource;
+interface MozXULTemplateBuilder;
+
+// Hack to make sure that we initialize the touch prefs properly
+[PrefControlled]
+interface XULElement : Element {
+  [SetterThrows]
+  attribute DOMString className;
+
+  // Layout properties
+  [SetterThrows]
+  attribute DOMString align;
+  [SetterThrows]
+  attribute DOMString dir;
+  [SetterThrows]
+  attribute DOMString flex;
+  [SetterThrows]
+  attribute DOMString flexGroup;
+  [SetterThrows]
+  attribute DOMString ordinal;
+  [SetterThrows]
+  attribute DOMString orient;
+  [SetterThrows]
+  attribute DOMString pack;
+
+  // Properties for hiding elements.
+  attribute boolean hidden;
+  attribute boolean collapsed;
+
+  // Property for hooking up to broadcasters
+  [SetterThrows]
+  attribute DOMString observes;
+
+  // Properties for hooking up to popups
+  [SetterThrows]
+  attribute DOMString menu;
+  [SetterThrows]
+  attribute DOMString contextMenu;
+  [SetterThrows]
+  attribute DOMString tooltip;
+
+  // Width/height properties
+  [SetterThrows]
+  attribute DOMString width;
+  [SetterThrows]
+  attribute DOMString height;
+  [SetterThrows]
+  attribute DOMString minWidth;
+  [SetterThrows]
+  attribute DOMString minHeight;
+  [SetterThrows]
+  attribute DOMString maxWidth;
+  [SetterThrows]
+  attribute DOMString maxHeight;
+
+  // Persistence
+  [SetterThrows]
+  attribute DOMString persist;
+
+  // Position properties for
+  // * popups - these are screen coordinates
+  // * other elements - these are client coordinates relative to parent stack.
+  [SetterThrows]
+  attribute DOMString left;
+  [SetterThrows]
+  attribute DOMString top;
+
+  // XUL Template Builder
+  [SetterThrows]
+  attribute DOMString datasources;
+  [SetterThrows]
+  attribute DOMString ref;
+
+  // Tooltip and status info
+  [SetterThrows]
+  attribute DOMString tooltipText;
+  [SetterThrows]
+  attribute DOMString statusText;
+
+  attribute boolean allowEvents;
+
+  readonly attribute MozRDFCompositeDataSource? database;
+  readonly attribute MozXULTemplateBuilder?     builder;
+  [Throws]
+  readonly attribute MozRDFResource?            resource;
+  [Throws]
+  readonly attribute MozControllers             controllers;
+  [Throws]
+  readonly attribute MozBoxObject?              boxObject;
+
+  [Throws]
+  void                      focus();
+  [Throws]
+  void                      blur();
+  [Throws]
+  void                      click();
+  void                      doCommand();
+
+  // XXXbz this isn't really a nodelist!  See bug 818548
+  NodeList            getElementsByAttribute(DOMString name,
+                                             DOMString value);
+  // XXXbz this isn't really a nodelist!  See bug 818548
+  [Throws]
+  NodeList            getElementsByAttributeNS(DOMString namespaceURI,
+                                               DOMString name,
+                                               DOMString value);
+  [Constant]
+  readonly attribute CSSStyleDeclaration style;
+};
+
+// And the things from nsIFrameLoaderOwner
+[NoInterfaceObject]
+interface MozFrameLoaderOwner {
+  [ChromeOnly]
+  readonly attribute MozFrameLoader? frameLoader;
+
+  [ChromeOnly, Throws]
+  void swapFrameLoaders(XULElement aOtherOwner);
+};
+
+XULElement implements GlobalEventHandlers;
+XULElement implements NodeEventHandlers;
+XULElement implements TouchEventHandlers;
+XULElement implements MozFrameLoaderOwner;
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -481,29 +481,19 @@ nsJSIID::HasInstance(nsIXPConnectWrapped
             if (!MorphSlimWrapper(cx, obj))
                 return NS_ERROR_FAILURE;
         } else {
             JSObject* unsafeObj =
                 XPCWrapper::Unwrap(cx, obj, /* stopAtOuter = */ false);
             JSObject* cur = unsafeObj ? unsafeObj : obj;
             nsISupports *identity;
             if (mozilla::dom::UnwrapDOMObjectToISupports(cur, identity)) {
-                nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(identity);
-                if (!ci) {
-                    // No classinfo means we're not implementing interfaces and all
-                    return NS_OK;
-                }
-
-                XPCCallContext ccx(JS_CALLER, cx);
-
-                AutoMarkingNativeSetPtr set(ccx);
-                set = XPCNativeSet::GetNewOrUsed(ccx, ci);
-                if (!set)
-                    return NS_ERROR_FAILURE;
-                *bp = set->HasInterfaceWithAncestor(iid);
+                nsCOMPtr<nsISupports> supp;
+                identity->QueryInterface(*iid, getter_AddRefs(supp));
+                *bp = supp;
                 return NS_OK;
             }
         }
 
         XPCWrappedNative* other_wrapper =
            XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
 
         if (!other_wrapper)
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -68,17 +68,16 @@ members = [
     'nsIDOMCharacterData.length',
     'nsIDOMNamedNodeMap.item',
     'nsIDOMNamedNodeMap.length',
     'nsIDOMText.splitText',
     'nsIDOMDOMStringList.*',
     'nsIDOMXULDocument.getBoxObjectFor',
 
     # dom/interfaces/css
-    'nsIDOMElementCSSInlineStyle.*',
     'nsIDOMRect.*',
 
     'nsIDOMEvent.type',
     'nsIDOMEvent.target',
     'nsIDOMEvent.currentTarget',
     'nsIDOMEvent.eventPhase',
     'nsIDOMEvent.bubbles',
     'nsIDOMEvent.cancelable',
@@ -236,19 +235,16 @@ members = [
     'nsIDOMXPathResult.snapshotLength',
     'nsIDOMXPathResult.resultType',
     'nsIDOMXPathResult.numberValue',
     'nsIDOMXPathResult.stringValue',
     'nsIDOMXPathResult.booleanValue',
     'nsIDOMXPathResult.singleNodeValue',
     'nsIDOMNSXPathExpression.evaluateWithContext',
 
-    # dom/interfaces/xul
-    'nsIDOMXULElement.*',
-
     # layout/xul/base/public
     'nsIBoxObject.x',
     'nsIBoxObject.y',
     'nsIBoxObject.screenX',
     'nsIBoxObject.screenY',
     'nsIBoxObject.width',
     'nsIBoxObject.height',
 
@@ -345,25 +341,16 @@ nsIDOMStorage_Clear_customMethodCallCode
     if (NS_SUCCEEDED(rv))
         JS_ClearNonGlobalObject(cx, obj);
 """
 
 customMethodCalls = {
     'nsIDOMStorage_Clear': {
         'code': nsIDOMStorage_Clear_customMethodCallCode
         },
-    'nsIDOMElementCSSInlineStyle_GetStyle': {
-        'thisType': 'nsStyledElement',
-        'code': '    /* XXXbz MathML elements inherit from nsStyledElement but\n'
-                '       don\'t actually implement GetStyle. */\n'
-                '    if (self->GetNameSpaceID() == kNameSpaceID_MathML)\n'
-                '      return xpc_qsThrow(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n'
-                '    nsIDOMCSSStyleDeclaration* result = self->Style();',
-        'canFail': False
-        },
     'nsIDOMWindow_GetOnmouseenter' : {
         'thisType' : 'nsIDOMWindow',
         'unwrapThisFailureFatal' : False
         },
     'nsIDOMWindow_SetOnmouseenter' : {
         'thisType' : 'nsIDOMWindow',
         'unwrapThisFailureFatal' : False
         },
--- a/xpfe/appshell/src/nsXULWindow.cpp
+++ b/xpfe/appshell/src/nsXULWindow.cpp
@@ -1489,18 +1489,18 @@ NS_IMETHODIMP nsXULWindow::SavePersisten
   nsAutoString                sizeString;
   nsAutoString                windowElementId;
   nsCOMPtr<nsIDOMXULDocument> ownerXULDoc;
 
   { // fetch docShellElement's ID and XUL owner document
     nsCOMPtr<nsIDOMDocument> ownerDoc;
     docShellElement->GetOwnerDocument(getter_AddRefs(ownerDoc));
     ownerXULDoc = do_QueryInterface(ownerDoc);
-    nsCOMPtr<nsIDOMXULElement> XULElement(do_QueryInterface(docShellElement));
-    if (XULElement)
+    nsCOMPtr<mozilla::dom::Element> XULElement(do_QueryInterface(docShellElement));
+    if (XULElement && XULElement->IsXUL())
       XULElement->GetId(windowElementId);
   }
 
   // (only for size elements which are persisted)
   if ((mPersistentAttributesDirty & PAD_POSITION) &&
       sizeMode == nsSizeMode_Normal) {
     if (persistString.Find("screenX") >= 0) {
       PR_snprintf(sizeBuf, sizeof(sizeBuf), "%d", NSToIntRound(x / scale));