Bug 1365092 - Moves side effects of HTMLAnchorElement's SetAttr, UnsetAttr, and ParseAttribute functions to the corresponding BeforeSetAttr and AfterSetAttr functions draft
authorKirk Steuber <ksteuber@mozilla.com>
Thu, 01 Jun 2017 09:33:30 -0700
changeset 589816 6970a0afa8a0b0ba7d0b44a5df85714dc4ccf091
parent 589815 4a665365caddcc308a5c09776b0ec1806b7194a7
child 589817 fbf89c086f1d4a0e958f54a8af898b9c6015ffab
push id62532
push userksteuber@mozilla.com
push dateTue, 06 Jun 2017 22:24:10 +0000
bugs1365092
milestone55.0a1
Bug 1365092 - Moves side effects of HTMLAnchorElement's SetAttr, UnsetAttr, and ParseAttribute functions to the corresponding BeforeSetAttr and AfterSetAttr functions This is necessary to facilitate the transition to cloning attributes instead of reparsing them. MozReview-Commit-ID: 2SZcYqWGJF6
dom/html/HTMLAnchorElement.cpp
dom/html/HTMLAnchorElement.h
--- a/dom/html/HTMLAnchorElement.cpp
+++ b/dom/html/HTMLAnchorElement.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/dom/HTMLAnchorElementBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/MemoryReporting.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLDNSPrefetch.h"
+#include "nsAttrValueOrString.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIURI.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
 
 namespace mozilla {
@@ -360,94 +361,47 @@ HTMLAnchorElement::GetHrefURI() const
   if (uri) {
     return uri.forget();
   }
 
   return GetHrefURIForAnchors();
 }
 
 nsresult
-HTMLAnchorElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                           nsIAtom* aPrefix, const nsAString& aValue,
-                           bool aNotify)
+HTMLAnchorElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
+                                 const nsAttrValueOrString* aValue,
+                                 bool aNotify)
 {
-  bool reset = false;
-  if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
-    // If we do not have a cached URI, we have some value here so we must reset
-    // our link state after calling the parent.
-    if (!Link::HasCachedURI()) {
-      reset = true;
-    }
-    // However, if we have a cached URI, we'll want to see if the value changed.
-    else {
-      nsAutoString val;
-      GetHref(val);
-      if (!val.Equals(aValue)) {
-        reset = true;
-      }
-    }
-    if (reset) {
+  if (aNamespaceID == kNameSpaceID_None) {
+    if (aName == nsGkAtoms::href) {
       CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
                         HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
     }
   }
 
-  nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
-                                              aValue, aNotify);
-
-  // The ordering of the parent class's SetAttr call and Link::ResetLinkState
-  // is important here!  The attribute is not set until SetAttr returns, and
-  // we will need the updated attribute value because notifying the document
-  // that content states have changed will call IntrinsicState, which will try
-  // to get updated information about the visitedness from Link.
-  if (reset) {
-    Link::ResetLinkState(!!aNotify, true);
-    if (IsInComposedDoc()) {
-      TryDNSPrefetch();
-    }
-  }
-
-  return rv;
+  return nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue,
+                                             aNotify);
 }
 
 nsresult
-HTMLAnchorElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify)
+HTMLAnchorElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
+                                const nsAttrValue* aValue,
+                                const nsAttrValue* aOldValue, bool aNotify)
 {
-  bool href =
-    (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID);
-
-  if (href) {
-    CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
-                      HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
+  if (aNamespaceID == kNameSpaceID_None) {
+    if (aName == nsGkAtoms::href) {
+      Link::ResetLinkState(aNotify, !!aValue);
+      if (aValue && IsInComposedDoc()) {
+        TryDNSPrefetch();
+      }
+    }
   }
 
-  nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
-                                                aNotify);
-
-  // The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
-  // is important here!  The attribute is not unset until UnsetAttr returns, and
-  // we will need the updated attribute value because notifying the document
-  // that content states have changed will call IntrinsicState, which will try
-  // to get updated information about the visitedness from Link.
-  if (href) {
-    Link::ResetLinkState(!!aNotify, false);
-  }
-
-  return rv;
-}
-
-bool
-HTMLAnchorElement::ParseAttribute(int32_t aNamespaceID,
-                                  nsIAtom* aAttribute,
-                                  const nsAString& aValue,
-                                  nsAttrValue& aResult)
-{
-  return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
-                                              aResult);
+  return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName,
+                                            aValue, aOldValue, aNotify);
 }
 
 EventStates
 HTMLAnchorElement::IntrinsicState() const
 {
   return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
 }
 
--- a/dom/html/HTMLAnchorElement.h
+++ b/dom/html/HTMLAnchorElement.h
@@ -61,30 +61,23 @@ public:
   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;
 
-  nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                   const nsAString& aValue, bool aNotify)
-  {
-    return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
-  }
-  virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
-                           nsIAtom* aPrefix, const nsAString& aValue,
-                           bool aNotify) override;
-  virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify) override;
-  virtual bool ParseAttribute(int32_t aNamespaceID,
-                                nsIAtom* aAttribute,
-                                const nsAString& aValue,
-                                nsAttrValue& aResult) override;
+  virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
+                                 const nsAttrValueOrString* aValue,
+                                 bool aNotify) override;
+  virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
+                                const nsAttrValue* aValue,
+                                const nsAttrValue* aOldValue,
+                                bool aNotify) override;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
                          bool aPreallocateChildren) const override;
 
   virtual EventStates IntrinsicState() const override;
 
   virtual void OnDNSPrefetchDeferred() override;
   virtual void OnDNSPrefetchRequested() override;