Bug 1451823 - support ping, rel, referrerPolicy, relList, hreflang, type and text on SVG a elements r=mystor
authorRobert Longson <longsonr@gmail.com>
Sat, 14 Apr 2018 14:53:37 +0100
changeset 466899 a1d4a3e6c77a29e7e63d5e88f5b4859b113df943
parent 466898 91406356569ce2b32ed48486cc516f490eec1ab8
child 466900 10a300d81060300bbedb3a870c7852b87738a87d
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmystor
bugs1451823
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1451823 - support ping, rel, referrerPolicy, relList, hreflang, type and text on SVG a elements r=mystor
dom/svg/SVGAElement.cpp
dom/svg/SVGAElement.h
dom/svg/nsSVGElement.cpp
dom/webidl/SVGAElement.webidl
testing/web-platform/tests/dom/lists/DOMTokenList-coverage-for-attributes.html
--- a/dom/svg/SVGAElement.cpp
+++ b/dom/svg/SVGAElement.cpp
@@ -29,26 +29,36 @@ SVGAElement::WrapNode(JSContext *aCx, JS
 
 nsSVGElement::StringInfo SVGAElement::sStringInfo[3] =
 {
   { &nsGkAtoms::href, kNameSpaceID_None, true },
   { &nsGkAtoms::href, kNameSpaceID_XLink, true },
   { &nsGkAtoms::target, kNameSpaceID_None, true }
 };
 
+// static
+const DOMTokenListSupportedToken SVGAElement::sSupportedRelValues[] = {
+  "noreferrer",
+  "noopener",
+  nullptr
+};
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_INTERFACE_MAP_BEGIN(SVGAElement)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAElement)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
   NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
   NS_INTERFACE_MAP_ENTRY(Link)
 NS_INTERFACE_MAP_END_INHERITING(SVGAElementBase)
 
+NS_IMPL_CYCLE_COLLECTION_INHERITED(SVGAElement,
+                                   SVGAElementBase,
+                                   mRelList)
+
 NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGAElement::SVGAElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : SVGAElementBase(aNodeInfo)
@@ -113,16 +123,96 @@ SVGAElement::GetDownload(nsAString& aDow
 }
 
 void
 SVGAElement::SetDownload(const nsAString& aDownload, ErrorResult& rv)
 {
   SetAttr(nsGkAtoms::download, aDownload, rv);
 }
 
