1/* 2 * Copyright (C) 2011 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/DataObjectItem.h" 33 34#include "core/clipboard/Pasteboard.h" 35#include "core/fileapi/Blob.h" 36#include "platform/clipboard/ClipboardMimeTypes.h" 37#include "public/platform/Platform.h" 38#include "public/platform/WebClipboard.h" 39 40namespace blink { 41 42PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromString(const String& type, const String& data) 43{ 44 RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, type)); 45 item->m_data = data; 46 return item.release(); 47} 48 49PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromFile(PassRefPtrWillBeRawPtr<File> file) 50{ 51 RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(FileKind, file->type())); 52 item->m_file = file; 53 return item.release(); 54} 55 56PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromURL(const String& url, const String& title) 57{ 58 RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, mimeTypeTextURIList)); 59 item->m_data = url; 60 item->m_title = title; 61 return item.release(); 62} 63 64PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromHTML(const String& html, const KURL& baseURL) 65{ 66 RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, mimeTypeTextHTML)); 67 item->m_data = html; 68 item->m_baseURL = baseURL; 69 return item.release(); 70} 71 72PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer) 73{ 74 RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(FileKind, String())); 75 item->m_sharedBuffer = buffer; 76 item->m_title = name; 77 return item.release(); 78} 79 80PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromPasteboard(const String& type, uint64_t sequenceNumber) 81{ 82 if (type == mimeTypeImagePng) 83 return adoptRefWillBeNoop(new DataObjectItem(FileKind, type, sequenceNumber)); 84 return adoptRefWillBeNoop(new DataObjectItem(StringKind, type, sequenceNumber)); 85} 86 87DataObjectItem::DataObjectItem(Kind kind, const String& type) 88 : m_source(InternalSource) 89 , m_kind(kind) 90 , m_type(type) 91 , m_sequenceNumber(0) 92{ 93} 94 95DataObjectItem::DataObjectItem(Kind kind, const String& type, uint64_t sequenceNumber) 96 : m_source(PasteboardSource) 97 , m_kind(kind) 98 , m_type(type) 99 , m_sequenceNumber(sequenceNumber) 100{ 101} 102 103PassRefPtrWillBeRawPtr<Blob> DataObjectItem::getAsFile() const 104{ 105 if (kind() != FileKind) 106 return nullptr; 107 108 if (m_source == InternalSource) { 109 if (m_file) 110 return m_file.get(); 111 ASSERT(m_sharedBuffer); 112 // FIXME: This code is currently impossible--we never populate m_sharedBuffer when dragging 113 // in. At some point though, we may need to support correctly converting a shared buffer 114 // into a file. 115 return nullptr; 116 } 117 118 ASSERT(m_source == PasteboardSource); 119 if (type() == mimeTypeImagePng) { 120 // FIXME: This is pretty inefficient. We copy the data from the browser 121 // to the renderer. We then place it in a blob in WebKit, which 122 // registers it and copies it *back* to the browser. When a consumer 123 // wants to read the data, we then copy the data back into the renderer. 124 // https://bugs.webkit.org/show_bug.cgi?id=58107 has been filed to track 125 // improvements to this code (in particular, add a registerClipboardBlob 126 // method to the blob registry; that way the data is only copied over 127 // into the renderer when it's actually read, not when the blob is 128 // initially constructed). 129 RefPtr<SharedBuffer> data = static_cast<PassRefPtr<SharedBuffer> >(blink::Platform::current()->clipboard()->readImage(blink::WebClipboard::BufferStandard)); 130 OwnPtr<BlobData> blobData = BlobData::create(); 131 blobData->appendBytes(data->data(), data->size()); 132 blobData->setContentType(mimeTypeImagePng); 133 return Blob::create(BlobDataHandle::create(blobData.release(), data->size())); 134 } 135 136 return nullptr; 137} 138 139String DataObjectItem::getAsString() const 140{ 141 ASSERT(m_kind == StringKind); 142 143 if (m_source == InternalSource) 144 return m_data; 145 146 ASSERT(m_source == PasteboardSource); 147 148 blink::WebClipboard::Buffer buffer = Pasteboard::generalPasteboard()->buffer(); 149 String data; 150 // This is ugly but there's no real alternative. 151 if (m_type == mimeTypeTextPlain) { 152 data = blink::Platform::current()->clipboard()->readPlainText(buffer); 153 } else if (m_type == mimeTypeTextHTML) { 154 blink::WebURL ignoredSourceURL; 155 unsigned ignored; 156 data = blink::Platform::current()->clipboard()->readHTML(buffer, &ignoredSourceURL, &ignored, &ignored); 157 } else { 158 data = blink::Platform::current()->clipboard()->readCustomData(buffer, m_type); 159 } 160 161 return blink::Platform::current()->clipboard()->sequenceNumber(buffer) == m_sequenceNumber ? data : String(); 162} 163 164bool DataObjectItem::isFilename() const 165{ 166 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=81261: When we properly support File dragout, 167 // we'll need to make sure this works as expected for DragDataChromium. 168 return m_kind == FileKind && m_file; 169} 170 171void DataObjectItem::trace(Visitor* visitor) 172{ 173 visitor->trace(m_file); 174} 175 176} // namespace blink 177