Home | History | Annotate | Download | only in clipboard
      1 // Copyright (c) 2012 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 "ui/base/clipboard/clipboard.h"
      6 
      7 #include <list>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/files/file_path.h"
     11 #include "base/logging.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/stl_util.h"
     14 #include "base/strings/utf_string_conversions.h"
     15 #include "third_party/skia/include/core/SkBitmap.h"
     16 #include "ui/base/clipboard/custom_data_helper.h"
     17 #include "ui/gfx/size.h"
     18 
     19 namespace ui {
     20 
     21 namespace {
     22 const char kMimeTypeFilename[] = "chromium/filename";
     23 const char kMimeTypeBitmap[] = "image/bmp";
     24 const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
     25 const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
     26 const size_t kMaxClipboardSize = 1;
     27 
     28 // Clipboard data format used by AuraClipboard.
     29 enum AuraClipboardFormat {
     30   TEXT      = 1 << 0,
     31   HTML      = 1 << 1,
     32   RTF       = 1 << 2,
     33   BOOKMARK  = 1 << 3,
     34   BITMAP    = 1 << 4,
     35   CUSTOM    = 1 << 5,
     36   WEB       = 1 << 6,
     37 };
     38 
     39 // ClipboardData contains data copied to the Clipboard for a variety of formats.
     40 // It mostly just provides APIs to cleanly access and manipulate this data.
     41 class ClipboardData {
     42  public:
     43   ClipboardData()
     44       : bitmap_data_(),
     45         web_smart_paste_(false),
     46         format_(0) {}
     47 
     48   virtual ~ClipboardData() {}
     49 
     50   // Bitmask of AuraClipboardFormat types.
     51   const int format() const { return format_; }
     52 
     53   const std::string& text() const { return text_; }
     54   void set_text(const std::string& text) {
     55     text_ = text;
     56     format_ |= TEXT;
     57   }
     58 
     59   const std::string& markup_data() const { return markup_data_; }
     60   void set_markup_data(const std::string& markup_data) {
     61     markup_data_ = markup_data;
     62     format_ |= HTML;
     63   }
     64 
     65   const std::string& rtf_data() const { return rtf_data_; }
     66   void SetRTFData(const std::string& rtf_data) {
     67     rtf_data_ = rtf_data;
     68     format_ |= RTF;
     69   }
     70 
     71   const std::string& url() const { return url_; }
     72   void set_url(const std::string& url) {
     73     url_ = url;
     74     format_ |= HTML;
     75   }
     76 
     77   const std::string& bookmark_title() const { return bookmark_title_; }
     78   void set_bookmark_title(const std::string& bookmark_title) {
     79     bookmark_title_ = bookmark_title;
     80     format_ |= BOOKMARK;
     81   }
     82 
     83   const std::string& bookmark_url() const { return bookmark_url_; }
     84   void set_bookmark_url(const std::string& bookmark_url) {
     85     bookmark_url_ = bookmark_url;
     86     format_ |= BOOKMARK;
     87   }
     88 
     89   uint8_t* bitmap_data() const { return bitmap_data_.get(); }
     90   const gfx::Size& bitmap_size() const { return bitmap_size_; }
     91   void SetBitmapData(const char* pixel_data, const char* size_data) {
     92     bitmap_size_ = *reinterpret_cast<const gfx::Size*>(size_data);
     93 
     94     // We assume 4-byte pixel data.
     95     size_t bitmap_data_len = 4 * bitmap_size_.width() * bitmap_size_.height();
     96     bitmap_data_.reset(new uint8_t[bitmap_data_len]);
     97     memcpy(bitmap_data_.get(), pixel_data, bitmap_data_len);
     98     format_ |= BITMAP;
     99   }
    100 
    101   const std::string& custom_data_format() const { return custom_data_format_; }
    102   const std::string& custom_data_data() const { return custom_data_data_; }
    103   void SetCustomData(const std::string& data_format,
    104                      const std::string& data_data) {
    105     if (data_data.size() == 0) {
    106       custom_data_data_.clear();
    107       custom_data_format_.clear();
    108       return;
    109     }
    110     custom_data_data_ = data_data;
    111     custom_data_format_ = data_format;
    112     format_ |= CUSTOM;
    113   }
    114 
    115   bool web_smart_paste() const { return web_smart_paste_; }
    116   void set_web_smart_paste(bool web_smart_paste) {
    117     web_smart_paste_ = web_smart_paste;
    118     format_ |= WEB;
    119   }
    120 
    121  private:
    122   // Plain text in UTF8 format.
    123   std::string text_;
    124 
    125   // HTML markup data in UTF8 format.
    126   std::string markup_data_;
    127   std::string url_;
    128 
    129   // RTF data.
    130   std::string rtf_data_;
    131 
    132   // Bookmark title in UTF8 format.
    133   std::string bookmark_title_;
    134   std::string bookmark_url_;
    135 
    136   // Filenames.
    137   std::vector<std::string> files_;
    138 
    139   // Bitmap images.
    140   scoped_ptr<uint8_t[]> bitmap_data_;
    141   gfx::Size bitmap_size_;
    142 
    143   // Data with custom format.
    144   std::string custom_data_format_;
    145   std::string custom_data_data_;
    146 
    147   // WebKit smart paste data.
    148   bool web_smart_paste_;
    149 
    150   int format_;
    151 
    152   DISALLOW_COPY_AND_ASSIGN(ClipboardData);
    153 };
    154 
    155 // Platform clipboard implementation for Aura. This handles things like format
    156 // conversion, versioning of clipboard items etc. The goal is to roughly provide
    157 // a substitute to platform clipboards on other platforms such as GtkClipboard
    158 // on gtk or winapi clipboard on win.
    159 class AuraClipboard {
    160  public:
    161   AuraClipboard() {}
    162 
    163   ~AuraClipboard() {
    164     Clear();
    165   }
    166 
    167   void Clear() {
    168     STLDeleteContainerPointers(data_list_.begin(), data_list_.end());
    169     data_list_.clear();
    170   }
    171 
    172   // Returns the number of entries currently in the clipboard stack.
    173   size_t GetNumClipboardEntries() {
    174     return data_list_.size();
    175   }
    176 
    177   // Returns the data currently on the top of the clipboard stack, NULL if the
    178   // clipboard stack is empty.
    179   const ClipboardData* GetData() const {
    180     if (data_list_.empty())
    181       return NULL;
    182     return data_list_.front();
    183   }
    184 
    185   // Returns true if the data on top of the clipboard stack has format |format|
    186   // or another format that can be converted to |format|.
    187   bool IsFormatAvailable(AuraClipboardFormat format) const {
    188     switch (format) {
    189       case TEXT:
    190         return HasFormat(TEXT) || HasFormat(BOOKMARK);
    191       default:
    192         return HasFormat(format);
    193     }
    194   }
    195 
    196   // Reads text from the data at the top of clipboard stack.
    197   void ReadText(string16* result) const {
    198     std::string utf8_result;
    199     ReadAsciiText(&utf8_result);
    200     *result = UTF8ToUTF16(utf8_result);
    201   }
    202 
    203   // Reads ascii text from the data at the top of clipboard stack.
    204   void ReadAsciiText(std::string* result) const {
    205     result->clear();
    206     const ClipboardData* data = GetData();
    207     if (!data)
    208       return;
    209     if (HasFormat(TEXT))
    210       *result = data->text();
    211     else if (HasFormat(HTML))
    212       *result = data->markup_data();
    213     else if (HasFormat(BOOKMARK))
    214       *result = data->bookmark_url();
    215   }
    216 
    217   // Reads HTML from the data at the top of clipboard stack.
    218   void ReadHTML(string16* markup,
    219                 std::string* src_url,
    220                 uint32* fragment_start,
    221                 uint32* fragment_end) const {
    222     markup->clear();
    223     if (src_url)
    224       src_url->clear();
    225     *fragment_start = 0;
    226     *fragment_end = 0;
    227 
    228     if (!HasFormat(HTML))
    229       return;
    230 
    231     const ClipboardData* data = GetData();
    232     *markup = UTF8ToUTF16(data->markup_data());
    233     *src_url = data->url();
    234 
    235     *fragment_start = 0;
    236     DCHECK_LE(markup->length(), kuint32max);
    237     *fragment_end = static_cast<uint32>(markup->length());
    238   }
    239 
    240   // Reads RTF from the data at the top of clipboard stack.
    241   void ReadRTF(std::string* result) const {
    242     result->clear();
    243     const ClipboardData* data = GetData();
    244     if (!HasFormat(RTF))
    245       return;
    246 
    247     *result = data->rtf_data();
    248   }
    249 
    250   // Reads image from the data at the top of clipboard stack.
    251   SkBitmap ReadImage() const {
    252     SkBitmap img;
    253     if (!HasFormat(BITMAP))
    254       return img;
    255 
    256     const ClipboardData* data = GetData();
    257     const gfx::Size size = data->bitmap_size();
    258     uint8_t* bitmap = data->bitmap_data();
    259     img.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height(), 0);
    260     img.allocPixels();
    261     img.eraseARGB(0, 0, 0, 0);
    262     memcpy(img.getPixels(), bitmap, size.width() * size.height() * 4);
    263     return img;
    264   }
    265 
    266   // Reads data of type |type| from the data at the top of clipboard stack.
    267   void ReadCustomData(const string16& type, string16* result) const {
    268     result->clear();
    269     const ClipboardData* data = GetData();
    270     if (!HasFormat(CUSTOM))
    271       return;
    272 
    273     ui::ReadCustomDataForType(data->custom_data_data().c_str(),
    274         data->custom_data_data().size(),
    275         type, result);
    276   }
    277 
    278   // Reads bookmark from the data at the top of clipboard stack.
    279   void ReadBookmark(string16* title, std::string* url) const {
    280     title->clear();
    281     url->clear();
    282     if (!HasFormat(BOOKMARK))
    283       return;
    284 
    285     const ClipboardData* data = GetData();
    286     *title = UTF8ToUTF16(data->bookmark_title());
    287     *url = data->bookmark_url();
    288   }
    289 
    290   void ReadData(const std::string& type, std::string* result) const {
    291     result->clear();
    292     const ClipboardData* data = GetData();
    293     if (!HasFormat(CUSTOM) || type != data->custom_data_format())
    294       return;
    295 
    296     *result = data->custom_data_data();
    297   }
    298 
    299   // Writes |data| to the top of the clipboard stack.
    300   void WriteData(ClipboardData* data) {
    301     DCHECK(data);
    302     AddToListEnsuringSize(data);
    303   }
    304 
    305  private:
    306   // True if the data on top of the clipboard stack has format |format|.
    307   bool HasFormat(AuraClipboardFormat format) const {
    308     const ClipboardData* data = GetData();
    309     if (!data)
    310       return false;
    311 
    312     return data->format() & format;
    313   }
    314 
    315   void AddToListEnsuringSize(ClipboardData* data) {
    316     DCHECK(data);
    317     data_list_.push_front(data);
    318 
    319     // If the size of list becomes more than the maximum allowed, we delete the
    320     // last element.
    321     if (data_list_.size() > kMaxClipboardSize) {
    322       ClipboardData* last = data_list_.back();
    323       data_list_.pop_back();
    324       delete last;
    325     }
    326   }
    327 
    328   // Stack containing various versions of ClipboardData.
    329   std::list<ClipboardData*> data_list_;
    330 
    331   DISALLOW_COPY_AND_ASSIGN(AuraClipboard);
    332 };
    333 
    334 AuraClipboard* aura_clipboard = NULL;
    335 
    336 AuraClipboard* GetClipboard() {
    337   if (!aura_clipboard)
    338     aura_clipboard = new AuraClipboard();
    339   return aura_clipboard;
    340 }
    341 
    342 void DeleteClipboard() {
    343   if (aura_clipboard)
    344     delete aura_clipboard;
    345   aura_clipboard = NULL;
    346 }
    347 
    348 // Helper class to build a ClipboardData object and write it to clipboard.
    349 class ClipboardDataBuilder {
    350  public:
    351   static void CommitToClipboard() {
    352     DCHECK(current_data_);
    353     GetClipboard()->WriteData(current_data_);
    354     current_data_ = NULL;
    355   }
    356 
    357   static void WriteText(const char* text_data, size_t text_len) {
    358     ClipboardData* data = GetCurrentData();
    359     data->set_text(std::string(text_data, text_len));
    360   }
    361 
    362   static void WriteHTML(const char* markup_data,
    363                         size_t markup_len,
    364                         const char* url_data,
    365                         size_t url_len) {
    366     ClipboardData* data = GetCurrentData();
    367     data->set_markup_data(std::string(markup_data, markup_len));
    368     data->set_url(std::string(url_data, url_len));
    369   }
    370 
    371   static void WriteRTF(const char* rtf_data, size_t rtf_len) {
    372     ClipboardData* data = GetCurrentData();
    373     data->SetRTFData(std::string(rtf_data, rtf_len));
    374   }
    375 
    376   static void WriteBookmark(const char* title_data,
    377                             size_t title_len,
    378                             const char* url_data,
    379                             size_t url_len) {
    380     ClipboardData* data = GetCurrentData();
    381     data->set_bookmark_title(std::string(title_data, title_len));
    382     data->set_bookmark_url(std::string(url_data, url_len));
    383   }
    384 
    385   static void WriteWebSmartPaste() {
    386     ClipboardData* data = GetCurrentData();
    387     data->set_web_smart_paste(true);
    388   }
    389 
    390   static void WriteBitmap(const char* pixel_data, const char* size_data) {
    391     ClipboardData* data = GetCurrentData();
    392     data->SetBitmapData(pixel_data, size_data);
    393   }
    394 
    395   static void WriteData(const std::string& format,
    396                         const char* data_data,
    397                         size_t data_len) {
    398     ClipboardData* data = GetCurrentData();
    399     data->SetCustomData(format, std::string(data_data, data_len));
    400   }
    401 
    402  private:
    403   static ClipboardData* GetCurrentData() {
    404     if (!current_data_)
    405       current_data_ = new ClipboardData;
    406     return current_data_;
    407   }
    408 
    409   static ClipboardData* current_data_;
    410 };
    411 
    412 ClipboardData* ClipboardDataBuilder::current_data_ = NULL;
    413 
    414 }  // namespace
    415 
    416 Clipboard::FormatType::FormatType() {
    417 }
    418 
    419 Clipboard::FormatType::FormatType(const std::string& native_format)
    420     : data_(native_format) {
    421 }
    422 
    423 Clipboard::FormatType::~FormatType() {
    424 }
    425 
    426 std::string Clipboard::FormatType::Serialize() const {
    427   return data_;
    428 }
    429 
    430 // static
    431 Clipboard::FormatType Clipboard::FormatType::Deserialize(
    432     const std::string& serialization) {
    433   return FormatType(serialization);
    434 }
    435 
    436 bool Clipboard::FormatType::operator<(const FormatType& other) const {
    437   return data_ < other.data_;
    438 }
    439 
    440 bool Clipboard::FormatType::Equals(const FormatType& other) const {
    441   return data_ == other.data_;
    442 }
    443 
    444 Clipboard::Clipboard() {
    445   DCHECK(CalledOnValidThread());
    446   // Make sure clipboard is created.
    447   GetClipboard();
    448 }
    449 
    450 Clipboard::~Clipboard() {
    451   DCHECK(CalledOnValidThread());
    452   DeleteClipboard();
    453 }
    454 
    455 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) {
    456   DCHECK(CalledOnValidThread());
    457   DCHECK(IsValidBuffer(buffer));
    458   for (ObjectMap::const_iterator iter = objects.begin();
    459        iter != objects.end(); ++iter) {
    460     DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
    461   }
    462   ClipboardDataBuilder::CommitToClipboard();
    463 }
    464 
    465 bool Clipboard::IsFormatAvailable(const FormatType& format,
    466                                   Buffer buffer) const {
    467   DCHECK(CalledOnValidThread());
    468   DCHECK(IsValidBuffer(buffer));
    469   AuraClipboard* clipboard = GetClipboard();
    470   if (GetPlainTextFormatType().Equals(format) ||
    471       GetUrlFormatType().Equals(format))
    472     return clipboard->IsFormatAvailable(TEXT);
    473   else if (GetHtmlFormatType().Equals(format))
    474     return clipboard->IsFormatAvailable(HTML);
    475   else if (GetRtfFormatType().Equals(format))
    476     return clipboard->IsFormatAvailable(RTF);
    477   else if (GetBitmapFormatType().Equals(format))
    478     return clipboard->IsFormatAvailable(BITMAP);
    479   else if (GetWebKitSmartPasteFormatType().Equals(format))
    480     return clipboard->IsFormatAvailable(WEB);
    481   else {
    482     const ClipboardData* data = clipboard->GetData();
    483     if (data && data->custom_data_format() == format.ToString())
    484       return true;
    485   }
    486   return false;
    487 }
    488 
    489 void Clipboard::Clear(Buffer buffer) {
    490   DCHECK(CalledOnValidThread());
    491   DCHECK(IsValidBuffer(buffer));
    492   AuraClipboard* clipboard = GetClipboard();
    493   clipboard->Clear();
    494 }
    495 
    496 void Clipboard::ReadAvailableTypes(Buffer buffer, std::vector<string16>* types,
    497     bool* contains_filenames) const {
    498   DCHECK(CalledOnValidThread());
    499   if (!types || !contains_filenames) {
    500     NOTREACHED();
    501     return;
    502   }
    503 
    504   types->clear();
    505   *contains_filenames = false;
    506   if (IsFormatAvailable(GetPlainTextFormatType(), buffer))
    507     types->push_back(UTF8ToUTF16(GetPlainTextFormatType().ToString()));
    508   if (IsFormatAvailable(GetHtmlFormatType(), buffer))
    509     types->push_back(UTF8ToUTF16(GetHtmlFormatType().ToString()));
    510   if (IsFormatAvailable(GetRtfFormatType(), buffer))
    511     types->push_back(UTF8ToUTF16(GetRtfFormatType().ToString()));
    512   if (IsFormatAvailable(GetBitmapFormatType(), buffer))
    513     types->push_back(UTF8ToUTF16(kMimeTypePNG));
    514 
    515   AuraClipboard* clipboard = GetClipboard();
    516   if (clipboard->IsFormatAvailable(CUSTOM) && clipboard->GetData()) {
    517     ui::ReadCustomDataTypes(clipboard->GetData()->custom_data_data().c_str(),
    518         clipboard->GetData()->custom_data_data().size(), types);
    519   }
    520 }
    521 
    522 void Clipboard::ReadText(Buffer buffer, string16* result) const {
    523   DCHECK(CalledOnValidThread());
    524   GetClipboard()->ReadText(result);
    525 }
    526 
    527 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const {
    528   DCHECK(CalledOnValidThread());
    529   GetClipboard()->ReadAsciiText(result);
    530 }
    531 
    532 void Clipboard::ReadHTML(Buffer buffer,
    533                          string16* markup,
    534                          std::string* src_url,
    535                          uint32* fragment_start,
    536                          uint32* fragment_end) const {
    537   DCHECK(CalledOnValidThread());
    538   GetClipboard()->ReadHTML(markup, src_url, fragment_start, fragment_end);
    539 }
    540 
    541 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const {
    542   DCHECK(CalledOnValidThread());
    543   GetClipboard()->ReadRTF(result);
    544 }
    545 
    546 SkBitmap Clipboard::ReadImage(Buffer buffer) const {
    547   DCHECK(CalledOnValidThread());
    548   return GetClipboard()->ReadImage();
    549 }
    550 
    551 void Clipboard::ReadCustomData(Buffer buffer,
    552                                const string16& type,
    553                                string16* result) const {
    554   DCHECK(CalledOnValidThread());
    555   GetClipboard()->ReadCustomData(type, result);
    556 }
    557 
    558 void Clipboard::ReadBookmark(string16* title, std::string* url) const {
    559   DCHECK(CalledOnValidThread());
    560   GetClipboard()->ReadBookmark(title, url);
    561 }
    562 
    563 void Clipboard::ReadData(const FormatType& format, std::string* result) const {
    564   DCHECK(CalledOnValidThread());
    565   GetClipboard()->ReadData(format.ToString(), result);
    566 }
    567 
    568 uint64 Clipboard::GetSequenceNumber(Buffer buffer) {
    569   DCHECK(CalledOnValidThread());
    570   return GetClipboard()->GetNumClipboardEntries();
    571 }
    572 
    573 void Clipboard::WriteText(const char* text_data, size_t text_len) {
    574   ClipboardDataBuilder::WriteText(text_data, text_len);
    575 }
    576 
    577 void Clipboard::WriteHTML(const char* markup_data,
    578                           size_t markup_len,
    579                           const char* url_data,
    580                           size_t url_len) {
    581   ClipboardDataBuilder::WriteHTML(markup_data, markup_len, url_data, url_len);
    582 }
    583 
    584 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) {
    585   ClipboardDataBuilder::WriteRTF(rtf_data, data_len);
    586 }
    587 
    588 void Clipboard::WriteBookmark(const char* title_data,
    589                               size_t title_len,
    590                               const char* url_data,
    591                               size_t url_len) {
    592   ClipboardDataBuilder::WriteBookmark(title_data, title_len, url_data, url_len);
    593 }
    594 
    595 void Clipboard::WriteWebSmartPaste() {
    596   ClipboardDataBuilder::WriteWebSmartPaste();
    597 }
    598 
    599 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) {
    600   ClipboardDataBuilder::WriteBitmap(pixel_data, size_data);
    601 }
    602 
    603 void Clipboard::WriteData(const FormatType& format,
    604                           const char* data_data,
    605                           size_t data_len) {
    606   ClipboardDataBuilder::WriteData(format.ToString(), data_data, data_len);
    607 }
    608 
    609 // static
    610 Clipboard::FormatType Clipboard::GetFormatType(
    611     const std::string& format_string) {
    612   return FormatType::Deserialize(format_string);
    613 }
    614 
    615 // static
    616 const Clipboard::FormatType& Clipboard::GetUrlFormatType() {
    617   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeURIList));
    618   return type;
    619 }
    620 
    621 // static
    622 const Clipboard::FormatType& Clipboard::GetUrlWFormatType() {
    623   return GetUrlFormatType();
    624 }
    625 
    626 // static
    627 const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() {
    628   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeText));
    629   return type;
    630 }
    631 
    632 // static
    633 const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() {
    634   return GetPlainTextFormatType();
    635 }
    636 
    637 // static
    638 const Clipboard::FormatType& Clipboard::GetFilenameFormatType() {
    639   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeFilename));
    640   return type;
    641 }
    642 
    643 // static
    644 const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() {
    645   return Clipboard::GetFilenameFormatType();
    646 }
    647 
    648 // static
    649 const Clipboard::FormatType& Clipboard::GetHtmlFormatType() {
    650   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeHTML));
    651   return type;
    652 }
    653 
    654 // static
    655 const Clipboard::FormatType& Clipboard::GetRtfFormatType() {
    656   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeRTF));
    657   return type;
    658 }
    659 
    660 // static
    661 const Clipboard::FormatType& Clipboard::GetBitmapFormatType() {
    662   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeBitmap));
    663   return type;
    664 }
    665 
    666 // static
    667 const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() {
    668   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebkitSmartPaste));
    669   return type;
    670 }
    671 
    672 // static
    673 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() {
    674   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData));
    675   return type;
    676 }
    677 
    678 // static
    679 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
    680   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
    681   return type;
    682 }
    683 
    684 }  // namespace ui
    685