Home | History | Annotate | Download | only in chromium
      1 /*
      2  * Copyright (c) 2008, 2009, 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "core/platform/chromium/ChromiumDataObject.h"
     33 
     34 #include "core/platform/Pasteboard.h"
     35 #include "platform/clipboard/ClipboardMimeTypes.h"
     36 #include "platform/clipboard/ClipboardUtilities.h"
     37 #include "public/platform/Platform.h"
     38 #include "public/platform/WebClipboard.h"
     39 
     40 namespace WebCore {
     41 
     42 PassRefPtr<ChromiumDataObject> ChromiumDataObject::createFromPasteboard(PasteMode pasteMode)
     43 {
     44     RefPtr<ChromiumDataObject> dataObject = create();
     45     blink::WebClipboard::Buffer buffer = Pasteboard::generalPasteboard()->buffer();
     46     uint64_t sequenceNumber = blink::Platform::current()->clipboard()->sequenceNumber(buffer);
     47     bool ignored;
     48     blink::WebVector<blink::WebString> webTypes = blink::Platform::current()->clipboard()->readAvailableTypes(buffer, &ignored);
     49     ListHashSet<String> types;
     50     for (size_t i = 0; i < webTypes.size(); ++i)
     51         types.add(webTypes[i]);
     52     for (ListHashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it) {
     53         if (pasteMode == PlainTextOnly && *it != mimeTypeTextPlain)
     54             continue;
     55         dataObject->m_itemList.append(ChromiumDataObjectItem::createFromPasteboard(*it, sequenceNumber));
     56     }
     57     return dataObject.release();
     58 }
     59 
     60 PassRefPtr<ChromiumDataObject> ChromiumDataObject::create()
     61 {
     62     return adoptRef(new ChromiumDataObject());
     63 }
     64 
     65 PassRefPtr<ChromiumDataObject> ChromiumDataObject::copy() const
     66 {
     67     return adoptRef(new ChromiumDataObject(*this));
     68 }
     69 
     70 size_t ChromiumDataObject::length() const
     71 {
     72     return m_itemList.size();
     73 }
     74 
     75 PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::item(unsigned long index)
     76 {
     77     if (index >= length())
     78         return 0;
     79     return m_itemList[index];
     80 }
     81 
     82 void ChromiumDataObject::deleteItem(unsigned long index)
     83 {
     84     if (index >= length())
     85         return;
     86     m_itemList.remove(index);
     87 }
     88 
     89 void ChromiumDataObject::clearAll()
     90 {
     91     m_itemList.clear();
     92 }
     93 
     94 PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::add(const String& data, const String& type)
     95 {
     96     RefPtr<ChromiumDataObjectItem> item = ChromiumDataObjectItem::createFromString(type, data);
     97     if (!internalAddStringItem(item))
     98         return 0;
     99     return item;
    100 }
    101 
    102 PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::add(PassRefPtr<File> file)
    103 {
    104     if (!file)
    105         return 0;
    106 
    107     RefPtr<ChromiumDataObjectItem> item = ChromiumDataObjectItem::createFromFile(file);
    108     m_itemList.append(item);
    109     return item;
    110 }
    111 
    112 void ChromiumDataObject::clearData(const String& type)
    113 {
    114     for (size_t i = 0; i < m_itemList.size(); ++i) {
    115         if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == type) {
    116             // Per the spec, type must be unique among all items of kind 'string'.
    117             m_itemList.remove(i);
    118             return;
    119         }
    120     }
    121 }
    122 
    123 void ChromiumDataObject::clearAllExceptFiles()
    124 {
    125     for (size_t i = 0; i < m_itemList.size(); ) {
    126         if (m_itemList[i]->kind() != ChromiumDataObjectItem::FileKind) {
    127             m_itemList.remove(i);
    128             continue;
    129         }
    130         ++i;
    131     }
    132 }
    133 
    134 ListHashSet<String> ChromiumDataObject::types() const
    135 {
    136     ListHashSet<String> results;
    137     bool containsFiles = false;
    138     for (size_t i = 0; i < m_itemList.size(); ++i) {
    139         switch (m_itemList[i]->kind()) {
    140         case ChromiumDataObjectItem::StringKind:
    141             results.add(m_itemList[i]->type());
    142             break;
    143         case ChromiumDataObjectItem::FileKind:
    144             containsFiles = true;
    145             break;
    146         }
    147     }
    148     if (containsFiles)
    149         results.add(mimeTypeFiles);
    150     return results;
    151 }
    152 
    153 String ChromiumDataObject::getData(const String& type) const
    154 {
    155     for (size_t i = 0; i < m_itemList.size(); ++i)  {
    156         if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == type)
    157             return m_itemList[i]->internalGetAsString();
    158     }
    159     return String();
    160 }
    161 
    162 bool ChromiumDataObject::setData(const String& type, const String& data)
    163 {
    164     clearData(type);
    165     if (!add(data, type))
    166         ASSERT_NOT_REACHED();
    167     return true;
    168 }
    169 
    170 void ChromiumDataObject::urlAndTitle(String& url, String* title) const
    171 {
    172     RefPtr<ChromiumDataObjectItem> item = findStringItem(mimeTypeTextURIList);
    173     if (!item)
    174         return;
    175     url = convertURIListToURL(item->internalGetAsString());
    176     if (title)
    177         *title = item->title();
    178 }
    179 
    180 void ChromiumDataObject::setURLAndTitle(const String& url, const String& title)
    181 {
    182     clearData(mimeTypeTextURIList);
    183     internalAddStringItem(ChromiumDataObjectItem::createFromURL(url, title));
    184 }
    185 
    186 void ChromiumDataObject::htmlAndBaseURL(String& html, KURL& baseURL) const
    187 {
    188     RefPtr<ChromiumDataObjectItem> item = findStringItem(mimeTypeTextHTML);
    189     if (!item)
    190         return;
    191     html = item->internalGetAsString();
    192     baseURL = item->baseURL();
    193 }
    194 
    195 void ChromiumDataObject::setHTMLAndBaseURL(const String& html, const KURL& baseURL)
    196 {
    197     clearData(mimeTypeTextHTML);
    198     internalAddStringItem(ChromiumDataObjectItem::createFromHTML(html, baseURL));
    199 }
    200 
    201 bool ChromiumDataObject::containsFilenames() const
    202 {
    203     for (size_t i = 0; i < m_itemList.size(); ++i)
    204         if (m_itemList[i]->isFilename())
    205             return true;
    206     return false;
    207 }
    208 
    209 Vector<String> ChromiumDataObject::filenames() const
    210 {
    211     Vector<String> results;
    212     for (size_t i = 0; i < m_itemList.size(); ++i)
    213         if (m_itemList[i]->isFilename())
    214             results.append(static_cast<File*>(m_itemList[i]->getAsFile().get())->path());
    215     return results;
    216 }
    217 
    218 void ChromiumDataObject::addFilename(const String& filename, const String& displayName)
    219 {
    220     internalAddFileItem(ChromiumDataObjectItem::createFromFile(File::createWithName(filename, displayName, File::AllContentTypes)));
    221 }
    222 
    223 void ChromiumDataObject::addSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
    224 {
    225     internalAddFileItem(ChromiumDataObjectItem::createFromSharedBuffer(name, buffer));
    226 }
    227 
    228 ChromiumDataObject::ChromiumDataObject()
    229     : m_modifierKeyState(0)
    230 {
    231 }
    232 
    233 ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other)
    234     : RefCounted<ChromiumDataObject>()
    235     , m_itemList(other.m_itemList)
    236     , m_modifierKeyState(0)
    237 {
    238 }
    239 
    240 PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::findStringItem(const String& type) const
    241 {
    242     for (size_t i = 0; i < m_itemList.size(); ++i) {
    243         if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == type)
    244             return m_itemList[i];
    245     }
    246     return 0;
    247 }
    248 
    249 bool ChromiumDataObject::internalAddStringItem(PassRefPtr<ChromiumDataObjectItem> item)
    250 {
    251     ASSERT(item->kind() == ChromiumDataObjectItem::StringKind);
    252     for (size_t i = 0; i < m_itemList.size(); ++i)
    253         if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == item->type())
    254             return false;
    255 
    256     m_itemList.append(item);
    257     return true;
    258 }
    259 
    260 void ChromiumDataObject::internalAddFileItem(PassRefPtr<ChromiumDataObjectItem> item)
    261 {
    262     ASSERT(item->kind() == ChromiumDataObjectItem::FileKind);
    263     m_itemList.append(item);
    264 }
    265 
    266 } // namespace WebCore
    267