Bug 1389650 - Remove nsIDOMHTMLAnchorElement; r=bz draft
authorKyle Machulis <kyle@nonpolynomial.com>
Fri, 22 Sep 2017 11:27:43 -0700
changeset 669220 924a3fcb66d527ebfbc97dbfd97a35d3f610a73e
parent 669219 53b44470cc8030ef73fd873085b6fe8f35c56fe6
child 732895 26382447fcbbc99d69fdd01187b901ebcff3ac94
push id81258
push userbmo:kyle@nonpolynomial.com
push dateFri, 22 Sep 2017 18:28:34 +0000
reviewersbz
bugs1389650
milestone58.0a1
Bug 1389650 - Remove nsIDOMHTMLAnchorElement; r=bz Removes the XPCOM interface for nsIDOMHTMLAnchorElement, replacing it with binding class usage. MozReview-Commit-ID: C8EJCvxNa7e
docshell/base/nsContextMenuInfo.cpp
docshell/base/nsDocShell.cpp
dom/base/nsContentAreaDragDrop.cpp
dom/html/HTMLAnchorElement.cpp
dom/html/HTMLAnchorElement.h
dom/html/HTMLAreaElement.h
dom/html/HTMLLinkElement.h
dom/interfaces/html/moz.build
dom/interfaces/html/nsIDOMHTMLAnchorElement.idl
dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
editor/libeditor/HTMLEditUtils.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditorDataTransfer.cpp
layout/generic/nsImageFrame.cpp
layout/printing/nsPrintEngine.cpp
xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
--- a/docshell/base/nsContextMenuInfo.cpp
+++ b/docshell/base/nsContextMenuInfo.cpp
@@ -7,32 +7,35 @@
 #include "nsContextMenuInfo.h"
 
 #include "nsIImageLoadingContent.h"
 #include "imgLoader.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMHTMLHtmlElement.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLImageElement.h"
-#include "nsIDOMHTMLAreaElement.h"
-#include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMWindow.h"
 #include "nsICSSDeclaration.h"
 #include "nsIDOMCSSValue.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsNetUtil.h"
 #include "nsUnicharUtils.h"
 #include "nsIDocument.h"
 #include "nsIPrincipal.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIContentPolicy.h"
 #include "imgRequestProxy.h"
+#include "mozilla/dom/HTMLAnchorElement.h"
+#include "mozilla/dom/HTMLAreaElement.h"
+#include "mozilla/dom/HTMLLinkElement.h"
 
+using mozilla::dom::HTMLAnchorElement;
+using mozilla::dom::HTMLAreaElement;
+using mozilla::dom::HTMLLinkElement;
 using mozilla::dom::Element;
 using mozilla::ErrorResult;
 
 NS_IMPL_ISUPPORTS(nsContextMenuInfo, nsIContextMenuInfo)
 
 nsContextMenuInfo::nsContextMenuInfo()
 {
 }
