Bug #243733 --> Port Thunderbird's fix for handling the opening of vCard attachments internally instead of

opening up a helper app to the trunk.

sr=bienvenu
This commit is contained in:
scott%scott-macgregor.org 2004-06-03 04:25:57 +00:00
Родитель bd994e5526
Коммит 6bba945421
5 изменённых файлов: 179 добавлений и 8 удалений

Просмотреть файл

@ -451,4 +451,11 @@
#define NS_MSGVCARDSERVICE_CONTRACTID \
"@mozilla.org/addressbook/msgvcardservice;1"
#define NS_MSGVCARDSTREAMLISTENER_CID \
{ 0xf4045da, 0x6187, 0x42ff, \
{ 0x9d, 0xf4, 0x80, 0x65, 0x44, 0xf, 0x76, 0x21 }}
#define NS_MSGVCARDSTREAMLISTENER_CONTRACTID \
"@mozilla.org/addressbook/msgvcardstreamlistener;1"
#endif // nsAbBaseCID_h__

Просмотреть файл

@ -86,6 +86,8 @@
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIDocShell.h"
#include "nsNetCID.h"
#include "nsIIOService.h"
// according to RFC 2849
// SEP = (CR LF / LF)
@ -2065,10 +2067,36 @@ NS_IMETHODIMP nsAddressBook::HandleContent(const char * aContentType,
rv = NS_OK;
}
}
else {
// The content-type was not x-application-addvcard...
return NS_ERROR_WONT_HANDLE_CONTENT;
else if (nsCRT::strcasecmp(aContentType, "text/x-vcard") == 0) {
// create a vcard stream listener that can parse the data stream
// and bring up the appropriate UI
// (1) cancel the current load operation. We'll restart it
request->Cancel(NS_ERROR_ABORT);
// get the url we were trying to open
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
rv = channel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// create a stream listener to handle the v-card data
nsCOMPtr<nsIStreamListener> strListener = do_CreateInstance(NS_MSGVCARDSTREAMLISTENER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_WONT_HANDLE_CONTENT); // no registered v-card handler so just return that we won't handle the content
// create a new channel and run the url again
nsCOMPtr<nsIIOService> netService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = netService->NewChannelFromURI(uri, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
rv = channel->AsyncOpen(strListener, aWindowContext);
}
else // The content-type was not x-application-addvcard...
return NS_ERROR_WONT_HANDLE_CONTENT;
return rv;
}

Просмотреть файл

@ -36,9 +36,21 @@
* ***** END LICENSE BLOCK ***** */
#include "nsMsgVCardService.h"
#include "nsIDOMWindowInternal.h"
#include "nsVCardObj.h"
#include "nsISupportsPrimitives.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIAbCard.h"
#include "nsIAddressBook.h"
#include "nsAbBaseCID.h"
#include "prmem.h"
#include "plstr.h"
#define FOUR_K 4096
NS_IMPL_ISUPPORTS1(nsMsgVCardService, nsIMsgVCardService)
nsMsgVCardService::nsMsgVCardService()
@ -106,3 +118,103 @@ NS_IMETHODIMP_(char *) nsMsgVCardService::VObjectAnyValue(VObject * o)
PL_strcpy(retval, (char *) vObjectAnyValue(o));
return retval;
}
// helper class used to process a stream of vcard data
NS_IMPL_ISUPPORTS1(nsMsgVCardStreamListener, nsIStreamListener)
nsMsgVCardStreamListener::nsMsgVCardStreamListener()
{
m_dataBuffer = nsnull;
}
nsMsgVCardStreamListener::~nsMsgVCardStreamListener()
{
PR_Free(m_dataBuffer);
}
NS_IMETHODIMP
nsMsgVCardStreamListener::OnStartRequest(nsIRequest* request, nsISupports* aSupport)
{
if (!m_dataBuffer)
m_dataBuffer = (char*) PR_CALLOC(FOUR_K+1);
return NS_OK;
}
NS_IMETHODIMP
nsMsgVCardStreamListener::OnStopRequest(nsIRequest* request, nsISupports* aSupport,
nsresult status)
{
NS_ENSURE_ARG_POINTER(aSupport);
NS_ENSURE_SUCCESS(status, status); // don't process the vcard if we got a status error
nsresult rv = NS_OK;
// take our vCard string and open up an address book window based on it
nsCOMPtr<nsIMsgVCardService> vCardService = do_GetService(NS_MSGVCARDSERVICE_CONTRACTID);
if (vCardService)
{
VObject * vObj = vCardService->Parse_MIME(mVCardData.get(), mVCardData.Length());
if (vObj)
{
nsCAutoString vCard;
int len = 0;
vCard.Adopt(vCardService->WriteMemoryVObjects(0, &len, vObj, PR_FALSE));
delete vObj;
nsCOMPtr<nsIDOMWindowInternal> parentWindow = do_GetInterface(aSupport);
NS_ENSURE_TRUE(parentWindow, NS_ERROR_FAILURE);
nsCOMPtr<nsIAddressBook> addressbook = do_CreateInstance(NS_ADDRESSBOOK_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsIAbCard> cardFromVCard;
rv = addressbook->EscapedVCardToAbCard(vCard.get(), getter_AddRefs(cardFromVCard));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
ifptr->SetData(cardFromVCard);
ifptr->SetDataIID(&NS_GET_IID(nsIAbCard));
nsCOMPtr<nsIDOMWindow> dialogWindow;
rv = parentWindow->OpenDialog(
NS_LITERAL_STRING("chrome://messenger/content/addressbook/abNewCardDialog.xul"),
EmptyString(),
NS_LITERAL_STRING("chrome,resizable=no,titlebar,modal,centerscreen"),
ifptr, getter_AddRefs(dialogWindow));
}
}
PR_FREEIF(m_dataBuffer);
return rv;
}
NS_IMETHODIMP nsMsgVCardStreamListener::OnDataAvailable(nsIRequest* request, nsISupports* aSupport,
nsIInputStream* inStream,
PRUint32 srcOffset,
PRUint32 count)
{
PRUint32 available, readCount, maxReadCount = FOUR_K;
PRUint32 writeCount;
nsresult rv = inStream->Available(&available);
while (NS_SUCCEEDED(rv) && available)
{
if (maxReadCount > available)
maxReadCount = available;
memset(m_dataBuffer, 0, FOUR_K+1);
rv = inStream->Read(m_dataBuffer, maxReadCount, &readCount);
if (NS_SUCCEEDED(rv))
{
// m_dataBuffer is null terminated so we can safely just append it to our vcard string
mVCardData += m_dataBuffer;
available -= readCount;
}
}
return rv;
}

Просмотреть файл

@ -40,6 +40,7 @@
#include "nsIMsgVCardService.h"
#include "nsISupports.h"
#include "nsIStreamListener.h"
class nsMsgVCardService : public nsIMsgVCardService
{
@ -51,4 +52,23 @@ public:
virtual ~nsMsgVCardService();
};
// a helper class for the vcard service which can process a vcard as an incoming
// stream and open it.
class nsMsgVCardStreamListener : public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
nsMsgVCardStreamListener();
virtual ~nsMsgVCardStreamListener();
protected:
char *m_dataBuffer;
nsCString mVCardData;
};
#endif /* nsMsgVCardService_h___ */

