From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- dom/base/AncestorIterator.h | 107 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 dom/base/AncestorIterator.h (limited to 'dom/base/AncestorIterator.h') diff --git a/dom/base/AncestorIterator.h b/dom/base/AncestorIterator.h new file mode 100644 index 0000000000..d8a56267fd --- /dev/null +++ b/dom/base/AncestorIterator.h @@ -0,0 +1,107 @@ +/* -*- 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/. */ + +/** + * Implementation of some generic iterators over ancestor nodes. + * + * Note that these keep raw pointers to the nodes they iterate from, and as + * such the DOM should not be mutated while they're in use. There are debug + * assertions (via nsMutationGuard) that check this in debug builds. + */ + +#ifndef mozilla_dom_AncestorIterator_h +#define mozilla_dom_AncestorIterator_h + +#include "nsINode.h" +#include "nsIContentInlines.h" +#include "FilteredNodeIterator.h" + +namespace mozilla::dom { + +#ifdef DEBUG +# define MUTATION_GUARD(class_name_) \ + nsMutationGuard mMutationGuard; \ + ~class_name_() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); } +#else +# define MUTATION_GUARD(class_name_) +#endif + +#define DEFINE_ANCESTOR_ITERATOR(name_, method_) \ + class Inclusive##name_ { \ + using Self = Inclusive##name_; \ + \ + public: \ + explicit Inclusive##name_(const nsINode& aNode) \ + : mCurrent(const_cast(&aNode)) {} \ + Self& begin() { return *this; } \ + std::nullptr_t end() const { return nullptr; } \ + bool operator!=(std::nullptr_t) const { return !!mCurrent; } \ + void operator++() { mCurrent = mCurrent->method_(); } \ + nsINode* operator*() { return mCurrent; } \ + \ + MUTATION_GUARD(Inclusive##name_) \ + \ + protected: \ + explicit Inclusive##name_(nsINode* aCurrent) : mCurrent(aCurrent) {} \ + nsINode* mCurrent; \ + }; \ + class name_ : public Inclusive##name_ { \ + public: \ + using Super = Inclusive##name_; \ + explicit name_(const nsINode& aNode) \ + : Inclusive##name_(aNode.method_()) {} \ + }; \ + template \ + class name_##OfTypeIterator : public FilteredNodeIterator { \ + public: \ + explicit name_##OfTypeIterator(const nsINode& aNode) \ + : FilteredNodeIterator(aNode) {} \ + }; \ + template \ + class Inclusive##name_##OfTypeIterator \ + : public FilteredNodeIterator { \ + public: \ + explicit Inclusive##name_##OfTypeIterator(const nsINode& aNode) \ + : FilteredNodeIterator(aNode) {} \ + }; + +DEFINE_ANCESTOR_ITERATOR(Ancestors, GetParentNode) +DEFINE_ANCESTOR_ITERATOR(FlatTreeAncestors, GetFlattenedTreeParentNode) + +#undef MUTATION_GUARD + +} // namespace mozilla::dom + +template +inline mozilla::dom::AncestorsOfTypeIterator nsINode::AncestorsOfType() + const { + return mozilla::dom::AncestorsOfTypeIterator(*this); +} + +template +inline mozilla::dom::InclusiveAncestorsOfTypeIterator +nsINode::InclusiveAncestorsOfType() const { + return mozilla::dom::InclusiveAncestorsOfTypeIterator(*this); +} + +template +inline mozilla::dom::FlatTreeAncestorsOfTypeIterator +nsINode::FlatTreeAncestorsOfType() const { + return mozilla::dom::FlatTreeAncestorsOfTypeIterator(*this); +} + +template +inline mozilla::dom::InclusiveFlatTreeAncestorsOfTypeIterator +nsINode::InclusiveFlatTreeAncestorsOfType() const { + return mozilla::dom::InclusiveFlatTreeAncestorsOfTypeIterator(*this); +} + +template +inline T* nsINode::FirstAncestorOfType() const { + return *(AncestorsOfType()); +} + +#endif // mozilla_dom_AncestorIterator.h -- cgit v1.2.3