@@ -58,77 +61,49 @@ nsContextMenuInfo::GetTargetNode(nsIDOMN
 }
 
 NS_IMETHODIMP
 nsContextMenuInfo::GetAssociatedLink(nsAString& aHRef)
 {
   NS_ENSURE_STATE(mAssociatedLink);
   aHRef.Truncate(0);
 
-  nsCOMPtr<nsIDOMElement> content(do_QueryInterface(mAssociatedLink));
-  nsAutoString localName;
-  if (content) {
-    content->GetLocalName(localName);
+  nsCOMPtr<nsIContent> content = do_QueryInterface(mAssociatedLink);
+  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(content);
+  if (anchor) {
+    anchor->GetHref(aHRef);
+    return NS_OK;
+  }
+  RefPtr<HTMLAreaElement> area = HTMLAreaElement::FromContent(content);
+  if (area) {
+    area->GetHref(aHRef);
+    return NS_OK;
+  }
+  RefPtr<HTMLLinkElement> link = HTMLLinkElement::FromContent(content);
+  if (link) {
+    link->GetHref(aHRef);
+    return NS_OK;
   }
 
-  nsCOMPtr<nsIDOMElement> linkContent;
-  ToLowerCase(localName);
-  if (localName.EqualsLiteral("a") ||
-      localName.EqualsLiteral("area") ||
-      localName.EqualsLiteral("link")) {
-    bool hasAttr;
-    content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
-    if (hasAttr) {
-      linkContent = content;
-      nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
-      if (anchor) {
-        anchor->GetHref(aHRef);
-      } else {
-        nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(linkContent));
-        if (area) {
-          area->GetHref(aHRef);
-        } else {
-          nsCOMPtr<nsIDOMHTMLLinkElement> link(do_QueryInterface(linkContent));
-          if (link) {
-            link->GetHref(aHRef);
-          }
-        }
-      }
+  nsCOMPtr<nsIDOMNode> curr;
+  mAssociatedLink->GetParentNode(getter_AddRefs(curr));
+  while (curr) {
+    content = do_QueryInterface(curr);
+    if (!content) {
+      break;
     }
-  } else {
-    nsCOMPtr<nsIDOMNode> curr;
-    mAssociatedLink->GetParentNode(getter_AddRefs(curr));
-    while (curr) {
-      content = do_QueryInterface(curr);
-      if (!content) {
-        break;
-      }
-      content->GetLocalName(localName);
-      ToLowerCase(localName);
-      if (localName.EqualsLiteral("a")) {
-        bool hasAttr;
-        content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
-        if (hasAttr) {
-          linkContent = content;
-          nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(
-            do_QueryInterface(linkContent));
-          if (anchor) {
-            anchor->GetHref(aHRef);
-          }
-        } else {
-          linkContent = nullptr; // Links can't be nested.
-        }
-        break;
-      }
+    RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(content);
+    if (anchor) {
+      anchor->GetHref(aHRef);
+      break;
+    }
 
-      nsCOMPtr<nsIDOMNode> temp = curr;
-      temp->GetParentNode(getter_AddRefs(curr));
-    }
+    nsCOMPtr<nsIDOMNode> temp = curr;
+    temp->GetParentNode(getter_AddRefs(curr));
   }
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContextMenuInfo::GetImageContainer(imgIContainer** aImageContainer)
 {
   NS_ENSURE_ARG_POINTER(aImageContainer);
   NS_ENSURE_STATE(mDOMNode);
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -130,17 +130,16 @@
 #include "nsITransportSecurityInfo.h"
 #include "nsINode.h"
 #include "nsINSSErrorsService.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsIApplicationCacheContainer.h"
 #include "nsStreamUtils.h"
 #include "nsIController.h"
 #include "nsPICommandUpdater.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsIWebBrowserChrome3.h"
 #include "nsITabChild.h"
 #include "nsISiteSecurityService.h"
 #include "nsStructuredCloneContainer.h"
 #include "nsIStructuredCloneContainer.h"
 #include "nsISupportsPrimitives.h"
 #ifdef MOZ_PLACES
 #include "nsIFaviconService.h"
@@ -14408,19 +14407,19 @@ nsDocShell::OnLinkClickSync(nsIContent* 
 
   // referer could be null here in some odd cases, but that's ok,
   // we'll just load the link w/o sending a referer in those cases.
 
   nsAutoString target(aTargetSpec);
 
   // If this is an anchor element, grab its type property to use as a hint
   nsAutoString typeHint;
-  nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(aContent));
-  if (anchor) {
-    anchor->GetType(typeHint);
+  if (IsElementAnchor(aContent) &&
+      aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::type)) {
+    aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, typeHint);
     NS_ConvertUTF16toUTF8 utf8Hint(typeHint);
     nsAutoCString type, dummy;
     NS_ParseRequestContentType(utf8Hint, type, dummy);
     CopyUTF8toUTF16(type, typeHint);
   }
 
   // Clone the URI now, in case a content policy or something messes
   // with it under InternalLoad; we do _not_ want to change the URI
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -20,17 +20,16 @@
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMDragEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMRange.h"
 #include "nsIFormControl.h"
 #include "nsIDOMHTMLAreaElement.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsITransferable.h"
 #include "nsComponentManagerUtils.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
 #include "nsNetUtil.h"
 #include "nsIFile.h"
 #include "nsFrameLoader.h"
@@ -52,16 +51,17 @@
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "nsIMIMEInfo.h"
 #include "nsRange.h"
 #include "TabParent.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLAreaElement.h"
+#include "mozilla/dom/HTMLAnchorElement.h"
 #include "nsVariant.h"
 
 using namespace mozilla::dom;
 
 class MOZ_STACK_CLASS DragDataProducer
 {
 public:
   DragDataProducer(nsPIDOMWindowOuter* aWindow,
@@ -469,19 +469,17 @@ DragDataProducer::Produce(DataTransfer* 
       if (form && !mIsAltKeyPressed && form->ControlType() != NS_FORM_OBJECT) {
         *aCanDrag = false;
         return NS_OK;
       }
 
       draggedNode = mTarget;
     }
 
-    nsCOMPtr<nsIDOMHTMLAreaElement>   area;   // client-side image map
     nsCOMPtr<nsIImageLoadingContent>  image;
-    nsCOMPtr<nsIDOMHTMLAnchorElement> link;
 
     nsCOMPtr<nsIContent> selectedImageOrLinkNode;
     GetDraggableSelectionData(selection, mSelectionTargetNode,
                               getter_AddRefs(selectedImageOrLinkNode),
                               &haveSelectedContent);
 
     // either plain text or anchor text is selected
     if (haveSelectedContent) {
@@ -496,29 +494,27 @@ DragDataProducer::Produce(DataTransfer* 
       //
       // if the alt key is down, don't start a drag if we're in an
       // anchor because we want to do selection.
       parentLink = FindParentLinkNode(draggedNode);
       if (parentLink && mIsAltKeyPressed) {
         *aCanDrag = false;
         return NS_OK;
       }
-
-      area  = do_QueryInterface(draggedNode);
       image = do_QueryInterface(draggedNode);
-      link  = do_QueryInterface(draggedNode);
     }
 
     {
       // set for linked images, and links
       nsCOMPtr<nsIContent> linkNode;
 
-      if (area) {
+      RefPtr<HTMLAreaElement> areaElem = HTMLAreaElement::FromContent(draggedNode);
+      RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(draggedNode);
+      if (areaElem) {
         // use the alt text (or, if missing, the href) as the title
-        HTMLAreaElement* areaElem = static_cast<HTMLAreaElement*>(area.get());
         areaElem->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
         if (mTitleString.IsEmpty()) {
           // this can be a relative link
           areaElem->GetAttribute(NS_LITERAL_STRING("href"), mTitleString);
         }
 
         // we'll generate HTML like <a href="absurl">alt text</a>
         mIsAnchor = true;
@@ -633,19 +629,19 @@ DragDataProducer::Produce(DataTransfer* 
           // If we are dragging around an image in an anchor, then we
           // are dragging the entire anchor
           linkNode = parentLink;
           nodeToSerialize = linkNode;
         } else {
           nodeToSerialize = do_QueryInterface(draggedNode);
         }
         dragNode = nodeToSerialize;
-      } else if (link) {
+      } else if (anchor) {
         // set linkNode. The code below will handle this
-        linkNode = do_QueryInterface(link);    // XXX test this
+        linkNode = do_QueryInterface(draggedNode);    // XXX test this
         GetNodeString(draggedNode, mTitleString);
       } else if (parentLink) {
         // parentLink will always be null if there's selected content
         linkNode = parentLink;
         nodeToSerialize = linkNode;
       } else if (!haveSelectedContent) {
         // nothing draggable
         return NS_OK;
--- a/dom/html/HTMLAnchorElement.cpp
+++ b/dom/html/HTMLAnchorElement.cpp
@@ -53,20 +53,23 @@ HTMLAnchorElement::~HTMLAnchorElement()
 
 bool
 HTMLAnchorElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::href) ||
          nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex);
 }
 
-NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLAnchorElement,
-                                             nsGenericHTMLElement,
-                                             nsIDOMHTMLAnchorElement,
-                                             Link)
+NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLAnchorElement)
+  NS_INTERFACE_TABLE_INHERITED(HTMLAnchorElement,
+                               Link)
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
+
+NS_IMPL_ADDREF_INHERITED(HTMLAnchorElement, Element)
+NS_IMPL_RELEASE_INHERITED(HTMLAnchorElement, Element)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLAnchorElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLAnchorElement,
                                                   nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelList)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
@@ -78,27 +81,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_ELEMENT_CLONE(HTMLAnchorElement)
 
 JSObject*
 HTMLAnchorElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return HTMLAnchorElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Charset, charset)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Coords, coords)
-NS_IMPL_URI_ATTR(HTMLAnchorElement, Href, href)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Hreflang, hreflang)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Name, name)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Rel, rel)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Rev, rev)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Shape, shape)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Type, type)
-NS_IMPL_STRING_ATTR(HTMLAnchorElement, Download, download)
-
 int32_t
 HTMLAnchorElement::TabIndexDefault()
 {
   return 0;
 }
 
 bool
 HTMLAnchorElement::Draggable() const
