• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
createFromString(const String & type,const String & data)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 
createFromFile(PassRefPtr<File> file)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 
createFromURL(const String & url,const String & title)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 
createFromHTML(const String & html,const KURL & baseURL)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 
createFromSharedBuffer(const String & name,PassRefPtr<SharedBuffer> buffer)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 
createFromPasteboard(const String & type,uint64_t sequenceNumber)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 
ChromiumDataObjectItem(Kind kind,const String & type)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 
ChromiumDataObjectItem(Kind kind,const String & type,uint64_t sequenceNumber)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 
getAsString(PassOwnPtr<StringCallback> callback,ExecutionContext * context) const104 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 
getAsFile() const112 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 
internalGetAsString() const150 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 
isFilename() const174 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