Fix for bug 824007 (Convert HTMLBodyElement, HTMLDataListElement, HTMLFontElement, HTMLFrameSetElement and HTMLLabelElement to new DOM bindings). r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Fri, 21 Dec 2012 15:07:28 +0100
changeset 116908 824e649bab0c7aa47bd6486e27825a5a97178673
parent 116907 840b27e186408d8d2d0e4cb7b123fa41e1bff4a6
child 116909 80c7c3eee490dacd5ade7ce5942730f917ff3ab4
push id24076
push userryanvm@gmail.com
push dateSun, 23 Dec 2012 20:50:19 +0000
treeherdermozilla-central@4f74d77d6d8b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs824007
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Fix for bug 824007 (Convert HTMLBodyElement, HTMLDataListElement, HTMLFontElement, HTMLFrameSetElement and HTMLLabelElement to new DOM bindings). r=bz.
content/html/content/src/HTMLBodyElement.cpp
content/html/content/src/HTMLBodyElement.h
content/html/content/src/HTMLDataListElement.cpp
content/html/content/src/HTMLDataListElement.h
content/html/content/src/HTMLDivElement.cpp
content/html/content/src/HTMLDivElement.h
content/html/content/src/HTMLElement.cpp
content/html/content/src/HTMLFontElement.cpp
content/html/content/src/HTMLFontElement.h
content/html/content/src/HTMLFrameSetElement.cpp
content/html/content/src/HTMLFrameSetElement.h
content/html/content/src/HTMLLabelElement.cpp
content/html/content/src/HTMLLabelElement.h
content/html/content/src/HTMLUnknownElement.cpp
content/html/content/src/HTMLUnknownElement.h
content/html/content/src/nsGenericHTMLElement.h
docshell/test/test_bug387979.html
dom/bindings/Bindings.conf
dom/encoding/TextDecoder.h
dom/encoding/TextEncoder.h
dom/encoding/test/test_utf16_files.html
dom/webidl/HTMLBodyElement.webidl
dom/webidl/HTMLDataListElement.webidl
dom/webidl/HTMLFontElement.webidl
dom/webidl/HTMLFrameSetElement.webidl
dom/webidl/HTMLLabelElement.webidl
dom/webidl/WebIDL.mk
--- a/content/html/content/src/HTMLBodyElement.cpp
+++ b/content/html/content/src/HTMLBodyElement.cpp
@@ -1,30 +1,31 @@
 /* -*- 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 "mozilla/Util.h"
 
 #include "HTMLBodyElement.h"
+#include "mozilla/dom/HTMLBodyElementBinding.h"
 #include "nsAttrValueInlines.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsMappedAttributes.h"
 #include "nsRuleData.h"
 #include "nsIDocShell.h"
 #include "nsIEditorDocShell.h"
 #include "nsRuleWalker.h"
-#include "mozilla/dom/EventHandlerBinding.h"
+#include "nsGlobalWindow.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Body)
 DOMCI_NODE_DATA(HTMLBodyElement, mozilla::dom::HTMLBodyElement)
 
 namespace mozilla {
 namespace dom {
 
 //----------------------------------------------------------------------
@@ -185,40 +186,138 @@ BodyRule::List(FILE* out, int32_t aInden
 #endif
 
 //----------------------------------------------------------------------
 
 HTMLBodyElement::~HTMLBodyElement()
 {
   if (mContentStyleRule) {
     mContentStyleRule->mPart = nullptr;
-    NS_RELEASE(mContentStyleRule);
   }
 }
 
+JSObject*
+HTMLBodyElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return HTMLBodyElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
 
 NS_IMPL_ADDREF_INHERITED(HTMLBodyElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLBodyElement, Element)
 
 // QueryInterface implementation for HTMLBodyElement
 NS_INTERFACE_TABLE_HEAD(HTMLBodyElement)
   NS_HTML_CONTENT_INTERFACE_TABLE1(HTMLBodyElement, nsIDOMHTMLBodyElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLBodyElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLBodyElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLBodyElement)
 
+NS_IMETHODIMP 
+HTMLBodyElement::SetBackground(const nsAString& aBackground)
+{
+  ErrorResult rv;
+  SetBackground(aBackground, rv);
+  return rv.ErrorCode();
+}
 
-NS_IMPL_STRING_ATTR(HTMLBodyElement, Background, background)
-NS_IMPL_STRING_ATTR(HTMLBodyElement, VLink, vlink)
-NS_IMPL_STRING_ATTR(HTMLBodyElement, ALink, alink)
-NS_IMPL_STRING_ATTR(HTMLBodyElement, Link, link)
-NS_IMPL_STRING_ATTR(HTMLBodyElement, Text, text)
-NS_IMPL_STRING_ATTR(HTMLBodyElement, BgColor, bgcolor)
+NS_IMETHODIMP
+HTMLBodyElement::GetBackground(nsAString& aBackground)
+{
+  nsString background;
+  GetBackground(background);
+  aBackground = background;
+  return NS_OK;
+}
+
+NS_IMETHODIMP 
+HTMLBodyElement::SetVLink(const nsAString& aVLink)
+{
+  ErrorResult rv;
+  SetVLink(aVLink, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLBodyElement::GetVLink(nsAString& aVLink)
+{
+  nsString vLink;
+  GetVLink(vLink);
+  aVLink = vLink;
+  return NS_OK;
+}
+
+NS_IMETHODIMP 
+HTMLBodyElement::SetALink(const nsAString& aALink)
+{
+  ErrorResult rv;
+  SetALink(aALink, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLBodyElement::GetALink(nsAString& aALink)
+{
+  nsString aLink;
+  GetALink(aLink);
+  aALink = aLink;
+  return NS_OK;
+}
+
+NS_IMETHODIMP 
+HTMLBodyElement::SetLink(const nsAString& aLink)
+{
+  ErrorResult rv;
+  SetLink(aLink, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLBodyElement::GetLink(nsAString& aLink)
+{
+  nsString link;
+  GetLink(link);
+  aLink = link;
+  return NS_OK;
+}
+
+NS_IMETHODIMP 
+HTMLBodyElement::SetText(const nsAString& aText)
+{
+  ErrorResult rv;
+  SetText(aText, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLBodyElement::GetText(nsAString& aText)
+{
+  nsString text;
+  GetText(text);
+  aText = text;
+  return NS_OK;
+}
+
+NS_IMETHODIMP 
+HTMLBodyElement::SetBgColor(const nsAString& aBgColor)
+{
+  ErrorResult rv;
+  SetBgColor(aBgColor, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLBodyElement::GetBgColor(nsAString& aBgColor)
+{
+  nsString bgColor;
+  GetBgColor(bgColor);
+  aBgColor = bgColor;
+  return NS_OK;
+}
 
 bool
 HTMLBodyElement::ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
@@ -384,71 +483,84 @@ HTMLBodyElement::GetAssociatedEditor()
   editorDocShell->GetEditor(&editor);
   return editor;
 }
 
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the superclass */
 // nsGenericHTMLElement::GetOnError returns
 // already_AddRefed<EventHandlerNonNull> while other getters return
 // EventHandlerNonNull*, so allow passing in the type to use here.