@@ -263,98 +255,51 @@ void
 HTMLAnchorElement::GetLinkTarget(nsAString& aTarget)
 {
   GetAttr(kNameSpaceID_None, nsGkAtoms::target, aTarget);
   if (aTarget.IsEmpty()) {
     GetBaseTarget(aTarget);
   }
 }
 
-NS_IMETHODIMP
+void
 HTMLAnchorElement::GetTarget(nsAString& aValue)
 {
   if (!GetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue)) {
     GetBaseTarget(aValue);
   }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-HTMLAnchorElement::SetTarget(const nsAString& aValue)
-{
-  return SetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue, true);
 }
 
 nsDOMTokenList*
 HTMLAnchorElement::RelList()
 {
   if (!mRelList) {
     mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
   }
   return mRelList;
 }
 
-#define IMPL_URI_PART(_part)                                 \
-  NS_IMETHODIMP                                              \
-  HTMLAnchorElement::Get##_part(nsAString& a##_part)         \
-  {                                                          \
-    Link::Get##_part(a##_part);                              \
-    return NS_OK;                                            \
-  }                                                          \
-  NS_IMETHODIMP                                              \
-  HTMLAnchorElement::Set##_part(const nsAString& a##_part)   \
-  {                                                          \
-    Link::Set##_part(a##_part);                              \
-    return NS_OK;                                            \
-  }
-
-IMPL_URI_PART(Protocol)
-IMPL_URI_PART(Host)
-IMPL_URI_PART(Hostname)
-IMPL_URI_PART(Pathname)
-IMPL_URI_PART(Search)
-IMPL_URI_PART(Port)
-IMPL_URI_PART(Hash)
-
-#undef IMPL_URI_PART
-
-NS_IMETHODIMP
+void
 HTMLAnchorElement::GetText(nsAString& aText)
 {
-  if(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  return NS_OK;
+  nsContentUtils::GetNodeTextContent(this, true, aText);
 }
 
-NS_IMETHODIMP
-HTMLAnchorElement::SetText(const nsAString& aText)
+void
+HTMLAnchorElement::SetText(const nsAString& aText, ErrorResult& aRv)
 {
-  return nsContentUtils::SetNodeTextContent(this, aText, false);
+  aRv = nsContentUtils::SetNodeTextContent(this, aText, false);
 }
 
-NS_IMETHODIMP
+void
 HTMLAnchorElement::ToString(nsAString& aSource)
 {
   return GetHref(aSource);
 }
 
-NS_IMETHODIMP
-HTMLAnchorElement::GetPing(nsAString& aValue)
-{
-  GetAttr(kNameSpaceID_None, nsGkAtoms::ping, aValue);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-HTMLAnchorElement::SetPing(const nsAString& aValue)
-{
-  return SetAttr(kNameSpaceID_None, nsGkAtoms::ping, aValue, true);
-}
-
 already_AddRefed<nsIURI>
 HTMLAnchorElement::GetHrefURI() const
 {
   nsCOMPtr<nsIURI> uri = Link::GetCachedURI();
   if (uri) {
     return uri.forget();
   }
 
--- a/dom/html/HTMLAnchorElement.h
+++ b/dom/html/HTMLAnchorElement.h
@@ -5,26 +5,24 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_HTMLAnchorElement_h
 #define mozilla_dom_HTMLAnchorElement_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Link.h"
 #include "nsGenericHTMLElement.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsDOMTokenList.h"
 
 namespace mozilla {
 class EventChainPostVisitor;
 class EventChainPreVisitor;
 namespace dom {
 
 class HTMLAnchorElement final : public nsGenericHTMLElement,
-                                public nsIDOMHTMLAnchorElement,
                                 public Link
 {
 public:
   using Element::GetText;
   using Element::SetText;
 
   explicit HTMLAnchorElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
     : nsGenericHTMLElement(aNodeInfo)
@@ -34,25 +32,25 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLAnchorElement,
                                            nsGenericHTMLElement)
 
+  NS_IMPL_FROMCONTENT_HTML_WITH_TAGS(HTMLAnchorElement, (a, anchor));
+
   virtual int32_t TabIndexDefault() override;
   virtual bool Draggable() const override;
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
 
-  // nsIDOMHTMLAnchorElement
-  NS_DECL_NSIDOMHTMLANCHORELEMENT
-
+  // DOM memory reporter participant
   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) override;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) override;
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
@@ -79,77 +77,80 @@ public:
   virtual EventStates IntrinsicState() const override;
 
   virtual void OnDNSPrefetchDeferred() override;
   virtual void OnDNSPrefetchRequested() override;
   virtual bool HasDeferredDNSPrefetchRequest() override;
 
   // WebIDL API
 
-  // The XPCOM GetHref is OK for us
+  void GetHref(nsAString& aValue)
+  {
+    GetURIAttr(nsGkAtoms::href, nullptr, aValue);
+  }
   void SetHref(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::href, aValue, rv);
   }
-  // The XPCOM GetTarget is OK for us
+  void GetTarget(nsAString& aValue);
   void SetTarget(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::target, aValue, rv);
   }
-  void GetDownload(DOMString& aValue)
+  void GetDownload(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::download, aValue);
   }
   void SetDownload(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::download, aValue, rv);
   }
