Bug 1637712 - Consider to move *Ancestor* API to nsINode r=emilio
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 20 May 2020 14:55:15 +0000
changeset 531248 2c5eea62791725beabc11d5fcfe17f0c5f515860
parent 531247 8b425b5dfb9f08cf17fab269b91b01aa861208b4
child 531249 ae4bb7a34b7e61c612afe22703363b0d17b821f3
push id37436
push userncsoregi@mozilla.com
push dateWed, 20 May 2020 21:30:50 +0000
treeherdermozilla-central@6c10970490f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1637712
milestone78.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 1637712 - Consider to move *Ancestor* API to nsINode r=emilio Differential Revision: https://phabricator.services.mozilla.com/D75169
dom/base/AncestorIterator.h
dom/base/FilteredNodeIterator.h
dom/base/nsContentUtils.cpp
dom/base/nsINode.cpp
dom/base/nsINode.h
dom/html/HTMLFormSubmission.cpp
editor/libeditor/HTMLAbsPositionEditor.cpp
editor/libeditor/HTMLEditSubActionHandler.cpp
editor/libeditor/HTMLEditUtils.h
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/WSRunObject.cpp
--- a/dom/base/AncestorIterator.h
+++ b/dom/base/AncestorIterator.h
@@ -51,21 +51,59 @@ namespace dom {
   };                                                                     \
   class name_ : public Inclusive##name_ {                                \
    public:                                                               \
     using Super = Inclusive##name_;                                      \
     explicit name_(const nsINode& aNode)                                 \
         : Inclusive##name_(aNode.method_()) {}                           \
   };                                                                     \
   template <typename T>                                                  \
-  using name_##OfType = FilteredNodeIterator<T, name_>;                  \
+  class name_##OfTypeIterator : public FilteredNodeIterator<T, name_> {  \
+   public:                                                               \
+    explicit name_##OfTypeIterator(const nsINode& aNode)                 \
+        : FilteredNodeIterator<T, name_>(aNode) {}                       \
+  };                                                                     \
   template <typename T>                                                  \
-  using Inclusive##name_##OfType = FilteredNodeIterator<T, Inclusive##name_>;
+  class Inclusive##name_##OfTypeIterator                                 \
+      : public FilteredNodeIterator<T, Inclusive##name_> {               \
+   public:                                                               \
+    explicit Inclusive##name_##OfTypeIterator(const nsINode& aNode)      \
+        : FilteredNodeIterator<T, Inclusive##name_>(aNode) {}            \
+  };
 
 DEFINE_ANCESTOR_ITERATOR(Ancestors, GetParentNode)
 DEFINE_ANCESTOR_ITERATOR(FlatTreeAncestors, GetFlattenedTreeParentNode)
 
 #undef MUTATION_GUARD
 
 }  // namespace dom
 }  // namespace mozilla
 
+template <typename T>
+inline mozilla::dom::AncestorsOfTypeIterator<T> nsINode::AncestorsOfType()
+    const {
+  return mozilla::dom::AncestorsOfTypeIterator<T>(*this);
+}
+
+template <typename T>
+inline mozilla::dom::InclusiveAncestorsOfTypeIterator<T>
+nsINode::InclusiveAncestorsOfType() const {
+  return mozilla::dom::InclusiveAncestorsOfTypeIterator<T>(*this);
+}
+
+template <typename T>
+inline mozilla::dom::FlatTreeAncestorsOfTypeIterator<T>
+nsINode::FlatTreeAncestorsOfType() const {
+  return mozilla::dom::FlatTreeAncestorsOfTypeIterator<T>(*this);
+}
+
+template <typename T>
+inline mozilla::dom::InclusiveFlatTreeAncestorsOfTypeIterator<T>
+nsINode::InclusiveFlatTreeAncestorsOfType() const {
+  return mozilla::dom::InclusiveFlatTreeAncestorsOfTypeIterator<T>(*this);
+}
+
+template <typename T>
+inline T* nsINode::FirstAncestorOfType() const {
+  return *(AncestorsOfType<T>());
+}
+
 #endif  // mozilla_dom_AncestorIterator.h