+void
+SVGAElement::GetPing(nsAString& aPing)
+{
+  GetAttr(nsGkAtoms::ping, aPing);
+}
+
+void
+SVGAElement::SetPing(const nsAString& aPing, ErrorResult& rv)
+{
+  SetAttr(nsGkAtoms::ping, aPing, rv);
+}
+
+void
+SVGAElement::GetRel(nsAString& aRel)
+{
+  GetAttr(nsGkAtoms::rel, aRel);
+}
+
+void
+SVGAElement::SetRel(const nsAString& aRel, ErrorResult& rv)
+{
+  SetAttr(nsGkAtoms::rel, aRel, rv);
+}
+
+void
+SVGAElement::GetReferrerPolicy(nsAString& aPolicy)
+{
+  GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aPolicy);
+}
+
+void
+SVGAElement::SetReferrerPolicy(const nsAString& aPolicy,
+                               mozilla::ErrorResult& rv)
+{
+  SetAttr(nsGkAtoms::referrerpolicy, aPolicy, rv);
+}
+
+nsDOMTokenList*
+SVGAElement:: RelList()
+{
+  if (!mRelList) {
+    mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
+  }
+  return mRelList;
+}
+
+void
+SVGAElement::GetHreflang(nsAString& aHreflang)
+{
+  GetAttr(nsGkAtoms::hreflang, aHreflang);
+}
+
+void
+SVGAElement::SetHreflang(const nsAString& aHreflang, mozilla::ErrorResult& rv)
+{
+  SetAttr(nsGkAtoms::hreflang, aHreflang, rv);
+}
+
+void SVGAElement::GetType(nsAString& aType)
+{
+  GetAttr(nsGkAtoms::type, aType);
+}
+
+void SVGAElement::SetType(const nsAString& aType, mozilla::ErrorResult& rv)
+{
+  SetAttr(nsGkAtoms::type, aType, rv);
+}
+
+void SVGAElement::GetText(nsAString& aText, mozilla::ErrorResult& rv)
+{
+  if (NS_WARN_IF(!nsContentUtils::GetNodeTextContent(this, true, aText, fallible))) {
+    rv.Throw(NS_ERROR_OUT_OF_MEMORY);
+  }
+}
+
+void SVGAElement::SetText(const nsAString& aText, mozilla::ErrorResult& rv)
+{
+  rv = nsContentUtils::SetNodeTextContent(this, aText, false);
+}
+
 //----------------------------------------------------------------------
 // nsIContent methods
 
 nsresult
 SVGAElement::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                         nsIContent *aBindingParent,
                         bool aCompileEventHandlers)
 {
--- a/dom/svg/SVGAElement.h
+++ b/dom/svg/SVGAElement.h
@@ -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/. */
 
 #ifndef mozilla_dom_SVGAElement_h
 #define mozilla_dom_SVGAElement_h
 
 #include "Link.h"
+#include "nsDOMTokenList.h"
 #include "nsSVGString.h"
 #include "mozilla/dom/SVGGraphicsElement.h"
 
 nsresult NS_NewSVGAElement(nsIContent **aResult,
                            already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 
@@ -22,24 +23,28 @@ class EventChainPreVisitor;
 namespace dom {
 
 typedef SVGGraphicsElement SVGAElementBase;
 
 class SVGAElement final : public SVGAElementBase,
                           public Link
 {
 protected:
+  using Element::GetText;
+
   explicit SVGAElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
   friend nsresult (::NS_NewSVGAElement(nsIContent **aResult,
                                        already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGAElement, SVGAElementBase)
+
   // nsINode interface methods
   void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
   virtual nsresult PostHandleEvent(
                      EventChainPostVisitor& aVisitor) override;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
                          bool aPreallocateChildren) const override;
 
   // nsIContent
@@ -62,31 +67,47 @@ public:
                                 bool aNotify) override;
 
   // Link
   virtual bool ElementHasHref() const override;
 
   // WebIDL
   already_AddRefed<SVGAnimatedString> Href();
   already_AddRefed<SVGAnimatedString> Target();
-  void GetDownload(nsAString & aDownload);
-  void SetDownload(const nsAString & aDownload, ErrorResult& rv);
+  void GetDownload(nsAString& aDownload);
+  void SetDownload(const nsAString& aDownload, ErrorResult& rv);
+  void GetPing(nsAString& aPing);
+  void SetPing(const nsAString& aPing, mozilla::ErrorResult& rv);
+  void GetRel(nsAString& aRel);
+  void SetRel(const nsAString& aRel, mozilla::ErrorResult& rv);
+  void SetReferrerPolicy(const nsAString& aReferrerPolicy, mozilla::ErrorResult& rv);
+  void GetReferrerPolicy(nsAString& aReferrerPolicy);
+  nsDOMTokenList* RelList();
+  void GetHreflang(nsAString& aHreflang);
+  void SetHreflang(const nsAString& aHreflang, mozilla::ErrorResult& rv);
+  void GetType(nsAString& aType);
+  void SetType(const nsAString& aType, mozilla::ErrorResult& rv);
+  void GetText(nsAString& aText, mozilla::ErrorResult& rv);
+  void SetText(const nsAString& aText, mozilla::ErrorResult& rv);
 
   void NodeInfoChanged(nsIDocument* aOldDoc) final
   {
     ClearHasPendingLinkUpdate();
     SVGAElementBase::NodeInfoChanged(aOldDoc);
   }
 
 protected:
   virtual ~SVGAElement();
 
   virtual StringAttributesInfo GetStringInfo() override;
 
   enum { HREF, XLINK_HREF, TARGET };
   nsSVGString mStringAttributes[3];
   static StringInfo sStringInfo[3];
+
+  RefPtr<nsDOMTokenList> mRelList;
+  static DOMTokenListSupportedToken sSupportedRelValues[];
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_SVGAElement_h
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -621,16 +621,21 @@ nsSVGElement::ParseAttribute(int32_t aNa
       }
     }
 
     if (aAttribute == nsGkAtoms::_class) {
       mClassAttribute.SetBaseValue(aValue, this, false);
       aResult.ParseAtomArray(aValue);
       return true;
     }
+
+    if (aAttribute == nsGkAtoms::rel) {
+      aResult.ParseAtomArray(aValue);
+      return true;
+    }
   }
 
   if (!foundMatch) {
     // Check for nsSVGString attribute
     StringAttributesInfo stringInfo = GetStringInfo();
     for (uint32_t i = 0; i < stringInfo.mStringCount; i++) {
       if (aNamespaceID == stringInfo.mStringInfo[i].mNamespaceID &&
           aAttribute == *stringInfo.mStringInfo[i].mName) {
--- a/dom/webidl/SVGAElement.webidl
+++ b/dom/webidl/SVGAElement.webidl
@@ -10,12 +10,27 @@
  * liability, trademark and document use rules apply.
  */
 
 interface SVGAElement : SVGGraphicsElement {
   readonly attribute SVGAnimatedString target;
 
   [SetterThrows]
   attribute DOMString download;
+  [SetterThrows]
+  attribute DOMString ping;
+  [SetterThrows]
+  attribute DOMString rel;
+  [SetterThrows]
+  attribute DOMString referrerPolicy;
+  [PutForwards=value]
+  readonly attribute DOMTokenList relList;
+  [SetterThrows]
+  attribute DOMString hreflang;
+  [SetterThrows]
+  attribute DOMString type;
+
+  [Throws]
+  attribute DOMString text;
 };
 
 SVGAElement implements SVGURIReference;
 
--- a/testing/web-platform/tests/dom/lists/DOMTokenList-coverage-for-attributes.html
+++ b/testing/web-platform/tests/dom/lists/DOMTokenList-coverage-for-attributes.html
@@ -5,33 +5,38 @@
 <script src="/resources/testharnessreport.js"></script>
 <div id=log></div>
 <script>
 "use strict";
 
 var pairs = [
   // Defined in DOM
   {attr: "classList", sup: ["anyElement"]},
+  // Defined in HTML except for a which is also SVG
+  {attr: "relList", sup: ["a", "area", "link"]},
   // Defined in HTML
   {attr: "htmlFor", sup: ["output"]},
-  {attr: "relList", sup: ["a", "area", "link"]},
   {attr: "sandbox", sup: ["iframe"]},
   {attr: "sizes", sup: ["link"]}
 ];
 var namespaces = [
   "http://www.w3.org/1999/xhtml",
   "http://www.w3.org/2000/svg",
   "http://www.w3.org/1998/Math/MathML",
   "http://example.com/",
   ""
 ];
 
 var elements = ["a", "area", "link", "iframe", "output", "td", "th"];
 function testAttr(pair, new_el){
-  return (pair.attr === "classList" || (new_el.namespaceURI === "http://www.w3.org/1999/xhtml" && pair.sup.indexOf(new_el.localName) != -1));
+  return (pair.attr === "classList" ||
+          (pair.attr === "relList" && new_el.localName === "a" &&
+           new_el.namespaceURI === "http://www.w3.org/2000/svg") ||
+          (new_el.namespaceURI === "http://www.w3.org/1999/xhtml" &&
+           pair.sup.indexOf(new_el.localName) != -1));
 }
 
 pairs.forEach(function(pair) {
   namespaces.forEach(function(ns) {
     elements.forEach(function(el) {
       var new_el = document.createElementNS(ns, el);
       if (testAttr(pair, new_el)) {
         test(function() {