-  // The XPCOM GetPing is OK for us
+  void GetPing(nsAString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::ping, aValue);
+  }
   void SetPing(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::ping, aValue, rv);
   }
-  void GetRel(DOMString& aValue)
+  void GetRel(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::rel, aValue);
   }
   void SetRel(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::rel, aValue, rv);
   }
   void SetReferrerPolicy(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::referrerpolicy, aValue, rv);
   }
   void GetReferrerPolicy(nsAString& aReferrer)
   {
     GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
   }
   nsDOMTokenList* RelList();
-  void GetHreflang(DOMString& aValue)
+  void GetHreflang(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::hreflang, aValue);
   }
   void SetHreflang(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::hreflang, aValue, rv);
   }
-  void GetType(DOMString& aValue)
+  void GetType(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::type, aValue);
   }
   void SetType(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::type, aValue, rv);
   }
-  // The XPCOM GetText is OK for us
-  void SetText(const nsAString& aValue, mozilla::ErrorResult& rv)
-  {
-    rv = SetText(aValue);
-  }
+  void GetText(nsAString& aValue);
+  void SetText(const nsAString& aValue, mozilla::ErrorResult& rv);
 
   // Link::GetOrigin is OK for us
 
   // Link::GetProtocol is OK for us
   // Link::SetProtocol is OK for us
 
   // Link::GetUsername is OK for us
   // Link::SetUsername is OK for us
