Commit 2ffbb484 authored by dcheng@chromium.org's avatar dcheng@chromium.org

Enable custom MIME types in web copy/paste.

Also fixes a leak that was accidentally introduced in http://src.chromium.org/viewvc/chrome?view=rev&revision=113018.

BUG=31037,106472
TEST=manual testing

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=113040

Review URL: http://codereview.chromium.org/8802004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113064 0039d316-1c4b-4281-b951-d872f2087c98
parent c4b47566
...@@ -186,6 +186,7 @@ class UI_EXPORT Clipboard { ...@@ -186,6 +186,7 @@ class UI_EXPORT Clipboard {
// Win: MS HTML Format, Other: Generic HTML format // Win: MS HTML Format, Other: Generic HTML format
static FormatType GetHtmlFormatType(); static FormatType GetHtmlFormatType();
static FormatType GetBitmapFormatType(); static FormatType GetBitmapFormatType();
static FormatType GetWebCustomDataFormatType();
// Embeds a pointer to a SharedMemory object pointed to by |bitmap_handle| // Embeds a pointer to a SharedMemory object pointed to by |bitmap_handle|
// belonging to |process| into a shared bitmap [CBF_SMBITMAP] slot in // belonging to |process| into a shared bitmap [CBF_SMBITMAP] slot in
......
...@@ -15,6 +15,8 @@ namespace ui { ...@@ -15,6 +15,8 @@ namespace ui {
namespace { namespace {
const char kMimeTypeBitmap[] = "image/bmp"; const char kMimeTypeBitmap[] = "image/bmp";
const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
// TODO(dcheng): This name is temporary. See crbug.com/106449
const char kMimeTypeWebCustomData[] = "chromium/x-web-custom-data";
// ClipboardData contains data copied to the Clipboard for a variety of formats. // ClipboardData contains data copied to the Clipboard for a variety of formats.
// It mostly just provides APIs to cleanly access and manipulate this data. // It mostly just provides APIs to cleanly access and manipulate this data.
...@@ -331,4 +333,9 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { ...@@ -331,4 +333,9 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() {
return std::string(kMimeTypeWebkitSmartPaste); return std::string(kMimeTypeWebkitSmartPaste);
} }
// static
Clipboard::FormatType Clipboard::GetWebCustomDataFormatType() {
return std::string(kMimeTypeWebCustomData);
}
} // namespace ui } // namespace ui
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/gtk/gtk_signal.h" #include "ui/base/gtk/gtk_signal.h"
#include "ui/base/x/x11_util.h" #include "ui/base/x/x11_util.h"
#include "ui/gfx/canvas_skia.h" #include "ui/gfx/canvas_skia.h"
...@@ -106,6 +107,8 @@ GdkFilterReturn SelectionChangeObserver::OnXEvent(GdkXEvent* xevent, ...@@ -106,6 +107,8 @@ GdkFilterReturn SelectionChangeObserver::OnXEvent(GdkXEvent* xevent,
const char kMimeTypeBitmap[] = "image/bmp"; const char kMimeTypeBitmap[] = "image/bmp";
const char kMimeTypeMozillaURL[] = "text/x-moz-url"; const char kMimeTypeMozillaURL[] = "text/x-moz-url";
const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
// TODO(dcheng): This name is temporary. See crbug.com/106449
const char kMimeTypeWebCustomData[] = "chromium/x-web-custom-data";
std::string GdkAtomToString(const GdkAtom& atom) { std::string GdkAtomToString(const GdkAtom& atom) {
gchar* name = gdk_atom_name(atom); gchar* name = gdk_atom_name(atom);
...@@ -390,6 +393,17 @@ void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, ...@@ -390,6 +393,17 @@ void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer,
if (IsFormatAvailable(GetBitmapFormatType(), buffer)) if (IsFormatAvailable(GetBitmapFormatType(), buffer))
types->push_back(UTF8ToUTF16(kMimeTypePNG)); types->push_back(UTF8ToUTF16(kMimeTypePNG));
*contains_filenames = false; *contains_filenames = false;
GtkClipboard* clipboard = LookupBackingClipboard(buffer);
if (!clipboard)
return;
GtkSelectionData* data = gtk_clipboard_wait_for_contents(
clipboard, StringToGdkAtom(GetWebCustomDataFormatType()));
if (!data)
return;
ReadCustomDataTypes(data->data, data->length, types);
gtk_selection_data_free(data);
} }
...@@ -491,8 +505,16 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const { ...@@ -491,8 +505,16 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
void Clipboard::ReadCustomData(Buffer buffer, void Clipboard::ReadCustomData(Buffer buffer,
const string16& type, const string16& type,
string16* result) const { string16* result) const {
// TODO(dcheng): Implement this. GtkClipboard* clipboard = LookupBackingClipboard(buffer);
NOTIMPLEMENTED(); if (!clipboard)
return;
GtkSelectionData* data = gtk_clipboard_wait_for_contents(
clipboard, StringToGdkAtom(GetWebCustomDataFormatType()));
if (!data)
return;
ReadCustomDataForType(data->data, data->length, type, result);
gtk_selection_data_free(data);
} }
void Clipboard::ReadBookmark(string16* title, std::string* url) const { void Clipboard::ReadBookmark(string16* title, std::string* url) const {
...@@ -541,6 +563,11 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { ...@@ -541,6 +563,11 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() {
return std::string(kMimeTypeWebkitSmartPaste); return std::string(kMimeTypeWebkitSmartPaste);
} }
// static
Clipboard::FormatType Clipboard::GetWebCustomDataFormatType() {
return std::string(kMimeTypeWebCustomData);
}
void Clipboard::InsertMapping(const char* key, void Clipboard::InsertMapping(const char* key,
char* data, char* data,
size_t data_len) { size_t data_len) {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#import "third_party/mozilla/NSPasteboard+Utils.h" #import "third_party/mozilla/NSPasteboard+Utils.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/canvas_skia.h" #include "ui/gfx/canvas_skia.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
...@@ -30,6 +31,9 @@ NSString* const kUTTypeURLName = @"public.url-name"; ...@@ -30,6 +31,9 @@ NSString* const kUTTypeURLName = @"public.url-name";
// actual data associated with this type. // actual data associated with this type.
NSString* const kWebSmartPastePboardType = @"NeXT smart paste pasteboard type"; NSString* const kWebSmartPastePboardType = @"NeXT smart paste pasteboard type";
// TODO(dcheng): This name is temporary. See crbug.com/106449.
NSString* const kWebCustomDataType = @"org.chromium.web-custom-data";
NSPasteboard* GetPasteboard() { NSPasteboard* GetPasteboard() {
// The pasteboard should not be nil in a UI session, but this handy DCHECK // The pasteboard should not be nil in a UI session, but this handy DCHECK
// can help track down problems if someone tries using clipboard code outside // can help track down problems if someone tries using clipboard code outside
...@@ -156,9 +160,10 @@ void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { ...@@ -156,9 +160,10 @@ void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) {
void Clipboard::WriteData(const char* format_name, size_t format_len, void Clipboard::WriteData(const char* format_name, size_t format_len,
const char* data_data, size_t data_len) { const char* data_data, size_t data_len) {
NSPasteboard* pb = GetPasteboard(); NSPasteboard* pb = GetPasteboard();
NSString* format = [[NSString alloc] initWithBytes:format_name scoped_nsobject<NSString> format(
length:format_len [[NSString alloc] initWithBytes:format_name
encoding:NSUTF8StringEncoding]; length:format_len
encoding:NSUTF8StringEncoding]);
[pb addTypes:[NSArray arrayWithObject:format] owner:nil]; [pb addTypes:[NSArray arrayWithObject:format] owner:nil];
[pb setData:[NSData dataWithBytes:data_data length:data_len] [pb setData:[NSData dataWithBytes:data_data length:data_len]
forType:format]; forType:format];
...@@ -224,6 +229,13 @@ void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, ...@@ -224,6 +229,13 @@ void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer,
if ([NSImage canInitWithPasteboard:GetPasteboard()]) if ([NSImage canInitWithPasteboard:GetPasteboard()])
types->push_back(UTF8ToUTF16(kMimeTypePNG)); types->push_back(UTF8ToUTF16(kMimeTypePNG));
*contains_filenames = false; *contains_filenames = false;
NSPasteboard* pb = GetPasteboard();
if ([[pb types] containsObject:kWebCustomDataType]) {
NSData* data = [pb dataForType:kWebCustomDataType];
if ([data length])
ReadCustomDataTypes([data bytes], [data length], types);
}
} }
void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const {
...@@ -309,8 +321,14 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const { ...@@ -309,8 +321,14 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
void Clipboard::ReadCustomData(Buffer buffer, void Clipboard::ReadCustomData(Buffer buffer,
const string16& type, const string16& type,
string16* result) const { string16* result) const {
// TODO(dcheng): Implement this. DCHECK_EQ(buffer, BUFFER_STANDARD);
NOTIMPLEMENTED();
NSPasteboard* pb = GetPasteboard();
if ([[pb types] containsObject:kWebCustomDataType]) {
NSData* data = [pb dataForType:kWebCustomDataType];
if ([data length])
ReadCustomDataForType([data bytes], [data length], type, result);
}
} }
void Clipboard::ReadBookmark(string16* title, std::string* url) const { void Clipboard::ReadBookmark(string16* title, std::string* url) const {
...@@ -416,4 +434,9 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { ...@@ -416,4 +434,9 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() {
return base::SysNSStringToUTF8(kWebSmartPastePboardType); return base::SysNSStringToUTF8(kWebSmartPastePboardType);
} }
// static
Clipboard::FormatType Clipboard::GetWebCustomDataFormatType() {
return base::SysNSStringToUTF8(kWebCustomDataType);
}
} // namespace ui } // namespace ui
...@@ -203,6 +203,14 @@ FORMATETC* ClipboardUtil::GetWebKitSmartPasteFormat() { ...@@ -203,6 +203,14 @@ FORMATETC* ClipboardUtil::GetWebKitSmartPasteFormat() {
return &format; return &format;
} }
FORMATETC* ClipboardUtil::GetWebCustomDataFormat() {
// TODO(dcheng): This name is temporary. See crbug.com/106449
static UINT cf =
RegisterClipboardFormat(L"Chromium Web Custom MIME Data Format");
static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
return &format;
}
bool ClipboardUtil::HasUrl(IDataObject* data_object) { bool ClipboardUtil::HasUrl(IDataObject* data_object) {
DCHECK(data_object); DCHECK(data_object);
......
...@@ -35,6 +35,7 @@ class UI_EXPORT ClipboardUtil { ...@@ -35,6 +35,7 @@ class UI_EXPORT ClipboardUtil {
static FORMATETC* GetFileDescriptorFormat(); static FORMATETC* GetFileDescriptorFormat();
static FORMATETC* GetFileContentFormatZero(); static FORMATETC* GetFileContentFormatZero();
static FORMATETC* GetWebKitSmartPasteFormat(); static FORMATETC* GetWebKitSmartPasteFormat();
static FORMATETC* GetWebCustomDataFormat();
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// These methods check to see if |data_object| has the requested type. // These methods check to see if |data_object| has the requested type.
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "base/win/wrapped_window_proc.h" #include "base/win/wrapped_window_proc.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_util_win.h" #include "ui/base/clipboard/clipboard_util_win.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/canvas_skia.h" #include "ui/gfx/canvas_skia.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
...@@ -377,6 +378,19 @@ void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, ...@@ -377,6 +378,19 @@ void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer,
if (::IsClipboardFormatAvailable(CF_DIB)) if (::IsClipboardFormatAvailable(CF_DIB))
types->push_back(UTF8ToUTF16(kMimeTypePNG)); types->push_back(UTF8ToUTF16(kMimeTypePNG));
*contains_filenames = false; *contains_filenames = false;
// Acquire the clipboard.
ScopedClipboard clipboard;
if (!clipboard.Acquire(GetClipboardWindow()))
return;
HANDLE hdata = ::GetClipboardData(
ClipboardUtil::GetWebCustomDataFormat()->cfFormat);
if (!hdata)
return;
ReadCustomDataTypes(::GlobalLock(hdata), ::GlobalSize(hdata), types);
::GlobalUnlock(hdata);
} }
void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const {
...@@ -547,8 +561,20 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const { ...@@ -547,8 +561,20 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
void Clipboard::ReadCustomData(Buffer buffer, void Clipboard::ReadCustomData(Buffer buffer,
const string16& type, const string16& type,
string16* result) const { string16* result) const {
// TODO(dcheng): Implement this. DCHECK_EQ(buffer, BUFFER_STANDARD);
NOTIMPLEMENTED();
// Acquire the clipboard.
ScopedClipboard clipboard;
if (!clipboard.Acquire(GetClipboardWindow()))
return;
HANDLE hdata = ::GetClipboardData(
ClipboardUtil::GetWebCustomDataFormat()->cfFormat);
if (!hdata)
return;
ReadCustomDataForType(::GlobalLock(hdata), ::GlobalSize(hdata), type, result);
::GlobalUnlock(hdata);
} }
void Clipboard::ReadBookmark(string16* title, std::string* url) const { void Clipboard::ReadBookmark(string16* title, std::string* url) const {
...@@ -732,6 +758,16 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { ...@@ -732,6 +758,16 @@ Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() {
ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat); ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat);
} }
// static
Clipboard::FormatType Clipboard::GetWebCustomDataFormatType() {
// TODO(dcheng): Clean up the duplicated constant.
// Clipboard::WritePickledData() takes a FormatType, but all the callers
// assume that it's a raw string. As a result, we return the format name here
// rather than returning a string-ified version of the registered clipboard
// format ID.
return "Chromium Web Custom MIME Data Format";
}
// static // static
void Clipboard::FreeData(unsigned int format, HANDLE data) { void Clipboard::FreeData(unsigned int format, HANDLE data) {
if (format == CF_BITMAP) if (format == CF_BITMAP)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "webkit/glue/webclipboard_impl.h" #include "webkit/glue/webclipboard_impl.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/pickle.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
...@@ -18,7 +19,9 @@ ...@@ -18,7 +19,9 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
#include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "webkit/glue/scoped_clipboard_writer_glue.h" #include "webkit/glue/scoped_clipboard_writer_glue.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/webkit_glue.h" #include "webkit/glue/webkit_glue.h"
#if WEBKIT_USING_CG #if WEBKIT_USING_CG
...@@ -243,9 +246,13 @@ void WebClipboardImpl::writeDataObject(const WebDragData& data) { ...@@ -243,9 +246,13 @@ void WebClipboardImpl::writeDataObject(const WebDragData& data) {
// The same is true of the other WebClipboard::write* methods. // The same is true of the other WebClipboard::write* methods.
ScopedClipboardWriterGlue scw(client_); ScopedClipboardWriterGlue scw(client_);
WebDropData data_object(data);
// TODO(dcheng): Properly support text/uri-list here. // TODO(dcheng): Properly support text/uri-list here.
scw.WriteText(data.plainText()); scw.WriteText(data_object.plain_text);
scw.WriteHTML(data.htmlText(), ""); scw.WriteHTML(data_object.text_html, "");
Pickle pickle;
ui::WriteCustomDataToPickle(data_object.custom_data, &pickle);
scw.WritePickledData(pickle, ui::Clipboard::GetWebCustomDataFormatType());
} }
bool WebClipboardImpl::ConvertBufferType(Buffer buffer, bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment