Fix for bug 824907 (Convert HTML table elements to WebIDL) - convert HTMLTableElement to WebIDL. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Sat, 29 Dec 2012 09:08:15 +0100
changeset 127601 08e18a8008ec0df4c0160f418df5942764427b0d
parent 127600 08a616b1e4f4b24d72ba731afc40521974246094
child 127602 7564aeb63a36912dc58cbdad0073c4ffbacd597f
push id297
push userlsblakk@mozilla.com
push dateTue, 26 Mar 2013 17:28:00 +0000
treeherdermozilla-release@64d7b45c34e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs824907
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 824907 (Convert HTML table elements to WebIDL) - convert HTMLTableElement to WebIDL. r=bz.
content/html/content/src/HTMLTableCaptionElement.cpp
content/html/content/src/HTMLTableCaptionElement.h
content/html/content/src/HTMLTableCellElement.cpp
content/html/content/src/HTMLTableCellElement.h
content/html/content/src/HTMLTableColElement.cpp
content/html/content/src/HTMLTableColElement.h
content/html/content/src/HTMLTableElement.cpp
content/html/content/src/HTMLTableElement.h
content/html/content/src/HTMLTableRowElement.cpp
content/html/content/src/HTMLTableRowElement.h
content/html/content/src/HTMLTableSectionElement.cpp
content/html/content/src/HTMLTableSectionElement.h
content/html/content/test/reflect.js
dom/bindings/Bindings.conf
dom/webidl/HTMLTableElement.webidl
dom/webidl/WebIDL.mk
js/xpconnect/src/dom_quickstubs.qsconf
--- a/content/html/content/src/HTMLTableElement.cpp
+++ b/content/html/content/src/HTMLTableElement.cpp
@@ -1,37 +1,23 @@
 /* -*- 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 "mozilla/dom/HTMLTableElement.h"
-#include "nsIDOMHTMLTableCaptionElem.h"
 #include "nsIDOMHTMLTableSectionElem.h"
-#include "nsCOMPtr.h"
-#include "nsIDOMEventTarget.h"
-#include "nsError.h"
-#include "nsContentList.h"
-#include "nsGenericHTMLElement.h"
 #include "nsAttrValueInlines.h"
-#include "nsGkAtoms.h"
-#include "nsStyleConsts.h"
-#include "nsPresContext.h"
-#include "nsHTMLParts.h"
 #include "nsRuleData.h"
-#include "nsStyleContext.h"
-#include "nsIDocument.h"
-#include "nsContentUtils.h"
-#include "nsIDOMElement.h"
-#include "nsIHTMLCollection.h"
 #include "nsHTMLStyleSheet.h"
+#include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/HTMLCollectionBinding.h"
-#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/HTMLTableElementBinding.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Table)
 DOMCI_NODE_DATA(HTMLTableElement, mozilla::dom::HTMLTableElement)
 
 namespace mozilla {
 namespace dom {
 
 /* ------------------------------ TableRowsCollection -------------------------------- */
@@ -125,39 +111,34 @@ NS_INTERFACE_MAP_END
 // rowgroups.  _code should be the code to execute for each rowgroup.  The
 // rowgroup's rows will be in the nsIDOMHTMLCollection* named "rows".  Note
 // that this may be null at any time.  This macro assumes an nsresult named
 // |rv| is in scope.
 #define DO_FOR_EACH_ROWGROUP(_code)                                  \
   do {                                                               \
     if (mParent) {                                                   \
       /* THead */                                                    \
-      nsCOMPtr<nsIDOMHTMLTableSectionElement> rowGroup;              \
-      rowGroup = mParent->GetTHead();                                \
+      HTMLTableSectionElement* rowGroup = mParent->GetTHead();       \
       nsCOMPtr<nsIDOMHTMLCollection> rows;                           \
       if (rowGroup) {                                                \
         rowGroup->GetRows(getter_AddRefs(rows));                     \
         do { /* gives scoping */                                     \
           _code                                                      \
         } while (0);                                                 \
       }                                                              \
       /* TBodies */                                                  \
-      nsContentList *_tbodies = mParent->TBodies();                  \
-      nsINode * _node;                                               \
-      uint32_t _tbodyIndex = 0;                                      \
-      _node = _tbodies->Item(_tbodyIndex);                           \
-      while (_node) {                                                \
-        rowGroup = do_QueryInterface(_node);                         \
-        if (rowGroup) {                                              \
+      for (nsIContent* _node = mParent->nsINode::GetFirstChild();    \
+           _node; _node = _node->GetNextSibling()) {                 \
+        if (_node->IsHTML(nsGkAtoms::tbody)) {                       \
+          rowGroup = static_cast<HTMLTableSectionElement*>(_node);   \
           rowGroup->GetRows(getter_AddRefs(rows));                   \
           do { /* gives scoping */                                   \
             _code                                                    \
           } while (0);                                               \
         }                                                            \
-        _node = _tbodies->Item(++_tbodyIndex);                       \
       }                                                              \
       /* orphan rows */                                              \
       rows = mOrphanRows;                                            \
       do { /* gives scoping */                                       \
         _code                                                        \
       } while (0);                                                   \
       /* TFoot */                                                    \
       rowGroup = mParent->GetTFoot();                                \
@@ -324,26 +305,32 @@ TableRowsCollection::ParentDestroyed()
 }
 
 /* --------------------------- HTMLTableElement ---------------------------- */
 
 HTMLTableElement::HTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo),
     mTableInheritedAttributes(TABLE_ATTRS_DIRTY)
 {
+  SetIsDOMBinding();
 }
 
 HTMLTableElement::~HTMLTableElement()
 {
   if (mRows) {
     mRows->ParentDestroyed();
   }
   ReleaseInheritedAttributes();
 }
 
+JSObject*
+HTMLTableElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return HTMLTableElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTableElement)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTableElement, nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTBodies)
   if (tmp->mRows) {
     tmp->mRows->ParentDestroyed();
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRows)
@@ -352,512 +339,549 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
                                                   nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTBodies)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRows)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(HTMLTableElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLTableElement, Element)
 
