ConnectedAncestorTracker.h (2598B)
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 #ifndef mozilla_ConnectedAncestorTracker_h 8 #define mozilla_ConnectedAncestorTracker_h 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/PresShell.h" 12 #include "mozilla/dom/Document.h" 13 #include "mozilla/dom/Element.h" 14 #include "nsIContent.h" 15 16 namespace mozilla { 17 18 /** 19 * AutoConnectedAncestorTracker is a struct which keeps referring the connected 20 * and closest ancestor of a content node. E.g., say, there are nodes are: 21 * Document -> <html> -> <body> -> <div> and starts tracking it with the <div>, 22 * and the <body> is removed, this refers the <html> with mConnectedAncestor. 23 * Note that even after reconnected the <body>, this won't refer the <div> as 24 * connected one. 25 */ 26 struct MOZ_STACK_CLASS AutoConnectedAncestorTracker final { 27 explicit AutoConnectedAncestorTracker(nsIContent& aContent) 28 : mContent(aContent), 29 mPresShell(aContent.IsInComposedDoc() 30 ? aContent.OwnerDoc()->GetPresShell() 31 : nullptr) { 32 if (mPresShell) { 33 mPresShell->AddConnectedAncestorTracker(*this); 34 } 35 } 36 ~AutoConnectedAncestorTracker() { 37 if (mPresShell) { 38 mPresShell->RemoveConnectedAncestorTracker(*this); 39 } 40 } 41 42 [[nodiscard]] bool ContentWasRemoved() const { 43 return mPresShell && mConnectedAncestor; 44 } 45 [[nodiscard]] dom::Element* GetConnectedElement() const { 46 return ContentWasRemoved() 47 ? mConnectedAncestor->GetAsElementOrParentElement() 48 : mContent->GetAsElementOrParentElement(); 49 } 50 [[nodiscard]] nsIContent* GetConnectedContent() const { 51 return ContentWasRemoved() ? nsIContent::FromNode(mConnectedAncestor) 52 : mContent.get(); 53 } 54 [[nodiscard]] nsINode& ConnectedNode() const { 55 return ContentWasRemoved() ? *mConnectedAncestor : mContent.ref(); 56 } 57 58 // Store the original content node. 59 const OwningNonNull<nsIContent> mContent; 60 // Store the connected ancestor node if and only if mContent has been deleted 61 // from the document. 62 nsCOMPtr<nsINode> mConnectedAncestor; 63 64 // The PresShell which manages this instance. 65 const RefPtr<PresShell> mPresShell; 66 67 AutoConnectedAncestorTracker* mPreviousTracker = nullptr; 68 }; 69 70 } // namespace mozilla 71 72 #endif // #ifndef mozilla_ConnectedAncestorTracker_h