Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
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 DOM Traversal's nsIDOMNodeIterator
9 : */
10 :
11 : #ifndef mozilla_dom_NodeIterator_h
12 : #define mozilla_dom_NodeIterator_h
13 :
14 : #include "nsIDOMNodeIterator.h"
15 : #include "nsTraversal.h"
16 : #include "nsCycleCollectionParticipant.h"
17 : #include "nsStubMutationObserver.h"
18 :
19 : class nsINode;
20 : class nsIDOMNode;
21 :
22 : namespace mozilla {
23 : namespace dom {
24 :
25 : class NodeIterator final : public nsIDOMNodeIterator,
26 : public nsTraversal,
27 : public nsStubMutationObserver
28 : {
29 : public:
30 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
31 : NS_DECL_NSIDOMNODEITERATOR
32 :
33 : NodeIterator(nsINode *aRoot,
34 : uint32_t aWhatToShow,
35 : NodeFilterHolder aFilter);
36 :
37 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
38 :
39 0 : NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(NodeIterator, nsIDOMNodeIterator)
40 :
41 : // WebIDL API
42 0 : nsINode* Root() const
43 : {
44 0 : return mRoot;
45 : }
46 0 : nsINode* GetReferenceNode() const
47 : {
48 0 : return mPointer.mNode;
49 : }
50 0 : bool PointerBeforeReferenceNode() const
51 : {
52 0 : return mPointer.mBeforeNode;
53 : }
54 0 : uint32_t WhatToShow() const
55 : {
56 0 : return mWhatToShow;
57 : }
58 0 : already_AddRefed<NodeFilter> GetFilter()
59 : {
60 0 : return mFilter.ToWebIDLCallback();
61 : }
62 0 : already_AddRefed<nsINode> NextNode(ErrorResult& aResult)
63 : {
64 0 : return NextOrPrevNode(&NodePointer::MoveToNext, aResult);
65 : }
66 0 : already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult)
67 : {
68 0 : return NextOrPrevNode(&NodePointer::MoveToPrevious, aResult);
69 : }
70 : // The XPCOM Detach() is fine for our purposes
71 :
72 : bool WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
73 :
74 : private:
75 : virtual ~NodeIterator();
76 :
77 : struct NodePointer {
78 0 : NodePointer() : mNode(nullptr) {}
79 : NodePointer(nsINode *aNode, bool aBeforeNode);
80 :
81 : typedef bool (NodePointer::*MoveToMethodType)(nsINode*);
82 : bool MoveToNext(nsINode *aRoot);
83 : bool MoveToPrevious(nsINode *aRoot);
84 :
85 : bool MoveForward(nsINode *aRoot, nsINode *aNode);
86 : void MoveBackward(nsINode *aParent, nsINode *aNode);
87 :
88 : void AdjustAfterRemoval(nsINode *aRoot, nsINode *aContainer, nsIContent *aChild, nsIContent *aPreviousSibling);
89 :
90 0 : void Clear() { mNode = nullptr; }
91 :
92 : nsINode *mNode;
93 : bool mBeforeNode;
94 : };
95 :
96 : // Implementation for some of our XPCOM getters
97 : typedef already_AddRefed<nsINode> (NodeIterator::*NodeGetter)(ErrorResult&);
98 0 : inline nsresult ImplNodeGetter(NodeGetter aGetter, nsIDOMNode** aRetval)
99 : {
100 0 : mozilla::ErrorResult rv;
101 0 : nsCOMPtr<nsINode> node = (this->*aGetter)(rv);
102 0 : if (rv.Failed()) {
103 0 : return rv.StealNSResult();
104 : }
105 0 : *aRetval = node ? node.forget().take()->AsDOMNode() : nullptr;
106 0 : return NS_OK;
107 : }
108 :
109 : // Have to return a strong ref, because the act of testing the node can
110 : // remove it from the DOM so we're holding the only ref to it.
111 : already_AddRefed<nsINode>
112 : NextOrPrevNode(NodePointer::MoveToMethodType aMove, ErrorResult& aResult);
113 :
114 : NodePointer mPointer;
115 : NodePointer mWorkingPointer;
116 : };
117 :
118 : } // namespace dom
119 :
120 : } // namespace mozilla
121 :
122 : #endif // mozilla_dom_NodeIterator_h
|