Bug 1694264 - Teach nsIMsgVCardService about Unicode. r=mkmelin
Also removes nsAbContentHandler, which used this service but is now dead code. Differential Revision: https://phabricator.services.mozilla.com/D106068 --HG-- extra : rebase_source : ad3a8cbabb910267696ac0dd9804c5d8b149092d extra : histedit_source : 4b2eb03b9622205ce1569356137e6969e3b431b6
This commit is contained in:
Родитель
49cfa33e8c
Коммит
6103223ef1
|
@ -431,9 +431,21 @@ MailDefaultHandler.prototype = {
|
|||
inputStream,
|
||||
inputStream.available()
|
||||
);
|
||||
|
||||
// Try to detect the character set and decode. Only UTF-8 is
|
||||
// valid from vCard 4.0, but we support older versions, so other
|
||||
// charsets are possible.
|
||||
let charset = Cc["@mozilla.org/messengercompose/computils;1"]
|
||||
.createInstance(Ci.nsIMsgCompUtils)
|
||||
.detectCharset(data);
|
||||
let buffer = new Uint8Array(
|
||||
Array.from(data, c => c.charCodeAt(0))
|
||||
);
|
||||
data = new TextDecoder(charset).decode(buffer);
|
||||
|
||||
let card = Cc["@mozilla.org/addressbook/msgvcardservice;1"]
|
||||
.getService(Ci.nsIMsgVCardService)
|
||||
.escapedVCardToAbCard(data);
|
||||
.vCardToAbCard(data);
|
||||
Services.ww.openWindow(
|
||||
null,
|
||||
"chrome://messenger/content/addressbook/abNewCardDialog.xhtml",
|
||||
|
|
|
@ -263,6 +263,9 @@ VCardService.prototype = {
|
|||
QueryInterface: ChromeUtils.generateQI(["nsIMsgVCardService"]),
|
||||
classID: Components.ID("{e2e0f615-bc5a-4441-a16b-a26e75949376}"),
|
||||
|
||||
vCardToAbCard(vCard) {
|
||||
return vCard ? VCardUtils.vCardToAbCard(vCard) : null;
|
||||
},
|
||||
escapedVCardToAbCard(vCard) {
|
||||
return vCard ? VCardUtils.vCardToAbCard(decodeURIComponent(vCard)) : null;
|
||||
},
|
||||
|
|
|
@ -27,16 +27,6 @@
|
|||
//
|
||||
#define NS_ABMANAGER_CONTRACTID "@mozilla.org/abmanager;1"
|
||||
|
||||
//
|
||||
// nsAbContentHandler
|
||||
//
|
||||
#define NS_ABCONTENTHANDLER_CID \
|
||||
{ \
|
||||
0xa72ad552, 0x0484, 0x4b5f, { \
|
||||
0x8d, 0x45, 0x2d, 0x79, 0x15, 0x8d, 0x22, 0xe3 \
|
||||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// JS/SQLite address book
|
||||
//
|
||||
|
|
|
@ -10,13 +10,21 @@ interface nsIAbCard;
|
|||
[scriptable, uuid(8b6ae917-676d-4f1f-bbad-2ecc9be0d9b1)]
|
||||
interface nsIMsgVCardService : nsISupports {
|
||||
|
||||
/**
|
||||
* Translates a vCard string into a nsIAbCard.
|
||||
*
|
||||
* @param vCardStr - The string containing the vCard data.
|
||||
* @return - A card containing the translated vCard data.
|
||||
*/
|
||||
nsIAbCard vCardToAbCard(in AString vCardStr);
|
||||
|
||||
/**
|
||||
* Translates an URL-encoded vCard string into a nsIAbCard.
|
||||
*
|
||||
* @param escapedVCardStr - The string containing the vCard data.
|
||||
* @return - A card containing the translated vCard data.
|
||||
*/
|
||||
nsIAbCard escapedVCardToAbCard(in string escapedVCardStr);
|
||||
nsIAbCard escapedVCardToAbCard(in AString escapedVCardStr);
|
||||
|
||||
/**
|
||||
* Translates a nsIAbCard into an URL-encoded vCard.
|
||||
|
@ -24,5 +32,5 @@ interface nsIMsgVCardService : nsISupports {
|
|||
* @param abCard - A card to be translated.
|
||||
* @return - The string containing the vCard data.
|
||||
*/
|
||||
ACString abCardToEscapedVCard(in nsIAbCard abCard);
|
||||
AString abCardToEscapedVCard(in nsIAbCard abCard);
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@ SOURCES += [
|
|||
"nsAbBooleanExpression.cpp",
|
||||
"nsAbBoolExprToLDAPFilter.cpp",
|
||||
"nsAbCardProperty.cpp",
|
||||
"nsAbContentHandler.cpp",
|
||||
"nsAbDirectoryQuery.cpp",
|
||||
"nsAbDirectoryQueryProxy.cpp",
|
||||
"nsAbDirProperty.cpp",
|
||||
|
|
|
@ -491,8 +491,12 @@ nsresult nsAbCardProperty::ConvertToEscapedVCard(nsACString& aResult) {
|
|||
do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAbCard> cardFromVCard;
|
||||
return vCardService->AbCardToEscapedVCard(this, aResult);
|
||||
nsAutoString result;
|
||||
rv = vCardService->AbCardToEscapedVCard(this, result);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aResult = NS_ConvertUTF16toUTF8(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAbCardProperty::ConvertToBase64EncodedXML(nsACString& result) {
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
/* -*- 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 "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "plstr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "mozIDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "nsIMsgVCardService.h"
|
||||
#include "nsIAbCard.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;
|
||||
|
||||
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_SEC_CONTEXT_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
} else {
|
||||
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, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAbCard> cardFromVCard;
|
||||
rv = vCardService->EscapedVCardToAbCard((const char*)data,
|
||||
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);
|
||||
|
||||
RefPtr<mozilla::dom::BrowsingContext> dialogWindow;
|
||||
return parentWindow->OpenDialog(
|
||||
u"chrome://messenger/content/addressbook/abNewCardDialog.xhtml"_ns,
|
||||
EmptyString(), u"chrome,resizable=no,titlebar,modal,centerscreen"_ns,
|
||||
cardFromVCard, getter_AddRefs(dialogWindow));
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#ifndef __nsAbContentHandler_h
|
||||
#define __nsAbContentHandler_h
|
||||
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsIContentHandler.h"
|
||||
|
||||
class nsAbContentHandler : public nsIContentHandler,
|
||||
public nsIStreamLoaderObserver {
|
||||
public:
|
||||
nsAbContentHandler();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSICONTENTHANDLER
|
||||
NS_DECL_NSISTREAMLOADEROBSERVER
|
||||
|
||||
private:
|
||||
virtual ~nsAbContentHandler();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -108,7 +108,6 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include "nsAbBaseCID.h"
|
||||
#include "nsAbCardProperty.h"
|
||||
#include "nsAbContentHandler.h"
|
||||
#include "nsAbDirProperty.h"
|
||||
#include "nsAbAddressCollector.h"
|
||||
|
||||
|
@ -397,7 +396,6 @@ NS_DEFINE_NAMED_CID(NS_MAILNEWSDLF_CID);
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// addrbook factories
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbContentHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbDirProperty)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbCardProperty)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAbAddressCollector, Init)
|
||||
|
@ -428,7 +426,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbOSXCard)
|
|||
NS_DEFINE_NAMED_CID(NS_ABCARDPROPERTY_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ABDIRPROPERTY_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ABADDRESSCOLLECTOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ABCONTENTHANDLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ABDIRECTORYQUERYARGUMENTS_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BOOLEANCONDITIONSTRING_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BOOLEANEXPRESSION_CID);
|
||||
|
@ -785,7 +782,6 @@ const mozilla::Module::CIDEntry kMailNewsCIDs[] = {
|
|||
{&kNS_ABCARDPROPERTY_CID, false, NULL, nsAbCardPropertyConstructor},
|
||||
{&kNS_ABDIRPROPERTY_CID, false, NULL, nsAbDirPropertyConstructor},
|
||||
{&kNS_ABADDRESSCOLLECTOR_CID, false, NULL, nsAbAddressCollectorConstructor},
|
||||
{&kNS_ABCONTENTHANDLER_CID, false, NULL, nsAbContentHandlerConstructor},
|
||||
#if defined(MOZ_MAPI_SUPPORT)
|
||||
{&kNS_ABOUTLOOKDIRECTORY_CID, false, NULL, nsAbOutlookDirectoryConstructor},
|
||||
{&kNS_ABOUTLOOKINTERFACE_CID, false, NULL, nsAbOutlookInterfaceConstructor},
|
||||
|
@ -996,10 +992,6 @@ const mozilla::Module::ContractIDEntry kMailNewsContracts[] = {
|
|||
{NS_ABCARDPROPERTY_CONTRACTID, &kNS_ABCARDPROPERTY_CID},
|
||||
{NS_ABDIRPROPERTY_CONTRACTID, &kNS_ABDIRPROPERTY_CID},
|
||||
{NS_ABADDRESSCOLLECTOR_CONTRACTID, &kNS_ABADDRESSCOLLECTOR_CID},
|
||||
{NS_CONTENT_HANDLER_CONTRACTID_PREFIX "application/x-addvcard",
|
||||
&kNS_ABCONTENTHANDLER_CID},
|
||||
{NS_CONTENT_HANDLER_CONTRACTID_PREFIX "text/x-vcard",
|
||||
&kNS_ABCONTENTHANDLER_CID},
|
||||
#if defined(MOZ_MAPI_SUPPORT)
|
||||
{NS_ABOUTLOOKDIRECTORY_CONTRACTID, &kNS_ABOUTLOOKDIRECTORY_CID},
|
||||
{NS_ABOUTLOOKINTERFACE_CONTRACTID, &kNS_ABOUTLOOKINTERFACE_CID},
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
#include "nsIAbDirectory.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsIUnicharLineInputStream.h"
|
||||
#include "nsIConverterInputStream.h"
|
||||
#include "nsIMsgVCardService.h"
|
||||
|
||||
#include "plstr.h"
|
||||
|
@ -46,9 +47,26 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName,
|
|||
inputStream->Close();
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint64_t totalBytes = bytesLeft;
|
||||
nsCOMPtr<nsILineInputStream> lineStream(do_QueryInterface(inputStream, &rv));
|
||||
|
||||
// Try to detect the character set and decode. Only UTF-8 is valid from
|
||||
// vCard 4.0, but we support older versions, so other charsets are possible.
|
||||
|
||||
nsAutoCString sourceCharset;
|
||||
rv = MsgDetectCharsetFromFile(pSrc, sourceCharset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIConverterInputStream> converterStream =
|
||||
do_CreateInstance("@mozilla.org/intl/converter-input-stream;1");
|
||||
NS_ENSURE_TRUE(converterStream, NS_ERROR_FAILURE);
|
||||
|
||||
rv = converterStream->Init(
|
||||
inputStream, sourceCharset.get(), 8192,
|
||||
nsIConverterInputStream::DEFAULT_REPLACEMENT_CHARACTER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIUnicharLineInputStream> lineStream(
|
||||
do_QueryInterface(converterStream, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMsgVCardService> vCardService =
|
||||
|
@ -56,14 +74,13 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool more = true;
|
||||
nsCString record;
|
||||
nsAutoString record;
|
||||
while (!(*pAbort) && more && NS_SUCCEEDED(rv)) {
|
||||
rv = ReadRecord(lineStream, record, &more);
|
||||
if (NS_SUCCEEDED(rv) && !record.IsEmpty()) {
|
||||
// Parse the vCard and build an nsIAbCard from it
|
||||
nsCOMPtr<nsIAbCard> cardFromVCard;
|
||||
rv = vCardService->EscapedVCardToAbCard(record.get(),
|
||||
getter_AddRefs(cardFromVCard));
|
||||
rv = vCardService->VCardToAbCard(record, getter_AddRefs(cardFromVCard));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIAbCard* outCard;
|
||||
|
@ -76,7 +93,7 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName,
|
|||
}
|
||||
if (NS_SUCCEEDED(rv) && pProgress) {
|
||||
// This won't be totally accurate, but its the best we can do
|
||||
// considering that lineStream won't give us how many bytes
|
||||
// considering that converterStream won't give us how many bytes
|
||||
// are actually left.
|
||||
bytesLeft -= record.Length();
|
||||
*pProgress = totalBytes - bytesLeft;
|
||||
|
@ -93,11 +110,11 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsVCardAddress::ReadRecord(nsILineInputStream* aLineStream,
|
||||
nsCString& aRecord, bool* aMore) {
|
||||
nsresult nsVCardAddress::ReadRecord(nsIUnicharLineInputStream* aLineStream,
|
||||
nsString& aRecord, bool* aMore) {
|
||||
bool more = true;
|
||||
nsresult rv;
|
||||
nsCString line;
|
||||
nsAutoString line;
|
||||
|
||||
aRecord.Truncate();
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
class nsIAbDirectory;
|
||||
class nsIFile;
|
||||
class nsILineInputStream;
|
||||
class nsIUnicharLineInputStream;
|
||||
|
||||
class nsVCardAddress {
|
||||
public:
|
||||
|
@ -21,8 +21,8 @@ class nsVCardAddress {
|
|||
uint32_t* pProgress);
|
||||
|
||||
private:
|
||||
static nsresult ReadRecord(nsILineInputStream* aLineStream,
|
||||
nsCString& aRecord, bool* aMore);
|
||||
static nsresult ReadRecord(nsIUnicharLineInputStream* aLineStream,
|
||||
nsString& aRecord, bool* aMore);
|
||||
};
|
||||
|
||||
#endif /* nsVCardAddress_h__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче