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