tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AncestorIterator.h (4903B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /**
      8 * Implementation of some generic iterators over ancestor nodes.
      9 *
     10 * Note that these keep raw pointers to the nodes they iterate from, and as
     11 * such the DOM should not be mutated while they're in use. There are debug
     12 * assertions (via nsMutationGuard) that check this in debug builds.
     13 */
     14 
     15 #ifndef mozilla_dom_AncestorIterator_h
     16 #define mozilla_dom_AncestorIterator_h
     17 
     18 #include "FilteredNodeIterator.h"
     19 #include "nsIContentInlines.h"
     20 #include "nsINode.h"
     21 
     22 namespace mozilla::dom {
     23 
     24 #ifdef DEBUG
     25 #  define MUTATION_GUARD(class_name_) \
     26    nsMutationGuard mMutationGuard;   \
     27    ~class_name_() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
     28 #else
     29 #  define MUTATION_GUARD(class_name_)
     30 #endif
     31 
     32 #define DEFINE_ANCESTOR_ITERATOR(name_, method_)                         \
     33  class Inclusive##name_ {                                               \
     34    using Self = Inclusive##name_;                                       \
     35                                                                         \
     36   public:                                                               \
     37    explicit Inclusive##name_(const nsINode& aNode)                      \
     38        : mCurrent(const_cast<nsINode*>(&aNode)) {}                      \
     39    Self& begin() { return *this; }                                      \
     40    std::nullptr_t end() const { return nullptr; }                       \
     41    bool operator!=(std::nullptr_t) const { return !!mCurrent; }         \
     42    void operator++() { mCurrent = mCurrent->method_(); }                \
     43    nsINode* operator*() { return mCurrent; }                            \
     44                                                                         \
     45    MUTATION_GUARD(Inclusive##name_)                                     \
     46                                                                         \
     47   protected:                                                            \
     48    explicit Inclusive##name_(nsINode* aCurrent) : mCurrent(aCurrent) {} \
     49    nsINode* mCurrent;                                                   \
     50  };                                                                     \
     51  class name_ : public Inclusive##name_ {                                \
     52   public:                                                               \
     53    using Super = Inclusive##name_;                                      \
     54    explicit name_(const nsINode& aNode)                                 \
     55        : Inclusive##name_(aNode.method_()) {}                           \
     56  };                                                                     \
     57  template <typename T>                                                  \
     58  class name_##OfTypeIterator : public FilteredNodeIterator<T, name_> {  \
     59   public:                                                               \
     60    explicit name_##OfTypeIterator(const nsINode& aNode)                 \
     61        : FilteredNodeIterator<T, name_>(aNode) {}                       \
     62  };                                                                     \
     63  template <typename T>                                                  \
     64  class Inclusive##name_##OfTypeIterator                                 \
     65      : public FilteredNodeIterator<T, Inclusive##name_> {               \
     66   public:                                                               \
     67    explicit Inclusive##name_##OfTypeIterator(const nsINode& aNode)      \
     68        : FilteredNodeIterator<T, Inclusive##name_>(aNode) {}            \
     69  };
     70 
     71 DEFINE_ANCESTOR_ITERATOR(Ancestors, GetParentNode)
     72 DEFINE_ANCESTOR_ITERATOR(FlatTreeAncestors, GetFlattenedTreeParentNode)
     73 
     74 #undef MUTATION_GUARD
     75 
     76 }  // namespace mozilla::dom
     77 
     78 template <typename T>
     79 inline mozilla::dom::AncestorsOfTypeIterator<T> nsINode::AncestorsOfType()
     80    const {
     81  return mozilla::dom::AncestorsOfTypeIterator<T>(*this);
     82 }
     83 
     84 template <typename T>
     85 inline mozilla::dom::InclusiveAncestorsOfTypeIterator<T>
     86 nsINode::InclusiveAncestorsOfType() const {
     87  return mozilla::dom::InclusiveAncestorsOfTypeIterator<T>(*this);
     88 }
     89 
     90 template <typename T>
     91 inline mozilla::dom::FlatTreeAncestorsOfTypeIterator<T>
     92 nsINode::FlatTreeAncestorsOfType() const {
     93  return mozilla::dom::FlatTreeAncestorsOfTypeIterator<T>(*this);
     94 }
     95 
     96 template <typename T>
     97 inline mozilla::dom::InclusiveFlatTreeAncestorsOfTypeIterator<T>
     98 nsINode::InclusiveFlatTreeAncestorsOfType() const {
     99  return mozilla::dom::InclusiveFlatTreeAncestorsOfTypeIterator<T>(*this);
    100 }
    101 
    102 template <typename T>
    103 inline T* nsINode::FirstAncestorOfType() const {
    104  return *(AncestorsOfType<T>());
    105 }
    106 
    107 #endif  // mozilla_dom_AncestorIterator.h