@@ -171,60 +172,61 @@ public:
 
   // Link::Link::GetSearch is OK for us
   // Link::Link::SetSearch is OK for us
 
   // Link::Link::GetHash is OK for us
   // Link::Link::SetHash is OK for us
 
   // The XPCOM URI decomposition attributes are fine for us
-  void GetCoords(DOMString& aValue)
+  void GetCoords(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::coords, aValue);
   }
   void SetCoords(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::coords, aValue, rv);
   }
-  void GetCharset(DOMString& aValue)
+  void GetCharset(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::charset, aValue);
   }
   void SetCharset(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::charset, aValue, rv);
   }
-  void GetName(DOMString& aValue)
+  void GetName(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::name, aValue);
   }
   void SetName(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::name, aValue, rv);
   }
-  void GetRev(DOMString& aValue)
+  void GetRev(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::rev, aValue);
   }
   void SetRev(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::rev, aValue, rv);
   }
-  void GetShape(DOMString& aValue)
+  void GetShape(nsAString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::shape, aValue);
   }
   void SetShape(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::shape, aValue, rv);
   }
   void Stringify(nsAString& aResult)
   {
     GetHref(aResult);
   }
+  void ToString(nsAString& aSource);
 
   virtual void NodeInfoChanged(nsIDocument* aOldDoc) final override
   {
     ClearHasPendingLinkUpdate();
     nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
   }
 
   static DOMTokenListSupportedToken sSupportedRelValues[];
