1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsHTMLFormatConverter.h"
9 #include "nsISupportsArray.h"
10 #include "nsIComponentManager.h"
13 #include "nsISupportsPrimitives.h"
15 #include "nsITransferable.h" // for mime defs, this is BAD
17 // HTML convertor stuff
18 #include "nsPrimitiveHelpers.h"
19 #include "nsIDocumentEncoder.h"
20 #include "nsContentUtils.h"
22 nsHTMLFormatConverter::nsHTMLFormatConverter()
26 nsHTMLFormatConverter::~nsHTMLFormatConverter()
30 NS_IMPL_ISUPPORTS(nsHTMLFormatConverter
, nsIFormatConverter
)
33 // GetInputDataFlavors
35 // Creates a new list and returns the list of all the flavors this converter
36 // knows how to import. In this case, it's just HTML.
38 // Flavors (strings) are wrapped in a primitive object so that JavaScript can
39 // access them easily via XPConnect.
42 nsHTMLFormatConverter::GetInputDataFlavors(nsISupportsArray
**_retval
)
45 return NS_ERROR_INVALID_ARG
;
47 nsresult rv
= NS_NewISupportsArray ( _retval
); // addrefs for us
48 if ( NS_SUCCEEDED(rv
) )
49 rv
= AddFlavorToList ( *_retval
, kHTMLMime
);
53 } // GetInputDataFlavors
57 // GetOutputDataFlavors
59 // Creates a new list and returns the list of all the flavors this converter
60 // knows how to export (convert). In this case, it's all sorts of things that HTML can be
63 // Flavors (strings) are wrapped in a primitive object so that JavaScript can
64 // access them easily via XPConnect.
67 nsHTMLFormatConverter::GetOutputDataFlavors(nsISupportsArray
**_retval
)
70 return NS_ERROR_INVALID_ARG
;
72 nsresult rv
= NS_NewISupportsArray ( _retval
); // addrefs for us
73 if ( NS_SUCCEEDED(rv
) ) {
74 rv
= AddFlavorToList ( *_retval
, kHTMLMime
);
79 // no one uses this flavor right now, so it's just slowing things down. If anyone cares I
80 // can put it back in.
81 rv
= AddFlavorToList ( *_retval
, kAOLMailMime
);
85 rv
= AddFlavorToList ( *_retval
, kUnicodeMime
);
91 } // GetOutputDataFlavors
97 // Convenience routine for adding a flavor wrapped in an nsISupportsCString object
101 nsHTMLFormatConverter :: AddFlavorToList ( nsISupportsArray
* inList
, const char* inFlavor
)
105 nsCOMPtr
<nsISupportsCString
> dataFlavor
=
106 do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID
, &rv
);
108 dataFlavor
->SetData ( nsDependentCString(inFlavor
) );
109 // add to list as an nsISupports so the correct interface gets the addref
110 // in AppendElement()
111 nsCOMPtr
<nsISupports
> genericFlavor ( do_QueryInterface(dataFlavor
) );
112 inList
->AppendElement ( genericFlavor
);
122 // Determines if we support the given conversion. Currently, this method only
123 // converts from HTML to others.
126 nsHTMLFormatConverter::CanConvert(const char *aFromDataFlavor
, const char *aToDataFlavor
, bool *_retval
)
129 return NS_ERROR_INVALID_ARG
;
132 if ( !nsCRT::strcmp(aFromDataFlavor
, kHTMLMime
) ) {
133 if ( !nsCRT::strcmp(aToDataFlavor
, kHTMLMime
) )
135 else if ( !nsCRT::strcmp(aToDataFlavor
, kUnicodeMime
) )
139 // no one uses this flavor right now, so it's just slowing things down. If anyone cares I
140 // can put it back in.
141 else if ( toFlavor
.Equals(kAOLMailMime
) )
154 // Convert data from one flavor to another. The data is wrapped in primitive objects so that it is
155 // accessible from JS. Currently, this only accepts HTML input, so anything else is invalid.
157 //XXX This method copies the data WAAAAY too many time for my liking. Grrrrrr. Mostly it's because
158 //XXX we _must_ put things into nsStrings so that the parser will accept it. Lame lame lame lame. We
159 //XXX also can't just get raw unicode out of the nsString, so we have to allocate heap to get
160 //XXX unicode out of the string. Lame lame lame.
163 nsHTMLFormatConverter::Convert(const char *aFromDataFlavor
, nsISupports
*aFromData
, uint32_t aDataLen
,
164 const char *aToDataFlavor
, nsISupports
**aToData
, uint32_t *aDataToLen
)
166 if ( !aToData
|| !aDataToLen
)
167 return NS_ERROR_INVALID_ARG
;
173 if ( !nsCRT::strcmp(aFromDataFlavor
, kHTMLMime
) ) {
174 nsAutoCString
toFlavor ( aToDataFlavor
);
176 // HTML on clipboard is going to always be double byte so it will be in a primitive
177 // class of nsISupportsString. Also, since the data is in two byte chunks the
178 // length represents the length in 1-byte chars, so we need to divide by two.
179 nsCOMPtr
<nsISupportsString
> dataWrapper0 ( do_QueryInterface(aFromData
) );
181 return NS_ERROR_INVALID_ARG
;
184 nsAutoString dataStr
;
185 dataWrapper0
->GetData ( dataStr
); //¥¥¥ COPY #1
186 // note: conversion to text/plain is done inside the clipboard. we do not need to worry
188 if ( toFlavor
.Equals(kHTMLMime
) || toFlavor
.Equals(kUnicodeMime
) ) {
190 if (toFlavor
.Equals(kHTMLMime
)) {
191 int32_t dataLen
= dataStr
.Length() * 2;
192 nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor
.get(), dataStr
.get(), dataLen
, aToData
);
194 *aDataToLen
= dataLen
;
197 res
= ConvertFromHTMLToUnicode(dataStr
, outStr
);
198 if (NS_SUCCEEDED(res
)) {
199 int32_t dataLen
= outStr
.Length() * 2;
200 nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor
.get(), outStr
.get(), dataLen
, aToData
);
202 *aDataToLen
= dataLen
;
205 } // else if HTML or Unicode
206 else if ( toFlavor
.Equals(kAOLMailMime
) ) {
208 if ( NS_SUCCEEDED(ConvertFromHTMLToAOLMail(dataStr
, outStr
)) ) {
209 int32_t dataLen
= outStr
.Length() * 2;
210 nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor
.get(), outStr
.get(), dataLen
, aToData
);
212 *aDataToLen
= dataLen
;
214 } // else if AOL mail
216 rv
= NS_ERROR_FAILURE
;
218 } // if we got html mime
220 rv
= NS_ERROR_FAILURE
;
228 // ConvertFromHTMLToUnicode
230 // Takes HTML and converts it to plain text but in unicode.
233 nsHTMLFormatConverter::ConvertFromHTMLToUnicode(const nsAutoString
& aFromStr
, nsAutoString
& aToStr
)
235 return nsContentUtils::ConvertToPlainText(aFromStr
,
237 nsIDocumentEncoder::OutputSelectionOnly
|
238 nsIDocumentEncoder::OutputAbsoluteLinks
|
239 nsIDocumentEncoder::OutputNoScriptContent
|
240 nsIDocumentEncoder::OutputNoFramesContent
,
242 } // ConvertFromHTMLToUnicode
246 nsHTMLFormatConverter::ConvertFromHTMLToAOLMail(const nsAutoString
& aFromStr
,
247 nsAutoString
& aToStr
)
249 aToStr
.AssignLiteral("<HTML>");
250 aToStr
.Append(aFromStr
);
251 aToStr
.AppendLiteral("</HTML>");