Просмотреть файл

@ -139,7 +139,7 @@
#include "nsAbDirectoryQuery.h"
#include "nsAbBooleanExpression.h"
#include "nsAbDirectoryQueryProxy.h"
#include "nsAbView.h"
#include "nsAbView.h"
#include "nsMsgVCardService.h"
#if defined(MOZ_LDAP_XPCOM)
@ -372,8 +372,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbLDAPProcessChangeLogData)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbDirectoryQueryProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbView)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbView)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgVCardService)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgVCardStreamListener)
////////////////////////////////////////////////////////////////////////////////
// bayesian spam filter factories
@ -802,8 +803,9 @@ static const nsModuleComponentInfo gComponents[] = {
{ "The addbook URL Interface", NS_ADDBOOKURL_CID,
NS_ADDBOOKURL_CONTRACTID, nsAddbookUrlConstructor },
{ "The addbook Protocol Handler", NS_ADDBOOK_HANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "addbook", nsAddbookProtocolHandlerConstructor },
{ "add vCard content handler", NS_ADDRESSBOOK_CID, NS_CONTENT_HANDLER_CONTRACTID_PREFIX"x-application-addvcard", nsAddressBookConstructor },
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "addbook", nsAddbookProtocolHandlerConstructor },
{ "add vCard content handler", NS_ADDRESSBOOK_CID, NS_CONTENT_HANDLER_CONTRACTID_PREFIX"x-application-addvcard", nsAddressBookConstructor },
{ "add vCard content handler", NS_ADDRESSBOOK_CID, NS_CONTENT_HANDLER_CONTRACTID_PREFIX"text/x-vcard", nsAddressBookConstructor },
{ "The directory factory service interface", NS_ABDIRFACTORYSERVICE_CID,
NS_ABDIRFACTORYSERVICE_CONTRACTID, nsAbDirFactoryServiceConstructor },
@ -849,8 +851,10 @@ static const nsModuleComponentInfo gComponents[] = {
#endif
{ "The directory query proxy interface", NS_ABDIRECTORYQUERYPROXY_CID,
NS_ABDIRECTORYQUERYPROXY_CONTRACTID, nsAbDirectoryQueryProxyConstructor},
{ "addressbook view", NS_ABVIEW_CID, NS_ABVIEW_CONTRACTID, nsAbViewConstructor},
{ "addressbook view", NS_ABVIEW_CID, NS_ABVIEW_CONTRACTID, nsAbViewConstructor},
{ "vcard helper service", NS_MSGVCARDSERVICE_CID, NS_MSGVCARDSERVICE_CONTRACTID, nsMsgVCardServiceConstructor },
{ "vcard stream listener", NS_MSGVCARDSTREAMLISTENER_CID, NS_MSGVCARDSTREAMLISTENER_CONTRACTID,
nsMsgVCardStreamListenerConstructor },
////////////////////////////////////////////////////////////////////////////////
// bayesian spam filter components