--- a/dom/base/FilteredNodeIterator.h
+++ b/dom/base/FilteredNodeIterator.h
@@ -18,21 +18,16 @@ namespace dom {
 
 template <typename T, typename Iter>
 class FilteredNodeIterator : public Iter {
  public:
   explicit FilteredNodeIterator(const nsINode& aNode) : Iter(aNode) {
     EnsureValid();
   }
 
-  static T* First(const nsINode& aNode) {
-    FilteredNodeIterator iter(aNode);
-    return *iter;
-  }
-
   FilteredNodeIterator& begin() { return *this; }
   using Iter::end;
 
   void operator++() {
     Iter::operator++();
     EnsureValid();
   }
 
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -4663,17 +4663,17 @@ already_AddRefed<DocumentFragment> nsCon
           aPreventScriptExecution);
     }
 
     return frag.forget();
   }
 
   AutoTArray<nsString, 32> tagStack;
   nsAutoString uriStr, nameStr;
-  for (Element* element : InclusiveAncestorsOfType<Element>(*aContextNode)) {
+  for (Element* element : aContextNode->InclusiveAncestorsOfType<Element>()) {
     nsString& tagName = *tagStack.AppendElement();
     // It mostly doesn't actually matter what tag name we use here: XML doesn't
     // have parsing that depends on the open tag stack, apart from namespace
     // declarations.  So this whole tagStack bit is just there to get the right
     // namespace declarations to the XML parser.  That said, the parser _is_
     // going to create elements with the tag names we provide here, so we need
     // to make sure they are not names that can trigger custom element
     // constructors.  Just make up a name that is never going to be a valid
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -387,17 +387,17 @@ bool nsINode::IsSelected(const uint32_t 
 
   return false;
 }
 
 nsIContent* nsINode::GetTextEditorRootContent(TextEditor** aTextEditor) {
   if (aTextEditor) {
     *aTextEditor = nullptr;
   }
-  for (auto* element : InclusiveAncestorsOfType<nsGenericHTMLElement>(*this)) {
+  for (auto* element : InclusiveAncestorsOfType<nsGenericHTMLElement>()) {
     RefPtr<TextEditor> textEditor = element->GetTextEditorInternal();
     if (!textEditor) {
       continue;
     }
 
     MOZ_ASSERT(!textEditor->AsHTMLEditor(),
                "If it were an HTML editor, needs to use GetRootElement()");
     Element* rootElement = textEditor->GetRoot();
@@ -903,17 +903,17 @@ nsIURI* nsINode::GetBaseURIObject() cons
 
 void nsINode::LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix) {
   if (Element* nsElement = GetNameSpaceElement()) {
     // XXX Waiting for DOM spec to list error codes.
 
     // Trace up the content parent chain looking for the namespace
     // declaration that defines the aNamespaceURI namespace. Once found,
     // return the prefix (i.e. the attribute localName).
-    for (Element* element : InclusiveAncestorsOfType<Element>(*nsElement)) {
+    for (Element* element : nsElement->InclusiveAncestorsOfType<Element>()) {
       uint32_t attrCount = element->GetAttrCount();
 
       for (uint32_t i = 0; i < attrCount; ++i) {
         const nsAttrName* name = element->GetAttrNameAt(i);
 
         if (name->NamespaceEquals(kNameSpaceID_XMLNS) &&
             element->AttrValueIs(kNameSpaceID_XMLNS, name->LocalName(),
                                  aNamespaceURI, eCaseMatters)) {
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -68,27 +68,35 @@ inline bool IsSpaceCharacter(char16_t aC
   return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' ||
          aChar == '\f';
 }
 inline bool IsSpaceCharacter(char aChar) {
   return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' ||
          aChar == '\f';
 }
 class AccessibleNode;
+template <typename T>
+class AncestorsOfTypeIterator;
 struct BoxQuadOptions;
 struct ConvertCoordinateOptions;
 class DocGroup;
 class Document;
 class DocumentFragment;
 class DocumentOrShadowRoot;
 class DOMPoint;
 class DOMQuad;
 class DOMRectReadOnly;
 class Element;
 class EventHandlerNonNull;
+template <typename T>
+class FlatTreeAncestorsOfTypeIterator;
+template <typename T>
+class InclusiveAncestorsOfTypeIterator;
+template <typename T>
+class InclusiveFlatTreeAncestorsOfTypeIterator;
 class MutationObservers;
 template <typename T>
 class Optional;
 class OwningNodeOrString;
 template <typename>
 class Sequence;
 class ShadowRoot;
 class SVGUseElement;
@@ -1085,16 +1093,38 @@ class nsINode : public mozilla::dom::Eve
    */
   void RemoveMutationObserver(nsIMutationObserver* aMutationObserver) {
     nsSlots* s = GetExistingSlots();
     if (s) {
       s->mMutationObservers.RemoveElement(aMutationObserver);
     }
   }
 
+  /**
+   * Helper methods to access ancestor node(s) of type T.
+   * The implementations of the methods are in mozilla/dom/AncestorIterator.h.
+   */
+  template <typename T>
+  inline mozilla::dom::AncestorsOfTypeIterator<T> AncestorsOfType() const;
+
+  template <typename T>
+  inline mozilla::dom::InclusiveAncestorsOfTypeIterator<T>
+  InclusiveAncestorsOfType() const;
+
+  template <typename T>
+  inline mozilla::dom::FlatTreeAncestorsOfTypeIterator<T>
+  FlatTreeAncestorsOfType() const;
+
+  template <typename T>
+  inline mozilla::dom::InclusiveFlatTreeAncestorsOfTypeIterator<T>
+  InclusiveFlatTreeAncestorsOfType() const;
+
+  template <typename T>
+  T* FirstAncestorOfType() const;
+
  private:
   /**
    * Walks aNode, its attributes and, if aDeep is true, its descendant nodes.
    * If aClone is true the nodes will be cloned. If aNewNodeInfoManager is
    * not null, it is used to create new nodeinfos for the nodes. Also reparents
    * the XPConnect wrappers for the nodes into aReparentScope if non-null.
    *
    * @param aNode Node to adopt/clone.
--- a/dom/html/HTMLFormSubmission.cpp
+++ b/dom/html/HTMLFormSubmission.cpp
@@ -827,18 +827,17 @@ nsresult HTMLFormSubmission::GetFromForm
   if (aSubmitter &&
       aSubmitter->HasAttr(kNameSpaceID_None, nsGkAtoms::formmethod)) {
     GetEnumAttr(aSubmitter, nsGkAtoms::formmethod, &method);
   } else {
     GetEnumAttr(aForm, nsGkAtoms::method, &method);
   }
 
   if (method == NS_FORM_METHOD_DIALOG) {
-    HTMLDialogElement* dialog =
-        AncestorsOfType<HTMLDialogElement>::First(*aForm);
+    HTMLDialogElement* dialog = aForm->FirstAncestorOfType<HTMLDialogElement>();
 
     // If there isn't one, or if it does not have an open attribute, do
     // nothing.
     if (!dialog || !dialog->Open()) {
       return NS_OK;
     }
 
     nsAutoString result;
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -75,17 +75,17 @@ HTMLEditor::GetAbsolutelyPositionedSelec
 
   Element* selectionContainerElement = GetSelectionContainerElement();
   if (NS_WARN_IF(!selectionContainerElement)) {
     return nullptr;
   }
 
   AutoTArray<RefPtr<Element>, 24> arrayOfParentElements;
   for (Element* element :
-       InclusiveAncestorsOfType<Element>(*selectionContainerElement)) {
+       selectionContainerElement->InclusiveAncestorsOfType<Element>()) {
     arrayOfParentElements.AppendElement(element);
   }
 
   nsAutoString positionValue;
   for (RefPtr<Element> element = selectionContainerElement; element;
        element = element->GetParentElement()) {
     if (element->IsHTMLElement(nsGkAtoms::html)) {
       NS_WARNING(
--- a/editor/libeditor/HTMLEditSubActionHandler.cpp
+++ b/editor/libeditor/HTMLEditSubActionHandler.cpp
@@ -1006,17 +1006,17 @@ AlignStateAtSelection::AlignStateAtSelec
       return;
     }
     // XXX In RTL document, is this expected?
     mFirstAlign = nsIHTMLEditor::eLeft;
     return;
   }
 
   for (nsIContent* containerContent :
-       InclusiveAncestorsOfType<nsIContent>(*editTargetContent)) {
+       editTargetContent->InclusiveAncestorsOfType<nsIContent>()) {
     // If the node is a parent `<table>` element of edit target, let's break
     // here to materialize the 'inline-block' behaviour of html tables
     // regarding to text alignment.
     if (containerContent != editTargetContent &&
         containerContent->IsHTMLElement(nsGkAtoms::table)) {
       return;
     }
 
@@ -8864,18 +8864,17 @@ nsIContent* HTMLEditor::GetMostAncestorI
   }
 
   if (!aNode.GetParent()) {
     return aNode.AsContent();
   }
 
   // Looks for the highest inline parent in the editing host.
   nsIContent* topMostInlineContent = aNode.AsContent();
-  for (nsIContent* content :
-       InclusiveAncestorsOfType<nsIContent>(*aNode.GetParent())) {
+  for (nsIContent* content : aNode.AncestorsOfType<nsIContent>()) {
     if (content == host || !HTMLEditUtils::IsInlineElement(*content)) {
       break;
     }
     topMostInlineContent = content;
   }
   return topMostInlineContent;
 }
 
--- a/editor/libeditor/HTMLEditUtils.h
+++ b/editor/libeditor/HTMLEditUtils.h
@@ -262,18 +262,17 @@ class HTMLEditUtils final {
     }
 
     nsIContent* nextContent = aStartContent.GetNextSibling();
     if (!nextContent) {
       if (!aStartContent.GetParentElement()) {
         NS_WARNING("Reached orphan node while climbing up the DOM tree");
         return nullptr;
       }
-      for (Element* parentElement : dom::InclusiveAncestorsOfType<Element>(
-               *aStartContent.GetParentNode())) {
+      for (Element* parentElement : aStartContent.AncestorsOfType<Element>()) {
         if (parentElement == &aCurrentBlock) {
           return nullptr;
         }
         if (parentElement == aAncestorLimiter) {
           NS_WARNING("Reached editing host while climbing up the DOM tree");
           return nullptr;
         }
         nextContent = parentElement->GetNextSibling();
@@ -375,18 +374,17 @@ class HTMLEditUtils final {
     }
 
     nsIContent* previousContent = aStartContent.GetPreviousSibling();
     if (!previousContent) {
       if (!aStartContent.GetParentElement()) {
         NS_WARNING("Reached orphan node while climbing up the DOM tree");
         return nullptr;
       }
-      for (Element* parentElement : dom::InclusiveAncestorsOfType<Element>(
-               *aStartContent.GetParentNode())) {
+      for (Element* parentElement : aStartContent.AncestorsOfType<Element>()) {
         if (parentElement == &aCurrentBlock) {
           return nullptr;
         }
         if (parentElement == aAncestorLimiter) {
           NS_WARNING("Reached editing host while climbing up the DOM tree");
           return nullptr;
         }
         previousContent = parentElement->GetPreviousSibling();
@@ -481,22 +479,17 @@ class HTMLEditUtils final {
         !aAncestorLimiter || aContent.IsInclusiveDescendantOf(aAncestorLimiter),
         "aContent isn't in aAncestorLimiter");
 
     // The caller has already reached the limiter.
     if (&aContent == aAncestorLimiter) {
       return nullptr;
     }
 
-    if (!aContent.GetParent()) {
-      return nullptr;
-    }
-
-    for (Element* element : dom::InclusiveAncestorsOfType<Element>(
-             const_cast<nsIContent&>(*aContent.GetParent()))) {
+    for (Element* element : aContent.AncestorsOfType<Element>()) {
       if (HTMLEditUtils::IsBlockElement(*element)) {
         return element;
       }
       // Now, we have reached the limiter, there is no block in its ancestors.
       if (element == aAncestorLimiter) {
         return nullptr;
       }
     }
@@ -529,18 +522,17 @@ class HTMLEditUtils final {
   /**
    * GetClosestAncestorTableElement() returns the nearest inclusive ancestor
    * <table> element of aContent.
    */
   static Element* GetClosestAncestorTableElement(const nsIContent& aContent) {
     if (!aContent.GetParent()) {
       return nullptr;
     }
-    for (Element* element : dom::InclusiveAncestorsOfType<Element>(
-             const_cast<nsIContent&>(aContent))) {
+    for (Element* element : aContent.InclusiveAncestorsOfType<Element>()) {
       if (HTMLEditUtils::IsTable(element)) {
         return element;
       }
     }
     return nullptr;
   }
 
   /**
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -2511,17 +2511,17 @@ Element* HTMLEditor::GetInclusiveAncesto
   Element* currentElement = aContent.GetAsElementOrParentElement();
   if (NS_WARN_IF(!currentElement)) {
     MOZ_ASSERT(!aContent.GetParentNode());
     return nullptr;
   }
 
   bool lookForLink = IsLinkTag(aTagName);
   bool lookForNamedAnchor = IsNamedAnchorTag(aTagName);
-  for (Element* element : InclusiveAncestorsOfType<Element>(*currentElement)) {
+  for (Element* element : currentElement->InclusiveAncestorsOfType<Element>()) {
     // Stop searching if parent is a body element.  Note: Originally used
     // IsRoot() to/ stop at table cells, but that's too messy when you are
     // trying to find the parent table.
     if (element->IsHTMLElement(nsGkAtoms::body)) {
       return nullptr;
     }
     if (lookForLink) {
       // Test if we have a link (an anchor with href set)
@@ -3060,18 +3060,17 @@ nsresult HTMLEditor::RemoveEmptyInclusiv
   // add a <br> later, so it won't be an empty wrapper in the end.
   Element* blockElement =
       HTMLEditUtils::GetAncestorBlockElement(aContent, editingHost);
   if (!blockElement || IsEmptyNode(*blockElement)) {
     return NS_OK;
   }
 
   OwningNonNull<nsIContent> content = aContent;
-  for (nsIContent* parentContent :
-       InclusiveAncestorsOfType<nsIContent>(*aContent.GetParent())) {
+  for (nsIContent* parentContent : aContent.AncestorsOfType<nsIContent>()) {
     if (HTMLEditUtils::IsBlockElement(*parentContent) ||
         parentContent->Length() != 1 ||
         !HTMLEditUtils::IsSimplyEditableNode(*parentContent) ||
         parentContent == editingHost) {
       break;
     }
     content = *parentContent;
   }
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -772,17 +772,17 @@ SplitNodeResult HTMLEditor::SplitAncesto
   // FontFaceStateCommand::SetState() calls RemoveInlinePropertyAsAction()
   // with nsGkAtoms::tt before calling SetInlinePropertyAsAction() if we
   // are handling a XUL command.  Only in that case, we need to check
   // IsCSSEnabled().
   bool useCSS = aProperty != nsGkAtoms::tt || IsCSSEnabled();
 
   AutoTArray<OwningNonNull<nsIContent>, 24> arrayOfParents;
   for (nsIContent* content :
-       InclusiveAncestorsOfType<nsIContent>(*aPointToSplit.GetContainer())) {
+       aPointToSplit.GetContainer()->InclusiveAncestorsOfType<nsIContent>()) {
     if (HTMLEditUtils::IsBlockElement(*content) || !content->GetParent() ||
         !EditorUtils::IsEditableContent(*content->GetParent(),
                                         EditorType::HTML)) {
       break;
     }
     arrayOfParents.AppendElement(*content);
   }
 
@@ -1202,17 +1202,17 @@ nsresult HTMLEditor::PromoteRangeIfStart
   // We assume that <a> is not nested.
   // XXX Shouldn't ignore the editing host.
   if (NS_WARN_IF(!aRange.GetStartContainer()) ||
       NS_WARN_IF(!aRange.GetEndContainer())) {
     return NS_ERROR_INVALID_ARG;
   }
   EditorRawDOMPoint newRangeStart(aRange.StartRef());
   for (Element* element :
-       InclusiveAncestorsOfType<Element>(*aRange.GetStartContainer())) {
+       aRange.GetStartContainer()->InclusiveAncestorsOfType<Element>()) {
     if (element->IsHTMLElement(nsGkAtoms::body)) {
       break;
     }
     if (!HTMLEditUtils::IsNamedAnchor(element)) {
       continue;
     }
     newRangeStart.Set(element);
     break;
@@ -1222,17 +1222,17 @@ nsresult HTMLEditor::PromoteRangeIfStart
     NS_WARNING(
         "HTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor() reached root "
         "element from start container");
     return NS_ERROR_FAILURE;
   }
 
   EditorRawDOMPoint newRangeEnd(aRange.EndRef());
   for (Element* element :
-       InclusiveAncestorsOfType<Element>(*aRange.GetEndContainer())) {
+       aRange.GetEndContainer()->InclusiveAncestorsOfType<Element>()) {
     if (element->IsHTMLElement(nsGkAtoms::body)) {
       break;
     }
     if (!HTMLEditUtils::IsNamedAnchor(element)) {
       continue;
     }
     newRangeEnd.SetAfter(element);
     break;
@@ -1257,17 +1257,17 @@ nsresult HTMLEditor::PromoteRangeIfStart
 
 nsresult HTMLEditor::PromoteInlineRange(nsRange& aRange) {
   if (NS_WARN_IF(!aRange.GetStartContainer()) ||
       NS_WARN_IF(!aRange.GetEndContainer())) {
     return NS_ERROR_INVALID_ARG;
   }
   EditorRawDOMPoint newRangeStart(aRange.StartRef());
   for (nsIContent* content :
-       InclusiveAncestorsOfType<nsIContent>(*aRange.GetStartContainer())) {
+       aRange.GetStartContainer()->InclusiveAncestorsOfType<nsIContent>()) {
     MOZ_ASSERT(newRangeStart.GetContainer() == content);
     if (content->IsHTMLElement(nsGkAtoms::body) ||
         !EditorUtils::IsEditableContent(*content, EditorType::HTML) ||
         !IsStartOfContainerOrBeforeFirstEditableChild(newRangeStart)) {
       break;
     }
     newRangeStart.Set(content);
   }
@@ -1275,17 +1275,17 @@ nsresult HTMLEditor::PromoteInlineRange(
     NS_WARNING(
         "HTMLEditor::PromoteInlineRange() reached root element from start "
         "container");
     return NS_ERROR_FAILURE;
   }
 
   EditorRawDOMPoint newRangeEnd(aRange.EndRef());
   for (nsIContent* content :
-       InclusiveAncestorsOfType<nsIContent>(*aRange.GetEndContainer())) {
+       aRange.GetEndContainer()->InclusiveAncestorsOfType<nsIContent>()) {
     MOZ_ASSERT(newRangeEnd.GetContainer() == content);
     if (content->IsHTMLElement(nsGkAtoms::body) ||
         !EditorUtils::IsEditableContent(*content, EditorType::HTML) ||
         !IsEndOfContainerOrEqualsOrAfterLastEditableChild(newRangeEnd)) {
       break;
     }
     newRangeEnd.SetAfter(content);
   }
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -715,17 +715,17 @@ nsIContent* WSRunScanner::GetEditableBlo
     return nullptr;
   }
   NS_ASSERTION(EditorUtils::IsEditableContent(*aContent, EditorType::HTML),
                "Given content is not editable");
   // XXX What should we do if scan range crosses block boundary?  Currently,
   //     it's not collapsed only when inserting composition string so that
   //     it's possible but shouldn't occur actually.
   nsIContent* editableBlockParentOrTopmotEditableInlineContent = nullptr;
-  for (nsIContent* content : InclusiveAncestorsOfType<nsIContent>(*aContent)) {
+  for (nsIContent* content : aContent->InclusiveAncestorsOfType<nsIContent>()) {
     if (!EditorUtils::IsEditableContent(*content, EditorType::HTML)) {
       break;
     }
     editableBlockParentOrTopmotEditableInlineContent = content;
     if (HTMLEditUtils::IsBlockElement(
             *editableBlockParentOrTopmotEditableInlineContent)) {
       break;
     }