--- a/dom/html/HTMLAreaElement.h
+++ b/dom/html/HTMLAreaElement.h
@@ -37,16 +37,17 @@ public:
                                            nsGenericHTMLElement)
 
   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
 
   virtual int32_t TabIndexDefault() override;
 
   // nsIDOMHTMLAreaElement
   NS_DECL_NSIDOMHTMLAREAELEMENT
+  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLAreaElement, area);
 
   virtual nsresult GetEventTargetParent(
                      EventChainPreVisitor& aVisitor) override;
   virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
   virtual bool IsLink(nsIURI** aURI) const override;
   virtual void GetLinkTarget(nsAString& aTarget) override;
   virtual already_AddRefed<nsIURI> GetHrefURI() const override;
 
--- a/dom/html/HTMLLinkElement.h
+++ b/dom/html/HTMLLinkElement.h
@@ -30,17 +30,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLLinkElement,
                                            nsGenericHTMLElement)
 
   // nsIDOMHTMLLinkElement
   NS_DECL_NSIDOMHTMLLINKELEMENT
-
+  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLinkElement, link);
   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
 
   void LinkAdded();
   void LinkRemoved();
 
   // nsIDOMEventTarget
   virtual nsresult GetEventTargetParent(
                      EventChainPreVisitor& aVisitor) override;
