summaryrefslogtreecommitdiffstats
path: root/mailnews/addrbook/src/nsAbContentHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mailnews/addrbook/src/nsAbContentHandler.cpp')
-rw-r--r--mailnews/addrbook/src/nsAbContentHandler.cpp184
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..6e283d82b
--- /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_NORMAL,
+ 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;
+}