-#define FORWARDED_EVENT_HELPER(name_, getter_type_)                            \
+#define FORWARDED_EVENT_HELPER(name_, forwardto_, type_, getter_type_)         \
   NS_IMETHODIMP                                                                \
   HTMLBodyElement::GetOn##name_(JSContext *cx, jsval *vp)                      \
   {                                                                            \
-    getter_type_ h = nsGenericHTMLElement::GetOn##name_();                     \
+    getter_type_ h = forwardto_::GetOn##name_();                               \
     vp->setObjectOrNull(h ? h->Callable() : nullptr);                          \
     return NS_OK;                                                              \
   }                                                                            \
   NS_IMETHODIMP                                                                \
   HTMLBodyElement::SetOn##name_(JSContext *cx, const jsval &v)                 \
   {                                                                            \
     JSObject *obj = GetWrapper();                                              \
     if (!obj) {                                                                \
       /* Just silently do nothing */                                           \
       return NS_OK;                                                            \
     }                                                                          \
-    nsRefPtr<EventHandlerNonNull> handler;                                     \
+    nsRefPtr<type_> handler;                                                   \
     JSObject *callable;                                                        \
     if (v.isObject() &&                                                        \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                   \
       bool ok;                                                                 \
-      handler = new EventHandlerNonNull(cx, obj, callable, &ok);               \
+      handler = new type_(cx, obj, callable, &ok);                             \
       if (!ok) {                                                               \
         return NS_ERROR_OUT_OF_MEMORY;                                         \
       }                                                                        \
     }                                                                          \
     ErrorResult rv;                                                            \
-    nsGenericHTMLElement::SetOn##name_(handler, rv);                           \
+    forwardto_::SetOn##name_(handler, rv);                                     \
     return rv.ErrorCode();                                                     \
   }
 #define FORWARDED_EVENT(name_, id_, type_, struct_)                            \
-  FORWARDED_EVENT_HELPER(name_, EventHandlerNonNull*)
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement, EventHandlerNonNull,     \
+                         EventHandlerNonNull*)
 #define ERROR_EVENT(name_, id_, type_, struct_)                                \
-  FORWARDED_EVENT_HELPER(name_, nsCOMPtr<EventHandlerNonNull>)
-#define WINDOW_EVENT(name_, id_, type_, struct_)                               \
-  NS_IMETHODIMP                                                                \
-  HTMLBodyElement::GetOn##name_(JSContext *cx, jsval *vp)                      \
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement,                          \
+                         EventHandlerNonNull, nsCOMPtr<EventHandlerNonNull>)
+#define WINDOW_EVENT_HELPER(name_, type_)                                      \
+  type_*                                                                       \
+  HTMLBodyElement::GetOn##name_()                                              \
   {                                                                            \
     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
     if (win && win->IsInnerWindow()) {                                         \
-      return win->GetOn##name_(cx, vp);                                        \
+      nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                 \
+      nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);      \
+      return globalWin->GetOn##name_();                                        \
     }                                                                          \
-    *vp = JSVAL_NULL;                                                          \
-    return NS_OK;                                                              \
+    return nullptr;                                                            \
   }                                                                            \
