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