1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3
* The contents of this file are subject to the Mozilla Public
4
* License Version 1.1 (the "License"); you may not use this file
5
* except in compliance with the License. You may obtain a copy of
6
* the License at http://www.mozilla.org/MPL/
8
* Software distributed under the License is distributed on an "AS
9
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
* implied. See the License for the specific language governing
11
* rights and limitations under the License.
13
* The Original Code is the Mozilla browser.
15
* The Initial Developer of the Original Code is Netscape
16
* Communications, Inc. Portions created by Netscape are
17
* Copyright (C) 1999, Mozilla. All Rights Reserved.
20
* Travis Bogard <travis@netscape.com>
23
#include "nsDocShell.h"
24
#include "nsDSURIContentListener.h"
25
#include "nsIChannel.h"
26
#include "nsXPIDLString.h"
27
#include "nsIServiceManager.h"
28
#include "nsIDOMWindowInternal.h"
30
//*****************************************************************************
31
//*** nsDSURIContentListener: Object Management
32
//*****************************************************************************
34
nsDSURIContentListener::nsDSURIContentListener() : mDocShell(nsnull),
35
mParentContentListener(nsnull)
39
nsDSURIContentListener::~nsDSURIContentListener()
44
nsDSURIContentListener::Init()
47
mCatMgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
48
NS_ENSURE_SUCCESS(rv, rv);
53
//*****************************************************************************
54
// nsDSURIContentListener::nsISupports
55
//*****************************************************************************
57
NS_IMPL_THREADSAFE_ADDREF(nsDSURIContentListener)
58
NS_IMPL_THREADSAFE_RELEASE(nsDSURIContentListener)
60
NS_INTERFACE_MAP_BEGIN(nsDSURIContentListener)
61
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener)
62
NS_INTERFACE_MAP_ENTRY(nsIURIContentListener)
63
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
66
//*****************************************************************************
67
// nsDSURIContentListener::nsIURIContentListener
68
//*****************************************************************************
71
nsDSURIContentListener::OnStartURIOpen(nsIURI* aURI, PRBool* aAbortOpen)
73
nsCOMPtr<nsIURIContentListener> parentListener;
74
GetParentContentListener(getter_AddRefs(parentListener));
76
return parentListener->OnStartURIOpen(aURI, aAbortOpen);
82
nsDSURIContentListener::DoContent(const char* aContentType,
83
PRBool aIsContentPreferred,
85
nsIStreamListener** aContentHandler,
86
PRBool* aAbortProcess)
89
NS_ENSURE_ARG_POINTER(aContentHandler);
90
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
92
*aAbortProcess = PR_FALSE;
94
// determine if the channel has just been retargeted to us...
95
nsLoadFlags loadFlags = 0;
96
nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(request);
99
aOpenedChannel->GetLoadFlags(&loadFlags);
101
if(loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)
103
// XXX: Why does this not stop the content too?
104
mDocShell->Stop(nsIWebNavigation::STOP_NETWORK);
106
mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL);
109
rv = mDocShell->CreateContentViewer(aContentType, request, aContentHandler);
111
// it's okay if we don't know how to handle the content
115
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
116
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_GetInterface(NS_STATIC_CAST(nsIDocShell*, mDocShell));
117
NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
125
nsDSURIContentListener::IsPreferred(const char* aContentType,
126
char ** aDesiredContentType,
129
NS_ENSURE_ARG_POINTER(aCanHandle);
130
NS_ENSURE_ARG_POINTER(aDesiredContentType);
132
// the docshell has no idea if it is the preferred content provider or not.
133
// It needs to ask it's parent if it is the preferred content handler or not...
135
nsCOMPtr<nsIURIContentListener> parentListener;
136
GetParentContentListener(getter_AddRefs(parentListener));
137
if (parentListener) {
138
return parentListener->IsPreferred(aContentType,
142
// we used to return false here if we didn't have a parent properly
143
// registered at the top of the docshell hierarchy to dictate what
144
// content types this docshell should be a preferred handler for. But
145
// this really makes it hard for developers using iframe or browser tags
146
// because then they need to make sure they implement
147
// nsIURIContentListener otherwise all link clicks would get sent to
148
// another window because we said we weren't the preferred handler type.
149
// I'm going to change the default now...if we can handle the content,
150
// and someone didn't EXPLICITLY set a nsIURIContentListener at the top
151
// of our docshell chain, then we'll now always attempt to process the
152
// content ourselves...
153
return CanHandleContent(aContentType,
160
nsDSURIContentListener::CanHandleContent(const char* aContentType,
161
PRBool aIsContentPreferred,
162
char ** aDesiredContentType,
163
PRBool* aCanHandleContent)
166
NS_ENSURE_ARG_POINTER(aCanHandleContent);
167
NS_ENSURE_ARG_POINTER(aDesiredContentType);
169
*aCanHandleContent = PR_FALSE;
171
if (aContentType && mCatMgr)
173
nsXPIDLCString value;
174
rv = mCatMgr->GetCategoryEntry("Gecko-Content-Viewers",
176
getter_Copies(value));
178
// If the category manager can't find what we're looking for
179
// it returns NS_ERROR_NOT_AVAILABLE, we don't want to propagate
180
// that to the caller since it's really not a failure
182
if (NS_FAILED(rv) && rv != NS_ERROR_NOT_AVAILABLE)
186
*aCanHandleContent = PR_TRUE;
193
nsDSURIContentListener::GetLoadCookie(nsISupports ** aLoadCookie)
195
return mDocShell->GetLoadCookie(aLoadCookie);
199
nsDSURIContentListener::SetLoadCookie(nsISupports * aLoadCookie)
201
return mDocShell->SetLoadCookie(aLoadCookie);
205
nsDSURIContentListener::GetParentContentListener(nsIURIContentListener**
208
if (mWeakParentContentListener)
210
nsCOMPtr<nsIURIContentListener> tempListener =
211
do_QueryReferent(mWeakParentContentListener);
212
*aParentListener = tempListener;
213
NS_IF_ADDREF(*aParentListener);
216
*aParentListener = mParentContentListener;
217
NS_IF_ADDREF(*aParentListener);
223
nsDSURIContentListener::SetParentContentListener(nsIURIContentListener*
228
// Store the parent listener as a weak ref. Parents not supporting
229
// nsISupportsWeakReference assert but may still be used.
230
mParentContentListener = nsnull;
231
mWeakParentContentListener = do_GetWeakReference(aParentListener);
232
if (!mWeakParentContentListener)
234
mParentContentListener = aParentListener;
239
mWeakParentContentListener = nsnull;
240
mParentContentListener = nsnull;
245
//*****************************************************************************
246
// nsDSURIContentListener: Helpers
247
//*****************************************************************************
249
//*****************************************************************************
250
// nsDSURIContentListener: Accessors
251
//*****************************************************************************
253
void nsDSURIContentListener::DocShell(nsDocShell* aDocShell)
255
mDocShell = aDocShell;
258
nsDocShell* nsDSURIContentListener::DocShell()