-  NS_IMETHODIMP                                                                \
-  HTMLBodyElement::SetOn##name_(JSContext *cx, const jsval &v)                 \
+  void                                                                         \
+  HTMLBodyElement::SetOn##name_(type_* handler, ErrorResult& error)            \
   {                                                                            \
     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
-    if (win && win->IsInnerWindow()) {                                         \
-      return win->SetOn##name_(cx, v);                                         \
+    if (!win || !win->IsInnerWindow()) {                                       \
+      return;                                                                  \
     }                                                                          \
-    return NS_OK;                                                              \
-  }
+                                                                               \
+    nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                   \
+    nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);        \
+    return globalWin->SetOn##name_(handler, error);                            \
+  }                                                                            \
+  FORWARDED_EVENT_HELPER(name_, HTMLBodyElement, type_, type_*)
+#define WINDOW_EVENT(name_, id_, type_, struct_)                               \
+  WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
+#define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
+  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h"
+#undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
+#undef WINDOW_EVENT_HELPER
 #undef ERROR_EVENT
 #undef FORWARDED_EVENT
 #undef FORWARDED_EVENT_HELPER
 #undef EVENT
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLBodyElement.h
+++ b/content/html/content/src/HTMLBodyElement.h
@@ -35,19 +35,19 @@ public:
 class HTMLBodyElement : public nsGenericHTMLElement,
                         public nsIDOMHTMLBodyElement
 {
 public:
   using Element::GetText;
   using Element::SetText;
 
   HTMLBodyElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsGenericHTMLElement(aNodeInfo),
-      mContentStyleRule(nullptr)
+    : nsGenericHTMLElement(aNodeInfo)
   {
+    SetIsDOMBinding();
   }
   virtual ~HTMLBodyElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
@@ -62,20 +62,79 @@ public:
   NS_DECL_NSIDOMHTMLBODYELEMENT
 
   // Event listener stuff; we need to declare only the ones we need to
   // forward to window that don't come from nsIDOMHTMLBodyElement.
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
 #define FORWARDED_EVENT(name_, id_, type_, struct_)                     \
   NS_IMETHOD GetOn##name_(JSContext *cx, jsval *vp);                    \
   NS_IMETHOD SetOn##name_(JSContext *cx, const jsval &v);
+#define WINDOW_EVENT_HELPER(name_, type_)                               \
+  type_* GetOn##name_();                                                \
+  void SetOn##name_(type_* handler, ErrorResult& error);
+#define WINDOW_EVENT(name_, id_, type_, struct_)                        \
+  WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
+#define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                  \
+  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h"
+#undef BEFOREUNLOAD_EVENT
+#undef WINDOW_EVENT
+#undef WINDOW_EVENT_HELPER
 #undef FORWARDED_EVENT
 #undef EVENT
 
+  void GetText(nsString& aText)
+  {
+    GetHTMLAttr(nsGkAtoms::text, aText);
+  }
+  void SetText(const nsAString& aText, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::text, aText, aError);
+  }
+  void GetLink(nsString& aLink)
+  {
+    GetHTMLAttr(nsGkAtoms::link, aLink);
+  }
+  void SetLink(const nsAString& aLink, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::link, aLink, aError);
+  }
+  void GetVLink(nsString& aVLink)
+  {
+    GetHTMLAttr(nsGkAtoms::vlink, aVLink);
+  }
+  void SetVLink(const nsAString& aVLink, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::vlink, aVLink, aError);
+  }
+  void GetALink(nsString& aALink)
+  {
+    GetHTMLAttr(nsGkAtoms::alink, aALink);
+  }
+  void SetALink(const nsAString& aALink, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::alink, aALink, aError);
+  }
+  void GetBgColor(nsString& aBgColor)
+  {
+    GetHTMLAttr(nsGkAtoms::bgcolor, aBgColor);
+  }
+  void SetBgColor(const nsAString& aBgColor, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::bgcolor, aBgColor, aError);
+  }
+  void GetBackground(nsString& aBackground)
+  {
+    GetHTMLAttr(nsGkAtoms::background, aBackground);
+  }
+  void SetBackground(const nsAString& aBackground, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::background, aBackground, aError);
+  }
+
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
                               nsAttrValue& aResult);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
@@ -83,15 +142,18 @@ public:
   virtual already_AddRefed<nsIEditor> GetAssociatedEditor();
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsXPCClassInfo* GetClassInfo();
   virtual nsIDOMNode* AsDOMNode() { return this; }
 private:
   nsresult GetColorHelper(nsIAtom* aAtom, nsAString& aColor);
 
 protected:
