1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
8 #include "nsDocShellEnumerator.h"
10 #include "nsIDocShellTreeItem.h"
12 nsDocShellEnumerator::nsDocShellEnumerator(int32_t inEnumerationDirection
)
15 , mDocShellType(nsIDocShellTreeItem::typeAll
)
17 , mEnumerationDirection(inEnumerationDirection
)
21 nsDocShellEnumerator::~nsDocShellEnumerator()
25 NS_IMPL_ISUPPORTS(nsDocShellEnumerator
, nsISimpleEnumerator
)
28 /* nsISupports getNext (); */
29 NS_IMETHODIMP
nsDocShellEnumerator::GetNext(nsISupports
**outCurItem
)
31 NS_ENSURE_ARG_POINTER(outCurItem
);
32 *outCurItem
= nullptr;
34 nsresult rv
= EnsureDocShellArray();
35 if (NS_FAILED(rv
)) return rv
;
37 if (mCurIndex
>= mItemArray
.Length()) {
38 return NS_ERROR_FAILURE
;
41 // post-increment is important here
42 nsCOMPtr
<nsISupports
> item
= do_QueryReferent(mItemArray
[mCurIndex
++], &rv
);
43 item
.forget(outCurItem
);
47 /* boolean hasMoreElements (); */
48 NS_IMETHODIMP
nsDocShellEnumerator::HasMoreElements(bool *outHasMore
)
50 NS_ENSURE_ARG_POINTER(outHasMore
);
53 nsresult rv
= EnsureDocShellArray();
54 if (NS_FAILED(rv
)) return rv
;
56 *outHasMore
= (mCurIndex
< mItemArray
.Length());
60 nsresult
nsDocShellEnumerator::GetEnumerationRootItem(nsIDocShellTreeItem
* *aEnumerationRootItem
)
62 NS_ENSURE_ARG_POINTER(aEnumerationRootItem
);
63 nsCOMPtr
<nsIDocShellTreeItem
> item
= do_QueryReferent(mRootItem
);
64 item
.forget(aEnumerationRootItem
);
68 nsresult
nsDocShellEnumerator::SetEnumerationRootItem(nsIDocShellTreeItem
* aEnumerationRootItem
)
70 mRootItem
= do_GetWeakReference(aEnumerationRootItem
);
75 nsresult
nsDocShellEnumerator::GetEnumDocShellType(int32_t *aEnumerationItemType
)
77 NS_ENSURE_ARG_POINTER(aEnumerationItemType
);
78 *aEnumerationItemType
= mDocShellType
;
82 nsresult
nsDocShellEnumerator::SetEnumDocShellType(int32_t aEnumerationItemType
)
84 mDocShellType
= aEnumerationItemType
;
89 nsresult
nsDocShellEnumerator::First()
92 return EnsureDocShellArray();
95 nsresult
nsDocShellEnumerator::EnsureDocShellArray()
100 return BuildDocShellArray(mItemArray
);
106 nsresult
nsDocShellEnumerator::ClearState()
114 nsresult
nsDocShellEnumerator::BuildDocShellArray(nsTArray
<nsWeakPtr
>& inItemArray
)
116 NS_ENSURE_TRUE(mRootItem
, NS_ERROR_NOT_INITIALIZED
);
118 nsCOMPtr
<nsIDocShellTreeItem
> item
= do_QueryReferent(mRootItem
);
119 return BuildArrayRecursive(item
, inItemArray
);
122 nsresult
nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem
* inItem
, nsTArray
<nsWeakPtr
>& inItemArray
)
126 // add this item to the array
127 if (mDocShellType
== nsIDocShellTreeItem::typeAll
||
128 inItem
->ItemType() == mDocShellType
) {
129 nsWeakPtr weakItem
= do_GetWeakReference(inItem
);
130 if (!inItemArray
.AppendElement(weakItem
))
131 return NS_ERROR_OUT_OF_MEMORY
;
135 rv
= inItem
->GetChildCount(&numChildren
);
136 if (NS_FAILED(rv
)) return rv
;
138 for (int32_t i
= 0; i
< numChildren
; ++i
)
140 nsCOMPtr
<nsIDocShellTreeItem
> curChild
;
141 rv
= inItem
->GetChildAt(i
, getter_AddRefs(curChild
));
142 if (NS_FAILED(rv
)) return rv
;
144 rv
= BuildArrayRecursive(curChild
, inItemArray
);
145 if (NS_FAILED(rv
)) return rv
;
152 nsresult
nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem
* inItem
, nsTArray
<nsWeakPtr
>& inItemArray
)
157 rv
= inItem
->GetChildCount(&numChildren
);
158 if (NS_FAILED(rv
)) return rv
;
160 for (int32_t i
= numChildren
- 1; i
>= 0; --i
)
162 nsCOMPtr
<nsIDocShellTreeItem
> curChild
;
163 rv
= inItem
->GetChildAt(i
, getter_AddRefs(curChild
));
164 if (NS_FAILED(rv
)) return rv
;
166 rv
= BuildArrayRecursive(curChild
, inItemArray
);
167 if (NS_FAILED(rv
)) return rv
;
170 // add this item to the array
171 if (mDocShellType
== nsIDocShellTreeItem::typeAll
||
172 inItem
->ItemType() == mDocShellType
) {
173 nsWeakPtr weakItem
= do_GetWeakReference(inItem
);
174 if (!inItemArray
.AppendElement(weakItem
))
175 return NS_ERROR_OUT_OF_MEMORY
;