--- a/dom/interfaces/html/moz.build
+++ b/dom/interfaces/html/moz.build
@@ -3,17 +3,16 @@
 # 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/.
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "DOM")
 
 XPIDL_SOURCES += [
-    'nsIDOMHTMLAnchorElement.idl',
     'nsIDOMHTMLAreaElement.idl',
     'nsIDOMHTMLBaseElement.idl',
     'nsIDOMHTMLButtonElement.idl',
     'nsIDOMHTMLCanvasElement.idl',
     'nsIDOMHTMLCollection.idl',
     'nsIDOMHTMLDocument.idl',
     'nsIDOMHTMLElement.idl',
     'nsIDOMHTMLFormElement.idl',
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMHTMLAnchorElement.idl
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- 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/. */
-
-#include "nsIDOMHTMLElement.idl"
-
-/**
- * The nsIDOMHTMLAnchorElement interface is the interface to a [X]HTML
- * a element.
- *
- * This interface is trying to follow the DOM Level 2 HTML specification:
- * http://www.w3.org/TR/DOM-Level-2-HTML/
- *
- * with changes from the work-in-progress WHATWG HTML specification:
- * http://www.whatwg.org/specs/web-apps/current-work/
- */
-
-[uuid(339c01c8-2d41-4626-b231-eec63f0241b6)]
-interface nsIDOMHTMLAnchorElement : nsISupports
-{
-           attribute DOMString        href;
-           attribute DOMString        target;
-
-           attribute DOMString        ping;
-           attribute DOMString        download;
-
-           attribute DOMString        rel;
-           attribute DOMString        hreflang;
-           attribute DOMString        type;
-
-  /**
-   * An alias for the textContent attribute.
-   */
-  [Null(Stringify)]
-           attribute DOMString        text;
-
-  // URL decomposition IDL attributes
-           attribute DOMString        protocol;
-           attribute DOMString        host;
-           attribute DOMString        hostname;
-           attribute DOMString        port;
-           attribute DOMString        pathname;
-           attribute DOMString        search;
-           attribute DOMString        hash;
-
-
-           attribute DOMString        charset;
-           attribute DOMString        coords;
-           attribute DOMString        name;
-           attribute DOMString        rev;
-           attribute DOMString        shape;
-
-  DOMString                 toString();
-};
--- a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
@@ -1,30 +1,30 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "WebBrowserPersistLocalDocument.h"
 #include "WebBrowserPersistDocumentParent.h"
 
+#include "mozilla/dom/HTMLAnchorElement.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLSharedElement.h"
 #include "mozilla/dom/TabParent.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsContentCID.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsFrameLoader.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIContent.h"
 #include "nsIDOMAttr.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLBaseElement.h"
 #include "nsIDOMHTMLCollection.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMHTMLInputElement.h"
@@ -937,17 +937,17 @@ PersistNodeFixup::FixupNode(nsIDOMNode *
     }
 
     nsCOMPtr<nsIContent> content = do_QueryInterface(aNodeIn);
     if (!content) {
         return NS_OK;
     }
 
     // Fix up href and file links in the elements
-    nsCOMPtr<nsIDOMHTMLAnchorElement> nodeAsAnchor = do_QueryInterface(aNodeIn);
+    RefPtr<dom::HTMLAnchorElement> nodeAsAnchor = dom::HTMLAnchorElement::FromContent(content);
     if (nodeAsAnchor) {
         rv = GetNodeToFixup(aNodeIn, aNodeOut);
         if (NS_SUCCEEDED(rv) && *aNodeOut) {
             FixupAnchor(*aNodeOut);
         }
         return rv;
     }
 
--- a/editor/libeditor/HTMLEditUtils.cpp
+++ b/editor/libeditor/HTMLEditUtils.cpp
@@ -13,21 +13,21 @@
 #include "nsAString.h"                  // for nsAString::IsEmpty
 #include "nsCOMPtr.h"                   // for nsCOMPtr, operator==, etc.
 #include "nsCaseTreatment.h"
 #include "nsDebug.h"                    // for NS_PRECONDITION, etc.
 #include "nsError.h"                    // for NS_SUCCEEDED
 #include "nsGkAtoms.h"                  // for nsGkAtoms, nsGkAtoms::a, etc.
 #include "nsHTMLTags.h"
 #include "nsIAtom.h"                    // for nsIAtom
-#include "nsIDOMHTMLAnchorElement.h"    // for nsIDOMHTMLAnchorElement
 #include "nsIDOMNode.h"                 // for nsIDOMNode
 #include "nsNameSpaceManager.h"        // for kNameSpaceID_None
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsString.h"                   // for nsAutoString
+#include "mozilla/dom/HTMLAnchorElement.h"
 
 namespace mozilla {
 
 /**
  * IsInlineStyle() returns true if aNode is an inline style.
  */
 bool
 HTMLEditUtils::IsInlineStyle(nsIDOMNode* aNode)
@@ -331,20 +331,21 @@ HTMLEditUtils::IsLink(nsIDOMNode *aNode)
   return node && IsLink(node);
 }
 
 bool
 HTMLEditUtils::IsLink(nsINode* aNode)
 {
   MOZ_ASSERT(aNode);
 
-  nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aNode);
+  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContentOrNull(aNode->AsContent());
   if (anchor) {
     nsAutoString tmpText;
-    if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && !tmpText.IsEmpty()) {
+    anchor->GetHref(tmpText);
+    if (!tmpText.IsEmpty()) {
       return true;
     }
   }
   return false;
 }
 
 bool
 HTMLEditUtils::IsNamedAnchor(nsIDOMNode *aNode)
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -22,17 +22,16 @@
 #include "TypeInState.h"
 
 #include "nsIDOMMozNamedAttrMap.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMAttr.h"
 #include "nsIDocumentInlines.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMMouseEvent.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsISelectionController.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsILinkHandler.h"
 #include "nsIInlineSpellChecker.h"
 
 #include "mozilla/css/Loader.h"
 #include "nsIDOMStyleSheet.h"
 
@@ -2589,29 +2588,35 @@ HTMLEditor::InsertLinkAroundSelection(ns
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
 
   if (selection->Collapsed()) {
     NS_WARNING("InsertLinkAroundSelection called but there is no selection!!!");
     return NS_OK;
   }
 
+
   // Be sure we were given an anchor element
-  nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aAnchorElement);
+  nsCOMPtr<nsIContent> content = do_QueryInterface(aAnchorElement);
+  if (!content) {
+    return NS_OK;
+  }
+
+  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(content);
   if (!anchor) {
     return NS_OK;
   }
 
   nsAutoString href;