-  BodyRule* mContentStyleRule;
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap) MOZ_OVERRIDE;
+
+  nsRefPtr<BodyRule> mContentStyleRule;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* HTMLBodyElement_h___ */
--- a/content/html/content/src/HTMLDataListElement.cpp
+++ b/content/html/content/src/HTMLDataListElement.cpp
@@ -1,25 +1,32 @@
 /* -*- 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 "HTMLDataListElement.h"
+#include "mozilla/dom/HTMLDataListElementBinding.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(DataList)
 DOMCI_NODE_DATA(HTMLDataListElement, mozilla::dom::HTMLDataListElement)
 
 namespace mozilla {
 namespace dom {
 
 HTMLDataListElement::~HTMLDataListElement()
 {
 }
 
+JSObject*
+HTMLDataListElement::WrapNode(JSContext *aCx, JSObject *aScope,
+                              bool *aTriedToWrap)
+{
+  return HTMLDataListElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLDataListElement,
                                                 nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mOptions)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLDataListElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLDataListElement,
@@ -46,19 +53,15 @@ HTMLDataListElement::MatchOptions(nsICon
 {
   return aContent->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
          !aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
 }
 
 NS_IMETHODIMP
 HTMLDataListElement::GetOptions(nsIDOMHTMLCollection** aOptions)
 {
-  if (!mOptions) {
-    mOptions = new nsContentList(this, MatchOptions, nullptr, nullptr, true);
-  }
-
-  NS_ADDREF(*aOptions = mOptions);
+  NS_ADDREF(*aOptions = Options());
 
   return NS_OK;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLDataListElement.h
+++ b/content/html/content/src/HTMLDataListElement.h
@@ -14,16 +14,17 @@ namespace dom {
 
 class HTMLDataListElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLDataListElement
 {
 public:
   HTMLDataListElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
+    SetIsDOMBinding();
   }
   virtual ~HTMLDataListElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
@@ -32,28 +33,40 @@ public:
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
 
   // nsIDOMHTMLDataListElement
   NS_DECL_NSIDOMHTMLDATALISTELEMENT
 
+  nsContentList* Options()
+  {
+    if (!mOptions) {
+      mOptions = new nsContentList(this, MatchOptions, nullptr, nullptr, true);
+    }
+
+    return mOptions;
+  }
+
+
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // This function is used to generate the nsContentList (option elements).
   static bool MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
                              nsIAtom* aAtom, void* aData);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLDataListElement,
                                            nsGenericHTMLElement)
 
   virtual nsXPCClassInfo* GetClassInfo();
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap) MOZ_OVERRIDE;
 
   // <option>'s list inside the datalist element.
   nsRefPtr<nsContentList> mOptions;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/HTMLFontElement.cpp
+++ b/content/html/content/src/HTMLFontElement.cpp
@@ -1,48 +1,100 @@
 /* -*- 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 "mozilla/Util.h"
 
 #include "HTMLFontElement.h"
+#include "mozilla/dom/HTMLFontElementBinding.h"
 #include "nsAttrValueInlines.h"
 #include "nsMappedAttributes.h"
 #include "nsRuleData.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Font)
 DOMCI_NODE_DATA(HTMLFontElement, mozilla::dom::HTMLFontElement)
 
 namespace mozilla {
 namespace dom {
 
 HTMLFontElement::~HTMLFontElement()
 {
 }
 
+JSObject*
+HTMLFontElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return HTMLFontElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
 NS_IMPL_ADDREF_INHERITED(HTMLFontElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLFontElement, Element)
 
 // QueryInterface implementation for HTMLFontElement
 NS_INTERFACE_TABLE_HEAD(HTMLFontElement)
   NS_HTML_CONTENT_INTERFACE_TABLE1(HTMLFontElement, nsIDOMHTMLFontElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLFontElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLFontElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLFontElement)
 
+NS_IMETHODIMP
+HTMLFontElement::GetColor(nsAString& aColor)
+{
+  nsString color;
+  GetColor(color);
+  aColor = color;
+  return NS_OK;
+}
 
-NS_IMPL_STRING_ATTR(HTMLFontElement, Color, color)
-NS_IMPL_STRING_ATTR(HTMLFontElement, Face, face)
-NS_IMPL_STRING_ATTR(HTMLFontElement, Size, size)
+NS_IMETHODIMP 
+HTMLFontElement::SetColor(const nsAString& aColor)
+{
+  ErrorResult rv;
+  SetColor(aColor, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLFontElement::GetFace(nsAString& aFace)
+{
+  nsString face;
+  GetFace(face);
+  aFace = face;
+  return NS_OK;
+}
 
+NS_IMETHODIMP 
+HTMLFontElement::SetFace(const nsAString& aFace)
+{
+  ErrorResult rv;
+  SetFace(aFace, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLFontElement::GetSize(nsAString& aSize)
+{
+  nsString size;
+  GetSize(size);
+  aSize = size;
+  return NS_OK;
+}
+
+NS_IMETHODIMP 
+HTMLFontElement::SetSize(const nsAString& aSize)
+{
+  ErrorResult rv;
+  SetSize(aSize, rv);
+  return rv.ErrorCode();
+}
 
 bool
 HTMLFontElement::ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
--- a/content/html/content/src/HTMLFontElement.h
+++ b/content/html/content/src/HTMLFontElement.h
@@ -13,16 +13,17 @@ namespace dom {
 
 class HTMLFontElement : public nsGenericHTMLElement,
                         public nsIDOMHTMLFontElement
 {
 public:
   HTMLFontElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
   {
+    SetIsDOMBinding();
   }
   virtual ~HTMLFontElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
@@ -31,23 +32,52 @@ public:
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
 
   // nsIDOMHTMLFontElement
   NS_DECL_NSIDOMHTMLFONTELEMENT
 
+  void GetColor(nsString& aColor)
+  {
+    GetHTMLAttr(nsGkAtoms::color, aColor);
+  }
+  void SetColor(const nsAString& aColor, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::color, aColor, aError);
+  }
+  void GetFace(nsString& aFace)
+  {
+    GetHTMLAttr(nsGkAtoms::face, aFace);
+  }
+  void SetFace(const nsAString& aFace, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::face, aFace, aError);
+  }
+  void GetSize(nsString& aSize)
+  {
+    GetHTMLAttr(nsGkAtoms::size, aSize);
+  }
+  void SetSize(const nsAString& aSize, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::size, aSize, aError);
+  }
+
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsXPCClassInfo* GetClassInfo();
   virtual nsIDOMNode* AsDOMNode() { return this; }
+
+protected:
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* HTMLFontElement_h___ */
--- a/content/html/content/src/HTMLFrameSetElement.cpp
+++ b/content/html/content/src/HTMLFrameSetElement.cpp
@@ -1,44 +1,82 @@
 /* -*- 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 "HTMLFrameSetElement.h"
+#include "mozilla/dom/HTMLFrameSetElementBinding.h"
 #include "mozilla/dom/EventHandlerBinding.h"
+#include "nsGlobalWindow.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
 DOMCI_NODE_DATA(HTMLFrameSetElement, mozilla::dom::HTMLFrameSetElement)
 
 namespace mozilla {
 namespace dom {
 
 HTMLFrameSetElement::~HTMLFrameSetElement()
 {
 }
 
+JSObject*
+HTMLFrameSetElement::WrapNode(JSContext *aCx, JSObject *aScope,
+                              bool *aTriedToWrap)
+{
+  return HTMLFrameSetElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
 
 NS_IMPL_ADDREF_INHERITED(HTMLFrameSetElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLFrameSetElement, Element)
 
 // QueryInterface implementation for HTMLFrameSetElement
 NS_INTERFACE_TABLE_HEAD(HTMLFrameSetElement)
   NS_HTML_CONTENT_INTERFACE_TABLE1(HTMLFrameSetElement,
                                    nsIDOMHTMLFrameSetElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLFrameSetElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLFrameSetElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLFrameSetElement)
 
+NS_IMETHODIMP 
+HTMLFrameSetElement::SetCols(const nsAString& aCols)
+{
+  ErrorResult rv;
+  SetCols(aCols, rv);
+  return rv.ErrorCode();
+}
 
-NS_IMPL_STRING_ATTR(HTMLFrameSetElement, Cols, cols)
-NS_IMPL_STRING_ATTR(HTMLFrameSetElement, Rows, rows)
+NS_IMETHODIMP
+HTMLFrameSetElement::GetCols(nsAString& aCols)
+{
+  nsString cols;
+  GetCols(cols);
+  aCols = cols;
+  return NS_OK;
+}
+
+NS_IMETHODIMP 
+HTMLFrameSetElement::SetRows(const nsAString& aRows)
+{
+  ErrorResult rv;
+  SetRows(aRows, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLFrameSetElement::GetRows(nsAString& aRows)
+{
+  nsString rows;
+  GetRows(rows);
+  aRows = rows;
+  return NS_OK;
+}
 
 nsresult
 HTMLFrameSetElement::SetAttr(int32_t aNameSpaceID,
                              nsIAtom* aAttribute,
                              nsIAtom* aPrefix,
                              const nsAString& aValue,
                              bool aNotify)
 {
@@ -310,72 +348,84 @@ HTMLFrameSetElement::ParseRowCol(const n
   
   return NS_OK;
 }
 
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
 // nsGenericHTMLElement::GetOnError returns
 // already_AddRefed<EventHandlerNonNull> while other getters return
 // EventHandlerNonNull*, so allow passing in the type to use here.
-#define FORWARDED_EVENT_HELPER(name_, getter_type_)                            \
+#define FORWARDED_EVENT_HELPER(name_, forwardto_, type_, getter_type_)         \
   NS_IMETHODIMP                                                                \
   HTMLFrameSetElement::GetOn##name_(JSContext *cx, jsval *vp)                  \
   {                                                                            \
-    getter_type_ h = nsGenericHTMLElement::GetOn##name_();                     \
+    getter_type_ h = forwardto_::GetOn##name_();                               \
     vp->setObjectOrNull(h ? h->Callable() : nullptr);                          \
     return NS_OK;                                                              \
   }                                                                            \
   NS_IMETHODIMP                                                                \
   HTMLFrameSetElement::SetOn##name_(JSContext *cx, const jsval &v)             \
   {                                                                            \
     JSObject *obj = GetWrapper();                                              \
     if (!obj) {                                                                \
       /* Just silently do nothing */                                           \
       return NS_OK;                                                            \
     }                                                                          \
-    nsRefPtr<EventHandlerNonNull> handler;                                     \
+    nsRefPtr<type_> handler;                                                   \
     JSObject *callable;                                                        \
     if (v.isObject() &&                                                        \
         JS_ObjectIsCallable(cx, callable = &v.toObject())) {                   \
       bool ok;                                                                 \
-      handler = new EventHandlerNonNull(cx, obj, callable, &ok);               \
+      handler = new type_(cx, obj, callable, &ok);                             \
       if (!ok) {                                                               \
         return NS_ERROR_OUT_OF_MEMORY;                                         \
       }                                                                        \
     }                                                                          \
     ErrorResult rv;                                                            \
-    nsGenericHTMLElement::SetOn##name_(handler, rv);                           \
+    forwardto_::SetOn##name_(handler, rv);                                     \
     return rv.ErrorCode();                                                     \
   }
 #define FORWARDED_EVENT(name_, id_, type_, struct_)                            \
-  FORWARDED_EVENT_HELPER(name_, EventHandlerNonNull*)
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement, EventHandlerNonNull,     \
+                         EventHandlerNonNull*)
 #define ERROR_EVENT(name_, id_, type_, struct_)                                \
-  FORWARDED_EVENT_HELPER(name_, nsCOMPtr<EventHandlerNonNull>)
-#define WINDOW_EVENT(name_, id_, type_, struct_)                               \
-  NS_IMETHODIMP                                                                \
-  HTMLFrameSetElement::GetOn##name_(JSContext *cx, jsval *vp)                  \
-  {                                                                            \
-    /* XXXbz note to self: add tests for this! */                              \
-    nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
-    if (win && win->IsInnerWindow()) {                                         \
-      return win->GetOn##name_(cx, vp);                                        \
-    }                                                                          \
-    *vp = JSVAL_NULL;                                                          \
-    return NS_OK;                                                              \
-  }                                                                            \
-  NS_IMETHODIMP                                                                \
-  HTMLFrameSetElement::SetOn##name_(JSContext *cx, const jsval &v)             \
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement,                          \
+                         EventHandlerNonNull, nsCOMPtr<EventHandlerNonNull>)
+#define WINDOW_EVENT_HELPER(name_, type_)                                      \
+  type_*                                                                       \
+  HTMLFrameSetElement::GetOn##name_()                                          \
   {                                                                            \
     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
     if (win && win->IsInnerWindow()) {                                         \
-      return win->SetOn##name_(cx, v);                                         \
+      nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                 \
+      nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);      \
+      return globalWin->GetOn##name_();                                        \
+    }                                                                          \
+    return nullptr;                                                            \
+  }                                                                            \
+  void                                                                         \
+  HTMLFrameSetElement::SetOn##name_(type_* handler, ErrorResult& error)        \
+  {                                                                            \
+    nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
+    if (!win || !win->IsInnerWindow()) {                                       \
+      return;                                                                  \
     }                                                                          \
-    return NS_OK;                                                              \
-  }
+                                                                               \
+    nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                   \
+    nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);        \
+    return globalWin->SetOn##name_(handler, error);                            \
+  }                                                                            \
+  FORWARDED_EVENT_HELPER(name_, HTMLFrameSetElement, type_, type_*)
+#define WINDOW_EVENT(name_, id_, type_, struct_)                               \
+  WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
+#define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
+  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h"
+#undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
+#undef WINDOW_EVENT_HELPER
 #undef ERROR_EVENT
 #undef FORWARDED_EVENT
 #undef FORWARDED_EVENT_HELPER
 #undef EVENT
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLFrameSetElement.h
+++ b/content/html/content/src/HTMLFrameSetElement.h
@@ -34,26 +34,29 @@ struct nsFramesetSpec {
  */
 #define NS_MAX_FRAMESET_SPEC_COUNT 16000
 
 //----------------------------------------------------------------------
 
 namespace mozilla {
 namespace dom {
 
+class BeforeUnloadEventHandlerNonNull;
+
 class HTMLFrameSetElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLFrameSetElement
 {
 public:
   HTMLFrameSetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo),
       mNumRows(0),
       mNumCols(0),
       mCurrentRowColHint(NS_STYLE_HINT_REFLOW)
   {
+    SetIsDOMBinding();
   }
   virtual ~HTMLFrameSetElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLFrameSetElement, frameset)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -64,23 +67,50 @@ public:
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
 
   // nsIDOMHTMLFrameSetElement
   NS_DECL_NSIDOMHTMLFRAMESETELEMENT
 
+  void GetCols(nsString& aCols)
+  {
+    GetHTMLAttr(nsGkAtoms::cols, aCols);
+  }
+  void SetCols(const nsAString& aCols, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::cols, aCols, aError);
+  }
+  void GetRows(nsString& aRows)
+  {
+    GetHTMLAttr(nsGkAtoms::rows, aRows);
+  }
+  void SetRows(const nsAString& aRows, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::rows, aRows, aError);
+  }
+
   // Event listener stuff; we need to declare only the ones we need to
   // forward to window that don't come from nsIDOMHTMLFrameSetElement.
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the superclass */
 #define FORWARDED_EVENT(name_, id_, type_, struct_)                     \
   NS_IMETHOD GetOn##name_(JSContext *cx, jsval *vp);                    \
   NS_IMETHOD SetOn##name_(JSContext *cx, const jsval &v);