-
 // QueryInterface implementation for HTMLTableElement
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLTableElement)
   NS_HTML_CONTENT_INTERFACE_TABLE1(HTMLTableElement, nsIDOMHTMLTableElement)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLTableElement,
                                                nsGenericHTMLElement)
 NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTableElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLTableElement)
 
 
 // the DOM spec says border, cellpadding, cellSpacing are all "wstring"
 // in fact, they are integers or they are meaningless.  so we store them
 // here as ints.
 
-NS_IMPL_STRING_ATTR(HTMLTableElement, Align, align)
-NS_IMPL_STRING_ATTR(HTMLTableElement, BgColor, bgcolor)
-NS_IMPL_STRING_ATTR(HTMLTableElement, Border, border)
-NS_IMPL_STRING_ATTR(HTMLTableElement, CellPadding, cellpadding)
-NS_IMPL_STRING_ATTR(HTMLTableElement, CellSpacing, cellspacing)
-NS_IMPL_STRING_ATTR(HTMLTableElement, Frame, frame)
-NS_IMPL_STRING_ATTR(HTMLTableElement, Rules, rules)
-NS_IMPL_STRING_ATTR(HTMLTableElement, Summary, summary)
-NS_IMPL_STRING_ATTR(HTMLTableElement, Width, width)
+NS_IMETHODIMP
+HTMLTableElement::SetAlign(const nsAString& aAlign)
+{
+  ErrorResult rv;
+  SetAlign(aAlign, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetAlign(nsAString& aAlign)
+{
+  nsString align;
+  GetAlign(align);
+  aAlign = align;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HTMLTableElement::SetBgColor(const nsAString& aBgColor)
+{
+  ErrorResult rv;
+  SetBgColor(aBgColor, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetBgColor(nsAString& aBgColor)
+{
+  nsString bgColor;
+  GetBgColor(bgColor);
+  aBgColor = bgColor;
+  return NS_OK;
+}
 
+NS_IMETHODIMP
+HTMLTableElement::SetBorder(const nsAString& aBorder)
+{
+  ErrorResult rv;
+  SetBorder(aBorder, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetBorder(nsAString& aBorder)
+{
+  nsString border;
+  GetBorder(border);
+  aBorder = border;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HTMLTableElement::SetCellPadding(const nsAString& aCellPadding)
+{
+  ErrorResult rv;
+  SetCellPadding(aCellPadding, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetCellPadding(nsAString& aCellPadding)
+{
+  nsString cellPadding;
+  GetCellPadding(cellPadding);
+  aCellPadding = cellPadding;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HTMLTableElement::SetCellSpacing(const nsAString& aCellSpacing)
+{
+  ErrorResult rv;
+  SetCellSpacing(aCellSpacing, rv);
+  return rv.ErrorCode();
+}
 
-already_AddRefed<nsIDOMHTMLTableCaptionElement>
-HTMLTableElement::GetCaption()
+NS_IMETHODIMP
+HTMLTableElement::GetCellSpacing(nsAString& aCellSpacing)
+{
+  nsString cellSpacing;
+  GetCellSpacing(cellSpacing);
+  aCellSpacing = cellSpacing;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HTMLTableElement::SetFrame(const nsAString& aFrame)
+{
+  ErrorResult rv;
+  SetFrame(aFrame, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetFrame(nsAString& aFrame)
+{
+  nsString frame;
+  GetFrame(frame);
+  aFrame = frame;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HTMLTableElement::SetRules(const nsAString& aRules)
+{
+  ErrorResult rv;
+  SetRules(aRules, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetRules(nsAString& aRules)
 {
-  for (nsIContent* cur = nsINode::GetFirstChild(); cur; cur = cur->GetNextSibling()) {
-    nsCOMPtr<nsIDOMHTMLTableCaptionElement> caption = do_QueryInterface(cur);
-    if (caption) {
-      return caption.forget();
-    }
-  }
-  return nullptr;
+  nsString rules;
+  GetRules(rules);
+  aRules = rules;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HTMLTableElement::SetSummary(const nsAString& aSummary)
+{
+  ErrorResult rv;
+  SetSummary(aSummary, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetSummary(nsAString& aSummary)
+{
+  nsString summary;
+  GetSummary(summary);
+  aSummary = summary;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HTMLTableElement::SetWidth(const nsAString& aWidth)
+{
+  ErrorResult rv;
+  SetWidth(aWidth, rv);
+  return rv.ErrorCode();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::GetWidth(nsAString& aWidth)
+{
+  nsString width;
+  GetWidth(width);
+  aWidth = width;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::GetCaption(nsIDOMHTMLTableCaptionElement** aValue)
 {
   nsCOMPtr<nsIDOMHTMLTableCaptionElement> caption = GetCaption();
   caption.forget(aValue);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::SetCaption(nsIDOMHTMLTableCaptionElement* aValue)
 {
-  nsresult rv = DeleteCaption();
-
-  if (NS_SUCCEEDED(rv)) {
-    if (aValue) {
-      nsCOMPtr<nsIDOMNode> resultingChild;
-      AppendChild(aValue, getter_AddRefs(resultingChild));
-    }
-  }
-
-  return rv;
-}
-
-already_AddRefed<nsIDOMHTMLTableSectionElement>
-HTMLTableElement::GetSection(nsIAtom *aTag)
-{
-  for (nsIContent* child = nsINode::GetFirstChild();
-       child;
-       child = child->GetNextSibling()) {
-    nsCOMPtr<nsIDOMHTMLTableSectionElement> section = do_QueryInterface(child);
-    if (section && child->NodeInfo()->Equals(aTag)) {
-      return section.forget();
-    }
-  }
-  return nullptr;
+  HTMLTableCaptionElement* caption =
+    static_cast<HTMLTableCaptionElement*>(aValue);
+  SetCaption(caption);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::GetTHead(nsIDOMHTMLTableSectionElement** aValue)
 {
-  *aValue = GetTHead().get();
+  NS_IF_ADDREF(*aValue = GetTHead());
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::SetTHead(nsIDOMHTMLTableSectionElement* aValue)
 {
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aValue));
-  NS_ENSURE_TRUE(content, NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
-
-  if (!content->NodeInfo()->Equals(nsGkAtoms::thead)) {
-    return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
-  }
-  
-  nsresult rv = DeleteTHead();
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (aValue) {
-    nsCOMPtr<nsIDOMNode> child;
-    rv = GetFirstChild(getter_AddRefs(child));
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-     
-    nsCOMPtr<nsIDOMNode> resultChild;
-    rv = InsertBefore(aValue, child, getter_AddRefs(resultChild));
-  }
-
-  return rv;
+  ErrorResult rv;
+  SetTHead(aValue, rv);
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 HTMLTableElement::GetTFoot(nsIDOMHTMLTableSectionElement** aValue)
 {
-  *aValue = GetTFoot().get();
+  NS_IF_ADDREF(*aValue = GetTFoot());
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::SetTFoot(nsIDOMHTMLTableSectionElement* aValue)
 {
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aValue));
-  NS_ENSURE_TRUE(content, NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
-
-  if (!content->NodeInfo()->Equals(nsGkAtoms::tfoot)) {
-    return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
-  }
-  
-  nsresult rv = DeleteTFoot();
-  if (NS_SUCCEEDED(rv)) {
-    if (aValue) {
-      nsCOMPtr<nsIDOMNode> resultingChild;
-      AppendChild(aValue, getter_AddRefs(resultingChild));
-    }
-  }
-
-  return rv;
+  ErrorResult rv;
+  SetTFoot(aValue, rv);
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 HTMLTableElement::GetRows(nsIDOMHTMLCollection** aValue)
 {
+  NS_ADDREF(*aValue = Rows());
+  return NS_OK;
+}
+
+nsIHTMLCollection*
+HTMLTableElement::Rows()
+{
   if (!mRows) {
     mRows = new TableRowsCollection(this);
   }
 
-  *aValue = mRows;
-  NS_ADDREF(*aValue);
-
-  return NS_OK;
+  return mRows;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::GetTBodies(nsIDOMHTMLCollection** aValue)
 {
   NS_ADDREF(*aValue = TBodies());
   return NS_OK;
 }
 
-nsContentList*
+nsIHTMLCollection*
 HTMLTableElement::TBodies()
 {
   if (!mTBodies) {
     // Not using NS_GetContentList because this should not be cached
     mTBodies = new nsContentList(this,
                                  kNameSpaceID_XHTML,
                                  nsGkAtoms::tbody,
                                  nsGkAtoms::tbody,
                                  false);
   }
 
   return mTBodies;
 }
 
+already_AddRefed<nsGenericHTMLElement>
+HTMLTableElement::CreateTHead()
+{
+  nsRefPtr<nsGenericHTMLElement> head = GetTHead();
+  if (!head) {
+    // Create a new head rowgroup.
+    nsCOMPtr<nsINodeInfo> nodeInfo;
+    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::thead,
+                                getter_AddRefs(nodeInfo));
+
+    head = NS_NewHTMLTableSectionElement(nodeInfo.forget());
+    if (!head) {
+      return nullptr;
+    }
+
+    ErrorResult rv;
+    nsINode::InsertBefore(*head, nsINode::GetFirstChild(), rv);
+  }
+  return head.forget();
+}
+
 NS_IMETHODIMP
 HTMLTableElement::CreateTHead(nsIDOMHTMLElement** aValue)
 {
-  *aValue = nullptr;
-
-  nsRefPtr<nsIDOMHTMLTableSectionElement> head = GetTHead();
-  if (head) {
-    // return the existing thead
-    head.forget(aValue);
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsINodeInfo> nodeInfo;
-  nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::thead,
-                              getter_AddRefs(nodeInfo));
-
-  nsCOMPtr<nsIContent> newHead =
-    NS_NewHTMLTableSectionElement(nodeInfo.forget());
-
-  if (!newHead) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIDOMNode> child;
-  nsresult rv = GetFirstChild(getter_AddRefs(child));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMHTMLElement> newHeadAsDOMElement = do_QueryInterface(newHead);
-
-  nsCOMPtr<nsIDOMNode> resultChild;
-  InsertBefore(newHeadAsDOMElement, child, getter_AddRefs(resultChild));
-  newHeadAsDOMElement.forget(aValue);
-  return NS_OK;
+  nsRefPtr<nsGenericHTMLElement> thead = CreateTHead();
+  return thead ? CallQueryInterface(thead, aValue) : NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::DeleteTHead()
 {
-  nsCOMPtr<nsIDOMHTMLTableSectionElement> childToDelete;
-  nsresult rv = GetTHead(getter_AddRefs(childToDelete));
-
-  if ((NS_SUCCEEDED(rv)) && childToDelete) {
-    nsCOMPtr<nsIDOMNode> resultingChild;
-    // mInner does the notification
-    RemoveChild(childToDelete, getter_AddRefs(resultingChild));
+  HTMLTableSectionElement* tHead = GetTHead();
+  if (tHead) {
+    mozilla::ErrorResult rv;
+    nsINode::RemoveChild(*tHead, rv);
+    MOZ_ASSERT(!rv.Failed());
   }
 
   return NS_OK;
 }
 
+already_AddRefed<nsGenericHTMLElement>
+HTMLTableElement::CreateTFoot()
+{
+  nsRefPtr<nsGenericHTMLElement> foot = GetTFoot();
+  if (!foot) {
+    // create a new foot rowgroup
+    nsCOMPtr<nsINodeInfo> nodeInfo;
+    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tfoot,
+                                getter_AddRefs(nodeInfo));
+
+    foot = NS_NewHTMLTableSectionElement(nodeInfo.forget());
+    if (!foot) {
+      return nullptr;
+    }
+    AppendChildTo(foot, true);
+  }
+
+  return foot.forget();
+}
+
 NS_IMETHODIMP
 HTMLTableElement::CreateTFoot(nsIDOMHTMLElement** aValue)
 {
-  *aValue = nullptr;
-
-  nsRefPtr<nsIDOMHTMLTableSectionElement> foot = GetTFoot();
-  if (foot) {
-    // return the existing tfoot
-    foot.forget(aValue);
-    return NS_OK;
-  }
-  // create a new foot rowgroup
-  nsCOMPtr<nsINodeInfo> nodeInfo;
-  nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tfoot,
-                              getter_AddRefs(nodeInfo));
-
-  nsCOMPtr<nsIContent> newFoot = NS_NewHTMLTableSectionElement(nodeInfo.forget());
-
-  if (!newFoot) {
-    return NS_OK;
-  }
-  AppendChildTo(newFoot, true);
-  nsCOMPtr<nsIDOMHTMLElement> newFootAsDOMElement = do_QueryInterface(newFoot);
-  newFootAsDOMElement.forget(aValue);
-  return NS_OK;
+  nsRefPtr<nsGenericHTMLElement> tfoot = CreateTFoot();
+  return tfoot ? CallQueryInterface(tfoot, aValue) : NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::DeleteTFoot()
 {
-  nsCOMPtr<nsIDOMHTMLTableSectionElement> childToDelete;
-  nsresult rv = GetTFoot(getter_AddRefs(childToDelete));
-
-  if ((NS_SUCCEEDED(rv)) && childToDelete) {
-    nsCOMPtr<nsIDOMNode> resultingChild;
-    // mInner does the notification
-    RemoveChild(childToDelete, getter_AddRefs(resultingChild));
+  HTMLTableSectionElement* tFoot = GetTFoot();
+  if (tFoot) {
+    mozilla::ErrorResult rv;
+    nsINode::RemoveChild(*tFoot, rv);
+    MOZ_ASSERT(!rv.Failed());
   }
 
   return NS_OK;
 }
 
+already_AddRefed<nsGenericHTMLElement>
+HTMLTableElement::CreateCaption()
+{
+  nsRefPtr<nsGenericHTMLElement> caption = GetCaption();
+  if (!caption) {
+    // Create a new caption.
+    nsCOMPtr<nsINodeInfo> nodeInfo;
+    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::caption,
+                                getter_AddRefs(nodeInfo));
+
+    caption = NS_NewHTMLTableCaptionElement(nodeInfo.forget());
+    if (!caption) {
+      return nullptr;
+    }
+
+    AppendChildTo(caption, true);
+  }
+  return caption.forget();
+}
+
 NS_IMETHODIMP
 HTMLTableElement::CreateCaption(nsIDOMHTMLElement** aValue)
 {
-  *aValue = nullptr;
-
-  if (nsRefPtr<nsIDOMHTMLTableCaptionElement> caption = GetCaption()) {
-    // return the existing caption
-    caption.forget(aValue);
-    return NS_OK;
-  }
-
-  // create a new head rowgroup
-  nsCOMPtr<nsINodeInfo> nodeInfo;
-  nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::caption,
-                              getter_AddRefs(nodeInfo));
-
-  nsCOMPtr<nsIContent> newCaption = NS_NewHTMLTableCaptionElement(nodeInfo.forget());
-
-  if (!newCaption) {
-    return NS_OK;
-  }
-
-  AppendChildTo(newCaption, true);
-  nsCOMPtr<nsIDOMHTMLElement> captionAsDOMElement =
-    do_QueryInterface(newCaption);
-  captionAsDOMElement.forget(aValue);
-  return NS_OK;
+  nsRefPtr<nsGenericHTMLElement> caption = CreateCaption();
+  return caption ? CallQueryInterface(caption, aValue) : NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLTableElement::DeleteCaption()
 {
-  nsCOMPtr<nsIDOMHTMLTableCaptionElement> childToDelete;
-  nsresult rv = GetCaption(getter_AddRefs(childToDelete));
-
-  if ((NS_SUCCEEDED(rv)) && childToDelete) {
-    nsCOMPtr<nsIDOMNode> resultingChild;
-    RemoveChild(childToDelete, getter_AddRefs(resultingChild));
+  HTMLTableCaptionElement* caption = GetCaption();
+  if (caption) {
+    mozilla::ErrorResult rv;
+    nsINode::RemoveChild(*caption, rv);
+    MOZ_ASSERT(!rv.Failed());
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-HTMLTableElement::InsertRow(int32_t aIndex, nsIDOMHTMLElement** aValue)
+already_AddRefed<nsGenericHTMLElement>
+HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
 {
   /* get the ref row at aIndex
      if there is one, 
        get its parent
        insert the new row just before the ref row
      else
        get the first row group
        insert the new row as its first child
   */
-  *aValue = nullptr;
-
   if (aIndex < -1) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
-  nsCOMPtr<nsIDOMHTMLCollection> rows;
-  GetRows(getter_AddRefs(rows));
-
-  uint32_t rowCount;
-  rows->GetLength(&rowCount);
-
+  nsIHTMLCollection* rows = Rows();
+  uint32_t rowCount = rows->Length();
   if ((uint32_t)aIndex > rowCount && aIndex != -1) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nullptr;
   }
 
   // use local variable refIndex so we can remember original aIndex
   uint32_t refIndex = (uint32_t)aIndex;
 
-  nsresult rv;
+  nsRefPtr<nsGenericHTMLElement> newRow;
   if (rowCount > 0) {
     if (refIndex == rowCount || aIndex == -1) {
       // we set refIndex to the last row so we can get the last row's
       // parent we then do an AppendChild below if (rowCount<aIndex)
 
       refIndex = rowCount - 1;
     }
 
-    nsCOMPtr<nsIDOMNode> refRow;
-    rows->Item(refIndex, getter_AddRefs(refRow));
+    Element* refRow = rows->Item(refIndex);
+    nsINode* parent = refRow->GetParentNode();
 
-    nsCOMPtr<nsIDOMNode> parent;
-
-    refRow->GetParentNode(getter_AddRefs(parent));
     // create the row
     nsCOMPtr<nsINodeInfo> nodeInfo;
     nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
                                 getter_AddRefs(nodeInfo));
 
-    nsCOMPtr<nsIContent> newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
+    newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
 
     if (newRow) {
-      nsCOMPtr<nsIDOMNode> newRowNode(do_QueryInterface(newRow));
-      nsCOMPtr<nsIDOMNode> retChild;
-
-      // If index is -1 or equal to the number of rows, the new row
+      // If aIndex is -1 or equal to the number of rows, the new row
       // is appended.
       if (aIndex == -1 || uint32_t(aIndex) == rowCount) {
-        rv = parent->AppendChild(newRowNode, getter_AddRefs(retChild));
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-      else
-      {
+        parent->AppendChild(*newRow, aError);
+      } else {
         // insert the new row before the reference row we found above
-        rv = parent->InsertBefore(newRowNode, refRow,
-                                  getter_AddRefs(retChild));
-        NS_ENSURE_SUCCESS(rv, rv);
+        parent->InsertBefore(*newRow, refRow, aError);
       }
 
-      if (retChild) {
-        CallQueryInterface(retChild, aValue);
+      if (aError.Failed()) {
+        return nullptr;
       }
     }
   } else {
     // the row count was 0, so 
     // find the first row group and insert there as first child
-    nsCOMPtr<nsIDOMNode> rowGroup;
-
+    nsCOMPtr<nsIContent> rowGroup;
     for (nsIContent* child = nsINode::GetFirstChild();
          child;
          child = child->GetNextSibling()) {
       nsINodeInfo *childInfo = child->NodeInfo();
       nsIAtom *localName = childInfo->NameAtom();
       if (childInfo->NamespaceID() == kNameSpaceID_XHTML &&
           (localName == nsGkAtoms::thead ||
            localName == nsGkAtoms::tbody ||
            localName == nsGkAtoms::tfoot)) {
-        rowGroup = do_QueryInterface(child);
-        NS_ASSERTION(rowGroup, "HTML node did not QI to nsIDOMNode");
+        rowGroup = child;
         break;
       }
     }
 
     if (!rowGroup) { // need to create a TBODY
       nsCOMPtr<nsINodeInfo> nodeInfo;
       nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tbody,
                                   getter_AddRefs(nodeInfo));
 
-      nsCOMPtr<nsIContent> newRowGroup =
-        NS_NewHTMLTableSectionElement(nodeInfo.forget());
-
-      if (newRowGroup) {
-        rv = AppendChildTo(newRowGroup, true);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rowGroup = do_QueryInterface(newRowGroup);
+      rowGroup = NS_NewHTMLTableSectionElement(nodeInfo.forget());
+      if (rowGroup) {
+        aError = AppendChildTo(rowGroup, true);
+        if (aError.Failed()) {
+          return nullptr;
+        }
       }
     }
 
     if (rowGroup) {
       nsCOMPtr<nsINodeInfo> nodeInfo;
       nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
                                   getter_AddRefs(nodeInfo));
 
-      nsCOMPtr<nsIContent> newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
+      newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
       if (newRow) {
-        nsCOMPtr<nsIDOMNode> firstRow;
-
-        nsCOMPtr<nsIDOMHTMLTableSectionElement> section =
-          do_QueryInterface(rowGroup);
-
-        if (section) {
-          nsCOMPtr<nsIDOMHTMLCollection> rows;
-          section->GetRows(getter_AddRefs(rows));
-          if (rows) {
-            rows->Item(0, getter_AddRefs(firstRow));
-          }
-        }
-        
-        nsCOMPtr<nsIDOMNode> retNode, newRowNode(do_QueryInterface(newRow));
-
-        rowGroup->InsertBefore(newRowNode, firstRow, getter_AddRefs(retNode));
-
-        if (retNode) {
-          CallQueryInterface(retNode, aValue);
-        }
+        HTMLTableSectionElement* section =
+          static_cast<HTMLTableSectionElement*>(rowGroup.get());
+        nsCOMPtr<nsIDOMHTMLCollection> rows;
+        section->GetRows(getter_AddRefs(rows));
+        rowGroup->InsertBefore(*newRow,
+                               static_cast<nsIHTMLCollection*>(rows.get())->Item(0),
+                               aError);
       }
     }
   }
 
-  return NS_OK;
+  return newRow.forget();
+}
+
+NS_IMETHODIMP
+HTMLTableElement::InsertRow(int32_t aIndex, nsIDOMHTMLElement** aValue)
+{
+  ErrorResult rv;
+  nsRefPtr<nsGenericHTMLElement> newRow = InsertRow(aIndex, rv);
+  return rv.Failed() ? rv.ErrorCode() : CallQueryInterface(newRow, aValue);
+}
+
+void
+HTMLTableElement::DeleteRow(int32_t aIndex, ErrorResult& aError)
+{
+  if (aIndex < -1) {
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return;
+  }
+
+  nsIHTMLCollection* rows = Rows();
+  uint32_t refIndex;
+  if (aIndex == -1) {
+    refIndex = rows->Length();
+    if (refIndex == 0) {
+      return;
+    }
+
+    --refIndex;
+  } else {
+    refIndex = (uint32_t)aIndex;
+  }
+
+  nsCOMPtr<nsIContent> row = rows->Item(refIndex);
+  if (!row) {
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return;
+  }
+
+  row->RemoveFromParent();
 }
 
 NS_IMETHODIMP
 HTMLTableElement::DeleteRow(int32_t aValue)
 {
-  if (aValue < -1) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-
-  nsCOMPtr<nsIDOMHTMLCollection> rows;
-  GetRows(getter_AddRefs(rows));
-
-  nsresult rv;
-  uint32_t refIndex;
-  if (aValue == -1) {
-    rv = rows->GetLength(&refIndex);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (refIndex == 0) {
-      return NS_OK;
-    }
-
-    --refIndex;
-  }
-  else {
-    refIndex = (uint32_t)aValue;
-  }
-
-  nsCOMPtr<nsIDOMNode> row;
-  rv = rows->Item(refIndex, getter_AddRefs(row));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!row) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-
-  nsCOMPtr<nsIDOMNode> parent;
-  row->GetParentNode(getter_AddRefs(parent));
-  NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
-
-  nsCOMPtr<nsIDOMNode> deleted_row;
-  return parent->RemoveChild(row, getter_AddRefs(deleted_row));
+  ErrorResult rv;
+  DeleteRow(aValue, rv);
+  return rv.ErrorCode();
 }
 
 static const nsAttrValue::EnumTable kFrameTable[] = {
   { "void",   NS_STYLE_TABLE_FRAME_NONE },
   { "above",  NS_STYLE_TABLE_FRAME_ABOVE },
   { "below",  NS_STYLE_TABLE_FRAME_BELOW },
   { "hsides", NS_STYLE_TABLE_FRAME_HSIDES },
   { "lhs",    NS_STYLE_TABLE_FRAME_LEFT },
--- a/content/html/content/src/HTMLTableElement.h
+++ b/content/html/content/src/HTMLTableElement.h
@@ -2,16 +2,18 @@
 /* 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 mozilla_dom_HTMLTableElement_h
 #define mozilla_dom_HTMLTableElement_h
 
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLTableElement.h"
+#include "mozilla/dom/HTMLTableCaptionElement.h"
+#include "mozilla/dom/HTMLTableSectionElement.h"
 #include "nsMappedAttributes.h"
 
 namespace mozilla {
 namespace dom {
 
 #define TABLE_ATTRS_DIRTY ((nsMappedAttributes*)0x1)
 
 class TableRowsCollection;
@@ -33,16 +35,152 @@ public:
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
 
   // nsIDOMHTMLTableElement
   NS_DECL_NSIDOMHTMLTABLEELEMENT
 
+  HTMLTableCaptionElement* GetCaption() const
+  {
+    return static_cast<HTMLTableCaptionElement*>(GetChild(nsGkAtoms::caption));
+  }
+  void SetCaption(HTMLTableCaptionElement* aCaption)
+  {
+    DeleteCaption();
+    if (aCaption) {
+      mozilla::ErrorResult rv;
+      nsINode::AppendChild(*aCaption, rv);
+    }
+  }
+  already_AddRefed<nsGenericHTMLElement> CreateCaption();
+
+  HTMLTableSectionElement* GetTHead() const
+  {
+    return static_cast<HTMLTableSectionElement*>(GetChild(nsGkAtoms::thead));
+  }
+  void SetTHead(nsIDOMHTMLTableSectionElement* aTHead, ErrorResult& aError)
+  {
+    nsCOMPtr<nsIContent> content = do_QueryInterface(aTHead);
+    if (!content || !content->IsHTML(nsGkAtoms::thead)) {
+      aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+      return;
+    }
+    HTMLTableSectionElement* thead =
+      static_cast<HTMLTableSectionElement*>(aTHead);
+
+    DeleteTHead();
+    if (thead) {
+      nsINode::InsertBefore(*thead, nsINode::GetFirstChild(), aError);
+    }
+  }
+  already_AddRefed<nsGenericHTMLElement> CreateTHead();
+
+  HTMLTableSectionElement* GetTFoot() const
+  {
+    return static_cast<HTMLTableSectionElement*>(GetChild(nsGkAtoms::tfoot));
+  }
+  void SetTFoot(nsIDOMHTMLTableSectionElement* aTFoot, ErrorResult& aError)
+  {
+    nsCOMPtr<nsIContent> content = do_QueryInterface(aTFoot);
+    if (!content || !content->IsHTML(nsGkAtoms::tfoot)) {
+      aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+      return;
+    }
+    HTMLTableSectionElement* tfoot =
+      static_cast<HTMLTableSectionElement*>(aTFoot);
+
+    DeleteTFoot();
+    if (tfoot) {
+      nsINode::AppendChild(*tfoot, aError);
+    }
+  }
+  already_AddRefed<nsGenericHTMLElement> CreateTFoot();
+
+  nsIHTMLCollection* TBodies();
+  nsIHTMLCollection* Rows();
+
+  already_AddRefed<nsGenericHTMLElement> InsertRow(int32_t aIndex,
+                                                   ErrorResult& aError);
+  void DeleteRow(int32_t aIndex, ErrorResult& aError);
+
+  void GetAlign(nsString& aAlign)
+  {
+    GetHTMLAttr(nsGkAtoms::align, aAlign);
+  }
+  void SetAlign(const nsAString& aAlign, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
+  }
+  void GetBorder(nsString& aBorder)
+  {
+    GetHTMLAttr(nsGkAtoms::border, aBorder);
+  }
+  void SetBorder(const nsAString& aBorder, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::border, aBorder, aError);
+  }
+  void GetFrame(nsString& aFrame)
+  {
+    GetHTMLAttr(nsGkAtoms::frame, aFrame);
+  }
+  void SetFrame(const nsAString& aFrame, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::frame, aFrame, aError);
+  }
+  void GetRules(nsString& aRules)
+  {
+    GetHTMLAttr(nsGkAtoms::rules, aRules);
+  }
+  void SetRules(const nsAString& aRules, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::rules, aRules, aError);
+  }
+  void GetSummary(nsString& aSummary)
+  {
+    GetHTMLAttr(nsGkAtoms::summary, aSummary);
+  }
+  void SetSummary(const nsAString& aSummary, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::summary, aSummary, aError);
+  }
+  void GetWidth(nsString& aWidth)
+  {
+    GetHTMLAttr(nsGkAtoms::width, aWidth);
+  }
+  void SetWidth(const nsAString& aWidth, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::width, aWidth, aError);
+  }
+  void GetBgColor(nsString& aBgColor)
+  {
+    GetHTMLAttr(nsGkAtoms::bgcolor, aBgColor);
+  }
+  void SetBgColor(const nsAString& aBgColor, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::bgcolor, aBgColor, aError);
+  }
+  void GetCellPadding(nsString& aCellPadding)
+  {
+    GetHTMLAttr(nsGkAtoms::cellpadding, aCellPadding);
+  }
+  void SetCellPadding(const nsAString& aCellPadding, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::cellpadding, aCellPadding, aError);
+  }
+  void GetCellSpacing(nsString& aCellSpacing)
+  {
+    GetHTMLAttr(nsGkAtoms::cellspacing, aCellSpacing);
+  }
+  void SetCellSpacing(const nsAString& aCellSpacing, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::cellspacing, aCellSpacing, aError);
+  }
+
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@@ -64,26 +202,31 @@ public:
    * Called when an attribute has just been changed
    */
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTableElement,
                                            nsGenericHTMLElement)
   nsMappedAttributes* GetAttributesMappedForCell();
-  already_AddRefed<nsIDOMHTMLTableSectionElement> GetTHead() {
-    return GetSection(nsGkAtoms::thead);
+
+protected:
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap) MOZ_OVERRIDE;
+
+  nsIContent* GetChild(nsIAtom *aTag) const
+  {
+    for (nsIContent* cur = nsINode::GetFirstChild(); cur;
+         cur = cur->GetNextSibling()) {
+      if (cur->IsHTML(aTag)) {
+        return cur;
+      }
+    }
+    return nullptr;
   }
-  already_AddRefed<nsIDOMHTMLTableSectionElement> GetTFoot() {
-    return GetSection(nsGkAtoms::tfoot);
-  }
-  already_AddRefed<nsIDOMHTMLTableCaptionElement> GetCaption();
-  nsContentList* TBodies();
-protected:
-  already_AddRefed<nsIDOMHTMLTableSectionElement> GetSection(nsIAtom *aTag);
 
   nsRefPtr<nsContentList> mTBodies;
   nsRefPtr<TableRowsCollection> mRows;
   // Sentinel value of TABLE_ATTRS_DIRTY indicates that this is dirty and needs
   // to be recalculated.
   nsMappedAttributes *mTableInheritedAttributes;
   void BuildInheritedAttributes();
   void ReleaseInheritedAttributes() {
--- a/content/html/content/test/reflect.js
+++ b/content/html/content/test/reflect.js
@@ -59,17 +59,16 @@ function reflectString(aParameters)
   var todoAttrs = {
     col: [ "align", "vAlign", "ch" ],
     colgroup: [ "align", "vAlign", "ch" ],
     form: [ "acceptCharset", "name", "target" ],
     img: [ "align" ],
     input: [ "accept", "alt", "formTarget", "max", "min", "name", "pattern", "placeholder", "step", "defaultValue" ],
     link: [ "crossOrigin" ],
     source: [ "media" ],
-    table: [ "border", "width" ],
     tbody: [ "align", "vAlign", "ch" ],
     td: [ "align", "vAlign", "ch" ],
     textarea: [ "name", "placeholder" ],
     tfoot: [ "align", "vAlign", "ch" ],
     th: [ "align", "vAlign", "ch" ],
     thead: [ "align", "vAlign", "ch" ],
     tr: [ "align", "vAlign", "ch" ],
   };
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -417,16 +417,23 @@ DOMInterfaces = {
     'headerFile': 'HTMLPropertiesCollection.h',
     'resultNotAddRefed': [ 'item', 'namedItem', 'names' ]
 },
 
 'HTMLScriptElement': {
   'hasInstanceInterface': 'nsIDOMHTMLScriptElement',
 },
 
+'HTMLTableElement': {
+    'hasInstanceInterface': 'nsIDOMHTMLTableElement',
+    'resultNotAddRefed': [
+        'caption', 'tHead', 'tFoot', 'tBodies', 'rows'
+    ]
+},
+
 'HTMLUListElement': {
     'headerFile' : 'mozilla/dom/HTMLSharedListElement.h'
 },
 
 'IID': [
 {
     'nativeType': 'nsIJSID',
     'headerFile': 'xpcjsid.h',
@@ -1105,16 +1112,20 @@ addExternalIface('ClientRect')
 addExternalIface("Counter")
 addExternalIface('CSSRule')
 addExternalIface('DOMRequest')
 addExternalIface('DOMStringList')
 addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('HTMLHeadElement', nativeType='mozilla::dom::Element')
 addExternalIface('HTMLCanvasElement', nativeType='mozilla::dom::HTMLCanvasElement')
+addExternalIface('HTMLTableCaptionElement',
+                 headerFile="nsIDOMHTMLTableCaptionElem.h")
+addExternalIface('HTMLTableSectionElement',
+                 headerFile="nsIDOMHTMLTableSectionElem.h")
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LockedFile')
 addExternalIface('MediaStream')
 addExternalIface('NamedNodeMap')
 addExternalIface('NodeIterator')
 addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
 addExternalIface('nsISupports', nativeType='nsISupports')
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLTableElement.webidl
@@ -0,0 +1,59 @@
+/* -*- 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 HTMLTableCaptionElement;
+interface HTMLTableSectionElement;
+
+interface HTMLTableElement : HTMLElement {
+           attribute HTMLTableCaptionElement? caption;
+  HTMLElement createCaption();
+  void deleteCaption();
+           [SetterThrows]
+           attribute HTMLTableSectionElement? tHead;
+  HTMLElement createTHead();
+  void deleteTHead();
+           [SetterThrows]
+           attribute HTMLTableSectionElement? tFoot;
+  HTMLElement createTFoot();
+  void deleteTFoot();
+  readonly attribute HTMLCollection tBodies;
+  //HTMLElement createTBody();
+  readonly attribute HTMLCollection rows;
+  [Throws]
+  HTMLElement insertRow(optional long index = -1);
+  [Throws]
+  void deleteRow(long index);
+  //         attribute boolean sortable;
+  //void stopSorting();
+/*
+};
+
+partial interface HTMLTableElement {
+*/
+           [SetterThrows]
+           attribute DOMString align;
+           [SetterThrows]
+           attribute DOMString border;
+           [SetterThrows]
+           attribute DOMString frame;
+           [SetterThrows]
+           attribute DOMString rules;
+           [SetterThrows]
+           attribute DOMString summary;
+           [SetterThrows]
+           attribute DOMString width;
+
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString bgColor;
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString cellPadding;
+  [TreatNullAs=EmptyString, SetterThrows] attribute DOMString cellSpacing;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -68,16 +68,17 @@ webidl_files = \
   HTMLLIElement.webidl \
   HTMLOListElement.webidl \
   HTMLOptionsCollection.webidl \
   HTMLParagraphElement.webidl \
   HTMLPreElement.webidl \
   HTMLPropertiesCollection.webidl \
   HTMLScriptElement.webidl \
   HTMLSpanElement.webidl \
+  HTMLTableElement.webidl \
   HTMLTitleElement.webidl \
   HTMLUListElement.webidl \
   ImageData.webidl \
   Location.webidl \
   MutationObserver.webidl \
   Node.webidl \
   NodeFilter.webidl \
   NodeList.webidl \
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -185,20 +185,16 @@ members = [
     'nsIDOMHTMLTableCellElement.cellIndex',
     'nsIDOMHTMLTableCellElement.rowSpan',
     'nsIDOMHTMLTableCellElement.abbr',
     'nsIDOMHTMLTableCellElement.scope',
     'nsIDOMHTMLTableCellElement.noWrap',
     'nsIDOMHTMLTableCellElement.width',
     'nsIDOMHTMLTableColElement.span',
     'nsIDOMHTMLTableColElement.width',
-    'nsIDOMHTMLTableElement.rows',
-    'nsIDOMHTMLTableElement.deleteRow',
-    'nsIDOMHTMLTableElement.summary',
-    'nsIDOMHTMLTableElement.insertRow',
     'nsIDOMHTMLTableRowElement.sectionRowIndex',
     'nsIDOMHTMLTableRowElement.rowIndex',
     'nsIDOMHTMLTableRowElement.cells',
     'nsIDOMHTMLTableRowElement.deleteCell',
     'nsIDOMHTMLTableRowElement.insertCell',
     'nsIDOMHTMLTableSectionElement.rows',
     'nsIDOMHTMLTableSectionElement.insertRow',
     'nsIDOMHTMLTableSectionElement.deleteRow',