diff options
Diffstat (limited to 'mailnews/addrbook/src/nsAbContentHandler.cpp')
-rw-r--r-- | mailnews/addrbook/src/nsAbContentHandler.cpp | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/mailnews/addrbook/src/nsAbContentHandler.cpp b/mailnews/addrbook/src/nsAbContentHandler.cpp new file mode 100644 index 000000000..3ee00148c --- /dev/null +++ b/mailnews/addrbook/src/nsAbContentHandler.cpp @@ -0,0 +1,184 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsAbContentHandler.h" +#include "nsAbBaseCID.h" +#include "nsNetUtil.h" +#include "nsCOMPtr.h" +#include "nsAutoPtr.h" +#include "nsNullPrincipal.h" +#include "nsISupportsPrimitives.h" +#include "plstr.h" +#include "nsPIDOMWindow.h" +#include "mozIDOMWindow.h" +#include "nsMsgUtils.h" +#include "nsIMsgVCardService.h" +#include "nsIAbCard.h" +#include "nsIAbManager.h" +#include "nsVCard.h" +#include "nsIChannel.h" +// +// nsAbContentHandler +// +nsAbContentHandler::nsAbContentHandler() +{ +} + +nsAbContentHandler::~nsAbContentHandler() +{ +} + +NS_IMPL_ISUPPORTS(nsAbContentHandler, nsIContentHandler, + nsIStreamLoaderObserver) + +NS_IMETHODIMP +nsAbContentHandler::HandleContent(const char *aContentType, + nsIInterfaceRequestor *aWindowContext, + nsIRequest *request) +{ + NS_ENSURE_ARG_POINTER(request); + + nsresult rv = NS_OK; + + // First of all, get the content type and make sure it is a content type we know how to handle! + if (PL_strcasecmp(aContentType, "application/x-addvcard") == 0) { + nsCOMPtr<nsIURI> uri; + nsCOMPtr<nsIChannel> aChannel = do_QueryInterface(request); + if (!aChannel) return NS_ERROR_FAILURE; + + rv = aChannel->GetURI(getter_AddRefs(uri)); + if (uri) + { + nsAutoCString path; + rv = uri->GetPath(path); + NS_ENSURE_SUCCESS(rv,rv); + + const char *startOfVCard = strstr(path.get(), "add?vcard="); + if (startOfVCard) + { + nsCString unescapedData; + + // XXX todo, explain why we is escaped twice + MsgUnescapeString(nsDependentCString(startOfVCard + strlen("add?vcard=")), + 0, unescapedData); + + if (!aWindowContext) + return NS_ERROR_FAILURE; + + nsCOMPtr<mozIDOMWindowProxy> domWindow = do_GetInterface(aWindowContext); + NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); + nsCOMPtr<nsPIDOMWindowOuter> parentWindow = nsPIDOMWindowOuter::From(domWindow); + parentWindow = parentWindow->GetOuterWindow(); + NS_ENSURE_ARG_POINTER(parentWindow); + + nsCOMPtr<nsIAbManager> ab = + do_GetService(NS_ABMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr <nsIAbCard> cardFromVCard; + rv = ab->EscapedVCardToAbCard(unescapedData.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<nsPIDOMWindowOuter> 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)); + NS_ENSURE_SUCCESS(rv, rv); + } + rv = NS_OK; + } + } + else if (PL_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); + + nsCOMPtr<nsIPrincipal> nullPrincipal = + do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // create a stream loader to handle the v-card data + nsCOMPtr<nsIStreamLoader> streamLoader; + rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), + uri, + this, + nullPrincipal, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + nsIContentPolicy::TYPE_OTHER); + NS_ENSURE_SUCCESS(rv, rv); + + } + else // The content-type was not application/x-addvcard... + return NS_ERROR_WONT_HANDLE_CONTENT; + + return rv; +} + +NS_IMETHODIMP +nsAbContentHandler::OnStreamComplete(nsIStreamLoader *aLoader, + nsISupports *aContext, nsresult aStatus, + uint32_t datalen, const uint8_t *data) +{ + NS_ENSURE_ARG_POINTER(aContext); + NS_ENSURE_SUCCESS(aStatus, aStatus); // 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) + { + nsAutoPtr<VObject> vObj(vCardService->Parse_MIME((const char *)data, datalen)); + if (vObj) + { + int32_t len = 0; + nsCString vCard; + vCard.Adopt(vCardService->WriteMemoryVObjects(0, &len, vObj, false)); + + nsCOMPtr<nsIAbManager> ab = + do_GetService(NS_ABMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr <nsIAbCard> cardFromVCard; + rv = ab->EscapedVCardToAbCard(vCard.get(), + getter_AddRefs(cardFromVCard)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<mozIDOMWindowProxy> domWindow = do_GetInterface(aContext); + NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); + nsCOMPtr<nsPIDOMWindowOuter> parentWindow = nsPIDOMWindowOuter::From(domWindow); + parentWindow = parentWindow->GetOuterWindow(); + NS_ENSURE_ARG_POINTER(parentWindow); + + nsCOMPtr<nsPIDOMWindowOuter> dialogWindow; + rv = parentWindow->OpenDialog( + NS_LITERAL_STRING("chrome://messenger/content/addressbook/abNewCardDialog.xul"), + EmptyString(), + NS_LITERAL_STRING("chrome,resizable=no,titlebar,modal,centerscreen"), + cardFromVCard, getter_AddRefs(dialogWindow)); + } + } + + return rv; +} |