+#define WINDOW_EVENT_HELPER(name_, type_)                               \
+  type_* GetOn##name_();                                                \
+  void SetOn##name_(type_* handler, ErrorResult& error);
+#define WINDOW_EVENT(name_, id_, type_, struct_)                        \
+  WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
+#define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                  \
+  WINDOW_EVENT_HELPER(name_, BeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h"
+#undef BEFOREUNLOAD_EVENT
+#undef WINDOW_EVENT
+#undef WINDOW_EVENT_HELPER
 #undef FORWARDED_EVENT
 #undef EVENT
 
   // These override the SetAttr methods in nsGenericHTMLElement (need
   // both here to silence compiler warnings).
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
@@ -114,16 +144,20 @@ public:
                                 nsAttrValue& aResult);
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               int32_t aModType) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsXPCClassInfo* GetClassInfo();
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
+protected:
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap) MOZ_OVERRIDE;
+
 private:
   nsresult ParseRowCol(const nsAString& aValue,
                        int32_t&         aNumSpecs,
                        nsFramesetSpec** aSpecs);
 
   /**
    * The number of size specs in our "rows" attr
    */
--- a/content/html/content/src/HTMLLabelElement.cpp
+++ b/content/html/content/src/HTMLLabelElement.cpp
@@ -2,31 +2,38 @@
 /* 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/. */
 
 /**
  * Implementation of HTML <label> elements.
  */
 #include "HTMLLabelElement.h"
