| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "webkit/glue/clipboard_conversion.h" | 7 #include "webkit/glue/clipboard_conversion.h" |
| 8 | 8 |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 | 10 |
| 11 #include "ChromiumDataObject.h" | 11 #include "ChromiumDataObject.h" |
| 12 #include "ClipboardUtilitiesChromium.h" | 12 #include "ClipboardUtilitiesChromium.h" |
| 13 #include "KURL.h" | 13 #include "KURL.h" |
| 14 #include "SharedBuffer.h" | 14 #include "SharedBuffer.h" |
| 15 #include <wtf/Vector.h> | 15 #include <wtf/Vector.h> |
| 16 | 16 |
| 17 #include "webkit/glue/glue_util.h" | 17 #include "webkit/glue/glue_util.h" |
| 18 | 18 |
| 19 namespace { | |
| 20 | |
| 21 // TODO(tc): CF_HTML logic should move into the browser process since it only | |
| 22 // makes sense on Windows. | |
| 23 #if defined(OS_WIN) | |
| 24 void append(WTF::Vector<char>& vector, const WebCore::CString& string) { | |
| 25 vector.append(string.data(), string.length()); | |
| 26 } | |
| 27 // Documentation for the CF_HTML format is available at | |
| 28 // http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp | |
| 29 void markupToCF_HTML(const WebCore::String& markup, | |
| 30 const WebCore::String& src_url, | |
| 31 WTF::Vector<char>& result) { | |
| 32 if (markup.isEmpty()) | |
| 33 return; | |
| 34 | |
| 35 #define MAX_DIGITS 10 | |
| 36 #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits) | |
| 37 #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u" | |
| 38 #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS) | |
| 39 | |
| 40 static const char* header = "Version:0.9\n" | |
| 41 "StartHTML:" NUMBER_FORMAT "\n" | |
| 42 "EndHTML:" NUMBER_FORMAT "\n" | |
| 43 "StartFragment:" NUMBER_FORMAT "\n" | |
| 44 "EndFragment:" NUMBER_FORMAT "\n"; | |
| 45 static const char* source_url_prefix = "SourceURL:"; | |
| 46 | |
| 47 static const char* start_markup = "<HTML>\n<BODY>\n<!--StartFragment-->\n"; | |
| 48 static const char* end_markup = "\n<!--EndFragment-->\n</BODY>\n</HTML>"; | |
| 49 | |
| 50 WebCore::CString source_url_utf8 = (src_url == WebCore::blankURL()) ? | |
| 51 "" : src_url.utf8(); | |
| 52 WebCore::CString markup_utf8 = markup.utf8(); | |
| 53 | |
| 54 // calculate offsets | |
| 55 size_t start_html_offset = strlen(header) - strlen(NUMBER_FORMAT) * 4 + | |
| 56 MAX_DIGITS * 4; | |
| 57 if (source_url_utf8.length()) { | |
| 58 start_html_offset += strlen(source_url_prefix) + | |
| 59 source_url_utf8.length() + 1; | |
| 60 } | |
| 61 size_t start_fragment_offset = start_html_offset + strlen(start_markup); | |
| 62 size_t end_fragment_offset = start_fragment_offset + markup_utf8.length(); | |
| 63 size_t end_html_offset = end_fragment_offset + strlen(end_markup); | |
| 64 | |
| 65 append(result, WebCore::String::format(header, start_html_offset, | |
| 66 end_html_offset, start_fragment_offset, end_fragment_offset).utf8()); | |
| 67 if (source_url_utf8.length()) { | |
| 68 append(result, source_url_prefix); | |
| 69 append(result, source_url_utf8); | |
| 70 result.append('\n'); | |
| 71 } | |
| 72 append(result, start_markup); | |
| 73 append(result, markup_utf8); | |
| 74 append(result, end_markup); | |
| 75 | |
| 76 #undef MAX_DIGITS | |
| 77 #undef MAKE_NUMBER_FORMAT_1 | |
| 78 #undef MAKE_NUMBER_FORMAT_2 | |
| 79 #undef NUMBER_FORMAT | |
| 80 } | |
| 81 #endif | |
| 82 | |
| 83 std::wstring HTMLToCFHTML(const WebCore::String& html, | |
| 84 const WebCore::KURL& url) { | |
| 85 #if defined(OS_WIN) | |
| 86 Vector<char> cf_html_data; | |
| 87 markupToCF_HTML(html, url, cf_html_data); | |
| 88 WebCore::String cf_html_str(cf_html_data.data(), cf_html_data.size()); | |
| 89 return webkit_glue::StringToStdWString(cf_html_str); | |
| 90 #else | |
| 91 return std::wstring(); | |
| 92 #endif | |
| 93 } | |
| 94 | |
| 95 WebCore::String CFHTMLToHTML(const std::wstring& cf_html_wstr) { | |
| 96 #if defined(OS_WIN) | |
| 97 WebCore::String cf_html = webkit_glue::StdWStringToString(cf_html_wstr); | |
| 98 // Obtain baseURL if present. | |
| 99 WebCore::String src_url_str("sourceURL:"); | |
| 100 WebCore::String src_url; | |
| 101 unsigned int line_start = cf_html.find(src_url_str, 0, false); | |
| 102 if (line_start != -1) { | |
| 103 unsigned int src_end = cf_html.find("\n", line_start, false); | |
| 104 unsigned int src_start = line_start + src_url_str.length(); | |
| 105 WebCore::String raw_src_url = cf_html.substring(src_start, src_end - src_sta
rt); | |
| 106 replaceNBSPWithSpace(raw_src_url); | |
| 107 src_url = raw_src_url.stripWhiteSpace(); | |
| 108 } | |
| 109 | |
| 110 // find the markup between "<!--StartFragment -->" and "<!--EndFragment | |
| 111 // -->", accounting for browser quirks | |
| 112 unsigned markup_start = cf_html.find("<html", 0, false); | |
| 113 unsigned tag_start = cf_html.find("startfragment", markup_start, false); | |
| 114 unsigned fragment_start = cf_html.find('>', tag_start) + 1; | |
| 115 unsigned tag_end = cf_html.find("endfragment", fragment_start, false); | |
| 116 unsigned fragment_end = cf_html.reverseFind('<', tag_end); | |
| 117 WebCore::String markup = cf_html.substring(fragment_start, | |
| 118 fragment_end - fragment_start).stripWhiteSpace(); | |
| 119 return markup; | |
| 120 #else | |
| 121 return WebCore::String(); | |
| 122 #endif | |
| 123 } | |
| 124 | |
| 125 } // namespace | |
| 126 | |
| 127 namespace webkit_glue { | 19 namespace webkit_glue { |
| 128 | 20 |
| 129 WebDropData ChromiumDataObjectToWebDropData( | 21 WebDropData ChromiumDataObjectToWebDropData( |
| 130 WebCore::ChromiumDataObject* data_object) { | 22 WebCore::ChromiumDataObject* data_object) { |
| 131 WebDropData drop_data; | 23 WebDropData drop_data; |
| 132 drop_data.url = KURLToGURL(data_object->url); | 24 drop_data.url = KURLToGURL(data_object->url); |
| 133 drop_data.url_title = StringToStdWString(data_object->url_title); | 25 drop_data.url_title = StringToStdWString(data_object->url_title); |
| 134 | 26 |
| 135 for (size_t i = 0; i < data_object->filenames.size(); ++i) { | 27 for (size_t i = 0; i < data_object->filenames.size(); ++i) { |
| 136 drop_data.filenames.push_back(StringToStdWString( | 28 drop_data.filenames.push_back(StringToStdWString( |
| 137 data_object->filenames[i])); | 29 data_object->filenames[i])); |
| 138 } | 30 } |
| 139 | 31 |
| 140 drop_data.plain_text = StringToStdWString(data_object->plain_text); | 32 drop_data.plain_text = StringToStdWString(data_object->plain_text); |
| 141 | 33 |
| 142 drop_data.cf_html = HTMLToCFHTML(data_object->text_html, data_object->url); | |
| 143 | |
| 144 drop_data.text_html = StringToStdWString(data_object->text_html); | 34 drop_data.text_html = StringToStdWString(data_object->text_html); |
| 35 drop_data.html_base_url = KURLToGURL(data_object->html_base_url); |
| 145 | 36 |
| 146 drop_data.file_description_filename = StringToStdWString( | 37 drop_data.file_description_filename = StringToStdWString( |
| 147 data_object->file_content_filename); | 38 data_object->file_content_filename); |
| 148 if (data_object->file_content) { | 39 if (data_object->file_content) { |
| 149 drop_data.file_contents.assign(data_object->file_content->data(), | 40 drop_data.file_contents.assign(data_object->file_content->data(), |
| 150 data_object->file_content->size()); | 41 data_object->file_content->size()); |
| 151 } | 42 } |
| 152 | 43 |
| 153 return drop_data; | 44 return drop_data; |
| 154 } | 45 } |
| 155 | 46 |
| 156 PassRefPtr<WebCore::ChromiumDataObject> WebDropDataToChromiumDataObject( | 47 PassRefPtr<WebCore::ChromiumDataObject> WebDropDataToChromiumDataObject( |
| 157 const WebDropData& drop_data) { | 48 const WebDropData& drop_data) { |
| 158 RefPtr<WebCore::ChromiumDataObject> data_object = | 49 RefPtr<WebCore::ChromiumDataObject> data_object = |
| 159 WebCore::ChromiumDataObject::create(); | 50 WebCore::ChromiumDataObject::create(); |
| 160 data_object->url = GURLToKURL(drop_data.url); | 51 data_object->url = GURLToKURL(drop_data.url); |
| 161 data_object->url_title = StdWStringToString(drop_data.url_title); | 52 data_object->url_title = StdWStringToString(drop_data.url_title); |
| 162 | 53 |
| 163 for (size_t i = 0; i < drop_data.filenames.size(); ++i) { | 54 for (size_t i = 0; i < drop_data.filenames.size(); ++i) { |
| 164 data_object->filenames.append(StdWStringToString(drop_data.filenames[i])); | 55 data_object->filenames.append(StdWStringToString(drop_data.filenames[i])); |
| 165 } | 56 } |
| 166 | 57 |
| 167 data_object->plain_text = StdWStringToString(drop_data.plain_text); | 58 data_object->plain_text = StdWStringToString(drop_data.plain_text); |
| 168 | 59 |
| 169 data_object->text_html = StdWStringToString(drop_data.text_html); | 60 data_object->text_html = StdWStringToString(drop_data.text_html); |
| 170 if (data_object->text_html.isEmpty()) { | 61 data_object->html_base_url = GURLToKURL(drop_data.html_base_url); |
| 171 // Use CF_HTML only if there's no text/html data. | |
| 172 data_object->text_html = CFHTMLToHTML(drop_data.cf_html); | |
| 173 } | |
| 174 | 62 |
| 175 data_object->file_content_filename = StdWStringToString( | 63 data_object->file_content_filename = StdWStringToString( |
| 176 drop_data.file_description_filename); | 64 drop_data.file_description_filename); |
| 177 if (!drop_data.file_contents.empty()) { | 65 if (!drop_data.file_contents.empty()) { |
| 178 data_object->file_content = | 66 data_object->file_content = |
| 179 WebCore::SharedBuffer::create(drop_data.file_contents.data(), | 67 WebCore::SharedBuffer::create(drop_data.file_contents.data(), |
| 180 drop_data.file_contents.size()); | 68 drop_data.file_contents.size()); |
| 181 } | 69 } |
| 182 | 70 |
| 183 return data_object; | 71 return data_object; |
| 184 } | 72 } |
| 185 | 73 |
| 186 } // namespace webkit_glue | 74 } // namespace webkit_glue |
| OLD | NEW |