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 blink {
     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 void DataObject::setData(const String& type, const String& data)
    156 {
    157     clearData(type);
    158     if (!add(data, type))
    159         ASSERT_NOT_REACHED();
    160 }
    161 
    162 void DataObject::urlAndTitle(String& url, String* title) const
    163 {
    164     RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextURIList);
    165     if (!item)
    166         return;
    167     url = convertURIListToURL(item->getAsString());
    168     if (title)
    169         *title = item->title();
    170 }
    171 
    172 void DataObject::setURLAndTitle(const String& url, const String& title)
    173 {
    174     clearData(mimeTypeTextURIList);
    175     internalAddStringItem(DataObjectItem::createFromURL(url, title));
    176 }
    177 
    178 void DataObject::htmlAndBaseURL(String& html, KURL& baseURL) const
    179 {
    180     RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextHTML);
    181     if (!item)
    182         return;
    183     html = item->getAsString();
    184     baseURL = item->baseURL();
    185 }
    186 
    187 void DataObject::setHTMLAndBaseURL(const String& html, const KURL& baseURL)
    188 {
    189     clearData(mimeTypeTextHTML);
    190     internalAddStringItem(DataObjectItem::createFromHTML(html, baseURL));
    191 }
    192 
    193 bool DataObject::containsFilenames() const
    194 {
    195     for (size_t i = 0; i < m_itemList.size(); ++i) {
    196         if (m_itemList[i]->isFilename())
    197             return true;
    198     }
    199     return false;
    200 }
    201 
    202 Vector<String> DataObject::filenames() const
    203 {
    204     Vector<String> results;
    205     for (size_t i = 0; i < m_itemList.size(); ++i) {
    206         if (m_itemList[i]->isFilename())
    207             results.append(static_cast<File*>(m_itemList[i]->getAsFile().get())->path());
    208     }
    209     return results;
    210 }
    211 
    212 void DataObject::addFilename(const String& filename, const String& displayName)
    213 {
    214     internalAddFileItem(DataObjectItem::createFromFile(File::createForUserProvidedFile(filename, displayName)));
    215 }
    216 
    217 void DataObject::addSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
    218 {
    219     internalAddFileItem(DataObjectItem::createFromSharedBuffer(name, buffer));
    220 }
    221 
    222 DataObject::DataObject()
    223     : m_modifierKeyState(0)
    224 {
    225 }
    226 
    227 DataObject::DataObject(const DataObject& other)
    228     : m_itemList(other.m_itemList)
    229     , m_modifierKeyState(0)
    230 {
    231 }
    232 
    233 PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::findStringItem(const String& type) const
    234 {
    235     for (size_t i = 0; i < m_itemList.size(); ++i) {
    236         if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type)
    237             return m_itemList[i];
    238     }
    239     return nullptr;
    240 }
    241 
    242 bool DataObject::internalAddStringItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
    243 {
    244     ASSERT(item->kind() == DataObjectItem::StringKind);
    245     for (size_t i = 0; i < m_itemList.size(); ++i) {
    246         if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == item->type())
    247             return false;
    248     }
    249 
    250     m_itemList.append(item);
    251     return true;
    252 }
    253 
    254 void DataObject::internalAddFileItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
    255 {
    256     ASSERT(item->kind() == DataObjectItem::FileKind);
    257     m_itemList.append(item);
    258 }
    259 
    260 void DataObject::trace(Visitor* visitor)
    261 {
    262 #if ENABLE(OILPAN)
    263     visitor->trace(m_itemList);
    264     HeapSupplementable<DataObject>::trace(visitor);
    265 #endif
    266 }
    267 
    268 } // namespace blink
    269