Bug 1338725 part 1. Change the matcher functions used for nsContentList to take an Element argument, not nsIContent. r=baku
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 13 Feb 2017 16:06:45 -0500
changeset 483380 2823220fff5ef2515da52266205d6e218a76bc46
parent 483379 45dd83a63162363fe69af8e65e8a79b24827ce38
child 483381 9624f564d36d2194d49a31127c2d5ca67b06f2e0
push id45320
push userhchang@mozilla.com
push dateTue, 14 Feb 2017 10:04:40 +0000
reviewersbaku
bugs1338725
milestone54.0a1
Bug 1338725 part 1. Change the matcher functions used for nsContentList to take an Element argument, not nsIContent. r=baku
dom/base/nsContentListDeclarations.h
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/html/HTMLAllCollection.cpp
dom/html/HTMLDataListElement.cpp
dom/html/HTMLDataListElement.h
dom/html/HTMLFieldSetElement.cpp
dom/html/HTMLFieldSetElement.h
dom/html/HTMLSelectElement.cpp
dom/html/HTMLSelectElement.h
dom/html/HTMLTableRowElement.cpp
dom/html/nsHTMLDocument.cpp
dom/html/nsHTMLDocument.h
dom/xul/XULDocument.cpp
dom/xul/XULDocument.h
--- a/dom/base/nsContentListDeclarations.h
+++ b/dom/base/nsContentListDeclarations.h
@@ -13,25 +13,31 @@
 class nsContentList;
 class nsIAtom;
 class nsIContent;
 class nsINode;
 // Can't use nsStringFwd.h because that's internal-API-only.
 class nsString;
 class nsAString;
 
+namespace mozilla {
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
+
 // Magic namespace id that means "match all namespaces".  This is
 // negative so it won't collide with actual namespace constants.
 #define kNameSpaceID_Wildcard INT32_MIN
 
 // This is a callback function type that can be used to implement an
 // arbitrary matching algorithm.  aContent is the content that may
 // match the list, while aNamespaceID, aAtom, and aData are whatever
 // was passed to the list's constructor.
-typedef bool (*nsContentListMatchFunc)(nsIContent* aContent,
+typedef bool (*nsContentListMatchFunc)(mozilla::dom::Element* aElement,
                                        int32_t aNamespaceID,
                                        nsIAtom* aAtom,
                                        void* aData);
 
 typedef void (*nsContentListDestroyFunc)(void* aData);
 
 /**
  * A function that allocates the matching data for this
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -6344,21 +6344,21 @@ nsContentUtils::StripNullChars(const nsA
 
 struct ClassMatchingInfo {
   nsAttrValue::AtomArray mClasses;
   nsCaseTreatment mCaseTreatment;
 };
 
 // static
 bool
-nsContentUtils::MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
+nsContentUtils::MatchClassNames(Element* aElement, int32_t aNamespaceID,
                                 nsIAtom* aAtom, void* aData)
 {
   // We can't match if there are no class names
-  const nsAttrValue* classAttr = aContent->GetClasses();
+  const nsAttrValue* classAttr = aElement->GetClasses();
   if (!classAttr) {
     return false;
   }
 
   // need to match *all* of the classes
   ClassMatchingInfo* info = static_cast<ClassMatchingInfo*>(aData);
   uint32_t length = info->mClasses.Length();
   if (!length) {
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2822,17 +2822,18 @@ private:
                                 bool aTrusted,
                                 bool *aDefaultAction = nullptr,
                                 bool aOnlyChromeDispatch = false);
 
   static void InitializeModifierStrings();
 
   static void DropFragmentParsers();
 
-  static bool MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
+  static bool MatchClassNames(mozilla::dom::Element* aElement,
+                              int32_t aNamespaceID,
                               nsIAtom* aAtom, void* aData);
   static void DestroyClassNameArray(void* aData);
   static void* AllocClassMatchingInfo(nsINode* aRootNode,
                                       const nsString* aClasses);
 
   // Fills in aInfo with the tokens from the supplied autocomplete attribute.
   static AutocompleteAttrState InternalSerializeAutocompleteAttribute(const nsAttrValue* aAttrVal,
                                                                       mozilla::dom::AutocompleteInfo& aInfo);
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -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/. */
 
 #include "mozilla/dom/HTMLAllCollection.h"
 
 #include "mozilla/dom/HTMLAllCollectionBinding.h"
 #include "mozilla/dom/Nullable.h"
+#include "mozilla/dom/Element.h"
 #include "nsHTMLDocument.h"
 
 namespace mozilla {
 namespace dom {
 
 HTMLAllCollection::HTMLAllCollection(nsHTMLDocument* aDocument)
   : mDocument(aDocument)
 {
@@ -81,24 +82,24 @@ IsAllNamedElement(nsIContent* aContent)
                                        nsGkAtoms::object,
                                        nsGkAtoms::select,
                                        nsGkAtoms::textarea,
                                        nsGkAtoms::frame,
                                        nsGkAtoms::frameset);
 }
 
 static bool
-DocAllResultMatch(nsIContent* aContent, int32_t aNamespaceID, nsIAtom* aAtom,
+DocAllResultMatch(Element* aElement, int32_t aNamespaceID, nsIAtom* aAtom,
                   void* aData)
 {
-  if (aContent->GetID() == aAtom) {
+  if (aElement->GetID() == aAtom) {
     return true;
   }
 
-  nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aContent);
+  nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aElement);
   if (!elm) {
     return false;
   }
 
   if (!IsAllNamedElement(elm)) {
     return false;
   }
 
--- a/dom/html/HTMLDataListElement.cpp
+++ b/dom/html/HTMLDataListElement.cpp
@@ -30,17 +30,17 @@ NS_IMPL_RELEASE_INHERITED(HTMLDataListEl
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLDataListElement)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLDataListElement)
 
 bool
-HTMLDataListElement::MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
+HTMLDataListElement::MatchOptions(Element* aElement, int32_t aNamespaceID,
                                   nsIAtom* aAtom, void* aData)
 {
-  return aContent->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
-         !aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+  return aElement->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
+         !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLDataListElement.h
+++ b/dom/html/HTMLDataListElement.h
@@ -32,18 +32,18 @@ public:
 
     return mOptions;
   }
 
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
   // This function is used to generate the nsContentList (option elements).
-  static bool MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
-                             nsIAtom* aAtom, void* aData);
+  static bool MatchOptions(Element* aElement, int32_t aNamespaceID,
+                           nsIAtom* aAtom, void* aData);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLDataListElement,
                                            nsGenericHTMLElement)
 protected:
   virtual ~HTMLDataListElement();
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -115,20 +115,20 @@ NS_IMETHODIMP
 HTMLFieldSetElement::GetType(nsAString& aType)
 {
   aType.AssignLiteral("fieldset");
   return NS_OK;
 }
 
 /* static */
 bool
-HTMLFieldSetElement::MatchListedElements(nsIContent* aContent, int32_t aNamespaceID,
+HTMLFieldSetElement::MatchListedElements(Element* aElement, int32_t aNamespaceID,
                                          nsIAtom* aAtom, void* aData)
 {
-  nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aContent);
+  nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aElement);
   return formControl;
 }
 
 NS_IMETHODIMP
 HTMLFieldSetElement::GetElements(nsIDOMHTMLCollection** aElements)
 {
   NS_ADDREF(*aElements = Elements());
   return NS_OK;
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -120,18 +120,18 @@ private:
 
   /**
    * Notify all elements (in mElements) that the first legend of the fieldset
    * has now changed.
    */
   void NotifyElementsForFirstLegendChange(bool aNotify);
 
   // This function is used to generate the nsContentList (listed form elements).
-  static bool MatchListedElements(nsIContent* aContent, int32_t aNamespaceID,
-                                    nsIAtom* aAtom, void* aData);
+  static bool MatchListedElements(Element* aElement, int32_t aNamespaceID,
+                                  nsIAtom* aAtom, void* aData);
 
   // listed form controls elements.
   RefPtr<nsContentList> mElements;
 
   // List of elements which have this fieldset as first fieldset ancestor.
   nsTArray<nsGenericHTMLFormElement*> mDependentElements;
 
   nsIContent* mFirstLegend;
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -743,22 +743,22 @@ HTMLSelectElement::SetLength(uint32_t aL
         MOZ_ASSERT(node);
       }
     }
   }
 }
 
 /* static */
 bool
