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:
mscott%netscape.com
2000-02-04 08:43:34 +00:00
parent e0f132e842
commit 5099d9d1c1
5 changed files with 102 additions and 37 deletions

View File

@@ -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="
%}

View File

@@ -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="
%}

View File

@@ -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,

View File

@@ -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;

View File

@@ -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__ */