Backed out changeset 26805294a547 (bug 1389650)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 26 Sep 2017 10:47:41 +0200
changeset 670374 2a16ec0d0828043aed627f480ef3c316390e83b2
parent 670373 19efc28f755bfe47e62ce10d4c4753a376bba6f8
child 670375 590f81062c5f6b6a5df5a0d992fde2d633527257
push id81612
push userbmo:dharvey@mozilla.com
push dateTue, 26 Sep 2017 10:16:26 +0000
bugs1389650
milestone58.0a1
backs out26805294a547518adc01e228fc77fcb7abd63220
Backed out changeset 26805294a547 (bug 1389650)
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
dom/webidl/HTMLAnchorElement.webidl
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,35 +7,32 @@
 #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()
 {
 }
@@ -61,54 +58,63 @@ nsContextMenuInfo::GetTargetNode(nsIDOMN
 }
 
 NS_IMETHODIMP
 nsContextMenuInfo::GetAssociatedLink(nsAString& aHRef)
 {
   NS_ENSURE_STATE(mAssociatedLink);
   aHRef.Truncate(0);
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mAssociatedLink));
-  nsCOMPtr<nsIContent> linkContent;
-  if (content &&
-      content->IsAnyOfHTMLElements(nsGkAtoms::a,
-                                   nsGkAtoms::area,
-                                   nsGkAtoms::link)) {
-    bool hasAttr = content->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
+  nsCOMPtr<nsIDOMElement> content(do_QueryInterface(mAssociatedLink));
+  nsAutoString localName;
+  if (content) {
+    content->GetLocalName(localName);
+  }
+
+  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;
-      RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(linkContent);
+      nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
       if (anchor) {
         anchor->GetHref(aHRef);
       } else {
-        RefPtr<HTMLAreaElement> area = HTMLAreaElement::FromContent(linkContent);
+        nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(linkContent));
         if (area) {
           area->GetHref(aHRef);
         } else {
-          RefPtr<HTMLLinkElement> link = HTMLLinkElement::FromContent(linkContent);
+          nsCOMPtr<nsIDOMHTMLLinkElement> link(do_QueryInterface(linkContent));
           if (link) {
             link->GetHref(aHRef);
           }
         }
       }
     }
   } else {
     nsCOMPtr<nsIDOMNode> curr;
     mAssociatedLink->GetParentNode(getter_AddRefs(curr));
     while (curr) {
       content = do_QueryInterface(curr);
       if (!content) {
         break;
       }
-      if (content->IsHTMLElement(nsGkAtoms::a)) {
+      content->GetLocalName(localName);
+      ToLowerCase(localName);
+      if (localName.EqualsLiteral("a")) {
         bool hasAttr;
-        hasAttr = content->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
+        content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
         if (hasAttr) {
           linkContent = content;
-          RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(linkContent);
+          nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(
+            do_QueryInterface(linkContent));
           if (anchor) {
             anchor->GetHref(aHRef);
           }
         } else {
           linkContent = nullptr; // Links can't be nested.
         }
         break;
       }
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -130,16 +130,17 @@
 #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"
@@ -14417,17 +14418,17 @@ 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;
-  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(aContent);
+  nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(aContent));
   if (anchor) {
     anchor->GetType(typeHint);
     NS_ConvertUTF16toUTF8 utf8Hint(typeHint);
     nsAutoCString type, dummy;
     NS_ParseRequestContentType(utf8Hint, type, dummy);
     CopyUTF8toUTF16(type, typeHint);
   }
 
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -20,16 +20,17 @@
 #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"
@@ -51,17 +52,16 @@
 #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,17 +469,19 @@ 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) {
@@ -494,26 +496,29 @@ 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;
 
-      RefPtr<HTMLAreaElement> areaElem = HTMLAreaElement::FromContentOrNull(draggedNode);
-      if (areaElem) {
+      if (area) {
         // 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;
@@ -628,19 +633,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 (draggedNode && draggedNode->IsHTMLElement(nsGkAtoms::a)) {
+      } else if (link) {
         // set linkNode. The code below will handle this
-        linkNode = do_QueryInterface(draggedNode);    // XXX test this
+        linkNode = do_QueryInterface(link);    // 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,23 +53,20 @@ HTMLAnchorElement::~HTMLAnchorElement()
 
 bool
 HTMLAnchorElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::href) ||
          nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex);
 }
 
-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_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLAnchorElement,
+                                             nsGenericHTMLElement,
+                                             nsIDOMHTMLAnchorElement,
+                                             Link)
 
 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
 
@@ -81,16 +78,27 @@ 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
@@ -255,53 +263,98 @@ void
 HTMLAnchorElement::GetLinkTarget(nsAString& aTarget)
 {
   GetAttr(kNameSpaceID_None, nsGkAtoms::target, aTarget);
   if (aTarget.IsEmpty()) {
     GetBaseTarget(aTarget);
   }
 }
 
-void
+NS_IMETHODIMP
 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;
 }
 
