/src/mozilla-central/widget/nsHTMLFormatConverter.cpp
Line | Count | Source (jump to first uncovered line) |
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 "nsArray.h" |
9 | | #include "nsCRT.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 | 0 | { |
24 | 0 | } |
25 | | |
26 | | nsHTMLFormatConverter::~nsHTMLFormatConverter() |
27 | 0 | { |
28 | 0 | } |
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(nsIArray **_retval) |
43 | 0 | { |
44 | 0 | if ( !_retval ) |
45 | 0 | return NS_ERROR_INVALID_ARG; |
46 | 0 | |
47 | 0 | nsCOMPtr<nsIMutableArray> array = nsArray::Create(); |
48 | 0 | nsresult rv = AddFlavorToList ( array, kHTMLMime ); |
49 | 0 |
|
50 | 0 | array.forget(_retval); |
51 | 0 | return rv; |
52 | 0 |
|
53 | 0 | } // 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(nsIArray **_retval) |
68 | 0 | { |
69 | 0 | if ( !_retval ) |
70 | 0 | return NS_ERROR_INVALID_ARG; |
71 | 0 | |
72 | 0 | nsCOMPtr<nsIMutableArray> array = nsArray::Create(); |
73 | 0 | nsresult rv = AddFlavorToList ( array, kHTMLMime ); |
74 | 0 | if ( NS_FAILED(rv) ) |
75 | 0 | return rv; |
76 | 0 | rv = AddFlavorToList ( array, kUnicodeMime ); |
77 | 0 | if ( NS_FAILED(rv) ) |
78 | 0 | return rv; |
79 | 0 | |
80 | 0 | array.forget(_retval); |
81 | 0 | return rv; |
82 | 0 |
|
83 | 0 | } // GetOutputDataFlavors |
84 | | |
85 | | |
86 | | // |
87 | | // AddFlavorToList |
88 | | // |
89 | | // Convenience routine for adding a flavor wrapped in an nsISupportsCString object |
90 | | // to a list |
91 | | // |
92 | | nsresult |
93 | | nsHTMLFormatConverter :: AddFlavorToList ( nsCOMPtr<nsIMutableArray>& inList, const char* inFlavor ) |
94 | 0 | { |
95 | 0 | nsresult rv; |
96 | 0 |
|
97 | 0 | nsCOMPtr<nsISupportsCString> dataFlavor = |
98 | 0 | do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); |
99 | 0 | if ( dataFlavor ) { |
100 | 0 | dataFlavor->SetData ( nsDependentCString(inFlavor) ); |
101 | 0 | // add to list as an nsISupports so the correct interface gets the addref |
102 | 0 | // in AppendElement() |
103 | 0 | nsCOMPtr<nsISupports> genericFlavor ( do_QueryInterface(dataFlavor) ); |
104 | 0 | inList->AppendElement ( genericFlavor ); |
105 | 0 | } |
106 | 0 | return rv; |
107 | 0 |
|
108 | 0 | } // AddFlavorToList |
109 | | |
110 | | |
111 | | // |
112 | | // CanConvert |
113 | | // |
114 | | // Determines if we support the given conversion. Currently, this method only |
115 | | // converts from HTML to others. |
116 | | // |
117 | | NS_IMETHODIMP |
118 | | nsHTMLFormatConverter::CanConvert(const char *aFromDataFlavor, const char *aToDataFlavor, bool *_retval) |
119 | 0 | { |
120 | 0 | if ( !_retval ) |
121 | 0 | return NS_ERROR_INVALID_ARG; |
122 | 0 | |
123 | 0 | *_retval = false; |
124 | 0 | if ( !nsCRT::strcmp(aFromDataFlavor, kHTMLMime) ) { |
125 | 0 | if ( !nsCRT::strcmp(aToDataFlavor, kHTMLMime) ) |
126 | 0 | *_retval = true; |
127 | 0 | else if ( !nsCRT::strcmp(aToDataFlavor, kUnicodeMime) ) |
128 | 0 | *_retval = true; |
129 | | #if NOT_NOW |
130 | | // pinkerton |
131 | | // no one uses this flavor right now, so it's just slowing things down. If anyone cares I |
132 | | // can put it back in. |
133 | | else if ( toFlavor.Equals(kAOLMailMime) ) |
134 | | *_retval = true; |
135 | | #endif |
136 | | } |
137 | 0 | return NS_OK; |
138 | 0 |
|
139 | 0 | } // CanConvert |
140 | | |
141 | | |
142 | | |
143 | | // |
144 | | // Convert |
145 | | // |
146 | | // Convert data from one flavor to another. The data is wrapped in primitive objects so that it is |
147 | | // accessible from JS. Currently, this only accepts HTML input, so anything else is invalid. |
148 | | // |
149 | | //XXX This method copies the data WAAAAY too many time for my liking. Grrrrrr. Mostly it's because |
150 | | //XXX we _must_ put things into nsStrings so that the parser will accept it. Lame lame lame lame. We |
151 | | //XXX also can't just get raw unicode out of the nsString, so we have to allocate heap to get |
152 | | //XXX unicode out of the string. Lame lame lame. |
153 | | // |
154 | | NS_IMETHODIMP |
155 | | nsHTMLFormatConverter::Convert(const char *aFromDataFlavor, nsISupports *aFromData, uint32_t aDataLen, |
156 | | const char *aToDataFlavor, nsISupports **aToData, uint32_t *aDataToLen) |
157 | 0 | { |
158 | 0 | if ( !aToData || !aDataToLen ) |
159 | 0 | return NS_ERROR_INVALID_ARG; |
160 | 0 | |
161 | 0 | nsresult rv = NS_OK; |
162 | 0 | *aToData = nullptr; |
163 | 0 | *aDataToLen = 0; |
164 | 0 |
|
165 | 0 | if ( !nsCRT::strcmp(aFromDataFlavor, kHTMLMime) ) { |
166 | 0 | nsAutoCString toFlavor ( aToDataFlavor ); |
167 | 0 |
|
168 | 0 | // HTML on clipboard is going to always be double byte so it will be in a primitive |
169 | 0 | // class of nsISupportsString. Also, since the data is in two byte chunks the |
170 | 0 | // length represents the length in 1-byte chars, so we need to divide by two. |
171 | 0 | nsCOMPtr<nsISupportsString> dataWrapper0 ( do_QueryInterface(aFromData) ); |
172 | 0 | if (!dataWrapper0) { |
173 | 0 | return NS_ERROR_INVALID_ARG; |
174 | 0 | } |
175 | 0 | |
176 | 0 | nsAutoString dataStr; |
177 | 0 | dataWrapper0->GetData ( dataStr ); // COPY #1 |
178 | 0 | // note: conversion to text/plain is done inside the clipboard. we do not need to worry |
179 | 0 | // about it here. |
180 | 0 | if ( toFlavor.Equals(kHTMLMime) || toFlavor.Equals(kUnicodeMime) ) { |
181 | 0 | nsresult res; |
182 | 0 | if (toFlavor.Equals(kHTMLMime)) { |
183 | 0 | int32_t dataLen = dataStr.Length() * 2; |
184 | 0 | nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor, dataStr.get(), dataLen, aToData ); |
185 | 0 | if ( *aToData ) |
186 | 0 | *aDataToLen = dataLen; |
187 | 0 | } else { |
188 | 0 | nsAutoString outStr; |
189 | 0 | res = ConvertFromHTMLToUnicode(dataStr, outStr); |
190 | 0 | if (NS_SUCCEEDED(res)) { |
191 | 0 | int32_t dataLen = outStr.Length() * 2; |
192 | 0 | nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor, outStr.get(), dataLen, aToData ); |
193 | 0 | if ( *aToData ) |
194 | 0 | *aDataToLen = dataLen; |
195 | 0 | } |
196 | 0 | } |
197 | 0 | } // else if HTML or Unicode |
198 | 0 | else if ( toFlavor.Equals(kAOLMailMime) ) { |
199 | 0 | nsAutoString outStr; |
200 | 0 | if ( NS_SUCCEEDED(ConvertFromHTMLToAOLMail(dataStr, outStr)) ) { |
201 | 0 | int32_t dataLen = outStr.Length() * 2; |
202 | 0 | nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor, outStr.get(), dataLen, aToData ); |
203 | 0 | if ( *aToData ) |
204 | 0 | *aDataToLen = dataLen; |
205 | 0 | } |
206 | 0 | } // else if AOL mail |
207 | 0 | else { |
208 | 0 | rv = NS_ERROR_FAILURE; |
209 | 0 | } |
210 | 0 | } // if we got html mime |
211 | 0 | else |
212 | 0 | rv = NS_ERROR_FAILURE; |
213 | 0 |
|
214 | 0 | return rv; |
215 | 0 |
|
216 | 0 | } // Convert |
217 | | |
218 | | |
219 | | // |
220 | | // ConvertFromHTMLToUnicode |
221 | | // |
222 | | // Takes HTML and converts it to plain text but in unicode. |
223 | | // |
224 | | NS_IMETHODIMP |
225 | | nsHTMLFormatConverter::ConvertFromHTMLToUnicode(const nsAutoString & aFromStr, nsAutoString & aToStr) |
226 | 0 | { |
227 | 0 | return nsContentUtils::ConvertToPlainText(aFromStr, |
228 | 0 | aToStr, |
229 | 0 | nsIDocumentEncoder::OutputSelectionOnly | |
230 | 0 | nsIDocumentEncoder::OutputAbsoluteLinks | |
231 | 0 | nsIDocumentEncoder::OutputNoScriptContent | |
232 | 0 | nsIDocumentEncoder::OutputNoFramesContent, |
233 | 0 | 0); |
234 | 0 | } // ConvertFromHTMLToUnicode |
235 | | |
236 | | |
237 | | NS_IMETHODIMP |
238 | | nsHTMLFormatConverter::ConvertFromHTMLToAOLMail(const nsAutoString & aFromStr, |
239 | | nsAutoString & aToStr) |
240 | 0 | { |
241 | 0 | aToStr.AssignLiteral("<HTML>"); |
242 | 0 | aToStr.Append(aFromStr); |
243 | 0 | aToStr.AppendLiteral("</HTML>"); |
244 | 0 |
|
245 | 0 | return NS_OK; |
246 | 0 | } |
247 | | |