More prepation for docshell landing. Add a IsPreferred method to nsIURIContentListener and use the Ispreferred
method when the load type is user click to find the preferred registered window for handling the content r=travis git-svn-id: svn://10.0.0.236/trunk@59758 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -51,4 +51,7 @@ nsIURILoader
|
||||
#define NS_DOCUMENTLOADER_SERVICE_PROGID \
|
||||
"component://netscape/docloaderservice"
|
||||
|
||||
#define NS_CONTENT_HANDLER_PROGID "component://netscape/uriloader/content-handler"
|
||||
#define NS_CONTENT_HANDLER_PROGID_PREFIX NS_CONTENT_HANDLER_PROGID "?type="
|
||||
|
||||
%}
|
||||
|
||||
@@ -34,7 +34,3 @@ interface nsIContentHandler : nsISupports
|
||||
in nsIChannel aChannel);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define NS_CONTENT_HANDLER_PROGID "component://netscape/uriloader/content-handler"
|
||||
#define NS_CONTENT_HANDLER_PROGID_PREFIX NS_CONTENT_HANDLER_PROGID "?type="
|
||||
%}
|
||||
|
||||
@@ -50,10 +50,10 @@ interface nsIURIContentListener : nsISupports
|
||||
*/
|
||||
void getProtocolHandler(in nsIURI aURI, out nsIProtocolHandler aProtocolHandler);
|
||||
|
||||
/* The URIDispatcher will give the content listener a shot at handling
|
||||
the content before it tries other means. If the content listener
|
||||
wants to handle the content then it should return a stream listener
|
||||
the data should be pushed into.
|
||||
/* doContent --> When the content listener is expected to process the
|
||||
content, the uri loader calls doContent. doContent needs to return a
|
||||
nsIStreamListener which the uri loader will push the content into.
|
||||
|
||||
aContentType --> the content type we need to handle
|
||||
aCommand --> verb for the action (this comes from layout???)
|
||||
aWindowTarget --> name of the target window if any
|
||||
@@ -72,10 +72,38 @@ interface nsIURIContentListener : nsISupports
|
||||
out nsIStreamListener aContentHandler,
|
||||
out boolean aAbortProcess);
|
||||
|
||||
/* returns true if we can handle the content and false if we can't.
|
||||
/* When given a uri to dispatch, if the load type is a user click,
|
||||
then the uri loader tries to find a preferred content handler for
|
||||
this content type. The thought is that many content listeners may
|
||||
be able to handle the same content type if they have to. i.e. the mail
|
||||
content window can handle text/html just like a browser window content
|
||||
listener. However, if the user clicks on a link with text/html content,
|
||||
we'd like the browser window to handle that content and not the mail window
|
||||
where the user may have clicked the link. That's why we have isPreferred.
|
||||
|
||||
aContentType --> the content type to handle
|
||||
aCommand --> verb for the action
|
||||
aWindowTarget --> name of the target window (if any)
|
||||
aDesiredContentType --> yes, we can accept aContentType but we would
|
||||
like it converted to aDesiredContentType. This argument can be null if
|
||||
you want the content directly as aContentType */
|
||||
like it converted to aDesiredContentType. This argument can be null if
|
||||
you want the content directly as aContentType
|
||||
boolean --> return true if you are a preferred content handler for aContentType
|
||||
and false otherwise.
|
||||
*/
|
||||
boolean isPreferred(in string aContentType,
|
||||
in nsURILoadCommand aCommand,
|
||||
in string aWindowTarget,
|
||||
out string aDesiredContentType);
|
||||
|
||||
/* When given a uri to dispatch, if the load type is anything but user click,
|
||||
the uri loader will call canHandleContent to see if the content listener
|
||||
can handle the content. The arguments are the same as isPreferred.
|
||||
|
||||
Note: I really envision canHandleContent as a method implemented by the docshell
|
||||
as the implementation is generic to all doc shells. The IsPreferred decision
|
||||
is a decision made by a top level application content listener that sits at the
|
||||
top of the docshell hiearchy.
|
||||
*/
|
||||
boolean canHandleContent(in string aContentType,
|
||||
in nsURILoadCommand aCommand,
|
||||
in string aWindowTarget,
|
||||
|
||||
@@ -575,48 +575,79 @@ nsresult nsURILoader::SetupLoadCookie(nsISupports * aWindowContext, nsISupports
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsURILoader::DispatchContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
nsIChannel * aChannel,
|
||||
nsISupports * aCtxt,
|
||||
nsIURIContentListener * aContentListener,
|
||||
char ** aContentTypeToUse,
|
||||
nsIURIContentListener ** aContentListenerToUse,
|
||||
PRBool * aAbortProcess)
|
||||
PRBool nsURILoader::ShouldHandleContent(nsIURIContentListener * aCntListener,
|
||||
const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aContentTypeToUse)
|
||||
{
|
||||
PRBool foundContentHandler = PR_FALSE;
|
||||
if (aCommand == nsIURILoader::viewUserClick)
|
||||
aCntListener->IsPreferred(aContentType, aCommand, aWindowTarget,
|
||||
aContentTypeToUse,
|
||||
&foundContentHandler);
|
||||
else
|
||||
aCntListener->CanHandleContent(aContentType, aCommand, aWindowTarget,
|
||||
aContentTypeToUse,
|
||||
&foundContentHandler);
|
||||
return foundContentHandler;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsURILoader::DispatchContent(const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
nsIChannel * aChannel,
|
||||
nsISupports * aCtxt,
|
||||
nsIURIContentListener * aContentListener,
|
||||
char ** aContentTypeToUse,
|
||||
nsIURIContentListener ** aContentListenerToUse,
|
||||
PRBool * aAbortProcess)
|
||||
{
|
||||
NS_ENSURE_ARG(aContentType);
|
||||
NS_ENSURE_ARG(aChannel);
|
||||
|
||||
// okay, now we've discovered the content type. We need to do the following:
|
||||
// (1) Give our uri content listener first crack at handling this content type.
|
||||
// (1) if aCommand is user click, we need to find the Preferred content handler
|
||||
// for this type...
|
||||
// (2) if aCommand is any other value, we'll use canHandleContent to find any handler
|
||||
// for the content.
|
||||
// We always start with the original content listener (if any) that originated the request
|
||||
// and then move on to registered content listeners.
|
||||
|
||||
// if we cannot find a registered content lister to handle the type, then we move on to
|
||||
// phase II which is to try to find a content handler in the registry for the content type.
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURIContentListener> listenerToUse = aContentListener;
|
||||
|
||||
// find a content handler that can and will handle the content
|
||||
PRBool canHandleContent = PR_FALSE;
|
||||
PRBool foundContentHandler = PR_FALSE;
|
||||
if (listenerToUse)
|
||||
listenerToUse->CanHandleContent(aContentType, aCommand, aWindowTarget,
|
||||
aContentTypeToUse,
|
||||
&canHandleContent);
|
||||
if (!canHandleContent) // if it can't handle the content, scan through the list of registered listeners
|
||||
foundContentHandler = ShouldHandleContent(listenerToUse, aContentType,
|
||||
aCommand, aWindowTarget, aContentTypeToUse);
|
||||
|
||||
|
||||
if (!foundContentHandler) // if it can't handle the content, scan through the list of registered listeners
|
||||
{
|
||||
PRInt32 i = 0;
|
||||
// keep looping until we are told to abort or we get a content listener back
|
||||
for(i = 0; i < m_listeners->Count() && !canHandleContent; i++)
|
||||
// keep looping until we get a content listener back
|
||||
for(i = 0; i < m_listeners->Count() && !foundContentHandler; i++)
|
||||
{
|
||||
//nsIURIContentListener's aren't refcounted.
|
||||
nsIURIContentListener * listener =(nsIURIContentListener*)m_listeners->ElementAt(i);
|
||||
if (listener)
|
||||
{
|
||||
rv = listener->CanHandleContent(aContentType, aCommand, aWindowTarget,
|
||||
aContentTypeToUse,
|
||||
&canHandleContent);
|
||||
if (canHandleContent)
|
||||
{
|
||||
foundContentHandler = ShouldHandleContent(listener, aContentType,
|
||||
aCommand, aWindowTarget, aContentTypeToUse);
|
||||
if (foundContentHandler)
|
||||
listenerToUse = listener;
|
||||
}
|
||||
}
|
||||
} // for loop
|
||||
} // if we can't handle the content
|
||||
|
||||
|
||||
if (canHandleContent && listenerToUse)
|
||||
if (foundContentHandler && listenerToUse)
|
||||
{
|
||||
*aContentListenerToUse = listenerToUse;
|
||||
NS_IF_ADDREF(*aContentListenerToUse);
|
||||
@@ -636,8 +667,8 @@ nsresult nsURILoader::DispatchContent(const char * aContentType,
|
||||
rv = nsComponentManager::CreateInstance(handlerProgID, nsnull, NS_GET_IID(nsIContentHandler), getter_AddRefs(aContentHandler));
|
||||
if (NS_SUCCEEDED(rv)) // we did indeed have a content handler for this type!! yippee...
|
||||
{
|
||||
rv = aContentHandler->HandleContent(aContentType, "view", aWindowTarget, aChannel);
|
||||
*aAbortProcess = PR_TRUE;
|
||||
rv = aContentHandler->HandleContent(aContentType, "view", aWindowTarget, aChannel);
|
||||
*aAbortProcess = PR_TRUE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
@@ -46,6 +46,13 @@ protected:
|
||||
|
||||
// prepare the load cookie for the window context
|
||||
nsresult SetupLoadCookie(nsISupports * aWindowContext, nsISupports ** aLoadCookie);
|
||||
|
||||
// a small helper function
|
||||
PRBool ShouldHandleContent(nsIURIContentListener * aCntListener,
|
||||
const char * aContentType,
|
||||
nsURILoadCommand aCommand,
|
||||
const char * aWindowTarget,
|
||||
char ** aContentTypeToUse);
|
||||
};
|
||||
|
||||
#endif /* nsURILoader_h__ */
|
||||
|
||||
Reference in New Issue
Block a user