1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/*
2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2008, 2009 Google Inc.
4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions
7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * are met:
8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *    documentation and/or other materials provided with the distribution.
13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */
26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h"
28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ClipboardChromium.h"
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "CachedImage.h"
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ChromiumDataObject.h"
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "ClipboardMimeTypes.h"
33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ClipboardUtilitiesChromium.h"
342bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "DataTransferItemsChromium.h"
35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Document.h"
360617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#include "DragData.h"
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Element.h"
380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FileList.h"
39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Frame.h"
40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "HTMLNames.h"
41a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "HTMLParserIdioms.h"
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Image.h"
43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "MIMETypeRegistry.h"
445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "NamedNodeMap.h"
45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Range.h"
46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderImage.h"
470617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#include "ScriptExecutionContext.h"
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "markup.h"
49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/text/StringBuilder.h>
51a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/text/WTFString.h>
52a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WebCore {
54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectusing namespace HTMLNames;
56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
60a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic String normalizeType(const String& type)
61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    String cleanType = type.stripWhiteSpace().lower();
63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc))
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return mimeTypeTextPlain;
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return cleanType;
66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
67635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
680617145a89917ae7735fe1c9538688ab9a577df5Kristian MonsenPassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame)
690617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
70bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return ClipboardChromium::create(DragAndDrop, dragData->platformData(), policy, frame);
710617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
720617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
73bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenClipboardChromium::ClipboardChromium(ClipboardType clipboardType,
74635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                                     PassRefPtr<ChromiumDataObject> dataObject,
750617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen                                     ClipboardAccessPolicy policy,
760617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen                                     Frame* frame)
77bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    : Clipboard(policy, clipboardType)
78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_dataObject(dataObject)
790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    , m_frame(frame)
80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
83bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenPassRefPtr<ClipboardChromium> ClipboardChromium::create(ClipboardType clipboardType,
840617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    PassRefPtr<ChromiumDataObject> dataObject, ClipboardAccessPolicy policy, Frame* frame)
85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
86bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return adoptRef(new ClipboardChromium(clipboardType, dataObject, policy, frame));
87635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
89635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::clearData(const String& type)
90635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (policy() != ClipboardWritable || !m_dataObject)
92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->clearData(normalizeType(type));
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT_NOT_REACHED();
97635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::clearAllData()
100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (policy() != ClipboardWritable)
102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->clearAll();
105635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
107635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectString ClipboardChromium::getData(const String& type, bool& success) const
108635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    success = false;
110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (policy() != ClipboardReadable || !m_dataObject)
111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return String();
112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_dataObject->getData(normalizeType(type), success);
114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
115635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool ClipboardChromium::setData(const String& type, const String& data)
117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (policy() != ClipboardWritable)
119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return false;
120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return m_dataObject->setData(normalizeType(type), data);
122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// extensions beyond IE's API
125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHashSet<String> ClipboardChromium::types() const
126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    HashSet<String> results;
128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return results;
130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!m_dataObject)
132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return results;
133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    results = m_dataObject->types();
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
13681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_dataObject->containsFilenames())
13781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        results.add(mimeTypeFiles);
13881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return results;
140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochPassRefPtr<FileList> ClipboardChromium::files() const
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (policy() != ClipboardReadable)
145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return FileList::create();
146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_dataObject)
148231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return FileList::create();
149231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
150a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    const Vector<String>& filenames = m_dataObject->filenames();
151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<FileList> fileList = FileList::create();
152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    for (size_t i = 0; i < filenames.size(); ++i)
153a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        fileList->append(File::create(filenames.at(i)));
154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return fileList.release();
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
158635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::setDragImage(CachedImage* image, Node* node, const IntPoint& loc)
159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (policy() != ClipboardImageWritable && policy() != ClipboardWritable)
161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_dragImage)
164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_dragImage->removeClient(this);
165635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_dragImage = image;
166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_dragImage)
167635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_dragImage->addClient(this);
168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
169635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_dragLoc = loc;
170635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_dragImageElement = node;
171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
172635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
173635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::setDragImage(CachedImage* img, const IntPoint& loc)
174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setDragImage(img, 0, loc);
176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::setDragImageElement(Node* node, const IntPoint& loc)
179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setDragImage(0, node, loc);
181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectDragImageRef ClipboardChromium::createDragImage(IntPoint& loc) const
184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DragImageRef result = 0;
186e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (m_dragImageElement) {
187e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (m_frame) {
188e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            result = m_frame->nodeImage(m_dragImageElement.get());
189e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            loc = m_dragLoc;
190e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        }
191e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    } else if (m_dragImage) {
192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        result = createDragImageFromImage(m_dragImage->image());
193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        loc = m_dragLoc;
194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
195635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return result;
196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
197635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic String imageToMarkup(const String& url, Element* element)
199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    StringBuilder markup;
201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    markup.append("<img src=\"");
202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    markup.append(url);
203a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    markup.append('"');
204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Copy over attributes.  If we are dragging an image, we expect things like
205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // the id to be copied as well.
2065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    NamedNodeMap* attrs = element->attributes();
207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    unsigned length = attrs->length();
208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (unsigned i = 0; i < length; ++i) {
209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        Attribute* attr = attrs->attributeItem(i);
210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (attr->localName() == "src")
211635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            continue;
212a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        markup.append(' ');
213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        markup.append(attr->localName());
214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        markup.append("=\"");
215635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        String escapedAttr = attr->value();
216635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        escapedAttr.replace("\"", "&quot;");
217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        markup.append(escapedAttr);
218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        markup.append('"');
219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    markup.append("/>");
222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return markup.toString();
223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic CachedImage* getCachedImage(Element* element)
226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
227635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Attempt to pull CachedImage from element
228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(element);
229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RenderObject* renderer = element->renderer();
230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!renderer || !renderer->isImage())
231635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return 0;
232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RenderImage* image = toRenderImage(renderer);
234635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (image->cachedImage() && !image->cachedImage()->errorOccurred())
235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return image->cachedImage();
236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return 0;
238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void writeImageToDataObject(ChromiumDataObject* dataObject, Element* element,
241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                                   const KURL& url)
242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
243635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Shove image data into a DataObject for use as a file
244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    CachedImage* cachedImage = getCachedImage(element);
245635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!cachedImage || !cachedImage->image() || !cachedImage->isLoaded())
246635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    SharedBuffer* imageBuffer = cachedImage->image()->data();
249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!imageBuffer || !imageBuffer->size())
250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
252a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    dataObject->setFileContent(imageBuffer);
253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Determine the filename for the file contents of the image.  We try to
255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // use the alt tag if one exists, otherwise we fall back on the suggested
256635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // filename in the http header, and finally we resort to using the filename
257635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // in the URL.
2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    String extension = MIMETypeRegistry::getPreferredExtensionForMIMEType(
259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        cachedImage->response().mimeType());
260a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    dataObject->setFileExtension(extension.isEmpty() ? "" : "." + extension);
261635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    String title = element->getAttribute(altAttr);
2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (title.isEmpty())
263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        title = cachedImage->response().suggestedFilename();
2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    title = ClipboardChromium::validateFileName(title, dataObject);
266a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    dataObject->setFileContentFilename(title + dataObject->fileExtension());
267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!m_dataObject)
272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
274a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeURL, url);
275a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setUrlTitle(title);
276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Write the bytes in the image to the file format.
278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    writeImageToDataObject(m_dataObject.get(), element, url);
279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    AtomicString imageURL = element->getAttribute(srcAttr);
281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (imageURL.isEmpty())
282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
284a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String fullURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(imageURL));
285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (fullURL.isEmpty())
286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Put img tag on the clipboard referencing the image
289a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeTextHTML, imageToMarkup(fullURL, element));
290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::writeURL(const KURL& url, const String& title, Frame*)
293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!m_dataObject)
295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
296ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    ASSERT(!url.isEmpty());
297a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeURL, url);
298a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setUrlTitle(title);
299635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // The URL can also be used as plain text.
301a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeTextPlain, url.string());
302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
303635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // The URL can also be used as an HTML fragment.
304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeTextHTML, urlToMarkup(url, title));
305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setHtmlBaseUrl(url);
306635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
307635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ClipboardChromium::writeRange(Range* selectedRange, Frame* frame)
309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(selectedRange);
311635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!m_dataObject)
312635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project         return;
313635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeTextHTML, createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs));
315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setHtmlBaseUrl(frame->document()->url());
316635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    String str = frame->editor()->selectedText();
318d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS)
319635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    replaceNewlinesWithWindowsStyleNewlines(str);
320635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
321635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    replaceNBSPWithSpace(str);
322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeTextPlain, str);
323635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockvoid ClipboardChromium::writePlainText(const String& text)
3268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
3278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    if (!m_dataObject)
3288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return;
3298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
3308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    String str = text;
3318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#if OS(WINDOWS)
3328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    replaceNewlinesWithWindowsStyleNewlines(str);
3338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#endif
3348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    replaceNBSPWithSpace(str);
335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_dataObject->setData(mimeTypeTextPlain, str);
3368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
3378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
338635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool ClipboardChromium::hasData()
339635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
340635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!m_dataObject)
341635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return false;
342635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return m_dataObject->hasData();
344635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
345635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
3462bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(DATA_TRANSFER_ITEMS)
3472bde8e466a4451c7319e3a072d118917957d6554Steve BlockPassRefPtr<DataTransferItems> ClipboardChromium::items()
3482bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3492bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<DataTransferItemsChromium> items = DataTransferItemsChromium::create(this, m_frame->document()->scriptExecutionContext());
3502bde8e466a4451c7319e3a072d118917957d6554Steve Block
3512bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_dataObject)
3522bde8e466a4451c7319e3a072d118917957d6554Steve Block        return items;
3532bde8e466a4451c7319e3a072d118917957d6554Steve Block
3542bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (isForCopyAndPaste() && policy() == ClipboardReadable) {
3552bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Iterate through the types and add them.
3562bde8e466a4451c7319e3a072d118917957d6554Steve Block        HashSet<String> types = m_dataObject->types();
3572bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (HashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it)
3582bde8e466a4451c7319e3a072d118917957d6554Steve Block            items->addPasteboardItem(*it);
3592bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3602bde8e466a4451c7319e3a072d118917957d6554Steve Block    return items;
3612bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3622bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
3632bde8e466a4451c7319e3a072d118917957d6554Steve Block
364635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} // namespace WebCore
365