Home | History | Annotate | Download | only in glue
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "webkit/glue/webclipboard_impl.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/string_util.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "googleurl/src/gurl.h"
     11 #include "net/base/escape.h"
     12 #include "third_party/skia/include/core/SkBitmap.h"
     13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h"
     14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h"
     15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
     16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
     17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
     18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
     19 #include "ui/base/clipboard/clipboard.h"
     20 #include "webkit/glue/scoped_clipboard_writer_glue.h"
     21 #include "webkit/glue/webkit_glue.h"
     22 
     23 #if WEBKIT_USING_CG
     24 #include "skia/ext/skia_utils_mac.h"
     25 #endif
     26 
     27 using WebKit::WebClipboard;
     28 using WebKit::WebData;
     29 using WebKit::WebImage;
     30 using WebKit::WebString;
     31 using WebKit::WebURL;
     32 using WebKit::WebVector;
     33 
     34 namespace webkit_glue {
     35 
     36 // Static
     37 std::string WebClipboardImpl::URLToMarkup(const WebURL& url,
     38     const WebString& title) {
     39   std::string markup("<a href=\"");
     40   markup.append(url.spec());
     41   markup.append("\">");
     42   // TODO(darin): HTML escape this
     43   markup.append(EscapeForHTML(UTF16ToUTF8(title)));
     44   markup.append("</a>");
     45   return markup;
     46 }
     47 
     48 // Static
     49 std::string WebClipboardImpl::URLToImageMarkup(const WebURL& url,
     50     const WebString& title) {
     51   std::string markup("<img src=\"");
     52   markup.append(url.spec());
     53   markup.append("\"");
     54   if (!title.isEmpty()) {
     55     markup.append(" alt=\"");
     56     markup.append(EscapeForHTML(UTF16ToUTF8(title)));
     57     markup.append("\"");
     58   }
     59   markup.append("/>");
     60   return markup;
     61 }
     62 
     63 WebClipboardImpl::~WebClipboardImpl() {
     64 }
     65 
     66 bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
     67   ui::Clipboard::FormatType format_type;
     68   ui::Clipboard::Buffer buffer_type;
     69 
     70   if (!ConvertBufferType(buffer, &buffer_type))
     71     return false;
     72 
     73   switch (format) {
     74     case FormatPlainText:
     75       return ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
     76                                         buffer_type) ||
     77           ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
     78                                      buffer_type);
     79     case FormatHTML:
     80       format_type = ui::Clipboard::GetHtmlFormatType();
     81       break;
     82     case FormatSmartPaste:
     83       format_type = ui::Clipboard::GetWebKitSmartPasteFormatType();
     84       break;
     85     case FormatBookmark:
     86 #if defined(OS_WIN) || defined(OS_MACOSX)
     87       format_type = ui::Clipboard::GetUrlWFormatType();
     88       break;
     89 #endif
     90     default:
     91       NOTREACHED();
     92       return false;
     93   }
     94 
     95   return ClipboardIsFormatAvailable(format_type, buffer_type);
     96 }
     97 
     98 WebString WebClipboardImpl::readPlainText(Buffer buffer) {
     99   ui::Clipboard::Buffer buffer_type;
    100   if (!ConvertBufferType(buffer, &buffer_type))
    101     return WebString();
    102 
    103   if (ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
    104                                  buffer_type)) {
    105     string16 text;
    106     ClipboardReadText(buffer_type, &text);
    107     if (!text.empty())
    108       return text;
    109   }
    110 
    111   if (ClipboardIsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
    112                                  buffer_type)) {
    113     std::string text;
    114     ClipboardReadAsciiText(buffer_type, &text);
    115     if (!text.empty())
    116       return ASCIIToUTF16(text);
    117   }
    118 
    119   return WebString();
    120 }
    121 
    122 WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url) {
    123   ui::Clipboard::Buffer buffer_type;
    124   if (!ConvertBufferType(buffer, &buffer_type))
    125     return WebString();
    126 
    127   string16 html_stdstr;
    128   GURL gurl;
    129   ClipboardReadHTML(buffer_type, &html_stdstr, &gurl);
    130   *source_url = gurl;
    131   return html_stdstr;
    132 }
    133 
    134 WebData WebClipboardImpl::readImage(Buffer buffer) {
    135   ui::Clipboard::Buffer buffer_type;
    136   if (!ConvertBufferType(buffer, &buffer_type))
    137     return WebData();
    138 
    139   std::string png_data;
    140   ClipboardReadImage(buffer_type, &png_data);
    141   return WebData(png_data);
    142 }
    143 
    144 void WebClipboardImpl::writeHTML(
    145     const WebString& html_text, const WebURL& source_url,
    146     const WebString& plain_text, bool write_smart_paste) {
    147   ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
    148   scw.WriteHTML(html_text, source_url.spec());
    149   scw.WriteText(plain_text);
    150 
    151   if (write_smart_paste)
    152     scw.WriteWebSmartPaste();
    153 }
    154 
    155 void WebClipboardImpl::writePlainText(const WebString& plain_text) {
    156   ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
    157   scw.WriteText(plain_text);
    158 }
    159 
    160 void WebClipboardImpl::writeURL(const WebURL& url, const WebString& title) {
    161   ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
    162 
    163   scw.WriteBookmark(title, url.spec());
    164   scw.WriteHTML(UTF8ToUTF16(URLToMarkup(url, title)), "");
    165   scw.WriteText(UTF8ToUTF16(std::string(url.spec())));
    166 }
    167 
    168 void WebClipboardImpl::writeImage(
    169     const WebImage& image, const WebURL& url, const WebString& title) {
    170   ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
    171 
    172   if (!image.isNull()) {
    173 #if WEBKIT_USING_SKIA
    174     const SkBitmap& bitmap = image.getSkBitmap();
    175 #elif WEBKIT_USING_CG
    176     const SkBitmap& bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
    177 #endif
    178     SkAutoLockPixels locked(bitmap);
    179     scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
    180   }
    181 
    182   // When writing the image, we also write the image markup so that pasting
    183   // into rich text editors, such as Gmail, reveals the image. We also don't
    184   // want to call writeText(), since some applications (WordPad) don't pick the
    185   // image if there is also a text format on the clipboard.
    186   if (!url.isEmpty()) {
    187     scw.WriteBookmark(title, url.spec());
    188     scw.WriteHTML(UTF8ToUTF16(URLToImageMarkup(url, title)), "");
    189   }
    190 }
    191 
    192 void WebClipboardImpl::writeData(const WebString& type,
    193                                  const WebString& data,
    194                                  const WebString& metadata) {
    195   // TODO(dcheng): Implement this stub.
    196 }
    197 
    198 WebVector<WebString> WebClipboardImpl::readAvailableTypes(
    199     Buffer buffer, bool* contains_filenames) {
    200   ui::Clipboard::Buffer buffer_type;
    201   std::vector<string16> types;
    202   if (ConvertBufferType(buffer, &buffer_type)) {
    203     ClipboardReadAvailableTypes(buffer_type, &types, contains_filenames);
    204   }
    205   return types;
    206 }
    207 
    208 bool WebClipboardImpl::readData(Buffer buffer, const WebString& type,
    209                                 WebString* data, WebString* metadata) {
    210   ui::Clipboard::Buffer buffer_type;
    211   if (!ConvertBufferType(buffer, &buffer_type))
    212     return false;
    213 
    214   string16 data_out;
    215   string16 metadata_out;
    216   bool result = ClipboardReadData(buffer_type, type, &data_out, &metadata_out);
    217   if (result) {
    218     *data = data_out;
    219     *metadata = metadata_out;
    220   }
    221   return result;
    222 }
    223 
    224 WebVector<WebString> WebClipboardImpl::readFilenames(Buffer buffer) {
    225   ui::Clipboard::Buffer buffer_type;
    226   std::vector<string16> filenames;
    227   if (ConvertBufferType(buffer, &buffer_type)) {
    228     ClipboardReadFilenames(buffer_type, &filenames);
    229   }
    230   return filenames;
    231 }
    232 
    233 bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
    234                                          ui::Clipboard::Buffer* result) {
    235   switch (buffer) {
    236     case BufferStandard:
    237       *result = ui::Clipboard::BUFFER_STANDARD;
    238       break;
    239     case BufferDrag:
    240       *result = ui::Clipboard::BUFFER_DRAG;
    241     case BufferSelection:
    242 #if defined(USE_X11)
    243       *result = ui::Clipboard::BUFFER_SELECTION;
    244       break;
    245 #endif
    246     default:
    247       NOTREACHED();
    248       return false;
    249   }
    250   return true;
    251 }
    252 
    253 }  // namespace webkit_glue
    254