ScriptableContentIterator.cpp (5997B)
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 #include "ScriptableContentIterator.h" 8 9 #include "mozilla/ContentIterator.h" 10 #include "nsINode.h" 11 #include "nsRange.h" 12 13 namespace mozilla { 14 15 NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptableContentIterator) 16 NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptableContentIterator) 17 18 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptableContentIterator) 19 NS_INTERFACE_MAP_ENTRY(nsIScriptableContentIterator) 20 NS_INTERFACE_MAP_ENTRY(nsISupports) 21 NS_INTERFACE_MAP_END 22 23 NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptableContentIterator) 24 25 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptableContentIterator) 26 if (tmp->mContentIterator) { 27 switch (tmp->mIteratorType) { 28 case POST_ORDER_ITERATOR: 29 default: 30 ImplCycleCollectionUnlink( 31 static_cast<PostContentIterator&>(*tmp->mContentIterator)); 32 break; 33 case PRE_ORDER_ITERATOR: 34 ImplCycleCollectionUnlink( 35 static_cast<PreContentIterator&>(*tmp->mContentIterator)); 36 break; 37 case SUBTREE_ITERATOR: 38 ImplCycleCollectionUnlink( 39 static_cast<ContentSubtreeIterator&>(*tmp->mContentIterator)); 40 break; 41 } 42 } 43 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 44 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptableContentIterator) 45 if (tmp->mContentIterator) { 46 switch (tmp->mIteratorType) { 47 case POST_ORDER_ITERATOR: 48 default: 49 ImplCycleCollectionTraverse( 50 cb, static_cast<PostContentIterator&>(*tmp->mContentIterator), 51 "mContentIterator"); 52 break; 53 case PRE_ORDER_ITERATOR: 54 ImplCycleCollectionTraverse( 55 cb, static_cast<PreContentIterator&>(*tmp->mContentIterator), 56 "mContentIterator"); 57 break; 58 case SUBTREE_ITERATOR: 59 ImplCycleCollectionTraverse( 60 cb, static_cast<ContentSubtreeIterator&>(*tmp->mContentIterator), 61 "mContentIterator"); 62 break; 63 } 64 } 65 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 66 67 ScriptableContentIterator::ScriptableContentIterator() 68 : mIteratorType(NOT_INITIALIZED) {} 69 70 void ScriptableContentIterator::EnsureContentIterator() { 71 if (mContentIterator) { 72 return; 73 } 74 switch (mIteratorType) { 75 case POST_ORDER_ITERATOR: 76 default: 77 mContentIterator = MakeUnique<PostContentIterator>(); 78 break; 79 case PRE_ORDER_ITERATOR: 80 mContentIterator = MakeUnique<PreContentIterator>(); 81 break; 82 case SUBTREE_ITERATOR: 83 mContentIterator = MakeUnique<ContentSubtreeIterator>(); 84 break; 85 } 86 } 87 88 NS_IMETHODIMP 89 ScriptableContentIterator::InitWithRootNode(IteratorType aType, 90 nsINode* aRoot) { 91 if (aType == NOT_INITIALIZED || 92 (mIteratorType != NOT_INITIALIZED && aType != mIteratorType)) { 93 return NS_ERROR_INVALID_ARG; 94 } 95 mIteratorType = aType; 96 EnsureContentIterator(); 97 return mContentIterator->Init(aRoot); 98 } 99 100 NS_IMETHODIMP 101 ScriptableContentIterator::InitWithRange(IteratorType aType, nsRange* aRange) { 102 if (aType == NOT_INITIALIZED || 103 (mIteratorType != NOT_INITIALIZED && aType != mIteratorType)) { 104 return NS_ERROR_INVALID_ARG; 105 } 106 mIteratorType = aType; 107 EnsureContentIterator(); 108 return mContentIterator->Init(aRange); 109 } 110 111 NS_IMETHODIMP 112 ScriptableContentIterator::InitWithRangeAllowCrossShadowBoundary( 113 IteratorType aType, nsRange* aRange) { 114 if (aType == NOT_INITIALIZED || 115 (mIteratorType != NOT_INITIALIZED && aType != mIteratorType) || 116 aType != SUBTREE_ITERATOR) { 117 return NS_ERROR_INVALID_ARG; 118 } 119 120 mIteratorType = aType; 121 MOZ_ASSERT(mIteratorType == SUBTREE_ITERATOR); 122 EnsureContentIterator(); 123 return static_cast<ContentSubtreeIterator*>(mContentIterator.get()) 124 ->InitWithAllowCrossShadowBoundary(aRange); 125 } 126 127 NS_IMETHODIMP 128 ScriptableContentIterator::InitWithPositions(IteratorType aType, 129 nsINode* aStartContainer, 130 uint32_t aStartOffset, 131 nsINode* aEndContainer, 132 uint32_t aEndOffset) { 133 if (aType == NOT_INITIALIZED || 134 (mIteratorType != NOT_INITIALIZED && aType != mIteratorType)) { 135 return NS_ERROR_INVALID_ARG; 136 } 137 mIteratorType = aType; 138 EnsureContentIterator(); 139 return mContentIterator->Init(aStartContainer, aStartOffset, aEndContainer, 140 aEndOffset); 141 } 142 143 NS_IMETHODIMP 144 ScriptableContentIterator::First() { 145 if (!mContentIterator) { 146 return NS_ERROR_NOT_INITIALIZED; 147 } 148 mContentIterator->First(); 149 return NS_OK; 150 } 151 152 NS_IMETHODIMP 153 ScriptableContentIterator::Last() { 154 if (!mContentIterator) { 155 return NS_ERROR_NOT_INITIALIZED; 156 } 157 mContentIterator->Last(); 158 return NS_OK; 159 } 160 161 NS_IMETHODIMP 162 ScriptableContentIterator::Next() { 163 if (!mContentIterator) { 164 return NS_ERROR_NOT_INITIALIZED; 165 } 166 mContentIterator->Next(); 167 return NS_OK; 168 } 169 170 NS_IMETHODIMP 171 ScriptableContentIterator::Prev() { 172 if (!mContentIterator) { 173 return NS_ERROR_NOT_INITIALIZED; 174 } 175 mContentIterator->Prev(); 176 return NS_OK; 177 } 178 179 NS_IMETHODIMP 180 ScriptableContentIterator::GetCurrentNode(nsINode** aNode) { 181 if (!mContentIterator) { 182 return NS_ERROR_NOT_INITIALIZED; 183 } 184 NS_IF_ADDREF(*aNode = mContentIterator->GetCurrentNode()); 185 return NS_OK; 186 } 187 188 NS_IMETHODIMP 189 ScriptableContentIterator::GetIsDone(bool* aIsDone) { 190 if (!mContentIterator) { 191 return NS_ERROR_NOT_INITIALIZED; 192 } 193 *aIsDone = mContentIterator->IsDone(); 194 return NS_OK; 195 } 196 197 NS_IMETHODIMP 198 ScriptableContentIterator::PositionAt(nsINode* aNode) { 199 if (!mContentIterator) { 200 return NS_ERROR_NOT_INITIALIZED; 201 } 202 return mContentIterator->PositionAt(aNode); 203 } 204 205 } // namespace mozilla