-void
-HTMLAnchorElement::GetText(nsAString& aText, mozilla::ErrorResult& aRv)
+#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
+HTMLAnchorElement::GetText(nsAString& aText)
 {
-  if (NS_WARN_IF(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible))) {
-    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+  if(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible)) {
+    return NS_ERROR_OUT_OF_MEMORY;
   }
+  return NS_OK;
 }
 
-void
-HTMLAnchorElement::SetText(const nsAString& aText, ErrorResult& aRv)
+NS_IMETHODIMP
+HTMLAnchorElement::SetText(const nsAString& aText)
 {
-  aRv = nsContentUtils::SetNodeTextContent(this, aText, false);
+  return nsContentUtils::SetNodeTextContent(this, aText, false);
 }
 
-void
+NS_IMETHODIMP
 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,24 +5,26 @@
  * 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)
@@ -32,25 +34,25 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLAnchorElement,
                                            nsGenericHTMLElement)
 
-  NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLAnchorElement, a);
-
   virtual int32_t TabIndexDefault() override;
   virtual bool Draggable() const override;
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
 
-  // DOM memory reporter participant
+  // nsIDOMHTMLAnchorElement
+  NS_DECL_NSIDOMHTMLANCHORELEMENT
+
   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;
@@ -77,85 +79,77 @@ public:
   virtual EventStates IntrinsicState() const override;
 
   virtual void OnDNSPrefetchDeferred() override;
   virtual void OnDNSPrefetchRequested() override;
   virtual bool HasDeferredDNSPrefetchRequest() override;
 
   // WebIDL API
 
-  void GetHref(nsAString& aValue)
-  {
-    GetURIAttr(nsGkAtoms::href, nullptr, aValue);
-  }
+  // The XPCOM GetHref is OK for us
   void SetHref(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::href, aValue, rv);
   }
-  void GetTarget(nsAString& aValue);
+  // The XPCOM GetTarget is OK for us
   void SetTarget(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::target, aValue, rv);
   }
   void GetDownload(DOMString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::download, aValue);
   }
   void SetDownload(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::download, aValue, rv);
   }
-  void GetPing(DOMString& aValue)
-  {
-    GetHTMLAttr(nsGkAtoms::ping, aValue);
-  }
+  // The XPCOM GetPing is OK for us
   void SetPing(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::ping, aValue, rv);
   }
   void GetRel(DOMString& 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(DOMString& aPolicy)
+  void GetReferrerPolicy(nsAString& aReferrer)
   {
-    GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aPolicy);
+    GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
   }
   nsDOMTokenList* RelList();
   void GetHreflang(DOMString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::hreflang, aValue);
   }
   void SetHreflang(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::hreflang, aValue, rv);
   }
-  // Needed for docshell
-  void GetType(nsAString& aValue)
-  {
-    GetHTMLAttr(nsGkAtoms::type, aValue);
-  }
   void GetType(DOMString& aValue)
   {
     GetHTMLAttr(nsGkAtoms::type, aValue);
   }
   void SetType(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::type, aValue, rv);
   }
-  void GetText(nsAString& aValue, mozilla::ErrorResult& rv);
-  void SetText(const nsAString& aValue, mozilla::ErrorResult& rv);
+  // The XPCOM GetText is OK for us
+  void SetText(const nsAString& aValue, mozilla::ErrorResult& rv)
+  {
+    rv = SetText(aValue);
+  }
 
   // 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