-HTMLSelectElement::MatchSelectedOptions(nsIContent* aContent,
+HTMLSelectElement::MatchSelectedOptions(Element* aElement,
                                         int32_t /* unused */,
                                         nsIAtom* /* unused */,
                                         void* /* unused*/)
 {
-  HTMLOptionElement* option = HTMLOptionElement::FromContent(aContent);
+  HTMLOptionElement* option = HTMLOptionElement::FromContent(aElement);
   return option && option->Selected();
 }
 
 nsIHTMLCollection*
 HTMLSelectElement::SelectedOptions()
 {
   if (!mSelectedOptions) {
     mSelectedOptions = new nsContentList(this, MatchSelectedOptions, nullptr,
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -247,17 +247,17 @@ public:
            ErrorResult& aRv);
   // Uses XPCOM Remove.
   void IndexedSetter(uint32_t aIndex, HTMLOptionElement* aOption,
                      ErrorResult& aRv)
   {
     mOptions->IndexedSetter(aIndex, aOption, aRv);
   }
 
-  static bool MatchSelectedOptions(nsIContent* aContent, int32_t, nsIAtom*,
+  static bool MatchSelectedOptions(Element* aElement, int32_t, nsIAtom*,
                                    void*);
 
   nsIHTMLCollection* SelectedOptions();
 
   int32_t SelectedIndex() const
   {
     return mSelectedIndex;
   }
--- a/dom/html/HTMLTableRowElement.cpp
+++ b/dom/html/HTMLTableRowElement.cpp
@@ -115,20 +115,20 @@ HTMLTableRowElement::SectionRowIndex() c
       return i;
     }
   }
 
   return -1;
 }
 
 static bool
-IsCell(nsIContent *aContent, int32_t aNamespaceID,
+IsCell(Element *aElement, int32_t aNamespaceID,
        nsIAtom* aAtom, void *aData)
 {
-  return aContent->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th);
+  return aElement->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th);
 }
 
 nsIHTMLCollection*
 HTMLTableRowElement::Cells()
 {
   if (!mCells) {
     mCells = new nsContentList(this,
                                IsCell,
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1100,41 +1100,41 @@ nsHTMLDocument::Applets()
 {
   if (!mApplets) {
     mApplets = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::applet, nsGkAtoms::applet);
   }
   return mApplets;
 }
 
 bool
-nsHTMLDocument::MatchLinks(nsIContent *aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchLinks(Element* aElement, int32_t aNamespaceID,
                            nsIAtom* aAtom, void* aData)
 {
-  nsIDocument* doc = aContent->GetUncomposedDoc();
+  nsIDocument* doc = aElement->GetUncomposedDoc();
 
   if (doc) {
-    NS_ASSERTION(aContent->IsInUncomposedDoc(),
+    NS_ASSERTION(aElement->IsInUncomposedDoc(),
                  "This method should never be called on content nodes that "
                  "are not in a document!");
 #ifdef DEBUG
     {
       nsCOMPtr<nsIHTMLDocument> htmldoc =
-        do_QueryInterface(aContent->GetUncomposedDoc());
+        do_QueryInterface(aElement->GetUncomposedDoc());
       NS_ASSERTION(htmldoc,
                    "Huh, how did this happen? This should only be used with "
                    "HTML documents!");
     }
 #endif
 
-    mozilla::dom::NodeInfo *ni = aContent->NodeInfo();
+    mozilla::dom::NodeInfo *ni = aElement->NodeInfo();
 
     nsIAtom *localName = ni->NameAtom();
     if (ni->NamespaceID() == kNameSpaceID_XHTML &&
         (localName == nsGkAtoms::a || localName == nsGkAtoms::area)) {
-      return aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
+      return aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
     }
   }
 
   return false;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
@@ -1148,34 +1148,34 @@ nsHTMLDocument::Links()
 {
   if (!mLinks) {
     mLinks = new nsContentList(this, MatchLinks, nullptr, nullptr);
   }
   return mLinks;
 }
 
 bool
-nsHTMLDocument::MatchAnchors(nsIContent *aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchAnchors(Element* aElement, int32_t aNamespaceID,
                              nsIAtom* aAtom, void* aData)
 {
-  NS_ASSERTION(aContent->IsInUncomposedDoc(),
+  NS_ASSERTION(aElement->IsInUncomposedDoc(),
                "This method should never be called on content nodes that "
                "are not in a document!");
 #ifdef DEBUG
   {
     nsCOMPtr<nsIHTMLDocument> htmldoc =
-      do_QueryInterface(aContent->GetUncomposedDoc());
+      do_QueryInterface(aElement->GetUncomposedDoc());
     NS_ASSERTION(htmldoc,
                  "Huh, how did this happen? This should only be used with "
                  "HTML documents!");
   }
 #endif
 
-  if (aContent->NodeInfo()->Equals(nsGkAtoms::a, kNameSpaceID_XHTML)) {
-    return aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name);
+  if (aElement->IsHTMLElement(nsGkAtoms::a)) {
+    return aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::name);
   }
 
   return false;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetAnchors(nsIDOMHTMLCollection** aAnchors)
 {
@@ -1942,24 +1942,24 @@ nsHTMLDocument::Writeln(const nsAString&
 void
 nsHTMLDocument::Writeln(JSContext* cx, const Sequence<nsString>& aText,
                         ErrorResult& rv)
 {
   WriteCommon(cx, aText, true, rv);
 }
 
 bool
-nsHTMLDocument::MatchNameAttribute(nsIContent* aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchNameAttribute(Element* aElement, int32_t aNamespaceID,
                                    nsIAtom* aAtom, void* aData)
 {
-  NS_PRECONDITION(aContent, "Must have content node to work with!");
+  NS_PRECONDITION(aElement, "Must have element to work with!");
   nsString* elementName = static_cast<nsString*>(aData);
   return
-    aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
-    aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+    aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
+    aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
                           *elementName, eCaseMatters);
 }
 
 /* static */
 void*
 nsHTMLDocument::UseExistingNameString(nsINode* aRootNode, const nsString* aName)
 {
   return const_cast<nsString*>(aName);
@@ -2269,20 +2269,20 @@ nsHTMLDocument::GetForms()
 {
   if (!mForms) {
     mForms = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::form, nsGkAtoms::form);
   }
 
   return mForms;
 }
 
-static bool MatchFormControls(nsIContent* aContent, int32_t aNamespaceID,
-                                nsIAtom* aAtom, void* aData)
+static bool MatchFormControls(Element* aElement, int32_t aNamespaceID,
+                              nsIAtom* aAtom, void* aData)
 {
-  return aContent->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL);
+  return aElement->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL);
 }
 
 nsContentList*
 nsHTMLDocument::GetFormControls()
 {
   if (!mFormControls) {
     mFormControls = new nsContentList(this, MatchFormControls, nullptr, nullptr);
   }
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -255,22 +255,23 @@ public:
 protected:
   ~nsHTMLDocument();
 
   nsresult GetBodySize(int32_t* aWidth,
                        int32_t* aHeight);
 
   nsIContent *MatchId(nsIContent *aContent, const nsAString& aId);
 
-  static bool MatchLinks(nsIContent *aContent, int32_t aNamespaceID,
+  static bool MatchLinks(mozilla::dom::Element* aElement, int32_t aNamespaceID,
+                         nsIAtom* aAtom, void* aData);
+  static bool MatchAnchors(mozilla::dom::Element* aElement, int32_t aNamespaceID,
                            nsIAtom* aAtom, void* aData);
-  static bool MatchAnchors(nsIContent *aContent, int32_t aNamespaceID,
-                             nsIAtom* aAtom, void* aData);
-  static bool MatchNameAttribute(nsIContent* aContent, int32_t aNamespaceID,
-                                   nsIAtom* aAtom, void* aData);
+  static bool MatchNameAttribute(mozilla::dom::Element* aElement,
+                                 int32_t aNamespaceID,
+                                 nsIAtom* aAtom, void* aData);
   static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
 
   static void DocumentWriteTerminationFunc(nsISupports *aRef);
 
   already_AddRefed<nsIURI> GetDomainURI();
 
   nsresult WriteCommon(JSContext *cx, const nsAString& aText,
                        bool aNewlineTerminate);
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -1927,48 +1927,48 @@ XULDocument::StartLayout(void)
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     return NS_OK;
 }
 
 /* static */
 bool
-XULDocument::MatchAttribute(nsIContent* aContent,
+XULDocument::MatchAttribute(Element* aElement,
                             int32_t aNamespaceID,
                             nsIAtom* aAttrName,
                             void* aData)
 {
-    NS_PRECONDITION(aContent, "Must have content node to work with!");
+    NS_PRECONDITION(aElement, "Must have content node to work with!");
     nsString* attrValue = static_cast<nsString*>(aData);
     if (aNamespaceID != kNameSpaceID_Unknown &&
         aNamespaceID != kNameSpaceID_Wildcard) {
         return attrValue->EqualsLiteral("*") ?
-            aContent->HasAttr(aNamespaceID, aAttrName) :
-            aContent->AttrValueIs(aNamespaceID, aAttrName, *attrValue,
+            aElement->HasAttr(aNamespaceID, aAttrName) :
+            aElement->AttrValueIs(aNamespaceID, aAttrName, *attrValue,
                                   eCaseMatters);
     }
 
     // Qualified name match. This takes more work.
 
-    uint32_t count = aContent->GetAttrCount();
+    uint32_t count = aElement->GetAttrCount();
     for (uint32_t i = 0; i < count; ++i) {
-        const nsAttrName* name = aContent->GetAttrNameAt(i);
+        const nsAttrName* name = aElement->GetAttrNameAt(i);
         bool nameMatch;
         if (name->IsAtom()) {
             nameMatch = name->Atom() == aAttrName;
         } else if (aNamespaceID == kNameSpaceID_Wildcard) {
             nameMatch = name->NodeInfo()->Equals(aAttrName);
         } else {
             nameMatch = name->NodeInfo()->QualifiedNameEquals(aAttrName);
         }
 
         if (nameMatch) {
             return attrValue->EqualsLiteral("*") ||
-                aContent->AttrValueIs(name->NamespaceID(), name->LocalName(),
+                aElement->AttrValueIs(name->NamespaceID(), name->LocalName(),
                                       *attrValue, eCaseMatters);
         }
     }
 
     return false;
 }
 
 nsresult
--- a/dom/xul/XULDocument.h
+++ b/dom/xul/XULDocument.h
@@ -174,17 +174,17 @@ public:
 
     virtual int GetDocumentLWTheme() override;
 
     virtual void ResetDocumentLWTheme() override { mDocLWTheme = Doc_Theme_Uninitialized; }
 
     NS_IMETHOD OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) override;
 
     static bool
-    MatchAttribute(nsIContent* aContent,
+    MatchAttribute(Element* aContent,
                    int32_t aNameSpaceID,
                    nsIAtom* aAttrName,
                    void* aData);
 
     NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULDocument, XMLDocument)
 
     void TraceProtos(JSTracer* aTrc, uint32_t aGCNumber);