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