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