-  nsresult rv = anchor->GetHref(href);
-  NS_ENSURE_SUCCESS(rv, rv);
+  anchor->GetHref(href);
   if (href.IsEmpty()) {
     return NS_OK;
   }
 
+  nsresult rv;
   AutoPlaceholderBatch beginBatching(this);
 
   // Set all attributes found on the supplied anchor element
   nsCOMPtr<nsIDOMMozNamedAttrMap> attrMap;
   aAnchorElement->GetAttributes(getter_AddRefs(attrMap));
   NS_ENSURE_TRUE(attrMap, NS_ERROR_FAILURE);
 
   uint32_t count;
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -34,17 +34,16 @@
 #include "nsGkAtoms.h"
 #include "nsIClipboard.h"
 #include "nsIContent.h"
 #include "nsIContentFilter.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIDOMElement.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLScriptElement.h"
 #include "nsIDOMNode.h"
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -38,17 +38,16 @@
 #include "nsTransform2D.h"
 #include "nsImageMap.h"
 #include "nsIIOService.h"
 #include "nsILoadGroup.h"
 #include "nsISupportsPriority.h"
 #include "nsNetUtil.h"
 #include "nsNetCID.h"
 #include "nsCSSRendering.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsNameSpaceManager.h"
 #include <algorithm>
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 #include "nsIDOMNode.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
@@ -76,16 +75,17 @@
 #include "mozilla/StyleSetHandleInlines.h"
 #include "nsBlockFrame.h"
 #include "nsStyleStructInlines.h"
 
 #include "mozilla/Preferences.h"
 
 #include "mozilla/dom/Link.h"
 #include "SVGImageContext.h"
+#include "mozilla/dom/HTMLAnchorElement.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 using namespace mozilla::layers;
 
 // sizes (pixels) for image icon, padding and border frame
@@ -1988,17 +1988,17 @@ nsImageFrame::GetAnchorHREFTargetAndNode
     nsCOMPtr<dom::Link> link(do_QueryInterface(content));
     if (link) {
       nsCOMPtr<nsIURI> href = content->GetHrefURI();
       if (href) {
         href->Clone(aHref);
       }
       status = (*aHref != nullptr);
 
-      nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(content));
+      RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(content);
       if (anchor) {
         anchor->GetTarget(aTarget);
       }
       NS_ADDREF(*aNode = content);
       break;
     }
   }
   return status;
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -100,17 +100,16 @@ static const char kPrintingPromptService
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIBaseWindow.h"
 #include "nsILayoutHistoryState.h"
 #include "nsFrameManager.h"
 #include "mozilla/ReflowInput.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIContentViewer.h"
 #include "nsIDocumentViewerPrint.h"
 
 #include "nsFocusManager.h"
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
@@ -40,17 +40,16 @@
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMFileList.h"
 #include "nsIDOMFocusEvent.h"
 #include "nsIDOMFormData.h"
 #include "nsIDOMGeoPositionError.h"
 #include "nsIDOMHistory.h"
-#include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLBaseElement.h"
 #include "nsIDOMHTMLButtonElement.h"
 #include "nsIDOMHTMLCanvasElement.h"
 #include "nsIDOMHTMLCollection.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMHTMLFormElement.h"
@@ -317,17 +316,16 @@ const ComponentsInterfaceShimEntry kComp
   DEFINE_SHIM(Event),
   DEFINE_SHIM(EventTarget),
   DEFINE_SHIM(FileList),
   DEFINE_SHIM(FocusEvent),
   DEFINE_SHIM(FormData),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIFrameLoader, FrameLoader),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMGeoPositionError, PositionError),
   DEFINE_SHIM(History),
-  DEFINE_SHIM(HTMLAnchorElement),
   DEFINE_SHIM(HTMLAreaElement),
   DEFINE_SHIM(HTMLBaseElement),
   DEFINE_SHIM(HTMLButtonElement),
   DEFINE_SHIM(HTMLCanvasElement),
   DEFINE_SHIM(HTMLCollection),
   DEFINE_SHIM(HTMLDocument),
   DEFINE_SHIM(HTMLElement),
   DEFINE_SHIM(HTMLFormElement),