C:\mindstorms\source\gecko\modified files\nsDSURIContentListener.cppC:\mindstorms\source\gecko\original files and diffs\nsDSURIContentListener.cpp
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * 2 *
3 * The contents of this file are subject to the Mozilla Public 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 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 5 * except in compliance with the License. You may obtain a copy of
6 * the License at http://www.mozilla.org/MPL/ 6 * the License at http://www.mozilla.org/MPL/
7 * 7 *
8 * Software distributed under the License is distributed on an "AS 8 * Software distributed under the License is distributed on an "AS
9 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 9 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10 * implied. See the License for the specific language governing 10 * implied. See the License for the specific language governing
11 * rights and limitations under the License. 11 * rights and limitations under the License.
12 * 12 *
13 * The Original Code is the Mozilla browser. 13 * The Original Code is the Mozilla browser.
14 * 14 *
15 * The Initial Developer of the Original Code is Netscape 15 * The Initial Developer of the Original Code is Netscape
16 * Communications Corporation. Portions created by Netscape are 16 * Communications, Inc. Portions created by Netscape are
17 * Copyright (C) 1998-2000 Netscape Communications Corporation. All 
18 * Rights Reserved.17 * Copyright (C) 1999, Mozilla. All Rights Reserved.
19 * 18 *
20 * Contributor(s): 19 * Contributor(s):
21 * Travis Bogard <travis@netscape.com> 20 * Travis Bogard <travis@netscape.com>
22 *  
23 * Alternatively, the contents of this file may be used under the 
24 * terms of the GNU General Public License Version 2 or later (the 
25 * "GPL"), in which case the provisions of the GPL are applicable  
26 * instead of those above. If you wish to allow use of your  
27 * version of this file only under the terms of the GPL and not to 
28 * allow others to use your version of this file under the MPL, 
29 * indicate your decision by deleting the provisions above and 
30 * replace them with the notice and other provisions required by 
31 * the GPL. If you do not delete the provisions above, a recipient 
32 * may use your version of this file under either the MPL or the 
33 * GPL. 
34 */ 21 */
35  22 
36#include "nsDocShell.h" 23#include "nsDocShell.h"
37#include "nsDSURIContentListener.h" 24#include "nsDSURIContentListener.h"
38#include "nsIChannel.h" 25#include "nsIChannel.h"
39#include "nsXPIDLString.h" 26#include "nsXPIDLString.h"
40#include "nsIServiceManager.h" 27#include "nsIServiceManager.h"
41#include "nsIDOMWindowInternal.h" 28#include "nsIDOMWindowInternal.h"
42  29 
43//***************************************************************************** 30//*****************************************************************************
44//*** nsDSURIContentListener: Object Management 31//*** nsDSURIContentListener: Object Management
45//***************************************************************************** 32//*****************************************************************************
46  33 
47nsDSURIContentListener::nsDSURIContentListener() : mDocShell(nsnull), 34nsDSURIContentListener::nsDSURIContentListener() : mDocShell(nsnull),
48    mParentContentListener(nsnull) 35    mParentContentListener(nsnull)
49{ 36{
50} 37}
51  38 
52nsDSURIContentListener::~nsDSURIContentListener() 39nsDSURIContentListener::~nsDSURIContentListener()
53{ 40{
54} 41}
55  42 
56nsresult 43nsresult
57nsDSURIContentListener::Init() 44nsDSURIContentListener::Init()
58{ 45{
59    nsresult rv = NS_OK; 46    nsresult rv = NS_OK;
60    mCatMgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); 47    mCatMgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
61    NS_ENSURE_SUCCESS(rv, rv); 48    NS_ENSURE_SUCCESS(rv, rv);
62    return rv; 49    return rv;
63} 50}
64  51 
65  52 
66//***************************************************************************** 53//*****************************************************************************
67// nsDSURIContentListener::nsISupports 54// nsDSURIContentListener::nsISupports
68//***************************************************************************** 55//*****************************************************************************
69  56 
70NS_IMPL_THREADSAFE_ADDREF(nsDSURIContentListener) 57NS_IMPL_THREADSAFE_ADDREF(nsDSURIContentListener)
71NS_IMPL_THREADSAFE_RELEASE(nsDSURIContentListener) 58NS_IMPL_THREADSAFE_RELEASE(nsDSURIContentListener)
72  59 
73NS_INTERFACE_MAP_BEGIN(nsDSURIContentListener) 60NS_INTERFACE_MAP_BEGIN(nsDSURIContentListener)
74    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener) 61    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener)
75    NS_INTERFACE_MAP_ENTRY(nsIURIContentListener) 62    NS_INTERFACE_MAP_ENTRY(nsIURIContentListener)
76    NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) 63    NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
77NS_INTERFACE_MAP_END 64NS_INTERFACE_MAP_END
78  65 
79//***************************************************************************** 66//*****************************************************************************
80// nsDSURIContentListener::nsIURIContentListener 67// nsDSURIContentListener::nsIURIContentListener
81//***************************************************************************** 68//*****************************************************************************
82  69 
83NS_IMETHODIMP 70NS_IMETHODIMP
84nsDSURIContentListener::OnStartURIOpen(nsIURI* aURI, PRBool* aAbortOpen) 71nsDSURIContentListener::OnStartURIOpen(nsIURI* aURI, PRBool* aAbortOpen)
85{ 72{
86    nsCOMPtr<nsIURIContentListener> parentListener; 73    nsCOMPtr<nsIURIContentListener> parentListener;
87    GetParentContentListener(getter_AddRefs(parentListener)); 74    GetParentContentListener(getter_AddRefs(parentListener));
88    if (parentListener) {75    if (parentListener)
89        nsresult result; 
90        result = parentListener->OnStartURIOpen(aURI, aAbortOpen);76        return parentListener->OnStartURIOpen(aURI, aAbortOpen);
91         
92        // if we should pay attention to parent 
93        if (result != NS_ERROR_NOT_IMPLEMENTED) 
94            return result; 
95        } 
96  77 
97    return NS_OK; 78    return NS_OK;
98} 79}
99  80 
100NS_IMETHODIMP 81NS_IMETHODIMP
101nsDSURIContentListener::DoContent(const char* aContentType, 82nsDSURIContentListener::DoContent(const char* aContentType,
102                                  PRBool aIsContentPreferred, 83                                  PRBool aIsContentPreferred,
103                                  nsIRequest* request, 84                                  nsIRequest* request,
104                                  nsIStreamListener** aContentHandler, 85                                  nsIStreamListener** aContentHandler,
105                                  PRBool* aAbortProcess) 86                                  PRBool* aAbortProcess)
106{ 87{
107    nsresult rv; 88    nsresult rv;
108    NS_ENSURE_ARG_POINTER(aContentHandler); 89    NS_ENSURE_ARG_POINTER(aContentHandler);
109    NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); 90    NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
110    if(aAbortProcess) 91    if(aAbortProcess)
111        *aAbortProcess = PR_FALSE; 92        *aAbortProcess = PR_FALSE;
112  93 
113    // determine if the channel has just been retargeted to us... 94    // determine if the channel has just been retargeted to us...
114    nsLoadFlags loadFlags = 0; 95    nsLoadFlags loadFlags = 0;
115    nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(request); 96    nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(request);
116  97 
117    if (aOpenedChannel) 98    if (aOpenedChannel)
118      aOpenedChannel->GetLoadFlags(&loadFlags); 99      aOpenedChannel->GetLoadFlags(&loadFlags);
119  100 
120    if(loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) 101    if(loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)
121    { 102    {
122        // XXX: Why does this not stop the content too? 103        // XXX: Why does this not stop the content too?
123        mDocShell->Stop(nsIWebNavigation::STOP_NETWORK); 104        mDocShell->Stop(nsIWebNavigation::STOP_NETWORK);
124  105 
125        mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL); 106        mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL);
126    } 107    }
127  108 
128    rv = mDocShell->CreateContentViewer(aContentType, request, aContentHandler); 109    rv = mDocShell->CreateContentViewer(aContentType, request, aContentHandler);
129    if (NS_FAILED(rv)) { 110    if (NS_FAILED(rv)) {
130       // it's okay if we don't know how to handle the content 111       // it's okay if we don't know how to handle the content
131        return NS_OK; 112        return NS_OK;
132    } 113    }
133  114 
134    if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { 115    if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
135        nsCOMPtr<nsIDOMWindowInternal> domWindow = do_GetInterface(NS_STATIC_CAST(nsIDocShell*, mDocShell)); 116        nsCOMPtr<nsIDOMWindowInternal> domWindow = do_GetInterface(NS_STATIC_CAST(nsIDocShell*, mDocShell));
136        NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); 117        NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
137        domWindow->Focus(); 118        domWindow->Focus();
138    } 119    }
139  120 
140    return NS_OK; 121    return NS_OK;
141} 122}
142  123 
143NS_IMETHODIMP 124NS_IMETHODIMP
144nsDSURIContentListener::IsPreferred(const char* aContentType, 125nsDSURIContentListener::IsPreferred(const char* aContentType,
145                                    char ** aDesiredContentType, 126                                    char ** aDesiredContentType,
146                                    PRBool* aCanHandle) 127                                    PRBool* aCanHandle)
147{ 128{
148    NS_ENSURE_ARG_POINTER(aCanHandle); 129    NS_ENSURE_ARG_POINTER(aCanHandle);
149    NS_ENSURE_ARG_POINTER(aDesiredContentType); 130    NS_ENSURE_ARG_POINTER(aDesiredContentType);
150  131 
151    // the docshell has no idea if it is the preferred content provider or not. 132    // the docshell has no idea if it is the preferred content provider or not.
152    // It needs to ask it's parent if it is the preferred content handler or not... 133    // It needs to ask it's parent if it is the preferred content handler or not...
153  134 
154    nsCOMPtr<nsIURIContentListener> parentListener; 135    nsCOMPtr<nsIURIContentListener> parentListener;
155    GetParentContentListener(getter_AddRefs(parentListener)); 136    GetParentContentListener(getter_AddRefs(parentListener));
156    if (parentListener) { 137    if (parentListener) {
157        nsresult result; 
158        result = parentListener->IsPreferred(aContentType,138        return parentListener->IsPreferred(aContentType,
159                                                   aDesiredContentType, 139                                                   aDesiredContentType,
160                                                   aCanHandle); 140                                                   aCanHandle);
161        // if we should pay attention to parent 
162        if (result != NS_ERROR_NOT_IMPLEMENTED) 
163            return result; 
164    } 141    }
165    // we used to return false here if we didn't have a parent properly 142    // we used to return false here if we didn't have a parent properly
166    // registered at the top of the docshell hierarchy to dictate what 143    // registered at the top of the docshell hierarchy to dictate what
167    // content types this docshell should be a preferred handler for. But 144    // content types this docshell should be a preferred handler for. But
168    // this really makes it hard for developers using iframe or browser tags 145    // this really makes it hard for developers using iframe or browser tags
169    // because then they need to make sure they implement 146    // because then they need to make sure they implement
170    // nsIURIContentListener otherwise all link clicks would get sent to 147    // nsIURIContentListener otherwise all link clicks would get sent to
171    // another window because we said we weren't the preferred handler type. 148    // another window because we said we weren't the preferred handler type.
172    // I'm going to change the default now...if we can handle the content, 149    // I'm going to change the default now...if we can handle the content,
173    // and someone didn't EXPLICITLY set a nsIURIContentListener at the top 150    // and someone didn't EXPLICITLY set a nsIURIContentListener at the top
174    // of our docshell chain, then we'll now always attempt to process the 151    // of our docshell chain, then we'll now always attempt to process the
175    // content ourselves... 152    // content ourselves...
176    return CanHandleContent(aContentType, 153    return CanHandleContent(aContentType,
177                            PR_TRUE, 154                            PR_TRUE,
178                            aDesiredContentType, 155                            aDesiredContentType,
179                            aCanHandle); 156                            aCanHandle);
180} 157}
181  158 
182NS_IMETHODIMP 159NS_IMETHODIMP
183nsDSURIContentListener::CanHandleContent(const char* aContentType, 160nsDSURIContentListener::CanHandleContent(const char* aContentType,
184                                         PRBool aIsContentPreferred, 161                                         PRBool aIsContentPreferred,
185                                         char ** aDesiredContentType, 162                                         char ** aDesiredContentType,
186                                         PRBool* aCanHandleContent) 163                                         PRBool* aCanHandleContent)
187{ 164{
188    nsresult rv; 165    nsresult rv;
189    NS_ENSURE_ARG_POINTER(aCanHandleContent); 166    NS_ENSURE_ARG_POINTER(aCanHandleContent);
190    NS_ENSURE_ARG_POINTER(aDesiredContentType); 167    NS_ENSURE_ARG_POINTER(aDesiredContentType);
191  168 
192    *aCanHandleContent = PR_FALSE; 169    *aCanHandleContent = PR_FALSE;
193  170 
194    if (aContentType && mCatMgr) 171    if (aContentType && mCatMgr)
195    { 172    {
196        nsXPIDLCString value; 173        nsXPIDLCString value;
197        rv = mCatMgr->GetCategoryEntry("Gecko-Content-Viewers", 174        rv = mCatMgr->GetCategoryEntry("Gecko-Content-Viewers",
198                                       aContentType, 175                                       aContentType,
199                                       getter_Copies(value)); 176                                       getter_Copies(value));
200  177 
201        // If the category manager can't find what we're looking for 178        // If the category manager can't find what we're looking for
202        // it returns NS_ERROR_NOT_AVAILABLE, we don't want to propagate 179        // it returns NS_ERROR_NOT_AVAILABLE, we don't want to propagate
203        // that to the caller since it's really not a failure 180        // that to the caller since it's really not a failure
204  181 
205        if (NS_FAILED(rv) && rv != NS_ERROR_NOT_AVAILABLE) 182        if (NS_FAILED(rv) && rv != NS_ERROR_NOT_AVAILABLE)
206            return rv; 183            return rv;
207  184 
208        if (value && *value) 185        if (value && *value)
209            *aCanHandleContent = PR_TRUE; 186            *aCanHandleContent = PR_TRUE;
210    } 187    }
211  188 
212    return NS_OK; 189    return NS_OK;
213} 190}
214  191 
215NS_IMETHODIMP 192NS_IMETHODIMP
216nsDSURIContentListener::GetLoadCookie(nsISupports ** aLoadCookie) 193nsDSURIContentListener::GetLoadCookie(nsISupports ** aLoadCookie)
217{ 194{
218    return mDocShell->GetLoadCookie(aLoadCookie); 195    return mDocShell->GetLoadCookie(aLoadCookie);
219} 196}
220  197 
221NS_IMETHODIMP 198NS_IMETHODIMP
222nsDSURIContentListener::SetLoadCookie(nsISupports * aLoadCookie) 199nsDSURIContentListener::SetLoadCookie(nsISupports * aLoadCookie)
223{ 200{
224    return mDocShell->SetLoadCookie(aLoadCookie); 201    return mDocShell->SetLoadCookie(aLoadCookie);
225} 202}
226  203 
227NS_IMETHODIMP 204NS_IMETHODIMP
228nsDSURIContentListener::GetParentContentListener(nsIURIContentListener** 205nsDSURIContentListener::GetParentContentListener(nsIURIContentListener**
229                                                 aParentListener) 206                                                 aParentListener)
230{ 207{
231    if (mWeakParentContentListener) 208    if (mWeakParentContentListener)
232    { 209    {
233        nsCOMPtr<nsIURIContentListener> tempListener = 210        nsCOMPtr<nsIURIContentListener> tempListener =
234            do_QueryReferent(mWeakParentContentListener); 211            do_QueryReferent(mWeakParentContentListener);
235        *aParentListener = tempListener; 212        *aParentListener = tempListener;
236        NS_IF_ADDREF(*aParentListener); 213        NS_IF_ADDREF(*aParentListener);
237    } 214    }
238    else { 215    else {
239        *aParentListener = mParentContentListener; 216        *aParentListener = mParentContentListener;
240        NS_IF_ADDREF(*aParentListener); 217        NS_IF_ADDREF(*aParentListener);
241    } 218    }
242    return NS_OK; 219    return NS_OK;
243} 220}
244  221 
245NS_IMETHODIMP 222NS_IMETHODIMP
246nsDSURIContentListener::SetParentContentListener(nsIURIContentListener* 223nsDSURIContentListener::SetParentContentListener(nsIURIContentListener*
247                                                 aParentListener) 224                                                 aParentListener)
248{ 225{
249    if (aParentListener) 226    if (aParentListener)
250    { 227    {
251        // Store the parent listener as a weak ref. Parents not supporting 228        // Store the parent listener as a weak ref. Parents not supporting
252        // nsISupportsWeakReference assert but may still be used. 229        // nsISupportsWeakReference assert but may still be used.
253        mParentContentListener = nsnull; 230        mParentContentListener = nsnull;
254        mWeakParentContentListener = do_GetWeakReference(aParentListener); 231        mWeakParentContentListener = do_GetWeakReference(aParentListener);
255        if (!mWeakParentContentListener) 232        if (!mWeakParentContentListener)
256        { 233        {
257            mParentContentListener = aParentListener; 234            mParentContentListener = aParentListener;
258        } 235        }
259    } 236    }
260    else 237    else
261    { 238    {
262        mWeakParentContentListener = nsnull; 239        mWeakParentContentListener = nsnull;
263        mParentContentListener = nsnull; 240        mParentContentListener = nsnull;
264    } 241    }
265    return NS_OK; 242    return NS_OK;
266} 243}
267  244 
268//***************************************************************************** 245//*****************************************************************************
269// nsDSURIContentListener: Helpers 246// nsDSURIContentListener: Helpers
270//***************************************************************************** 247//*****************************************************************************
271  248 
272//***************************************************************************** 249//*****************************************************************************
273// nsDSURIContentListener: Accessors 250// nsDSURIContentListener: Accessors
274//***************************************************************************** 251//*****************************************************************************
275  252 
276void nsDSURIContentListener::DocShell(nsDocShell* aDocShell) 253void nsDSURIContentListener::DocShell(nsDocShell* aDocShell)
277{ 254{
278    mDocShell = aDocShell; 255    mDocShell = aDocShell;
279} 256}
280  257 
281nsDocShell* nsDSURIContentListener::DocShell() 258nsDocShell* nsDSURIContentListener::DocShell()
282{ 259{
283    return mDocShell; 260    return mDocShell;
284} 261}
285  262