Bug 1288590: Rename nsAttrInfo to mozilla::dom::BorrowedAttrInfo. r=bholley
authorEmilio Cobos Álvarez <ecoal95@gmail.com>
Fri, 22 Jul 2016 14:11:41 -0700
changeset 306948 fba6db64d336d8145e605a1304d266a5162bdd49
parent 306947 78313fb0c8f96140689286778bf040282f2c8100
child 306949 38583e7686b7a283daf83b30f29eb47bd1fc36a0
push id30502
push usercbook@mozilla.com
push dateThu, 28 Jul 2016 15:43:16 +0000
treeherdermozilla-central@9ec789c0ee5b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1288590
milestone50.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 1288590: Rename nsAttrInfo to mozilla::dom::BorrowedAttrInfo. r=bholley Unfortunately couldn't add all the debug checks that I'd want, since we can't assert that is not safe to run script in quite a few places :( MozReview-Commit-ID: 8m3Wm1WntZs
accessible/windows/sdn/sdnAccessible.cpp
dom/base/BorrowedAttrInfo.cpp
dom/base/BorrowedAttrInfo.h
dom/base/DocumentFragment.h
dom/base/Element.cpp
dom/base/Element.h
dom/base/moz.build
dom/base/nsAttrAndChildArray.cpp
dom/base/nsAttrAndChildArray.h
dom/base/nsAttrInfo.h
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsGenericDOMDataNode.cpp
dom/base/nsGenericDOMDataNode.h
dom/base/nsIContent.h
dom/base/nsXHTMLContentSerializer.cpp
dom/base/nsXMLContentSerializer.cpp
dom/html/HTMLMenuItemElement.cpp
dom/svg/SVGUseElement.cpp
dom/xbl/nsXBLBinding.cpp
dom/xbl/nsXBLPrototypeBinding.cpp
layout/style/ServoBindings.cpp
layout/style/ServoElementSnapshot.h
--- a/accessible/windows/sdn/sdnAccessible.cpp
+++ b/accessible/windows/sdn/sdnAccessible.cpp
@@ -14,16 +14,17 @@
 #include "nsIAccessibleTypes.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsNameSpaceManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWinUtils.h"
 #include "nsRange.h"
 
