1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/xpwidgets/nsHTMLFormatConverter.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,255 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsHTMLFormatConverter.h" 1.10 + 1.11 +#include "nsCRT.h" 1.12 +#include "nsISupportsArray.h" 1.13 +#include "nsIComponentManager.h" 1.14 +#include "nsCOMPtr.h" 1.15 +#include "nsXPCOM.h" 1.16 +#include "nsISupportsPrimitives.h" 1.17 + 1.18 +#include "nsITransferable.h" // for mime defs, this is BAD 1.19 + 1.20 +// HTML convertor stuff 1.21 +#include "nsPrimitiveHelpers.h" 1.22 +#include "nsIDocumentEncoder.h" 1.23 +#include "nsContentUtils.h" 1.24 + 1.25 +nsHTMLFormatConverter::nsHTMLFormatConverter() 1.26 +{ 1.27 +} 1.28 + 1.29 +nsHTMLFormatConverter::~nsHTMLFormatConverter() 1.30 +{ 1.31 +} 1.32 + 1.33 +NS_IMPL_ISUPPORTS(nsHTMLFormatConverter, nsIFormatConverter) 1.34 + 1.35 +// 1.36 +// GetInputDataFlavors 1.37 +// 1.38 +// Creates a new list and returns the list of all the flavors this converter 1.39 +// knows how to import. In this case, it's just HTML. 1.40 +// 1.41 +// Flavors (strings) are wrapped in a primitive object so that JavaScript can 1.42 +// access them easily via XPConnect. 1.43 +// 1.44 +NS_IMETHODIMP 1.45 +nsHTMLFormatConverter::GetInputDataFlavors(nsISupportsArray **_retval) 1.46 +{ 1.47 + if ( !_retval ) 1.48 + return NS_ERROR_INVALID_ARG; 1.49 + 1.50 + nsresult rv = NS_NewISupportsArray ( _retval ); // addrefs for us 1.51 + if ( NS_SUCCEEDED(rv) ) 1.52 + rv = AddFlavorToList ( *_retval, kHTMLMime ); 1.53 + 1.54 + return rv; 1.55 + 1.56 +} // GetInputDataFlavors 1.57 + 1.58 + 1.59 +// 1.60 +// GetOutputDataFlavors 1.61 +// 1.62 +// Creates a new list and returns the list of all the flavors this converter 1.63 +// knows how to export (convert). In this case, it's all sorts of things that HTML can be 1.64 +// converted to. 1.65 +// 1.66 +// Flavors (strings) are wrapped in a primitive object so that JavaScript can 1.67 +// access them easily via XPConnect. 1.68 +// 1.69 +NS_IMETHODIMP 1.70 +nsHTMLFormatConverter::GetOutputDataFlavors(nsISupportsArray **_retval) 1.71 +{ 1.72 + if ( !_retval ) 1.73 + return NS_ERROR_INVALID_ARG; 1.74 + 1.75 + nsresult rv = NS_NewISupportsArray ( _retval ); // addrefs for us 1.76 + if ( NS_SUCCEEDED(rv) ) { 1.77 + rv = AddFlavorToList ( *_retval, kHTMLMime ); 1.78 + if ( NS_FAILED(rv) ) 1.79 + return rv; 1.80 +#if NOT_NOW 1.81 +// pinkerton 1.82 +// no one uses this flavor right now, so it's just slowing things down. If anyone cares I 1.83 +// can put it back in. 1.84 + rv = AddFlavorToList ( *_retval, kAOLMailMime ); 1.85 + if ( NS_FAILED(rv) ) 1.86 + return rv; 1.87 +#endif 1.88 + rv = AddFlavorToList ( *_retval, kUnicodeMime ); 1.89 + if ( NS_FAILED(rv) ) 1.90 + return rv; 1.91 + } 1.92 + return rv; 1.93 + 1.94 +} // GetOutputDataFlavors 1.95 + 1.96 + 1.97 +// 1.98 +// AddFlavorToList 1.99 +// 1.100 +// Convenience routine for adding a flavor wrapped in an nsISupportsCString object 1.101 +// to a list 1.102 +// 1.103 +nsresult 1.104 +nsHTMLFormatConverter :: AddFlavorToList ( nsISupportsArray* inList, const char* inFlavor ) 1.105 +{ 1.106 + nsresult rv; 1.107 + 1.108 + nsCOMPtr<nsISupportsCString> dataFlavor = 1.109 + do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); 1.110 + if ( dataFlavor ) { 1.111 + dataFlavor->SetData ( nsDependentCString(inFlavor) ); 1.112 + // add to list as an nsISupports so the correct interface gets the addref 1.113 + // in AppendElement() 1.114 + nsCOMPtr<nsISupports> genericFlavor ( do_QueryInterface(dataFlavor) ); 1.115 + inList->AppendElement ( genericFlavor); 1.116 + } 1.117 + return rv; 1.118 + 1.119 +} // AddFlavorToList 1.120 + 1.121 + 1.122 +// 1.123 +// CanConvert 1.124 +// 1.125 +// Determines if we support the given conversion. Currently, this method only 1.126 +// converts from HTML to others. 1.127 +// 1.128 +NS_IMETHODIMP 1.129 +nsHTMLFormatConverter::CanConvert(const char *aFromDataFlavor, const char *aToDataFlavor, bool *_retval) 1.130 +{ 1.131 + if ( !_retval ) 1.132 + return NS_ERROR_INVALID_ARG; 1.133 + 1.134 + *_retval = false; 1.135 + if ( !nsCRT::strcmp(aFromDataFlavor, kHTMLMime) ) { 1.136 + if ( !nsCRT::strcmp(aToDataFlavor, kHTMLMime) ) 1.137 + *_retval = true; 1.138 + else if ( !nsCRT::strcmp(aToDataFlavor, kUnicodeMime) ) 1.139 + *_retval = true; 1.140 +#if NOT_NOW 1.141 +// pinkerton 1.142 +// no one uses this flavor right now, so it's just slowing things down. If anyone cares I 1.143 +// can put it back in. 1.144 + else if ( toFlavor.Equals(kAOLMailMime) ) 1.145 + *_retval = true; 1.146 +#endif 1.147 + } 1.148 + return NS_OK; 1.149 + 1.150 +} // CanConvert 1.151 + 1.152 + 1.153 + 1.154 +// 1.155 +// Convert 1.156 +// 1.157 +// Convert data from one flavor to another. The data is wrapped in primitive objects so that it is 1.158 +// accessible from JS. Currently, this only accepts HTML input, so anything else is invalid. 1.159 +// 1.160 +//XXX This method copies the data WAAAAY too many time for my liking. Grrrrrr. Mostly it's because 1.161 +//XXX we _must_ put things into nsStrings so that the parser will accept it. Lame lame lame lame. We 1.162 +//XXX also can't just get raw unicode out of the nsString, so we have to allocate heap to get 1.163 +//XXX unicode out of the string. Lame lame lame. 1.164 +// 1.165 +NS_IMETHODIMP 1.166 +nsHTMLFormatConverter::Convert(const char *aFromDataFlavor, nsISupports *aFromData, uint32_t aDataLen, 1.167 + const char *aToDataFlavor, nsISupports **aToData, uint32_t *aDataToLen) 1.168 +{ 1.169 + if ( !aToData || !aDataToLen ) 1.170 + return NS_ERROR_INVALID_ARG; 1.171 + 1.172 + nsresult rv = NS_OK; 1.173 + *aToData = nullptr; 1.174 + *aDataToLen = 0; 1.175 + 1.176 + if ( !nsCRT::strcmp(aFromDataFlavor, kHTMLMime) ) { 1.177 + nsAutoCString toFlavor ( aToDataFlavor ); 1.178 + 1.179 + // HTML on clipboard is going to always be double byte so it will be in a primitive 1.180 + // class of nsISupportsString. Also, since the data is in two byte chunks the 1.181 + // length represents the length in 1-byte chars, so we need to divide by two. 1.182 + nsCOMPtr<nsISupportsString> dataWrapper0 ( do_QueryInterface(aFromData) ); 1.183 + if (!dataWrapper0) { 1.184 + return NS_ERROR_INVALID_ARG; 1.185 + } 1.186 + 1.187 + nsAutoString dataStr; 1.188 + dataWrapper0->GetData ( dataStr ); //еее COPY #1 1.189 + // note: conversion to text/plain is done inside the clipboard. we do not need to worry 1.190 + // about it here. 1.191 + if ( toFlavor.Equals(kHTMLMime) || toFlavor.Equals(kUnicodeMime) ) { 1.192 + nsresult res; 1.193 + if (toFlavor.Equals(kHTMLMime)) { 1.194 + int32_t dataLen = dataStr.Length() * 2; 1.195 + nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor.get(), dataStr.get(), dataLen, aToData ); 1.196 + if ( *aToData ) 1.197 + *aDataToLen = dataLen; 1.198 + } else { 1.199 + nsAutoString outStr; 1.200 + res = ConvertFromHTMLToUnicode(dataStr, outStr); 1.201 + if (NS_SUCCEEDED(res)) { 1.202 + int32_t dataLen = outStr.Length() * 2; 1.203 + nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor.get(), outStr.get(), dataLen, aToData ); 1.204 + if ( *aToData ) 1.205 + *aDataToLen = dataLen; 1.206 + } 1.207 + } 1.208 + } // else if HTML or Unicode 1.209 + else if ( toFlavor.Equals(kAOLMailMime) ) { 1.210 + nsAutoString outStr; 1.211 + if ( NS_SUCCEEDED(ConvertFromHTMLToAOLMail(dataStr, outStr)) ) { 1.212 + int32_t dataLen = outStr.Length() * 2; 1.213 + nsPrimitiveHelpers::CreatePrimitiveForData ( toFlavor.get(), outStr.get(), dataLen, aToData ); 1.214 + if ( *aToData ) 1.215 + *aDataToLen = dataLen; 1.216 + } 1.217 + } // else if AOL mail 1.218 + else { 1.219 + rv = NS_ERROR_FAILURE; 1.220 + } 1.221 + } // if we got html mime 1.222 + else 1.223 + rv = NS_ERROR_FAILURE; 1.224 + 1.225 + return rv; 1.226 + 1.227 +} // Convert 1.228 + 1.229 + 1.230 +// 1.231 +// ConvertFromHTMLToUnicode 1.232 +// 1.233 +// Takes HTML and converts it to plain text but in unicode. 1.234 +// 1.235 +NS_IMETHODIMP 1.236 +nsHTMLFormatConverter::ConvertFromHTMLToUnicode(const nsAutoString & aFromStr, nsAutoString & aToStr) 1.237 +{ 1.238 + return nsContentUtils::ConvertToPlainText(aFromStr, 1.239 + aToStr, 1.240 + nsIDocumentEncoder::OutputSelectionOnly | 1.241 + nsIDocumentEncoder::OutputAbsoluteLinks | 1.242 + nsIDocumentEncoder::OutputNoScriptContent | 1.243 + nsIDocumentEncoder::OutputNoFramesContent, 1.244 + 0); 1.245 +} // ConvertFromHTMLToUnicode 1.246 + 1.247 + 1.248 +NS_IMETHODIMP 1.249 +nsHTMLFormatConverter::ConvertFromHTMLToAOLMail(const nsAutoString & aFromStr, 1.250 + nsAutoString & aToStr) 1.251 +{ 1.252 + aToStr.AssignLiteral("<HTML>"); 1.253 + aToStr.Append(aFromStr); 1.254 + aToStr.AppendLiteral("</HTML>"); 1.255 + 1.256 + return NS_OK; 1.257 +} 1.258 +