Home | History | Annotate | Download | only in clipboard
      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/clipboard/DataObject.h"
     33 
     34 #include "core/clipboard/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 PassRefPtrWillBeRawPtr<DataObject> DataObject::createFromPasteboard(PasteMode pasteMode)
     43 {
     44     RefPtrWillBeRawPtr<DataObject> 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(DataObjectItem::createFromPasteboard(*it, sequenceNumber));
     56     }
     57     return dataObject.release();
     58 }
     59 
     60 PassRefPtrWillBeRawPtr<DataObject> DataObject::create()
     61 {
     62     return adoptRefWillBeNoop(new DataObject());
     63 }
     64 
     65 PassRefPtrWillBeRawPtr<DataObject> DataObject::copy() const
     66 {
     67     return adoptRefWillBeNoop(new DataObject(*this));
     68 }
     69 
     70 DataObject::~DataObject()
     71 {
     72 }
     73 
     74 size_t DataObject::length() const
     75 {
     76     return m_itemList.size();
     77 }
     78 
     79 PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::item(unsigned long index)
     80 {
     81     if (index >= length())
     82         return nullptr;
     83     return m_itemList[index];
     84 }
     85 
     86 void DataObject::deleteItem(unsigned long index)
     87 {
     88     if (index >= length())
     89         return;
     90     m_itemList.remove(index);
     91 }
     92 
     93 void DataObject::clearAll()
     94 {
     95     m_itemList.clear();
     96 }
     97 
     98 PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::add(const String& data, const String& type)
     99 {
    100     RefPtrWillBeRawPtr<DataObjectItem> item = DataObjectItem::createFromString(type, data);
    101     if (!internalAddStringItem(item))
    102         return nullptr;
    103     return item;
    104 }
    105 
    106 PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::add(PassRefPtrWillBeRawPtr<File> file)
    107 {
    108     if (!file)
    109         return nullptr;
    110 
    111     RefPtrWillBeRawPtr<DataObjectItem> item = DataObjectItem::createFromFile(file);
    112     m_itemList.append(item);
    113     return item;
    114 }
    115 
    116 void DataObject::clearData(const String& type)
    117 {
    118     for (size_t i = 0; i < m_itemList.size(); ++i) {
    119         if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type) {
    120             // Per the spec, type must be unique among all items of kind 'string'.
    121             m_itemList.remove(i);
    122             return;
    123         }
    124     }
    125 }
    126 
    127 ListHashSet<String> DataObject::types() const
    128 {
    129     ListHashSet<String> results;
    130     bool containsFiles = false;
    131     for (size_t i = 0; i < m_itemList.size(); ++i) {
    132         switch (m_itemList[i]->kind()) {
    133         case DataObjectItem::StringKind:
    134             results.add(m_itemList[i]->type());
    135             break;
    136         case DataObjectItem::FileKind:
    137             containsFiles = true;
    138             break;
    139         }
    140     }
    141     if (containsFiles)
    142         results.add(mimeTypeFiles);
    143     return results;
    144 }
    145 
    146 String DataObject::getData(const String& type) const
    147 {
    148     for (size_t i = 0; i < m_itemList.size(); ++i)  {
    149         if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type)
    150             return m_itemList[i]->getAsString();
    151     }
    152     return String();
    153 }
    154 
    155 bool DataObject::setData(const String& type, const String& data)
    156 {
    157     clearData(type);
    158     if (!add(data, type))
    159         ASSERT_NOT_REACHED();
    160     return true;
    161 }
    162 
    163 void DataObject::urlAndTitle(String& url, String* title) const
    164 {
    165     RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextURIList);
    166     if (!item)
    167         return;
    168     url = convertURIListToURL(item->getAsString());
    169     if (title)
    170         *title = item->title();
    171 }
    172 
    173 void DataObject::setURLAndTitle(const String& url, const String& title)
    174 {
    175     clearData(mimeTypeTextURIList);
    176     internalAddStringItem(DataObjectItem::createFromURL(url, title));
    177 }
    178 
    179 void DataObject::htmlAndBaseURL(String& html, KURL& baseURL) const
    180 {
    181     RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextHTML);
    182     if (!item)
    183         return;
    184     html = item->getAsString();
    185     baseURL = item->baseURL();
    186 }
    187 
    188 void DataObject::setHTMLAndBaseURL(const String& html, const KURL& baseURL)
    189 {
    190     clearData(mimeTypeTextHTML);
    191     internalAddStringItem(DataObjectItem::createFromHTML(html, baseURL));
    192 }
    193 
    194 bool DataObject::containsFilenames() const
    195 {
    196     for (size_t i = 0; i < m_itemList.size(); ++i) {
    197         if (m_itemList[i]->isFilename())
    198             return true;
    199     }
    200     return false;
    201 }
    202 
    203 Vector<String> DataObject::filenames() const
    204 {
    205     Vector<String> results;
    206     for (size_t i = 0; i < m_itemList.size(); ++i) {
    207         if (m_itemList[i]->isFilename())
    208             results.append(static_cast<File*>(m_itemList[i]->getAsFile().get())->path());
    209     }
    210     return results;
    211 }
    212 
    213 void DataObject::addFilename(const String& filename, const String& displayName)
    214 {
    215     internalAddFileItem(DataObjectItem::createFromFile(File::createWithName(filename, displayName, File::AllContentTypes)));
    216 }
    217 
    218 void DataObject::addSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
    219 {
    220     internalAddFileItem(DataObjectItem::createFromSharedBuffer(name, buffer));
    221 }
    222 
    223 DataObject::DataObject()
    224     : m_modifierKeyState(0)
    225 {
    226 }
    227 
    228 DataObject::DataObject(const DataObject& other)
    229     : m_itemList(other.m_itemList)
    230     , m_modifierKeyState(0)
    231 {
    232 }
    233 
    234 PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::findStringItem(const String& type) const
    235 {
    236     for (size_t i = 0; i < m_itemList.size(); ++i) {
    237         if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type)
    238             return m_itemList[i];
    239     }
    240     return nullptr;
    241 }
    242 
    243 bool DataObject::internalAddStringItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
    244 {
    245     ASSERT(item->kind() == DataObjectItem::StringKind);
    246     for (size_t i = 0; i < m_itemList.size(); ++i) {
    247         if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == item->type())
    248             return false;
    249     }
    250 
    251     m_itemList.append(item);
    252     return true;
    253 }
    254 
    255 void DataObject::internalAddFileItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
    256 {
    257     ASSERT(item->kind() == DataObjectItem::FileKind);
    258     m_itemList.append(item);
    259 }
    260 
    261 void DataObject::trace(Visitor* visitor)
    262 {
    263     visitor->trace(m_itemList);
    264     WillBeHeapSupplementable<DataObject>::trace(visitor);
    265 }
    266 
    267 } // namespace WebCore
    268