Line data Source code
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 "PartialSHistory.h"
8 :
9 : #include "nsIWebNavigation.h"
10 :
11 : namespace mozilla {
12 : namespace dom {
13 :
14 0 : NS_IMPL_CYCLE_COLLECTION(PartialSHistory, mOwnerFrameLoader, mGroupedSHistory)
15 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(PartialSHistory)
16 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(PartialSHistory)
17 :
18 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PartialSHistory)
19 0 : NS_INTERFACE_MAP_ENTRY(nsIPartialSHistory)
20 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPartialSHistory)
21 0 : NS_INTERFACE_MAP_ENTRY(nsISHistoryListener)
22 0 : NS_INTERFACE_MAP_ENTRY(nsIPartialSHistoryListener)
23 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
24 0 : NS_INTERFACE_MAP_END
25 :
26 0 : PartialSHistory::PartialSHistory(nsIFrameLoader* aOwnerFrameLoader)
27 : : mCount(0),
28 : mGlobalIndexOffset(0),
29 : mActive(nsIPartialSHistory::STATE_ACTIVE),
30 0 : mOwnerFrameLoader(aOwnerFrameLoader)
31 : {
32 0 : MOZ_ASSERT(aOwnerFrameLoader);
33 0 : }
34 :
35 : already_AddRefed<nsISHistory>
36 0 : PartialSHistory::GetSessionHistory()
37 : {
38 0 : if (!mOwnerFrameLoader) {
39 : // Cycle collected?
40 0 : return nullptr;
41 : }
42 :
43 0 : nsCOMPtr<nsIDocShell> docShell;
44 0 : mOwnerFrameLoader->GetDocShell(getter_AddRefs(docShell));
45 0 : if (!docShell) {
46 0 : return nullptr;
47 : }
48 :
49 0 : nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
50 0 : nsCOMPtr<nsISHistory> shistory;
51 0 : webNav->GetSessionHistory(getter_AddRefs(shistory));
52 0 : return shistory.forget();
53 : }
54 :
55 : already_AddRefed<TabParent>
56 0 : PartialSHistory::GetTabParent()
57 : {
58 0 : if (!mOwnerFrameLoader) {
59 : // Cycle collected?
60 0 : return nullptr;
61 : }
62 :
63 0 : nsCOMPtr<nsITabParent> tabParent;
64 0 : mOwnerFrameLoader->GetTabParent(getter_AddRefs(tabParent));
65 0 : return RefPtr<TabParent>(static_cast<TabParent*>(tabParent.get())).forget();
66 : }
67 :
68 : NS_IMETHODIMP
69 0 : PartialSHistory::GetCount(uint32_t* aResult)
70 : {
71 0 : if (!aResult) {
72 0 : return NS_ERROR_INVALID_POINTER;
73 : }
74 :
75 : // If we have direct reference to nsISHistory, simply pass through.
76 0 : nsCOMPtr<nsISHistory> shistory(GetSessionHistory());
77 0 : if (shistory) {
78 : int32_t count;
79 0 : nsresult rv = shistory->GetCount(&count);
80 0 : if (NS_FAILED(rv) || count < 0) {
81 0 : *aResult = 0;
82 0 : return NS_ERROR_FAILURE;
83 : }
84 0 : *aResult = count;
85 0 : return NS_OK;
86 : }
87 :
88 : // Otherwise use the cached value.
89 0 : *aResult = mCount;
90 0 : return NS_OK;
91 : }
92 :
93 : NS_IMETHODIMP
94 0 : PartialSHistory::GetGlobalIndex(int32_t* aResult)
95 : {
96 0 : if (!aResult) {
97 0 : return NS_ERROR_INVALID_POINTER;
98 : }
99 :
100 0 : nsCOMPtr<nsISHistory> shistory = GetSessionHistory();
101 0 : if (shistory) {
102 : int32_t idx;
103 0 : nsresult rv = shistory->GetIndex(&idx);
104 0 : NS_ENSURE_SUCCESS(rv, rv);
105 :
106 0 : *aResult = idx + GetGlobalIndexOffset();
107 0 : return NS_OK;
108 : }
109 :
110 0 : *aResult = mIndex + GetGlobalIndexOffset();
111 0 : return NS_OK;
112 : }
113 :
114 : NS_IMETHODIMP
115 0 : PartialSHistory::GetGlobalIndexOffset(uint32_t* aResult)
116 : {
117 0 : if (!aResult) {
118 0 : return NS_ERROR_INVALID_POINTER;
119 : }
120 :
121 : // If we have direct reference to nsISHistory, simply pass through.
122 0 : nsCOMPtr<nsISHistory> shistory(GetSessionHistory());
123 0 : if (shistory) {
124 : int32_t offset;
125 0 : nsresult rv = shistory->GetGlobalIndexOffset(&offset);
126 0 : if (NS_FAILED(rv) || offset < 0) {
127 0 : *aResult = 0;
128 0 : return NS_ERROR_FAILURE;
129 : }
130 0 : *aResult = offset;
131 0 : return NS_OK;
132 : }
133 :
134 : // Otherwise use the cached value.
135 0 : *aResult = mGlobalIndexOffset;
136 0 : return NS_OK;
137 : }
138 :
139 : NS_IMETHODIMP
140 0 : PartialSHistory::GetOwnerFrameLoader(nsIFrameLoader** aResult)
141 : {
142 0 : nsCOMPtr<nsIFrameLoader> loader(mOwnerFrameLoader);
143 0 : loader.forget(aResult);
144 0 : return NS_OK;
145 : }
146 :
147 : NS_IMETHODIMP
148 0 : PartialSHistory::OnAttachGroupedSHistory(nsIGroupedSHistory* aGroup, uint32_t aOffset)
149 : {
150 0 : MOZ_ASSERT(!mGroupedSHistory, "Only may join a single GroupedSHistory");
151 :
152 0 : mActive = nsIPartialSHistory::STATE_ACTIVE;
153 0 : mGlobalIndexOffset = aOffset;
154 0 : mGroupedSHistory = aGroup;
155 :
156 : // If we have direct reference to nsISHistory, simply pass through.
157 0 : nsCOMPtr<nsISHistory> shistory(GetSessionHistory());
158 0 : if (shistory) {
159 : // nsISHistory uses int32_t
160 0 : if (aOffset > INT32_MAX) {
161 0 : return NS_ERROR_FAILURE;
162 : }
163 0 : return shistory->OnAttachGroupedSHistory(aOffset);
164 : }
165 :
166 : // Otherwise notify through TabParent.
167 0 : RefPtr<TabParent> tabParent(GetTabParent());
168 0 : if (!tabParent) {
169 : // We have neither shistory nor tabParent?
170 0 : NS_WARNING("Unable to get shitory nor tabParent!");
171 0 : return NS_ERROR_UNEXPECTED;
172 : }
173 0 : Unused << tabParent->SendNotifyAttachGroupedSHistory(aOffset);
174 :
175 0 : return NS_OK;
176 : }
177 :
178 : NS_IMETHODIMP
179 0 : PartialSHistory::HandleSHistoryUpdate(uint32_t aCount, uint32_t aIndex, bool aTruncate)
180 : {
181 : // Update our local cache of mCount and mIndex
182 0 : mCount = aCount;
183 0 : mIndex = aIndex;
184 0 : return SHistoryDidUpdate(aTruncate);
185 : }
186 :
187 : nsresult
188 0 : PartialSHistory::SHistoryDidUpdate(bool aTruncate /* = false */)
189 : {
190 0 : if (!mOwnerFrameLoader) {
191 : // Cycle collected?
192 0 : return NS_ERROR_UNEXPECTED;
193 : }
194 :
195 0 : if (!mGroupedSHistory) {
196 : // It's OK if we don't have a grouped history, that just means that we
197 : // aren't in a grouped shistory, so we don't need to do anything.
198 0 : return NS_OK;
199 : }
200 :
201 0 : mGroupedSHistory->HandleSHistoryUpdate(this, aTruncate);
202 0 : return NS_OK;
203 : }
204 :
205 : NS_IMETHODIMP
206 0 : PartialSHistory::OnActive(uint32_t aGlobalLength, uint32_t aTargetLocalIndex)
207 : {
208 0 : MOZ_ASSERT(mGroupedSHistory);
209 :
210 0 : mActive = nsIPartialSHistory::STATE_ACTIVE;
211 :
212 : // In-process case.
213 0 : nsCOMPtr<nsISHistory> shistory(GetSessionHistory());
214 0 : if (shistory) {
215 : // nsISHistory uses int32_t
216 0 : if (aGlobalLength > INT32_MAX || aTargetLocalIndex > INT32_MAX) {
217 0 : return NS_ERROR_FAILURE;
218 : }
219 0 : return shistory->OnPartialSHistoryActive(aGlobalLength, aTargetLocalIndex);
220 : }
221 :
222 : // Cross-process case.
223 0 : RefPtr<TabParent> tabParent(GetTabParent());
224 0 : if (!tabParent) {
225 : // We have neither shistory nor tabParent?
226 0 : NS_WARNING("Unable to get shitory nor tabParent!");
227 0 : return NS_ERROR_UNEXPECTED;
228 : }
229 0 : Unused << tabParent->SendNotifyPartialSHistoryActive(aGlobalLength,
230 : aTargetLocalIndex);
231 :
232 0 : return NS_OK;
233 : }
234 :
235 : NS_IMETHODIMP
236 0 : PartialSHistory::OnDeactive()
237 : {
238 0 : MOZ_ASSERT(mGroupedSHistory);
239 :
240 0 : mActive = nsIPartialSHistory::STATE_INACTIVE;
241 :
242 : // In-process case.
243 0 : nsCOMPtr<nsISHistory> shistory(GetSessionHistory());
244 0 : if (shistory) {
245 0 : if (NS_FAILED(shistory->OnPartialSHistoryDeactive())) {
246 0 : return NS_ERROR_FAILURE;
247 : }
248 0 : return NS_OK;
249 : }
250 :
251 : // Cross-process case.
252 0 : RefPtr<TabParent> tabParent(GetTabParent());
253 0 : if (!tabParent) {
254 : // We have neither shistory nor tabParent?
255 0 : NS_WARNING("Unable to get shitory nor tabParent!");
256 0 : return NS_ERROR_UNEXPECTED;
257 : }
258 0 : Unused << tabParent->SendNotifyPartialSHistoryDeactive();
259 0 : return NS_OK;
260 : }
261 :
262 : NS_IMETHODIMP
263 0 : PartialSHistory::GetActiveState(int32_t* aActive)
264 : {
265 0 : *aActive = mActive;
266 0 : return NS_OK;
267 : }
268 :
269 : NS_IMETHODIMP
270 0 : PartialSHistory::SetActiveState(int32_t aActive)
271 : {
272 0 : mActive = aActive;
273 0 : return NS_OK;
274 : }
275 :
276 : NS_IMETHODIMP
277 0 : PartialSHistory::GetGroupedSHistory(nsIGroupedSHistory** aGrouped)
278 : {
279 0 : nsCOMPtr<nsIGroupedSHistory> shistory = mGroupedSHistory;
280 0 : shistory.forget(aGrouped);
281 0 : return NS_OK;
282 : }
283 :
284 : /*******************************************************************************
285 : * nsIPartialSHistoryListener
286 : ******************************************************************************/
287 :
288 : NS_IMETHODIMP
289 0 : PartialSHistory::OnRequestCrossBrowserNavigation(uint32_t aIndex)
290 : {
291 0 : if (!mOwnerFrameLoader) {
292 : // Cycle collected?
293 0 : return NS_ERROR_UNEXPECTED;
294 : }
295 :
296 0 : nsCOMPtr<nsISupports> promise;
297 0 : return mOwnerFrameLoader->RequestGroupedHistoryNavigation(aIndex, getter_AddRefs(promise));
298 : }
299 :
300 : /*******************************************************************************
301 : * nsISHistoryListener
302 : ******************************************************************************/
303 :
304 : NS_IMETHODIMP
305 0 : PartialSHistory::OnLengthChanged(int32_t aCount)
306 : {
307 0 : return SHistoryDidUpdate(/* aTruncate = */ true);
308 : }
309 :
310 : NS_IMETHODIMP
311 0 : PartialSHistory::OnIndexChanged(int32_t aIndex)
312 : {
313 0 : return SHistoryDidUpdate(/* aTruncate = */ false);
314 : }
315 :
316 : NS_IMETHODIMP
317 0 : PartialSHistory::OnHistoryNewEntry(nsIURI *aNewURI, int32_t aOldIndex)
318 : {
319 0 : return NS_ERROR_NOT_IMPLEMENTED;
320 : }
321 :
322 : NS_IMETHODIMP
323 0 : PartialSHistory::OnHistoryGoBack(nsIURI *aBackURI, bool *_retval)
324 : {
325 0 : return NS_ERROR_NOT_IMPLEMENTED;
326 : }
327 :
328 : NS_IMETHODIMP
329 0 : PartialSHistory::OnHistoryGoForward(nsIURI *aForwardURI, bool *_retval)
330 : {
331 0 : return NS_ERROR_NOT_IMPLEMENTED;
332 : }
333 :
334 : NS_IMETHODIMP
335 0 : PartialSHistory::OnHistoryReload(nsIURI *aReloadURI, uint32_t aReloadFlags, bool *_retval)
336 : {
337 0 : return NS_ERROR_NOT_IMPLEMENTED;
338 : }
339 :
340 : NS_IMETHODIMP
341 0 : PartialSHistory::OnHistoryGotoIndex(int32_t aIndex, nsIURI *aGotoURI, bool *_retval)
342 : {
343 0 : return NS_ERROR_NOT_IMPLEMENTED;
344 : }
345 :
346 : NS_IMETHODIMP
347 0 : PartialSHistory::OnHistoryPurge(int32_t aNumEntries, bool *_retval)
348 : {
349 0 : return NS_ERROR_NOT_IMPLEMENTED;
350 : }
351 :
352 : NS_IMETHODIMP
353 0 : PartialSHistory::OnHistoryReplaceEntry(int32_t aIndex)
354 : {
355 0 : return NS_ERROR_NOT_IMPLEMENTED;
356 : }
357 :
358 : } // namespace dom
359 : } // namespace mozilla
|