summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/chromium/ClipboardChromium.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/platform/chromium/ClipboardChromium.cpp
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/platform/chromium/ClipboardChromium.cpp')
-rw-r--r--Source/WebCore/platform/chromium/ClipboardChromium.cpp352
1 files changed, 352 insertions, 0 deletions
diff --git a/Source/WebCore/platform/chromium/ClipboardChromium.cpp b/Source/WebCore/platform/chromium/ClipboardChromium.cpp
new file mode 100644
index 0000000..46b4339
--- /dev/null
+++ b/Source/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ClipboardChromium.h"
+
+#include "CachedImage.h"
+#include "ChromiumDataObject.h"
+#include "ClipboardMimeTypes.h"
+#include "ClipboardUtilitiesChromium.h"
+#include "Document.h"
+#include "DragData.h"
+#include "Element.h"
+#include "FileList.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "Image.h"
+#include "MIMETypeRegistry.h"
+#include "NamedNodeMap.h"
+#include "Range.h"
+#include "RenderImage.h"
+#include "ScriptExecutionContext.h"
+#include "markup.h"
+
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
+// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
+
+static String normalizeType(const String& type)
+{
+ String cleanType = type.stripWhiteSpace().lower();
+ if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc))
+ return mimeTypeTextPlain;
+ return cleanType;
+}
+
+PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame)
+{
+ return ClipboardChromium::create(DragAndDrop, dragData->platformData(), policy, frame);
+}
+
+ClipboardChromium::ClipboardChromium(ClipboardType clipboardType,
+ PassRefPtr<ChromiumDataObject> dataObject,
+ ClipboardAccessPolicy policy,
+ Frame* frame)
+ : Clipboard(policy, clipboardType)
+ , m_dataObject(dataObject)
+ , m_frame(frame)
+{
+}
+
+PassRefPtr<ClipboardChromium> ClipboardChromium::create(ClipboardType clipboardType,
+ PassRefPtr<ChromiumDataObject> dataObject, ClipboardAccessPolicy policy, Frame* frame)
+{
+ return adoptRef(new ClipboardChromium(clipboardType, dataObject, policy, frame));
+}
+
+PassRefPtr<ClipboardChromium> ClipboardChromium::create(ClipboardType clipboardType,
+ ClipboardAccessPolicy policy, Frame* frame)
+{
+ RefPtr<ChromiumDataObject> dataObject =
+ policy == ClipboardWritable ?
+ ChromiumDataObject::createWritable(clipboardType) :
+ ChromiumDataObject::createReadable(clipboardType);
+ return adoptRef(new ClipboardChromium(clipboardType, dataObject, policy, frame));
+}
+
+void ClipboardChromium::clearData(const String& type)
+{
+ if (policy() != ClipboardWritable || !m_dataObject)
+ return;
+
+ m_dataObject->clearData(normalizeType(type));
+
+ ASSERT_NOT_REACHED();
+}
+
+void ClipboardChromium::clearAllData()
+{
+ if (policy() != ClipboardWritable)
+ return;
+
+ m_dataObject->clearAll();
+}
+
+String ClipboardChromium::getData(const String& type, bool& success) const
+{
+ success = false;
+ if (policy() != ClipboardReadable || !m_dataObject)
+ return String();
+
+ return m_dataObject->getData(normalizeType(type), success);
+}
+
+bool ClipboardChromium::setData(const String& type, const String& data)
+{
+ if (policy() != ClipboardWritable)
+ return false;
+
+ return m_dataObject->setData(normalizeType(type), data);
+}
+
+// extensions beyond IE's API
+HashSet<String> ClipboardChromium::types() const
+{
+ HashSet<String> results;
+ if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
+ return results;
+
+ if (!m_dataObject)
+ return results;
+
+ results = m_dataObject->types();
+
+ return results;
+}
+
+PassRefPtr<FileList> ClipboardChromium::files() const
+{
+ if (policy() != ClipboardReadable)
+ return FileList::create();
+
+ if (!m_dataObject)
+ return FileList::create();
+
+ const Vector<String>& filenames = m_dataObject->filenames();
+ RefPtr<FileList> fileList = FileList::create();
+ for (size_t i = 0; i < filenames.size(); ++i)
+ fileList->append(File::create(filenames.at(i)));
+
+ return fileList.release();
+}
+
+void ClipboardChromium::setDragImage(CachedImage* image, Node* node, const IntPoint& loc)
+{
+ if (policy() != ClipboardImageWritable && policy() != ClipboardWritable)
+ return;
+
+ if (m_dragImage)
+ m_dragImage->removeClient(this);
+ m_dragImage = image;
+ if (m_dragImage)
+ m_dragImage->addClient(this);
+
+ m_dragLoc = loc;
+ m_dragImageElement = node;
+}
+
+void ClipboardChromium::setDragImage(CachedImage* img, const IntPoint& loc)
+{
+ setDragImage(img, 0, loc);
+}
+
+void ClipboardChromium::setDragImageElement(Node* node, const IntPoint& loc)
+{
+ setDragImage(0, node, loc);
+}
+
+DragImageRef ClipboardChromium::createDragImage(IntPoint& loc) const
+{
+ DragImageRef result = 0;
+ if (m_dragImageElement) {
+ if (m_frame) {
+ result = m_frame->nodeImage(m_dragImageElement.get());
+ loc = m_dragLoc;
+ }
+ } else if (m_dragImage) {
+ result = createDragImageFromImage(m_dragImage->image());
+ loc = m_dragLoc;
+ }
+ return result;
+}
+
+static String imageToMarkup(const String& url, Element* element)
+{
+ StringBuilder markup;
+ markup.append("<img src=\"");
+ markup.append(url);
+ markup.append('"');
+ // Copy over attributes. If we are dragging an image, we expect things like
+ // the id to be copied as well.
+ NamedNodeMap* attrs = element->attributes();
+ unsigned length = attrs->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Attribute* attr = attrs->attributeItem(i);
+ if (attr->localName() == "src")
+ continue;
+ markup.append(' ');
+ markup.append(attr->localName());
+ markup.append("=\"");
+ String escapedAttr = attr->value();
+ escapedAttr.replace("\"", "&quot;");
+ markup.append(escapedAttr);
+ markup.append('"');
+ }
+
+ markup.append("/>");
+ return markup.toString();
+}
+
+static CachedImage* getCachedImage(Element* element)
+{
+ // Attempt to pull CachedImage from element
+ ASSERT(element);
+ RenderObject* renderer = element->renderer();
+ if (!renderer || !renderer->isImage())
+ return 0;
+
+ RenderImage* image = toRenderImage(renderer);
+ if (image->cachedImage() && !image->cachedImage()->errorOccurred())
+ return image->cachedImage();
+
+ return 0;
+}
+
+static void writeImageToDataObject(ChromiumDataObject* dataObject, Element* element,
+ const KURL& url)
+{
+ // Shove image data into a DataObject for use as a file
+ CachedImage* cachedImage = getCachedImage(element);
+ if (!cachedImage || !cachedImage->image() || !cachedImage->isLoaded())
+ return;
+
+ SharedBuffer* imageBuffer = cachedImage->image()->data();
+ if (!imageBuffer || !imageBuffer->size())
+ return;
+
+ dataObject->setFileContent(imageBuffer);
+
+ // Determine the filename for the file contents of the image. We try to
+ // use the alt tag if one exists, otherwise we fall back on the suggested
+ // filename in the http header, and finally we resort to using the filename
+ // in the URL.
+ String extension = MIMETypeRegistry::getPreferredExtensionForMIMEType(
+ cachedImage->response().mimeType());
+ dataObject->setFileExtension(extension.isEmpty() ? "" : "." + extension);
+ String title = element->getAttribute(altAttr);
+ if (title.isEmpty())
+ title = cachedImage->response().suggestedFilename();
+
+ title = ClipboardChromium::validateFileName(title, dataObject);
+ dataObject->setFileContentFilename(title + dataObject->fileExtension());
+}
+
+void ClipboardChromium::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
+{
+ if (!m_dataObject)
+ return;
+
+ m_dataObject->setData(mimeTypeURL, url);
+ m_dataObject->setUrlTitle(title);
+
+ // Write the bytes in the image to the file format.
+ writeImageToDataObject(m_dataObject.get(), element, url);
+
+ AtomicString imageURL = element->getAttribute(srcAttr);
+ if (imageURL.isEmpty())
+ return;
+
+ String fullURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(imageURL));
+ if (fullURL.isEmpty())
+ return;
+
+ // Put img tag on the clipboard referencing the image
+ m_dataObject->setData(mimeTypeTextHTML, imageToMarkup(fullURL, element));
+}
+
+void ClipboardChromium::writeURL(const KURL& url, const String& title, Frame*)
+{
+ if (!m_dataObject)
+ return;
+ ASSERT(!url.isEmpty());
+ m_dataObject->setData(mimeTypeURL, url);
+ m_dataObject->setUrlTitle(title);
+
+ // The URL can also be used as plain text.
+ m_dataObject->setData(mimeTypeTextPlain, url.string());
+
+ // The URL can also be used as an HTML fragment.
+ m_dataObject->setData(mimeTypeTextHTML, urlToMarkup(url, title));
+ m_dataObject->setHtmlBaseUrl(url);
+}
+
+void ClipboardChromium::writeRange(Range* selectedRange, Frame* frame)
+{
+ ASSERT(selectedRange);
+ if (!m_dataObject)
+ return;
+
+ m_dataObject->setData(mimeTypeTextHTML, createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs));
+ m_dataObject->setHtmlBaseUrl(frame->document()->url());
+
+ String str = frame->editor()->selectedText();
+#if OS(WINDOWS)
+ replaceNewlinesWithWindowsStyleNewlines(str);
+#endif
+ replaceNBSPWithSpace(str);
+ m_dataObject->setData(mimeTypeTextPlain, str);
+}
+
+void ClipboardChromium::writePlainText(const String& text)
+{
+ if (!m_dataObject)
+ return;
+
+ String str = text;
+#if OS(WINDOWS)
+ replaceNewlinesWithWindowsStyleNewlines(str);
+#endif
+ replaceNBSPWithSpace(str);
+ m_dataObject->setData(mimeTypeTextPlain, str);
+}
+
+bool ClipboardChromium::hasData()
+{
+ if (!m_dataObject)
+ return false;
+
+ return m_dataObject->hasData();
+}
+
+} // namespace WebCore