+#include "mozilla/dom/HTMLLabelElementBinding.h"
 #include "nsEventDispatcher.h"
 #include "nsFocusManager.h"
 
 // construction, destruction
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Label)
 DOMCI_NODE_DATA(HTMLLabelElement, mozilla::dom::HTMLLabelElement)
 
 namespace mozilla {
 namespace dom {
 
 HTMLLabelElement::~HTMLLabelElement()
 {
 }
 
+JSObject*
+HTMLLabelElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return HTMLLabelElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
 // nsISupports 
 
 
 NS_IMPL_ADDREF_INHERITED(HTMLLabelElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLLabelElement, Element)
 
 // QueryInterface implementation for HTMLLabelElement
 NS_INTERFACE_TABLE_HEAD(HTMLLabelElement)
@@ -50,18 +57,32 @@ HTMLLabelElement::GetForm(nsIDOMHTMLForm
 NS_IMETHODIMP
 HTMLLabelElement::GetControl(nsIDOMHTMLElement** aElement)
 {
   nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(GetLabeledElement());
   element.forget(aElement);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+HTMLLabelElement::SetHtmlFor(const nsAString& aHtmlFor)
+{
+  ErrorResult rv;
+  SetHtmlFor(aHtmlFor, rv);
+  return rv.ErrorCode();
+}
 
-NS_IMPL_STRING_ATTR(HTMLLabelElement, HtmlFor, _for)
+NS_IMETHODIMP
+HTMLLabelElement::GetHtmlFor(nsAString& aHtmlFor)
+{
+  nsString htmlFor;
+  GetHtmlFor(htmlFor);
+  aHtmlFor = htmlFor;
+  return NS_OK;
+}
 
 void
 HTMLLabelElement::Focus(ErrorResult& aError)
 {
   // retarget the focus method at the for content
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
     nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(GetLabeledElement());
@@ -231,18 +252,18 @@ HTMLLabelElement::PerformAccesskey(bool 
     nsAutoPopupStatePusher popupStatePusher(aIsTrustedEvent ?
                                             openAllowed : openAbused);
 
     nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this), presContext,
                                 &event);
   }
 }
 
-Element*
-HTMLLabelElement::GetLabeledElement()
+nsGenericHTMLElement*
+HTMLLabelElement::GetLabeledElement() const
 {
   nsAutoString elementId;
 
   if (!GetAttr(kNameSpaceID_None, nsGkAtoms::_for, elementId)) {
     // No @for, so we are a label for our first form control element.
     // Do a depth-first traversal to look for the first form control element.
     return GetFirstLabelableDescendant();
   }
@@ -251,30 +272,30 @@ HTMLLabelElement::GetLabeledElement()
   // and this element should be a labelable form control.
   nsIDocument* doc = GetCurrentDoc();
   if (!doc) {
     return nullptr;
   }
 
   Element* element = doc->GetElementById(elementId);
   if (element && element->IsLabelable()) {
-    return element;
+    return static_cast<nsGenericHTMLElement*>(element);
   }
 
   return nullptr;
 }
 
-Element*
-HTMLLabelElement::GetFirstLabelableDescendant()
+nsGenericHTMLElement*
+HTMLLabelElement::GetFirstLabelableDescendant() const
 {
   for (nsIContent* cur = nsINode::GetFirstChild(); cur;
        cur = cur->GetNextNode(this)) {
     Element* element = cur->IsElement() ? cur->AsElement() : nullptr;
     if (element && element->IsLabelable()) {
-      return element;
+      return static_cast<nsGenericHTMLElement*>(element);
     }
   }
 
   return nullptr;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLLabelElement.h
+++ b/content/html/content/src/HTMLLabelElement.h
@@ -18,16 +18,17 @@ namespace dom {
 class HTMLLabelElement : public nsGenericHTMLFormElement,
                          public nsIDOMHTMLLabelElement
 {
 public:
   HTMLLabelElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericHTMLFormElement(aNodeInfo),
       mHandlingEvent(false)
   {
+    SetIsDOMBinding();
   }
   virtual ~HTMLLabelElement();
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLabelElement, label)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -38,16 +39,30 @@ public:
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   // nsIDOMHTMLLabelElement
   NS_DECL_NSIDOMHTMLLABELELEMENT
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
 
+  using nsGenericHTMLFormElement::GetForm;
+  void GetHtmlFor(nsString& aHtmlFor)
+  {
+    GetHTMLAttr(nsGkAtoms::_for, aHtmlFor);
+  }
+  void SetHtmlFor(const nsAString& aHtmlFor, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::_for, aHtmlFor, aError);
+  }
+  nsGenericHTMLElement* GetControl() const
+  {
+    return GetLabeledElement();
+  }
+
   virtual void Focus(mozilla::ErrorResult& aError) MOZ_OVERRIDE;
 
   // nsIFormControl
   NS_IMETHOD_(uint32_t) GetType() const { return NS_FORM_LABEL; }
   NS_IMETHOD Reset();
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
 
   virtual bool IsDisabled() const { return false; }
@@ -57,19 +72,22 @@ public:
   virtual void PerformAccesskey(bool aKeyCausesActivation,
                                 bool aIsTrustedEvent);
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
-  mozilla::dom::Element* GetLabeledElement();
+  nsGenericHTMLElement* GetLabeledElement() const;
 protected:
-  mozilla::dom::Element* GetFirstLabelableDescendant();
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap) MOZ_OVERRIDE;
+
+  nsGenericHTMLElement* GetFirstLabelableDescendant() const;
 
   // XXX It would be nice if we could use an event flag instead.
   bool mHandlingEvent;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -1079,16 +1079,20 @@ public:
 
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
   virtual bool IsNodeOfType(uint32_t aFlags) const;
   virtual void SaveSubtreeState();
 
   // nsIFormControl
   virtual mozilla::dom::Element* GetFormElement();
+  nsHTMLFormElement* GetForm() const
+  {
+    return mForm;
+  }
   virtual void SetForm(nsIDOMHTMLFormElement* aForm);
   virtual void ClearForm(bool aRemoveFromForm);
 
   nsresult GetForm(nsIDOMHTMLFormElement** aForm);
 
   NS_IMETHOD SaveState()
   {
     return NS_OK;
--- a/docshell/test/test_bug387979.html
+++ b/docshell/test/test_bug387979.html
@@ -16,17 +16,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 387979 **/
 function a(s) {
 	var r;
 	try { r = frames[0].document.body; }
 	catch (e) { r = e; }
-        is(r instanceof HTMLBodyElement, true,
+        is(r instanceof frames[0].HTMLBodyElement, true,
            "Can't get body" + s);
 }
 var p = 0;
 function b() {
 	switch (++p) {
 	case 1:
 		frames[0].location = "about:blank";
 		break;
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -279,26 +279,38 @@ DOMInterfaces = {
     'resultNotAddRefed': [ 'gain' ],
 }],
 
 'HTMLCollection': {
     'nativeType': 'nsIHTMLCollection',
     'resultNotAddRefed': [ 'item' ]
 },
 
+'HTMLDataListElement': {
+    'resultNotAddRefed': [
+        'options'
+    ]
+},
+
 'HTMLElement': {
     'nativeType': 'nsGenericHTMLElement',
     'hasXPConnectImpls': True,
     'hasInstanceInterface': 'nsIDOMHTMLElement',
     'resultNotAddRefed': [
         'itemType', 'itemRef', 'itemProp', 'properties', 'contextMenu', 'style',
         'offsetParent'
     ]
 },
 
+'HTMLLabelElement': {
+    'resultNotAddRefed': [
+        'form', 'control'
+    ]
+},
+
 'HTMLOptionsCollection': {
     'nativeType': 'nsHTMLOptionCollection',
     'headerFile': 'nsHTMLSelectElement.h',
     'resultNotAddRefed': [ 'item' ],
     'binaryNames': {
         '__indexedsettercreator': 'SetOption'
     }
 },
--- a/dom/encoding/test/test_utf16_files.html
+++ b/dom/encoding/test/test_utf16_files.html
@@ -36,17 +36,17 @@ function runTest() {
   tests.forEach(function(test) {
     var t = async_test(test.name);
     var fails = test.fails;
     var ifr = test.ifr;
     ifr.onload = ifr.onerror = function() {
       t.step(fails ? function() {
         assert_equals(ifr.document.body, null, ifr.name + " should NOT load.");
       } : function() {
-        assert_true(ifr.document.body instanceof HTMLBodyElement, ifr.name + " should load.");
+        assert_true(ifr.document.body instanceof ifr.HTMLBodyElement, ifr.name + " should load.");
       });
       t.done();
     };
   });
 }
 
 </script>
 </body>
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLBodyElement.webidl
@@ -0,0 +1,62 @@
+/* -*- 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/
+ *
+ * © 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 HTMLBodyElement : HTMLElement {
+  [SetterThrows]
+  attribute EventHandler onafterprint;
+  [SetterThrows]
+  attribute EventHandler onbeforeprint;
+  [SetterThrows]
+  attribute BeforeUnloadEventHandler onbeforeunload;
+  //[SetterThrows]
+  //attribute EventHandler onblur;
+  //[SetterThrows]
+  //attribute OnErrorEventHandler onerror;
+  //[SetterThrows]
+  //attribute EventHandler onfocus;
+  [SetterThrows]
+  attribute EventHandler onhashchange;
+  //[SetterThrows]
+  //attribute EventHandler onload;
+  [SetterThrows]
+  attribute EventHandler onmessage;
+  [SetterThrows]
+  attribute EventHandler onoffline;
+  [SetterThrows]
+  attribute EventHandler ononline;
+  [SetterThrows]
+  attribute EventHandler onpopstate;
+  [SetterThrows]
+  attribute EventHandler onpagehide;
+  [SetterThrows]
+  attribute EventHandler onpageshow;
+  [SetterThrows]
+  attribute EventHandler onresize;
+  //[SetterThrows]
+  //attribute EventHandler onscroll;
+  //[SetterThrows]
+  //attribute EventHandler onstorage;
+  [SetterThrows]
+  attribute EventHandler onunload;
+/*
+};
+
+partial interface HTMLBodyElement {
+*/
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString text;
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString link;
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString vLink;
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString aLink;
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString bgColor;
+  [SetterThrows]                          attribute DOMString background;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLDataListElement.webidl
@@ -0,0 +1,16 @@
+/* -*- 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/
+ *
+ * © 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 HTMLDataListElement : HTMLElement {
+  readonly attribute HTMLCollection options;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLFontElement.webidl
@@ -0,0 +1,18 @@
+/* -*- 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/
+ *
+ * © 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 HTMLFontElement : HTMLElement {
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString color;
+  [SetterThrows]                          attribute DOMString face;
+  [SetterThrows]                          attribute DOMString size;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLFrameSetElement.webidl
@@ -0,0 +1,54 @@
+/* -*- 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/
+ *
+ * © 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 HTMLFrameSetElement : HTMLElement {
+  [SetterThrows]
+  attribute DOMString cols;
+  [SetterThrows]
+  attribute DOMString rows;
+  [SetterThrows]
+  attribute EventHandler onafterprint;
+  [SetterThrows]
+  attribute EventHandler onbeforeprint;
+  [SetterThrows]
+  attribute BeforeUnloadEventHandler onbeforeunload;
+  //[SetterThrows]
+  //attribute EventHandler onblur;
+  //[SetterThrows]
+  //attribute EventHandler onerror;
+  //[SetterThrows]
+  //attribute EventHandler onfocus;
+  [SetterThrows]
+  attribute EventHandler onhashchange;
+  //attribute EventHandler onload;
+  [SetterThrows]
+  attribute EventHandler onmessage;
+  [SetterThrows]
+  attribute EventHandler onoffline;
+  [SetterThrows]
+  attribute EventHandler ononline;
+  [SetterThrows]
+  attribute EventHandler onpagehide;
+  [SetterThrows]
+  attribute EventHandler onpageshow;
+  [SetterThrows]
+  attribute EventHandler onpopstate;
+  [SetterThrows]
+  attribute EventHandler onresize;
+  //[SetterThrows]
+  //attribute EventHandler onscroll;
+  //[SetterThrows]
+  //attribute EventHandler onstorage;
+  [SetterThrows]
+  attribute EventHandler onunload;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLLabelElement.webidl
@@ -0,0 +1,18 @@
+/* -*- 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/
+ *
+ * © 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 HTMLLabelElement : HTMLElement {
+  readonly attribute HTMLFormElement? form;
+           attribute DOMString htmlFor;
+  readonly attribute HTMLElement? control;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -39,19 +39,24 @@ webidl_files = \
   EventTarget.webidl \
   File.webidl \
   FileHandle.webidl \
   FileList.webidl \
   FileReaderSync.webidl \
   FormData.webidl \
   Function.webidl \
   GainNode.webidl \
+  HTMLBodyElement.webidl \
   HTMLCollection.webidl \
+  HTMLDataListElement.webidl \
   HTMLDivElement.webidl \
   HTMLElement.webidl \
+  HTMLFontElement.webidl \
+  HTMLFrameSetElement.webidl \
+  HTMLLabelElement.webidl \
   HTMLOptionsCollection.webidl \
   HTMLPropertiesCollection.webidl \
   ImageData.webidl \
   Location.webidl \
   MutationObserver.webidl \
   Node.webidl \
   NodeFilter.webidl \
   NodeList.webidl \