widget/xpwidgets/nsHTMLFormatConverter.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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"
     8 #include "nsCRT.h"
     9 #include "nsISupportsArray.h"
    10 #include "nsIComponentManager.h"
    11 #include "nsCOMPtr.h"
    12 #include "nsXPCOM.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()
    23 {
    24 }
    26 nsHTMLFormatConverter::~nsHTMLFormatConverter()
    27 {
    28 }
    30 NS_IMPL_ISUPPORTS(nsHTMLFormatConverter, nsIFormatConverter)
    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;
    47   nsresult rv = NS_NewISupportsArray ( _retval );  // addrefs for us
    48   if ( NS_SUCCEEDED(rv) )
    49     rv = AddFlavorToList ( *_retval, kHTMLMime );
    51   return rv;
    53 } // GetInputDataFlavors
    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;
    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;
    91 } // GetOutputDataFlavors
    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;
   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;
   116 } // AddFlavorToList
   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;
   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;
   147 } // CanConvert
   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;
   169   nsresult rv = NS_OK;
   170   *aToData = nullptr;
   171   *aDataToLen = 0;
   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) );
   180     if (!dataWrapper0) {
   181       return NS_ERROR_INVALID_ARG;
   182     }
   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;      
   222   return rv;
   224 } // Convert
   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
   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>");
   253   return NS_OK;
   254 }

mercurial