|
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/. */ |
|
5 |
|
6 #include "nsHTMLFormatConverter.h" |
|
7 |
|
8 #include "nsCRT.h" |
|
9 #include "nsISupportsArray.h" |
|
10 #include "nsIComponentManager.h" |
|
11 #include "nsCOMPtr.h" |
|
12 #include "nsXPCOM.h" |
|
13 #include "nsISupportsPrimitives.h" |
|
14 |
|
15 #include "nsITransferable.h" // for mime defs, this is BAD |
|
16 |
|
17 // HTML convertor stuff |
|
18 #include "nsPrimitiveHelpers.h" |
|
19 #include "nsIDocumentEncoder.h" |
|
20 #include "nsContentUtils.h" |
|
21 |
|
22 nsHTMLFormatConverter::nsHTMLFormatConverter() |
|
23 { |
|
24 } |
|
25 |
|
26 nsHTMLFormatConverter::~nsHTMLFormatConverter() |
|
27 { |
|
28 } |
|
29 |
|
30 NS_IMPL_ISUPPORTS(nsHTMLFormatConverter, nsIFormatConverter) |
|
31 |
|
32 // |
|
33 // GetInputDataFlavors |
|
34 // |
|
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. |
|
37 // |
|
38 // Flavors (strings) are wrapped in a primitive object so that JavaScript can |
|
39 // access them easily via XPConnect. |
|
40 // |
|
41 NS_IMETHODIMP |
|
42 nsHTMLFormatConverter::GetInputDataFlavors(nsISupportsArray **_retval) |
|
43 { |
|
44 if ( !_retval ) |
|
45 return NS_ERROR_INVALID_ARG; |
|
46 |
|
47 nsresult rv = NS_NewISupportsArray ( _retval ); // addrefs for us |
|
48 if ( NS_SUCCEEDED(rv) ) |
|
49 rv = AddFlavorToList ( *_retval, kHTMLMime ); |
|
50 |
|
51 return rv; |
|
52 |
|
53 } // GetInputDataFlavors |
|
54 |
|
55 |
|
56 // |
|
57 // GetOutputDataFlavors |
|
58 // |
|
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 |
|
61 // converted to. |
|
62 // |
|
63 // Flavors (strings) are wrapped in a primitive object so that JavaScript can |
|
64 // access them easily via XPConnect. |
|
65 // |
|
66 NS_IMETHODIMP |
|
67 nsHTMLFormatConverter::GetOutputDataFlavors(nsISupportsArray **_retval) |
|
68 { |
|
69 if ( !_retval ) |
|
70 return NS_ERROR_INVALID_ARG; |
|
71 |
|
72 nsresult rv = NS_NewISupportsArray ( _retval ); // addrefs for us |
|
73 if ( NS_SUCCEEDED(rv) ) { |
|
74 rv = AddFlavorToList ( *_retval, kHTMLMime ); |
|
75 if ( NS_FAILED(rv) ) |
|
76 return rv; |
|
77 #if NOT_NOW |
|
78 // pinkerton |
|
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 ); |
|
82 if ( NS_FAILED(rv) ) |
|
83 return rv; |
|
84 #endif |
|
85 rv = AddFlavorToList ( *_retval, kUnicodeMime ); |
|
86 if ( NS_FAILED(rv) ) |
|
87 return rv; |
|
88 } |
|
89 return rv; |
|
90 |
|
91 } // GetOutputDataFlavors |
|
92 |
|
93 |
|
94 // |
|
95 // AddFlavorToList |
|
96 // |
|
97 // Convenience routine for adding a flavor wrapped in an nsISupportsCString object |
|
98 // to a list |
|
99 // |
|
100 nsresult |
|
101 nsHTMLFormatConverter :: AddFlavorToList ( nsISupportsArray* inList, const char* inFlavor ) |
|
102 { |
|
103 nsresult rv; |
|
104 |
|
105 nsCOMPtr<nsISupportsCString> dataFlavor = |
|
106 do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); |
|
107 if ( dataFlavor ) { |
|
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); |
|
113 } |
|
114 return rv; |
|
115 |
|
116 } // AddFlavorToList |
|
117 |
|
118 |
|
119 // |
|
120 // CanConvert |
|
121 // |
|
122 // Determines if we support the given conversion. Currently, this method only |
|
123 // converts from HTML to others. |
|
124 // |
|
125 NS_IMETHODIMP |
|
126 nsHTMLFormatConverter::CanConvert(const char *aFromDataFlavor, const char *aToDataFlavor, bool *_retval) |
|
127 { |
|
128 if ( !_retval ) |
|
129 return NS_ERROR_INVALID_ARG; |
|
130 |
|
131 *_retval = false; |
|
132 if ( !nsCRT::strcmp(aFromDataFlavor, kHTMLMime) ) { |
|
133 if ( !nsCRT::strcmp(aToDataFlavor, kHTMLMime) ) |
|
134 *_retval = true; |
|
135 else if ( !nsCRT::strcmp(aToDataFlavor, kUnicodeMime) ) |
|
136 *_retval = true; |
|
137 #if NOT_NOW |
|
138 // pinkerton |
|
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) ) |
|
142 *_retval = true; |
|
143 #endif |
|
144 } |
|
145 return NS_OK; |
|
146 |
|
147 } // CanConvert |
|
148 |
|
149 |
|
150 |
|
151 // |
|
152 // Convert |
|
153 // |
|
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. |
|
156 // |
|
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. |
|
161 // |
|
162 NS_IMETHODIMP |
|
163 nsHTMLFormatConverter::Convert(const char *aFromDataFlavor, nsISupports *aFromData, uint32_t aDataLen, |
|
164 const char *aToDataFlavor, nsISupports **aToData, uint32_t *aDataToLen) |
|
165 { |
|
166 if ( !aToData || !aDataToLen ) |
|
167 return NS_ERROR_INVALID_ARG; |
|
168 |
|
169 nsresult rv = NS_OK; |
|
170 *aToData = nullptr; |
|
171 *aDataToLen = 0; |
|
172 |
|
173 if ( !nsCRT::strcmp(aFromDataFlavor, kHTMLMime) ) { |
|
174 nsAutoCString toFlavor ( aToDataFlavor ); |
|
175 |
|
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) ); |
|
180 if (!dataWrapper0) { |
|
181 return NS_ERROR_INVALID_ARG; |
|
182 } |
|
183 |
|
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 |
|
187 // about it here. |
|
188 if ( toFlavor.Equals(kHTMLMime) || toFlavor.Equals(kUnicodeMime) ) { |
|
189 nsresult res; |
|
190 if (toFlavor.Equals(kHTMLMime)) { |
|
191 int32_t dataLen = dataStr.Length() * 2; |
|
192 nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor.get(), dataStr.get(), dataLen, aToData ); |
|
193 if ( *aToData ) |
|
194 *aDataToLen = dataLen; |
|
195 } else { |
|
196 nsAutoString outStr; |
|
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 ); |
|
201 if ( *aToData ) |
|
202 *aDataToLen = dataLen; |
|
203 } |
|
204 } |
|
205 } // else if HTML or Unicode |
|
206 else if ( toFlavor.Equals(kAOLMailMime) ) { |
|
207 nsAutoString outStr; |
|
208 if ( NS_SUCCEEDED(ConvertFromHTMLToAOLMail(dataStr, outStr)) ) { |
|
209 int32_t dataLen = outStr.Length() * 2; |
|
210 nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor.get(), outStr.get(), dataLen, aToData ); |
|
211 if ( *aToData ) |
|
212 *aDataToLen = dataLen; |
|
213 } |
|
214 } // else if AOL mail |
|
215 else { |
|
216 rv = NS_ERROR_FAILURE; |
|
217 } |
|
218 } // if we got html mime |
|
219 else |
|
220 rv = NS_ERROR_FAILURE; |
|
221 |
|
222 return rv; |
|
223 |
|
224 } // Convert |
|
225 |
|
226 |
|
227 // |
|
228 // ConvertFromHTMLToUnicode |
|
229 // |
|
230 // Takes HTML and converts it to plain text but in unicode. |
|
231 // |
|
232 NS_IMETHODIMP |
|
233 nsHTMLFormatConverter::ConvertFromHTMLToUnicode(const nsAutoString & aFromStr, nsAutoString & aToStr) |
|
234 { |
|
235 return nsContentUtils::ConvertToPlainText(aFromStr, |
|
236 aToStr, |
|
237 nsIDocumentEncoder::OutputSelectionOnly | |
|
238 nsIDocumentEncoder::OutputAbsoluteLinks | |
|
239 nsIDocumentEncoder::OutputNoScriptContent | |
|
240 nsIDocumentEncoder::OutputNoFramesContent, |
|
241 0); |
|
242 } // ConvertFromHTMLToUnicode |
|
243 |
|
244 |
|
245 NS_IMETHODIMP |
|
246 nsHTMLFormatConverter::ConvertFromHTMLToAOLMail(const nsAutoString & aFromStr, |
|
247 nsAutoString & aToStr) |
|
248 { |
|
249 aToStr.AssignLiteral("<HTML>"); |
|
250 aToStr.Append(aFromStr); |
|
251 aToStr.AppendLiteral("</HTML>"); |
|
252 |
|
253 return NS_OK; |
|
254 } |
|
255 |