@@ -176,16 +170,17 @@ public:
   // Link::Link::SetPathname is OK for us
 
   // 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)
   {
     GetHTMLAttr(nsGkAtoms::coords, aValue);
   }
   void SetCoords(const nsAString& aValue, mozilla::ErrorResult& rv)
   {
     SetHTMLAttr(nsGkAtoms::coords, aValue, rv);
   }
@@ -220,17 +215,16 @@ public:
   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,17 +37,16 @@ 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,16 +3,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 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',
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/html/nsIDOMHTMLAnchorElement.idl
@@ -0,0 +1,55 @@
+/* -*- 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,31 +1,31 @@
 /* -*- 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/HTMLObjectElement.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"
@@ -936,17 +936,17 @@ PersistNodeFixup::FixupNode(nsIDOMNode *
     }
 
     nsCOMPtr<nsIContent> content = do_QueryInterface(aNodeIn);
     if (!content) {
         return NS_OK;
     }
 
     // Fix up href and file links in the elements
-    RefPtr<dom::HTMLAnchorElement> nodeAsAnchor = dom::HTMLAnchorElement::FromContent(content);
+    nsCOMPtr<nsIDOMHTMLAnchorElement> nodeAsAnchor = do_QueryInterface(aNodeIn);
     if (nodeAsAnchor) {
         rv = GetNodeToFixup(aNodeIn, aNodeOut);
         if (NS_SUCCEEDED(rv) && *aNodeOut) {
             FixupAnchor(*aNodeOut);
         }
         return rv;
     }
 
--- a/dom/webidl/HTMLAnchorElement.webidl
+++ b/dom/webidl/HTMLAnchorElement.webidl
@@ -26,17 +26,17 @@ interface HTMLAnchorElement : HTMLElemen
            attribute DOMString referrerPolicy;
            [PutForwards=value]
   readonly attribute DOMTokenList relList;
            [CEReactions, SetterThrows]
            attribute DOMString hreflang;
            [CEReactions, SetterThrows]
            attribute DOMString type;
 
-           [CEReactions, Throws]
+           [CEReactions, SetterThrows]
            attribute DOMString text;
 };
 
 HTMLAnchorElement implements HTMLHyperlinkElementUtils;
 
 // http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis
 partial interface HTMLAnchorElement {
            [CEReactions, SetterThrows]
--- 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,28 +331,24 @@ HTMLEditUtils::IsLink(nsIDOMNode *aNode)
   return node && IsLink(node);
 }
 
 bool
 HTMLEditUtils::IsLink(nsINode* aNode)
 {
   MOZ_ASSERT(aNode);
 
-  if (!aNode->IsContent()) {
-    return false;
+  nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aNode);
+  if (anchor) {
+    nsAutoString tmpText;
+    if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && !tmpText.IsEmpty()) {
+      return true;
+    }
   }
-
-  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContentOrNull(aNode->AsContent());
-  if (!anchor) {
-    return false;
-  }
-
-  nsAutoString tmpText;
-  anchor->GetHref(tmpText);
-  return !tmpText.IsEmpty();
+  return false;
 }
 
 bool
 HTMLEditUtils::IsNamedAnchor(nsIDOMNode *aNode)
 {
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   return node && IsNamedAnchor(node);
 }
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -22,16 +22,17 @@
 #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"
 
@@ -2588,31 +2589,29 @@ 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<nsIContent> content = do_QueryInterface(aAnchorElement);
-  RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContentOrNull(content);
+  nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aAnchorElement);
   if (!anchor) {
     return NS_OK;
   }
 
   nsAutoString href;
-  anchor->GetHref(href);
+  nsresult rv = anchor->GetHref(href);
+  NS_ENSURE_SUCCESS(rv, rv);
   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,16 +34,17 @@
 #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 "nsIDOMHTMLScriptElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDocument.h"
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -38,16 +38,17 @@
 #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"
@@ -75,17 +76,16 @@
 #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);
 
-      RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::FromContent(content);
+      nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(content));
       if (anchor) {
         anchor->GetTarget(aTarget);
       }
       NS_ADDREF(*aNode = content);
       break;
     }
   }
   return status;
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -99,16 +99,17 @@ 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,16 +40,17 @@
 #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"
@@ -315,16 +316,17 @@ 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),