Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/docshell/base/nsDocShellEnumerator.cpp
Line
Count
Source (jump to first uncovered line)
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 "nsDocShellEnumerator.h"
8
9
#include "nsIDocShellTreeItem.h"
10
11
nsDocShellEnumerator::nsDocShellEnumerator(int32_t aEnumerationDirection)
12
  : mRootItem(nullptr)
13
  , mCurIndex(0)
14
  , mDocShellType(nsIDocShellTreeItem::typeAll)
15
  , mArrayValid(false)
16
  , mEnumerationDirection(aEnumerationDirection)
17
0
{
18
0
}
19
20
nsDocShellEnumerator::~nsDocShellEnumerator()
21
0
{
22
0
}
23
24
NS_IMETHODIMP
25
nsDocShellEnumerator::GetNext(nsISupports** aResult)
26
0
{
27
0
  NS_ENSURE_ARG_POINTER(aResult);
28
0
  *aResult = nullptr;
29
0
30
0
  nsresult rv = EnsureDocShellArray();
31
0
  if (NS_FAILED(rv)) {
32
0
    return rv;
33
0
  }
34
0
35
0
  if (mCurIndex >= mItemArray.Length()) {
36
0
    return NS_ERROR_FAILURE;
37
0
  }
38
0
39
0
  // post-increment is important here
40
0
  nsCOMPtr<nsISupports> item = do_QueryReferent(mItemArray[mCurIndex++], &rv);
41
0
  item.forget(aResult);
42
0
  return rv;
43
0
}
44
45
NS_IMETHODIMP
46
nsDocShellEnumerator::HasMoreElements(bool* aResult)
47
0
{
48
0
  NS_ENSURE_ARG_POINTER(aResult);
49
0
  *aResult = false;
50
0
51
0
  nsresult rv = EnsureDocShellArray();
52
0
  if (NS_FAILED(rv)) {
53
0
    return rv;
54
0
  }
55
0
56
0
  *aResult = (mCurIndex < mItemArray.Length());
57
0
  return NS_OK;
58
0
}
59
60
nsresult
61
nsDocShellEnumerator::GetEnumerationRootItem(
62
    nsIDocShellTreeItem** aEnumerationRootItem)
63
0
{
64
0
  NS_ENSURE_ARG_POINTER(aEnumerationRootItem);
65
0
  nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
66
0
  item.forget(aEnumerationRootItem);
67
0
  return NS_OK;
68
0
}
69
70
nsresult
71
nsDocShellEnumerator::SetEnumerationRootItem(
72
    nsIDocShellTreeItem* aEnumerationRootItem)
73
0
{
74
0
  mRootItem = do_GetWeakReference(aEnumerationRootItem);
75
0
  ClearState();
76
0
  return NS_OK;
77
0
}
78
79
nsresult
80
nsDocShellEnumerator::GetEnumDocShellType(int32_t* aEnumerationItemType)
81
0
{
82
0
  NS_ENSURE_ARG_POINTER(aEnumerationItemType);
83
0
  *aEnumerationItemType = mDocShellType;
84
0
  return NS_OK;
85
0
}
86
87
nsresult
88
nsDocShellEnumerator::SetEnumDocShellType(int32_t aEnumerationItemType)
89
0
{
90
0
  mDocShellType = aEnumerationItemType;
91
0
  ClearState();
92
0
  return NS_OK;
93
0
}
94
95
nsresult
96
nsDocShellEnumerator::First()
97
0
{
98
0
  mCurIndex = 0;
99
0
  return EnsureDocShellArray();
100
0
}
101
102
nsresult
103
nsDocShellEnumerator::EnsureDocShellArray()
104
0
{
105
0
  if (!mArrayValid) {
106
0
    mArrayValid = true;
107
0
    return BuildDocShellArray(mItemArray);
108
0
  }
109
0
110
0
  return NS_OK;
111
0
}
112
113
nsresult
114
nsDocShellEnumerator::ClearState()
115
0
{
116
0
  mItemArray.Clear();
117
0
  mArrayValid = false;
118
0
  mCurIndex = 0;
119
0
  return NS_OK;
120
0
}
121
122
nsresult
123
nsDocShellEnumerator::BuildDocShellArray(nsTArray<nsWeakPtr>& aItemArray)
124
0
{
125
0
  NS_ENSURE_TRUE(mRootItem, NS_ERROR_NOT_INITIALIZED);
126
0
  aItemArray.Clear();
127
0
  nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
128
0
  return BuildArrayRecursive(item, aItemArray);
129
0
}
130
131
nsresult
132
nsDocShellForwardsEnumerator::BuildArrayRecursive(
133
    nsIDocShellTreeItem* aItem,
134
    nsTArray<nsWeakPtr>& aItemArray)
135
0
{
136
0
  nsresult rv;
137
0
138
0
  // add this item to the array
139
0
  if (mDocShellType == nsIDocShellTreeItem::typeAll ||
140
0
      aItem->ItemType() == mDocShellType) {
141
0
    if (!aItemArray.AppendElement(do_GetWeakReference(aItem))) {
142
0
      return NS_ERROR_OUT_OF_MEMORY;
143
0
    }
144
0
  }
145
0
146
0
  int32_t numChildren;
147
0
  rv = aItem->GetChildCount(&numChildren);
148
0
  if (NS_FAILED(rv)) {
149
0
    return rv;
150
0
  }
151
0
152
0
  for (int32_t i = 0; i < numChildren; ++i) {
153
0
    nsCOMPtr<nsIDocShellTreeItem> curChild;
154
0
    rv = aItem->GetChildAt(i, getter_AddRefs(curChild));
155
0
    if (NS_FAILED(rv)) {
156
0
      return rv;
157
0
    }
158
0
159
0
    rv = BuildArrayRecursive(curChild, aItemArray);
160
0
    if (NS_FAILED(rv)) {
161
0
      return rv;
162
0
    }
163
0
  }
164
0
165
0
  return NS_OK;
166
0
}
167
168
nsresult
169
nsDocShellBackwardsEnumerator::BuildArrayRecursive(
170
    nsIDocShellTreeItem* aItem,
171
    nsTArray<nsWeakPtr>& aItemArray)
172
0
{
173
0
  nsresult rv;
174
0
175
0
  int32_t numChildren;
176
0
  rv = aItem->GetChildCount(&numChildren);
177
0
  if (NS_FAILED(rv)) {
178
0
    return rv;
179
0
  }
180
0
181
0
  for (int32_t i = numChildren - 1; i >= 0; --i) {
182
0
    nsCOMPtr<nsIDocShellTreeItem> curChild;
183
0
    rv = aItem->GetChildAt(i, getter_AddRefs(curChild));
184
0
    if (NS_FAILED(rv)) {
185
0
      return rv;
186
0
    }
187
0
188
0
    rv = BuildArrayRecursive(curChild, aItemArray);
189
0
    if (NS_FAILED(rv)) {
190
0
      return rv;
191
0
    }
192
0
  }
193
0
194
0
  // add this item to the array
195
0
  if (mDocShellType == nsIDocShellTreeItem::typeAll ||
196
0
      aItem->ItemType() == mDocShellType) {
197
0
    if (!aItemArray.AppendElement(do_GetWeakReference(aItem))) {
198
0
      return NS_ERROR_OUT_OF_MEMORY;
199
0
    }
200
0
  }
201
0
202
0
  return NS_OK;
203
0
}