+#include "mozilla/dom/BorrowedAttrInfo.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 STDMETHODIMP
 sdnAccessible::QueryInterface(REFIID aREFIID, void** aInstancePtr)
 {
@@ -144,17 +145,17 @@ sdnAccessible::get_attributes(unsigned  
 
   *aNumAttribs = static_cast<unsigned short>(numAttribs);
 
   for (uint32_t index = 0; index < numAttribs; index++) {
     aNameSpaceIDs[index] = 0;
     aAttribValues[index] = aAttribNames[index] = nullptr;
     nsAutoString attributeValue;
 
-    nsAttrInfo attr = elm->GetAttrInfoAt(index);
+    dom::BorrowedAttrInfo attr = elm->GetAttrInfoAt(index);
     attr.mValue->ToString(attributeValue);
 
     aNameSpaceIDs[index] = static_cast<short>(attr.mName->NamespaceID());
     aAttribNames[index] = ::SysAllocString(attr.mName->LocalName()->GetUTF16String());
     aAttribValues[index] = ::SysAllocString(attributeValue.get());
   }
 
   return S_OK;
new file mode 100644
--- /dev/null
+++ b/dom/base/BorrowedAttrInfo.cpp
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/dom/BorrowedAttrInfo.h"
+
+namespace mozilla {
+namespace dom {
+
+BorrowedAttrInfo::BorrowedAttrInfo(const nsAttrName* aName,
+                                   const nsAttrValue* aValue)
+  : mName(aName)
+  , mValue(aValue)
+{
+  MOZ_ASSERT_IF(mName, mValue);
+}
+
+BorrowedAttrInfo::BorrowedAttrInfo(const BorrowedAttrInfo& aOther)
+  : mName(aOther.mName)
+  , mValue(aOther.mValue)
+{
+  MOZ_ASSERT_IF(mName, mValue);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/base/BorrowedAttrInfo.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 BorrowedAttrInfo_h__
+#define BorrowedAttrInfo_h__
+
+#include "mozilla/Assertions.h"
+
+class nsAttrName;
+class nsAttrValue;
+
+namespace mozilla {
+namespace dom {
+
+/**
+ * Struct that stores info on an attribute. The name and value must either both
+ * be null or both be non-null.
+ *
+ * Note that, just as the pointers returned by GetAttrNameAt, the pointers that
+ * this struct hold are only valid until the element or its attributes are
+ * mutated (directly or via script).
+ */
+struct BorrowedAttrInfo
+{
+  BorrowedAttrInfo()
+    : mName(nullptr)
+    , mValue(nullptr)
+  {
+  }
+
+  BorrowedAttrInfo(const nsAttrName* aName, const nsAttrValue* aValue);
+
+  BorrowedAttrInfo(const BorrowedAttrInfo& aOther);
+
+  const nsAttrName* mName;
+  const nsAttrValue* mValue;
+
+  explicit operator bool() const { return mName != nullptr; }
+};
+
+} // namespace dom
+} // namespace mozilla
+#endif
--- a/dom/base/DocumentFragment.h
+++ b/dom/base/DocumentFragment.h
@@ -3,19 +3,19 @@
 /* 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_DocumentFragment_h__
 #define mozilla_dom_DocumentFragment_h__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/BorrowedAttrInfo.h"
 #include "mozilla/dom/FragmentOrElement.h"
 #include "nsIDOMDocumentFragment.h"
-#include "nsAttrInfo.h"
 
 class nsIAtom;
 class nsAString;
 class nsIDocument;
 class nsIContent;
 
 namespace mozilla {
 namespace dom {
@@ -84,19 +84,19 @@ public:
                              bool aNotify) override
   {
     return NS_OK;
   }
   virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const override
   {
     return nullptr;
   }
-  virtual nsAttrInfo GetAttrInfoAt(uint32_t aIndex) const override
+  virtual BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const override
   {
-    return nsAttrInfo(nullptr, nullptr);
+    return BorrowedAttrInfo(nullptr, nullptr);
   }
   virtual uint32_t GetAttrCount() const override
   {
     return 0;
   }
 
   virtual bool IsNodeOfType(uint32_t aFlags) const override;
 
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -2200,17 +2200,17 @@ Element::MaybeCheckSameAttrVal(int32_t a
                                          this);
 
   // If we have no listeners and aNotify is false, we are almost certainly
   // coming from the content sink and will almost certainly have no previous
   // value.  Even if we do, setting the value is cheap when we have no
   // listeners and don't plan to notify.  The check for aNotify here is an
   // optimization, the check for *aHasListeners is a correctness issue.
   if (*aHasListeners || aNotify) {
-    nsAttrInfo info(GetAttrInfo(aNamespaceID, aName));
+    BorrowedAttrInfo info(GetAttrInfo(aNamespaceID, aName));
     if (info.mValue) {
       // Check whether the old value is the same as the new one.  Note that we
       // only need to actually _get_ the old value if we have listeners or
       // if the element is a custom element (because it may have an
       // attribute changed callback).
       if (*aHasListeners || GetCustomElementData()) {
         // Need to store the old value.
         //
@@ -2531,36 +2531,36 @@ Element::SetMappedAttribute(nsIDocument*
 EventListenerManager*
 Element::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
                                         bool* aDefer)
 {
   *aDefer = true;
   return GetOrCreateListenerManager();
 }
 
-nsAttrInfo
+BorrowedAttrInfo
 Element::GetAttrInfo(int32_t aNamespaceID, nsIAtom* aName) const
 {
   NS_ASSERTION(nullptr != aName, "must have attribute name");
   NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
                "must have a real namespace ID!");
 
   int32_t index = mAttrsAndChildren.IndexOfAttr(aName, aNamespaceID);
   if (index < 0) {
-    return nsAttrInfo(nullptr, nullptr);
+    return BorrowedAttrInfo(nullptr, nullptr);
   }
 
   return mAttrsAndChildren.AttrInfoAt(index);
 }
 
-nsAttrInfo
+BorrowedAttrInfo
 Element::GetAttrInfoAt(uint32_t aIndex) const
 {
   if (aIndex >= mAttrsAndChildren.AttrCount()) {
-    return nsAttrInfo(nullptr, nullptr);
+    return BorrowedAttrInfo(nullptr, nullptr);
   }
 
   return mAttrsAndChildren.AttrInfoAt(aIndex);
 }
 
 bool
 Element::GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                  nsAString& aResult) const
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -504,17 +504,17 @@ public:
                           nsCaseTreatment aCaseSensitive) const;
   virtual int32_t FindAttrValueIn(int32_t aNameSpaceID,
                                   nsIAtom* aName,
                                   AttrValuesArray* aValues,
                                   nsCaseTreatment aCaseSensitive) const override;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify) override;
   virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const override;
-  virtual nsAttrInfo GetAttrInfoAt(uint32_t aIndex) const override;
+  virtual BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const override;
   virtual uint32_t GetAttrCount() const override;
   virtual bool IsNodeOfType(uint32_t aFlags) const override;
 
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override
   {
     List(out, aIndent, EmptyCString());
   }
@@ -968,17 +968,17 @@ public:
   /**
    * Get the attr info for the given namespace ID and attribute name.  The
    * namespace ID must not be kNameSpaceID_Unknown and the name must not be
    * null.  Note that this can only return info on attributes that actually
    * live on this element (and is only virtual to handle XUL prototypes).  That
    * is, this should only be called from methods that only care about attrs
    * that effectively live in mAttrsAndChildren.
    */
-  virtual nsAttrInfo GetAttrInfo(int32_t aNamespaceID, nsIAtom* aName) const;
+  virtual BorrowedAttrInfo GetAttrInfo(int32_t aNamespaceID, nsIAtom* aName) const;
 
   virtual void NodeInfoChanged()
   {
   }
 
   /**
    * Parse a string into an nsAttrValue for a CORS attribute.  This
    * never fails.  The resulting value is an enumerated value whose
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -43,17 +43,16 @@ EXPORTS += [
     'AutocompleteFieldList.h',
     'Crypto.h',
     'HTMLSplitOnSpacesTokenizer.h',
     'IframeSandboxKeywordList.h',
     'mozAutoDocUpdate.h',
     'mozFlushType.h',
     'nsAtomListUtils.h',
     'nsAttrAndChildArray.h',
-    'nsAttrInfo.h',
     'nsAttrName.h',
     'nsAttrValue.h',
     'nsAttrValueInlines.h',
     'nsCaseTreatment.h',
     'nsChildContentList.h',
     'nsContentCID.h',
     'nsContentCreatorFunctions.h',
     'nsContentList.h',
@@ -148,16 +147,17 @@ EXPORTS.mozilla += [
 
 EXPORTS.mozilla.dom += [
     '!UseCounterList.h',
     'AnonymousContent.h',
     'Attr.h',
     'BarProps.h',
     'BlobSet.h',
     'BodyUtil.h',
+    'BorrowedAttrInfo.h',
     'ChildIterator.h',
     'ChromeNodeList.h',
     'ChromeUtils.h',
     'Comment.h',
     'CustomElementsRegistry.h',
     'DirectionalityUtils.h',
     'DocumentFragment.h',
     'DocumentType.h',
@@ -208,16 +208,17 @@ EXPORTS.mozilla.dom += [
 ]
 
 UNIFIED_SOURCES += [
     'AnonymousContent.cpp',
     'Attr.cpp',
     'BarProps.cpp',
     'BlobSet.cpp',
     'BodyUtil.cpp',
+    'BorrowedAttrInfo.cpp',
     'ChildIterator.cpp',
     'ChromeNodeList.cpp',
     'ChromeUtils.cpp',
     'Comment.cpp',
     'Crypto.cpp',
     'CustomElementsRegistry.cpp',
     'DirectionalityUtils.cpp',
     'DocumentFragment.cpp',
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -479,28 +479,28 @@ nsAttrAndChildArray::RemoveAttrAt(uint32
   RefPtr<nsMappedAttributes> mapped =
     GetModifiableMapped(nullptr, nullptr, false);
 
   mapped->RemoveAttrAt(aPos - nonmapped, aValue);
 
   return MakeMappedUnique(mapped);
 }
 
-nsAttrInfo
+BorrowedAttrInfo
 nsAttrAndChildArray::AttrInfoAt(uint32_t aPos) const
 {
   NS_ASSERTION(aPos < AttrCount(),
                "out-of-bounds access in nsAttrAndChildArray");
 
   uint32_t nonmapped = NonMappedAttrCount();
   if (aPos < nonmapped) {
-    return nsAttrInfo(&ATTRS(mImpl)[aPos].mName, &ATTRS(mImpl)[aPos].mValue);
+    return BorrowedAttrInfo(&ATTRS(mImpl)[aPos].mName, &ATTRS(mImpl)[aPos].mValue);
   }
 
-  return nsAttrInfo(mImpl->mMappedAttrs->NameAt(aPos - nonmapped),
+  return BorrowedAttrInfo(mImpl->mMappedAttrs->NameAt(aPos - nonmapped),
                     mImpl->mMappedAttrs->AttrAt(aPos - nonmapped));
 }
 
 const nsAttrName*
 nsAttrAndChildArray::AttrNameAt(uint32_t aPos) const
 {
   NS_ASSERTION(aPos < AttrCount(),
                "out-of-bounds access in nsAttrAndChildArray");
--- a/dom/base/nsAttrAndChildArray.h
+++ b/dom/base/nsAttrAndChildArray.h
@@ -9,19 +9,19 @@
  * the two is unified to minimize footprint.
  */
 
 #ifndef nsAttrAndChildArray_h___
 #define nsAttrAndChildArray_h___
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/dom/BorrowedAttrInfo.h"
 
 #include "nscore.h"
-#include "nsAttrInfo.h"
 #include "nsAttrName.h"
 #include "nsAttrValue.h"
 #include "nsCaseTreatment.h"
 
 class nsINode;
 class nsIContent;
 class nsMappedAttributes;
 class nsHTMLStyleSheet;
@@ -42,16 +42,17 @@ class nsMappedAttributeElement;
 #define ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK \
     ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
 
 
 #define ATTRSIZE (sizeof(InternalAttr) / sizeof(void*))
 
 class nsAttrAndChildArray
 {
+  typedef mozilla::dom::BorrowedAttrInfo BorrowedAttrInfo;
 public:
   nsAttrAndChildArray();
   ~nsAttrAndChildArray();
 
   uint32_t ChildCount() const
   {
     return mImpl ? (mImpl->mAttrAndChildCount >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) : 0;
   }
@@ -96,17 +97,17 @@ public:
   // Remove the attr at position aPos.  The value of the attr is placed in
   // aValue; any value that was already in aValue is destroyed.
   nsresult RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue);
 
   // Returns attribute name at given position, *not* out-of-bounds safe
   const nsAttrName* AttrNameAt(uint32_t aPos) const;
 
   // Returns the attribute info at a given position, *not* out-of-bounds safe
-  nsAttrInfo AttrInfoAt(uint32_t aPos) const;
+  BorrowedAttrInfo AttrInfoAt(uint32_t aPos) const;
 
   // Returns attribute name at given position or null if aPos is out-of-bounds
   const nsAttrName* GetSafeAttrNameAt(uint32_t aPos) const;
 
   const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
   int32_t IndexOfAttr(nsIAtom* aLocalName, int32_t aNamespaceID = kNameSpaceID_None) const;
 
   nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
deleted file mode 100644
--- a/dom/base/nsAttrInfo.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 nsAttrInfo_h__
-#define nsAttrInfo_h__
-
-#include "mozilla/Assertions.h"
-
-class nsAttrName;
-class nsAttrValue;
-
-/**
- * Struct that stores info on an attribute. The name and value must
- * either both be null or both be non-null.
- */
-struct nsAttrInfo
-{
-  nsAttrInfo()
-    : mName(nullptr)
-    , mValue(nullptr)
-  {
-  }
-
-  nsAttrInfo(const nsAttrName* aName, const nsAttrValue* aValue)
-    : mName(aName)
-    , mValue(aValue)
-  {
-    MOZ_ASSERT_IF(aName, aValue);
-  }
-
-  nsAttrInfo(const nsAttrInfo& aOther)
-    : mName(aOther.mName)
-    , mValue(aOther.mValue)
-  {
-  }
-
-  const nsAttrName* mName;
-  const nsAttrValue* mValue;
-
-  explicit operator bool() const { return mName != nullptr; }
-};
-
-#endif
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -4440,17 +4440,17 @@ nsContentUtils::CreateContextualFragment
 
     // see if we need to add xmlns declarations
     uint32_t count = content->GetAttrCount();
     bool setDefaultNamespace = false;
     if (count > 0) {
       uint32_t index;
 
       for (index = 0; index < count; index++) {
-        const nsAttrInfo info = content->GetAttrInfoAt(index);
+        const BorrowedAttrInfo info = content->GetAttrInfoAt(index);
         const nsAttrName* name = info.mName;
         if (name->NamespaceEquals(kNameSpaceID_XMLNS)) {
           info.mValue->ToString(uriStr);
 
           // really want something like nsXMLContentSerializer::SerializeAttr
           tagName.AppendLiteral(" xmlns"); // space important
           if (name->GetPrefix()) {
             tagName.Append(char16_t(':'));
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -641,17 +641,17 @@ public:
    * @return true if aContent has an attribute aName in namespace aNameSpaceID,
    * and the attribute value is non-empty.
    */
   static bool HasNonEmptyAttr(const nsIContent* aContent, int32_t aNameSpaceID,
                                 nsIAtom* aName);
 
   /**
    * Method that gets the primary presContext for the node.
-   * 
+   *
    * @param aContent The content node.
    * @return the presContext, or nullptr if the content is not in a document
    *         (if GetCurrentDoc returns nullptr)
    */
   static nsPresContext* GetContextForContent(const nsIContent* aContent);
 
   /**
    * Method to do security and content policy checks on the image URI
--- a/dom/base/nsGenericDOMDataNode.cpp
+++ b/dom/base/nsGenericDOMDataNode.cpp
@@ -642,20 +642,20 @@ nsGenericDOMDataNode::UnsetAttr(int32_t 
 }
 
 const nsAttrName*
 nsGenericDOMDataNode::GetAttrNameAt(uint32_t aIndex) const
 {
   return nullptr;
 }
 
-nsAttrInfo
+BorrowedAttrInfo
 nsGenericDOMDataNode::GetAttrInfoAt(uint32_t aIndex) const
 {
-  return nsAttrInfo(nullptr, nullptr);
+  return BorrowedAttrInfo(nullptr, nullptr);
 }
 
 uint32_t
 nsGenericDOMDataNode::GetAttrCount() const
 {
   return 0;
 }
 
--- a/dom/base/nsGenericDOMDataNode.h
+++ b/dom/base/nsGenericDOMDataNode.h
@@ -118,17 +118,17 @@ public:
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                            nsIAtom* aPrefix, const nsAString& aValue,
                            bool aNotify) override;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify) override;
   virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const override;
-  virtual nsAttrInfo GetAttrInfoAt(uint32_t aIndex) const override;
+  virtual mozilla::dom::BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const override;
   virtual uint32_t GetAttrCount() const override;
   virtual const nsTextFragment *GetText() override;
   virtual uint32_t TextLength() const override;
   virtual nsresult SetText(const char16_t* aBuffer, uint32_t aLength,
                            bool aNotify) override;
   // Need to implement this here too to avoid hiding.
   nsresult SetText(const nsAString& aStr, bool aNotify)
   {
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -2,17 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 nsIContent_h___
 #define nsIContent_h___
 
 #include "mozilla/Attributes.h"
-#include "nsAttrInfo.h"
+#include "mozilla/dom/BorrowedAttrInfo.h"
 #include "nsCaseTreatment.h" // for enum, cannot be forward-declared
 #include "nsINode.h"
 
 // Forward declarations
 class nsAString;
 class nsIAtom;
 class nsIURI;
 class nsRuleWalker;
@@ -463,17 +463,17 @@ public:
    * @note    The pointer returned by this function is only valid until the
    *          next call of either GetAttrNameAt or SetAttr on the element.
    */
   virtual const nsAttrName* GetAttrNameAt(uint32_t aIndex) const = 0;
 
   /**
    * Gets the attribute info (name and value) for this content at a given index.
    */
-  virtual nsAttrInfo GetAttrInfoAt(uint32_t aIndex) const = 0;
+  virtual mozilla::dom::BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const = 0;
 
   /**
    * Get the number of all specified attributes.
    *
    * @return the number of attributes
    */
   virtual uint32_t GetAttrCount() const = 0;
 
--- a/dom/base/nsXHTMLContentSerializer.cpp
+++ b/dom/base/nsXHTMLContentSerializer.cpp
@@ -301,17 +301,17 @@ nsXHTMLContentSerializer::SerializeAttri
   // XXX Unfortunately we need a namespace manager to get
   // attribute URIs.
   for (index = 0; index < count; index++) {
 
     if (aSkipAttr == index) {
         continue;
     }
 
-    nsAttrInfo info = aContent->GetAttrInfoAt(index);
+    BorrowedAttrInfo info = aContent->GetAttrInfoAt(index);
     const nsAttrName* name = info.mName;
 
     int32_t namespaceID = name->NamespaceID();
     nsIAtom* attrName = name->LocalName();
     nsIAtom* attrPrefix = name->GetPrefix();
 
     // Filter out any attribute starting with [-|_]moz
     nsDependentAtomString attrNameStr(attrName);
--- a/dom/base/nsXMLContentSerializer.cpp
+++ b/dom/base/nsXMLContentSerializer.cpp
@@ -725,17 +725,17 @@ nsXMLContentSerializer::ScanNamespaceDec
   nsAutoString uriStr, valueStr;
 
   count = aContent->GetAttrCount();
 
   // First scan for namespace declarations, pushing each on the stack
   uint32_t skipAttr = count;
   for (index = 0; index < count; index++) {
 
-    const nsAttrInfo info = aContent->GetAttrInfoAt(index);
+    const BorrowedAttrInfo info = aContent->GetAttrInfoAt(index);
     const nsAttrName* name = info.mName;
 
     int32_t namespaceID = name->NamespaceID();
     nsIAtom *attrName = name->LocalName();
 
     if (namespaceID == kNameSpaceID_XMLNS ||
         // Also push on the stack attrs named "xmlns" in the null
         // namespace... because once we serialize those out they'll look like
--- a/dom/html/HTMLMenuItemElement.cpp
+++ b/dom/html/HTMLMenuItemElement.cpp
@@ -411,30 +411,30 @@ void
 HTMLMenuItemElement::WalkRadioGroup(Visitor* aVisitor)
 {
   nsIContent* parent = GetParent();
   if (!parent) {
     aVisitor->Visit(this);
     return;
   }
 
-  nsAttrInfo info1(GetAttrInfo(kNameSpaceID_None,
+  BorrowedAttrInfo info1(GetAttrInfo(kNameSpaceID_None,
                                nsGkAtoms::radiogroup));
   bool info1Empty = !info1.mValue || info1.mValue->IsEmptyString();
 
   for (nsIContent* cur = parent->GetFirstChild();
        cur;
        cur = cur->GetNextSibling()) {
     HTMLMenuItemElement* menuitem = HTMLMenuItemElement::FromContent(cur);
 
     if (!menuitem || menuitem->GetType() != CMD_TYPE_RADIO) {
       continue;
     }
 
-    nsAttrInfo info2(menuitem->GetAttrInfo(kNameSpaceID_None,
+    BorrowedAttrInfo info2(menuitem->GetAttrInfo(kNameSpaceID_None,
                                            nsGkAtoms::radiogroup));
     bool info2Empty = !info2.mValue || info2.mValue->IsEmptyString();
 
     if (info1Empty != info2Empty ||
         (info1.mValue && info2.mValue && !info1.mValue->Equals(*info2.mValue))) {
       continue;
     }
 
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -296,17 +296,17 @@ SVGUseElement::CreateAnonymousContent()
     nsCOMPtr<nsIContent> svgNode;
     NS_NewSVGSVGElement(getter_AddRefs(svgNode), nodeInfo.forget(),
                         NOT_FROM_PARSER);
 
     if (!svgNode)
       return nullptr;
 
     // copy attributes
-    nsAttrInfo info;
+    BorrowedAttrInfo info;
     uint32_t i;
     for (i = 0; (info = newcontent->GetAttrInfoAt(i)); i++) {
       nsAutoString value;
       int32_t nsID = info.mName->NamespaceID();
       nsIAtom* lname = info.mName->LocalName();
 
       info.mValue->ToString(value);
 
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -401,17 +401,17 @@ nsXBLBinding::GenerateAnonymousContent()
     }
 
     mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent);
   }
 
   // Always check the content element for potential attributes.
   // This shorthand hack always happens, even when we didn't
   // build anonymous content.
-  nsAttrInfo attrInfo;
+  BorrowedAttrInfo attrInfo;
   for (uint32_t i = 0; (attrInfo = content->GetAttrInfoAt(i)); ++i) {
     int32_t namespaceID = attrInfo.mName->NamespaceID();
     // Hold a strong reference here so that the atom doesn't go away during
     // UnsetAttr.
     nsCOMPtr<nsIAtom> name = attrInfo.mName->LocalName();
 
     if (name != nsGkAtoms::includes) {
       if (!nsContentUtils::HasNonEmptyAttr(mBoundElement, namespaceID, name)) {
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -1120,17 +1120,17 @@ nsXBLPrototypeBinding::Write(nsIObjectOu
 
   aStream->Write8(XBLBinding_Serialize_NoMoreItems);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (mBinding) {
     uint32_t attributes = mBinding->GetAttrCount();
     nsAutoString attrValue;
     for (uint32_t i = 0; i < attributes; ++i) {
-      nsAttrInfo attrInfo = mBinding->GetAttrInfoAt(i);
+      BorrowedAttrInfo attrInfo = mBinding->GetAttrInfoAt(i);
       const nsAttrName* name = attrInfo.mName;
       nsDependentAtomString attrName(attrInfo.mName->LocalName());
       attrInfo.mValue->ToString(attrValue);
 
       rv = aStream->Write8(XBLBinding_Serialize_Attribute);
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = WriteNamespace(aStream, name->NamespaceID());
@@ -1410,17 +1410,17 @@ nsXBLPrototypeBinding::WriteContentNode(
   rv = aStream->Write32(count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t i;
   for (i = 0; i < count; i++) {
     // Write out the namespace id, the namespace prefix, the local tag name,
     // and the value, in that order.
 
-    const nsAttrInfo attrInfo = aNode->GetAttrInfoAt(i);
+    const BorrowedAttrInfo attrInfo = aNode->GetAttrInfoAt(i);
     const nsAttrName* name = attrInfo.mName;
 
     // XXXndeakin don't write out xbl:inherits?
     int32_t namespaceID = name->NamespaceID();
     rv = WriteNamespace(aStream, namespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsAutoString prefixStr;
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -208,17 +208,17 @@ DoMatch(Implementor* aElement, nsIAtom* 
 {
   if (aNS) {
     int32_t ns = nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNS);
     NS_ENSURE_TRUE(ns != kNameSpaceID_Unknown, false);
     const nsAttrValue* value = aElement->GetParsedAttr(aName, ns);
     return value && aMatch(value);
   }
   // No namespace means any namespace - we have to check them all. :-(
-  nsAttrInfo attrInfo;
+  BorrowedAttrInfo attrInfo;
   for (uint32_t i = 0; (attrInfo = aElement->GetAttrInfoAt(i)); ++i) {
     if (attrInfo.mName->LocalName() != aName) {
       continue;
     }
     if (aMatch(attrInfo.mValue)) {
       return true;
     }
   }
--- a/layout/style/ServoElementSnapshot.h
+++ b/layout/style/ServoElementSnapshot.h
@@ -4,19 +4,19 @@
  * 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_ServoElementSnapshot_h
 #define mozilla_ServoElementSnapshot_h
 
 #include "mozilla/EventStates.h"
 #include "mozilla/TypedEnumBits.h"
+#include "mozilla/dom/BorrowedAttrInfo.h"
 #include "nsAttrName.h"
 #include "nsAttrValue.h"
-#include "nsAttrInfo.h"
 #include "nsChangeHint.h"
 #include "nsIAtom.h"
 
 namespace mozilla {
 
 namespace dom {
 class Element;
 } // namespace dom
@@ -56,16 +56,17 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Se
  * This class holds all non-tree-structural state of an element that might be
  * used for selector matching eventually.
  *
  * This means the attributes, and the element state, such as :hover, :active,
  * etc...
  */
 class ServoElementSnapshot
 {
+  typedef dom::BorrowedAttrInfo BorrowedAttrInfo;
   typedef dom::Element Element;
   typedef EventStates::ServoType ServoStateType;
 
 public:
   typedef ServoElementSnapshotFlags Flags;
 
   /**
    * Empty snapshot, with no data at all.
@@ -111,22 +112,22 @@ public:
 
   nsRestyleHint ExplicitRestyleHint() { return mExplicitRestyleHint; }
 
   nsChangeHint ExplicitChangeHint() { return mExplicitChangeHint; }
 
   /**
    * Needed methods for attribute matching.
    */
-  nsAttrInfo GetAttrInfoAt(uint32_t aIndex) const
+  BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const
   {
     if (aIndex >= mAttrs.Length()) {
-      return nsAttrInfo(nullptr, nullptr);
+      return BorrowedAttrInfo(nullptr, nullptr);
     }
-    return nsAttrInfo(&mAttrs[aIndex].mName, &mAttrs[aIndex].mValue);
+    return BorrowedAttrInfo(&mAttrs[aIndex].mName, &mAttrs[aIndex].mValue);
   }
 
   const nsAttrValue* GetParsedAttr(nsIAtom* aLocalName) const
   {
     return GetParsedAttr(aLocalName, kNameSpaceID_None);
   }
 
   const nsAttrValue* GetParsedAttr(nsIAtom* aLocalName,