diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-19 01:20:01 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-19 01:20:01 +0000 |
commit | 22cf8687fe6c4fc4dbb2b9b2ac41d7d45f656d83 (patch) | |
tree | df838980effe3721bdc41b6acea356bf6352df8e | |
parent | 234ebdecf98582ca141b9066b1e5f4f74d3bdbff (diff) | |
download | chromium_src-22cf8687fe6c4fc4dbb2b9b2ac41d7d45f656d83.zip chromium_src-22cf8687fe6c4fc4dbb2b9b2ac41d7d45f656d83.tar.gz chromium_src-22cf8687fe6c4fc4dbb2b9b2ac41d7d45f656d83.tar.bz2 |
Remove cf_html from webdropdata.h. This is windows
specific code so we should handle it before we get
to webkit.
CF_HTML needs the source URL to resolve relative URLs
so I added that to the format and plumb it through
from webcore.
I also did some small refactoring so we only have one
implementation of converting to/from CF_HTML and regular
markup. We can tweak these converters (and add unit tests)
in follow up changes.
Review URL: http://codereview.chromium.org/11247
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5662 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/clipboard.h | 8 | ||||
-rw-r--r-- | base/clipboard_util.cc | 147 | ||||
-rw-r--r-- | base/clipboard_util.h | 12 | ||||
-rw-r--r-- | base/clipboard_win.cc | 109 | ||||
-rw-r--r-- | base/scoped_clipboard_writer.cc | 2 | ||||
-rw-r--r-- | chrome/browser/web_contents_view_win.cc | 4 | ||||
-rw-r--r-- | chrome/common/os_exchange_data.cc | 23 | ||||
-rw-r--r-- | chrome/common/os_exchange_data.h | 8 | ||||
-rw-r--r-- | chrome/common/os_exchange_data_unittest.cc | 30 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 4 | ||||
-rw-r--r-- | webkit/glue/clipboard_conversion.cc | 116 | ||||
-rw-r--r-- | webkit/glue/webdropdata.cc | 7 | ||||
-rw-r--r-- | webkit/glue/webdropdata.h | 11 | ||||
-rw-r--r-- | webkit/port/platform/chromium/ChromiumDataObject.cpp | 1 | ||||
-rw-r--r-- | webkit/port/platform/chromium/ChromiumDataObject.h | 1 | ||||
-rw-r--r-- | webkit/port/platform/chromium/ClipboardChromium.cpp | 2 | ||||
-rw-r--r-- | webkit/port/platform/chromium/DragDataChromium.cpp | 30 |
17 files changed, 224 insertions, 291 deletions
diff --git a/base/clipboard.h b/base/clipboard.h index 14ee655..2943f0e 100644 --- a/base/clipboard.h +++ b/base/clipboard.h @@ -168,14 +168,6 @@ class Clipboard { // Safely write to system clipboard. Free |handle| on failure. void WriteToClipboard(FormatType format, HANDLE handle); - static void MarkupToHTMLClipboardFormat(const std::string& markup, - const std::string& src_url, - std::string* html_fragment); - - static void ParseHTMLClipboardFormat(const std::string& html_fragment, - std::wstring* markup, - std::string* src_url); - static void ParseBookmarkClipboardFormat(const std::wstring& bookmark, std::wstring* title, std::string* url); diff --git a/base/clipboard_util.cc b/base/clipboard_util.cc index 9d35db4..5b64732 100644 --- a/base/clipboard_util.cc +++ b/base/clipboard_util.cc @@ -306,26 +306,25 @@ bool ClipboardUtil::GetPlainText(IDataObject* data_object, return success; } -bool ClipboardUtil::GetCFHtml(IDataObject* data_object, - std::wstring* cf_html) { - DCHECK(data_object && cf_html); - if (FAILED(data_object->QueryGetData(GetHtmlFormat()))) - return false; +bool ClipboardUtil::GetHtml(IDataObject* data_object, + std::wstring* html, std::string* base_url) { + DCHECK(data_object && html && base_url); - STGMEDIUM store; - if (FAILED(data_object->GetData(GetHtmlFormat(), &store))) - return false; + if (SUCCEEDED(data_object->QueryGetData(GetHtmlFormat()))) { + STGMEDIUM store; + if (SUCCEEDED(data_object->GetData(GetHtmlFormat(), &store))) { + // MS CF html + ScopedHGlobal<char> data(store.hGlobal); - // MS CF html - ScopedHGlobal<char> data(store.hGlobal); - cf_html->assign(UTF8ToWide(std::string(data.get(), data.Size()))); - ReleaseStgMedium(&store); - return true; -} + std::string html_utf8; + CFHtmlToHtml(std::string(data.get(), data.Size()), &html_utf8, base_url); + html->assign(UTF8ToWide(html_utf8)); + + ReleaseStgMedium(&store); + return true; + } + } -bool ClipboardUtil::GetTextHtml(IDataObject* data_object, - std::wstring* text_html) { - DCHECK(data_object && text_html); if (FAILED(data_object->QueryGetData(GetTextHtmlFormat()))) return false; @@ -333,9 +332,9 @@ bool ClipboardUtil::GetTextHtml(IDataObject* data_object, if (FAILED(data_object->GetData(GetTextHtmlFormat(), &store))) return false; - // raw html + // text/html ScopedHGlobal<wchar_t> data(store.hGlobal); - text_html->assign(data.get()); + html->assign(data.get()); ReleaseStgMedium(&store); return true; } @@ -373,3 +372,113 @@ bool ClipboardUtil::GetFileContents(IDataObject* data_object, return true; } +// HtmlToCFHtml and CFHtmlToHtml are based on similar methods in +// WebCore/platform/win/ClipboardUtilitiesWin.cpp. +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * + * 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. + */ + +// Helper method for converting from text/html to MS CF_HTML. +// Documentation for the CF_HTML format is available at +// http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx +std::string ClipboardUtil::HtmlToCFHtml(const std::string& html, + const std::string& base_url) { + if (html.empty()) + return std::string(); + + #define MAX_DIGITS 10 + #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits) + #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u" + #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS) + + static const char* header = "Version:0.9\r\n" + "StartHTML:" NUMBER_FORMAT "\r\n" + "EndHTML:" NUMBER_FORMAT "\r\n" + "StartFragment:" NUMBER_FORMAT "\r\n" + "EndFragment:" NUMBER_FORMAT "\r\n"; + static const char* source_url_prefix = "SourceURL:"; + + static const char* start_markup = + "<html>\r\n<body>\r\n<!--StartFragment-->\r\n"; + static const char* end_markup = + "\r\n<!--EndFragment-->\r\n</body>\r\n</html>"; + + // Calculate offsets + size_t start_html_offset = strlen(header) - strlen(NUMBER_FORMAT) * 4 + + MAX_DIGITS * 4; + if (!base_url.empty()) { + start_html_offset += strlen(source_url_prefix) + + base_url.length() + 1; + } + size_t start_fragment_offset = start_html_offset + strlen(start_markup); + size_t end_fragment_offset = start_fragment_offset + html.length(); + size_t end_html_offset = end_fragment_offset + strlen(end_markup); + + std::string result = StringPrintf(header, start_html_offset, + end_html_offset, start_fragment_offset, end_fragment_offset); + if (!base_url.empty()) { + result.append(source_url_prefix); + result.append(base_url); + result.append("\r\n"); + } + result.append(start_markup); + result.append(html); + result.append(end_markup); + + #undef MAX_DIGITS + #undef MAKE_NUMBER_FORMAT_1 + #undef MAKE_NUMBER_FORMAT_2 + #undef NUMBER_FORMAT + + return result; +} + +// Helper method for converting from MS CF_HTML to text/html. +void ClipboardUtil::CFHtmlToHtml(const std::string& cf_html, + std::string* html, + std::string* base_url) { + // Obtain base_url if present. + static std::string src_url_str("SourceURL:"); + size_t line_start = cf_html.find(src_url_str); + if (line_start != std::string::npos) { + size_t src_end = cf_html.find("\n", line_start); + size_t src_start = line_start + src_url_str.length(); + if (src_end != std::string::npos && src_start != std::string::npos) { + *base_url = cf_html.substr(src_start, src_end - src_start); + } + } + + // Find the markup between "<!--StartFragment -->" and "<!--EndFragment-->". + std::string cf_html_lower = StringToLowerASCII(cf_html); + size_t markup_start = cf_html_lower.find("<html", 0); + size_t tag_start = cf_html.find("StartFragment", markup_start); + size_t fragment_start = cf_html.find('>', tag_start) + 1; + size_t tag_end = cf_html.find("EndFragment", fragment_start); + size_t fragment_end = cf_html.rfind('<', tag_end); + if (fragment_start != std::string::npos && + fragment_end != std::string::npos) { + *html = cf_html.substr(fragment_start, fragment_end - fragment_start); + TrimWhitespace(*html, TRIM_ALL, html); + } +} diff --git a/base/clipboard_util.h b/base/clipboard_util.h index 89c7b69..9b55819 100644 --- a/base/clipboard_util.h +++ b/base/clipboard_util.h @@ -43,10 +43,16 @@ class ClipboardUtil { static bool GetFilenames(IDataObject* data_object, std::vector<std::wstring>* filenames); static bool GetPlainText(IDataObject* data_object, std::wstring* plain_text); - static bool GetCFHtml(IDataObject* data_object, std::wstring* cf_html); - static bool GetTextHtml(IDataObject* data_object, std::wstring* text_html); + static bool GetHtml(IDataObject* data_object, std::wstring* text_html, + std::string* base_url); static bool GetFileContents(IDataObject* data_object, std::wstring* filename, std::string* file_contents); -}; + // A helper method for converting between MS CF_HTML format and plain + // text/html. + static std::string HtmlToCFHtml(const std::string& html, + const std::string& base_url); + static void CFHtmlToHtml(const std::string& cf_html, std::string* html, + std::string* base_url); +}; diff --git a/base/clipboard_win.cc b/base/clipboard_win.cc index 814065d..adc2c25 100644 --- a/base/clipboard_win.cc +++ b/base/clipboard_win.cc @@ -178,14 +178,13 @@ void Clipboard::WriteHTML(const char* markup_data, size_t markup_len, const char* url_data, size_t url_len) { - std::string html_fragment, - markup(markup_data, markup_len), - url; + std::string markup(markup_data, markup_len); + std::string url; if (url_len > 0) url.assign(url_data, url_len); - MarkupToHTMLClipboardFormat(markup, url, &html_fragment); + std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); HGLOBAL glob = CreateGlobalData(html_fragment); WriteToClipboard(GetHtmlFormatType(), glob); @@ -437,7 +436,9 @@ void Clipboard::ReadHTML(std::wstring* markup, std::string* src_url) const { std::string html_fragment(static_cast<const char*>(::GlobalLock(data))); ::GlobalUnlock(data); - ParseHTMLClipboardFormat(html_fragment, markup, src_url); + std::string markup_utf8; + ClipboardUtil::CFHtmlToHtml(html_fragment, &markup_utf8, src_url); + markup->assign(UTF8ToWide(markup_utf8)); } void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const { @@ -509,104 +510,6 @@ void Clipboard::ReadFiles(std::vector<std::wstring>* files) const { } // static -void Clipboard::MarkupToHTMLClipboardFormat(const std::string& markup, - const std::string& src_url, - std::string* html_fragment) { - DCHECK(html_fragment); - // Documentation for the CF_HTML format is available at - // http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp - - if (markup.empty()) { - html_fragment->clear(); - return; - } - - html_fragment->assign("Version:0.9"); - - std::string start_html("\nStartHTML:"); - std::string end_html("\nEndHTML:"); - std::string start_fragment("\nStartFragment:"); - std::string end_fragment("\nEndFragment:"); - std::string source_url("\nSourceURL:"); - - bool has_source_url = !src_url.empty() && - !StartsWithASCII(src_url, "about:", false); - if (has_source_url) - source_url.append(src_url); - - std::string start_markup("\n<HTML>\n<BODY>\n<!--StartFragment-->\n"); - std::string end_markup("\n<!--EndFragment-->\n</BODY>\n</HTML>"); - - // calculate offsets - const size_t kMaxDigits = 10; // number of digits in UINT_MAX in base 10 - - size_t start_html_offset, start_fragment_offset; - size_t end_fragment_offset, end_html_offset; - - start_html_offset = html_fragment->length() + - start_html.length() + end_html.length() + - start_fragment.length() + end_fragment.length() + - (has_source_url ? source_url.length() : 0) + - (4*kMaxDigits); - - start_fragment_offset = start_html_offset + start_markup.length(); - end_fragment_offset = start_fragment_offset + markup.length(); - end_html_offset = end_fragment_offset + end_markup.length(); - - // fill in needed data - start_html.append(StringPrintf("%010u", start_html_offset)); - end_html.append(StringPrintf("%010u", end_html_offset)); - start_fragment.append(StringPrintf("%010u", start_fragment_offset)); - end_fragment.append(StringPrintf("%010u", end_fragment_offset)); - start_markup.append(markup); - - // create full html_fragment string from the fragments - html_fragment->append(start_html); - html_fragment->append(end_html); - html_fragment->append(start_fragment); - html_fragment->append(end_fragment); - if (has_source_url) - html_fragment->append(source_url); - html_fragment->append(start_markup); - html_fragment->append(end_markup); -} - -// static -void Clipboard::ParseHTMLClipboardFormat(const std::string& html_frag, - std::wstring* markup, - std::string* src_url) { - if (src_url) { - // Obtain SourceURL, if present - std::string src_url_str("SourceURL:"); - size_t line_start = html_frag.find(src_url_str, 0); - if (line_start != std::string::npos) { - size_t src_start = line_start+src_url_str.length(); - size_t src_end = html_frag.find("\n", line_start); - - if (src_end != std::string::npos) - *src_url = html_frag.substr(src_start, src_end - src_start); - } - } - - if (markup) { - // Find the markup between "<!--StartFragment -->" and - // "<!--EndFragment -->", accounting for browser quirks - size_t markup_start = html_frag.find('<', 0); - size_t tag_start = html_frag.find("StartFragment", markup_start); - size_t frag_start = html_frag.find('>', tag_start) + 1; - // Here we do something slightly differently than WebKit. Webkit does a - // forward find for EndFragment, but that seems to be a bug if the html - // fragment actually includes the string "EndFragment" - size_t tag_end = html_frag.rfind("EndFragment", std::string::npos); - size_t frag_end = html_frag.rfind('<', tag_end); - - TrimWhitespace(UTF8ToWide(html_frag.substr(frag_start, - frag_end - frag_start)), - TRIM_ALL, markup); - } -} - -// static void Clipboard::ParseBookmarkClipboardFormat(const std::wstring& bookmark, std::wstring* title, std::string* url) { diff --git a/base/scoped_clipboard_writer.cc b/base/scoped_clipboard_writer.cc index 9711f216..5821cd6 100644 --- a/base/scoped_clipboard_writer.cc +++ b/base/scoped_clipboard_writer.cc @@ -38,7 +38,7 @@ void ScopedClipboardWriter::WriteHTML(const std::wstring& markup, Clipboard::ObjectMapParams params; params.push_back( Clipboard::ObjectMapParam(utf8_markup.begin(), - utf8_markup.end())); + utf8_markup.end())); if (!src_url.empty()) { params.push_back(Clipboard::ObjectMapParam(src_url.begin(), src_url.end())); diff --git a/chrome/browser/web_contents_view_win.cc b/chrome/browser/web_contents_view_win.cc index dcf8136..90da9cd 100644 --- a/chrome/browser/web_contents_view_win.cc +++ b/chrome/browser/web_contents_view_win.cc @@ -100,8 +100,8 @@ void WebContentsViewWin::StartDragging(const WebDropData& drop_data) { data->SetFileContents(drop_data.file_description_filename, drop_data.file_contents); } - if (!drop_data.cf_html.empty()) - data->SetCFHtml(drop_data.cf_html); + if (!drop_data.text_html.empty()) + data->SetHtml(drop_data.text_html, drop_data.html_base_url); if (drop_data.url.is_valid()) { if (drop_data.url.SchemeIs("javascript")) { // We don't want to allow javascript URLs to be dragged to the desktop, diff --git a/chrome/common/os_exchange_data.cc b/chrome/common/os_exchange_data.cc index 36553c1..e86ce33 100644 --- a/chrome/common/os_exchange_data.cc +++ b/chrome/common/os_exchange_data.cc @@ -335,11 +335,20 @@ void OSExchangeData::SetFileContents(const std::wstring& filename, ClipboardUtil::GetFileContentFormatZero()->cfFormat, storage)); } -void OSExchangeData::SetCFHtml(const std::wstring& cf_html) { - std::string utf8 = WideToUTF8(cf_html); - STGMEDIUM* storage = GetStorageForBytes(utf8.c_str(), utf8.size()); +void OSExchangeData::SetHtml(const std::wstring& html, const GURL& base_url) { + // Add both MS CF_HTML and text/html format. CF_HTML should be in utf-8. + std::string utf8_html = WideToUTF8(html); + std::string url = base_url.is_valid() ? base_url.spec() : std::string(); + + std::string cf_html = ClipboardUtil::HtmlToCFHtml(utf8_html, url); + STGMEDIUM* storage = GetStorageForBytes(cf_html.c_str(), cf_html.size()); contents_.push_back(new StoredDataInfo( ClipboardUtil::GetHtmlFormat()->cfFormat, storage)); + + STGMEDIUM* storage_plain = GetStorageForBytes(utf8_html.c_str(), + utf8_html.size()); + contents_.push_back(new StoredDataInfo( + ClipboardUtil::GetTextHtmlFormat()->cfFormat, storage_plain)); } bool OSExchangeData::GetString(std::wstring* data) const { @@ -395,8 +404,12 @@ bool OSExchangeData::GetFileContents(std::wstring* filename, file_contents); } -bool OSExchangeData::GetCFHtml(std::wstring* cf_html) const { - return ClipboardUtil::GetCFHtml(source_object_, cf_html); +bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const { + std::string url; + bool success = ClipboardUtil::GetHtml(source_object_, html, &url); + if (success) + *base_url = GURL(url); + return success; } bool OSExchangeData::HasString() const { diff --git a/chrome/common/os_exchange_data.h b/chrome/common/os_exchange_data.h index 55ed6ad..735e366 100644 --- a/chrome/common/os_exchange_data.h +++ b/chrome/common/os_exchange_data.h @@ -56,8 +56,9 @@ class OSExchangeData : public IDataObject { // Adds the bytes of a file (CFSTR_FILECONTENTS and CFSTR_FILEDESCRIPTOR). void SetFileContents(const std::wstring& filename, const std::string& file_contents); - // Adds a snippet of Windows HTML (CF_HTML). - void SetCFHtml(const std::wstring& cf_html); + // Adds a snippet of HTML. |html| is just raw html but this sets both + // text/html and CF_HTML. + void SetHtml(const std::wstring& html, const GURL& base_url); // These functions retrieve data of the specified type. If data exists, the // functions return and the result is in the out parameter. If the data does @@ -70,7 +71,7 @@ class OSExchangeData : public IDataObject { bool GetPickledData(CLIPFORMAT format, Pickle* data) const; bool GetFileContents(std::wstring* filename, std::string* file_contents) const; - bool GetCFHtml(std::wstring* cf_html) const; + bool GetHtml(std::wstring* html, GURL* base_url) const; // Test whether or not data of certain types is present, without actually // returning anything. @@ -141,4 +142,3 @@ class OSExchangeData : public IDataObject { }; #endif // #ifndef CHROME_COMMON_OS_EXCHANGE_DATA_H__ - diff --git a/chrome/common/os_exchange_data_unittest.cc b/chrome/common/os_exchange_data_unittest.cc index f54cb72..427208f 100644 --- a/chrome/common/os_exchange_data_unittest.cc +++ b/chrome/common/os_exchange_data_unittest.cc @@ -5,6 +5,7 @@ #include <atlbase.h> #include <shlobj.h> +#include "base/clipboard_util.h" #include "base/pickle.h" #include "base/ref_counted.h" #include "base/scoped_handle.h" @@ -313,16 +314,33 @@ TEST(OSExchangeDataTest, FileContents) { TEST(OSExchangeDataTest, Html) { scoped_refptr<OSExchangeData> data(new OSExchangeData); - std::wstring html(L"Version:0.9\nStartHTML:71\nEndHTML:160\n" - L"StartFragment:130\nEndFragment:150\n<HTML>\n<BODY>\n" - L"<!--StartFragment-->\n<b>bold.</b> <i><b>This is bold italic.</b></i>\n" - L"<!--EndFragment-->\n</BODY>\n</HTML>"); - data->SetCFHtml(html); + GURL url("http://www.google.com/"); + std::wstring html( + L"<HTML>\n<BODY>\n" + L"<b>bold.</b> <i><b>This is bold italic.</b></i>\n" + L"</BODY>\n</HTML>"); + data->SetHtml(html, url); scoped_refptr<OSExchangeData> copy(new OSExchangeData(data.get())); std::wstring read_html; - EXPECT_TRUE(copy->GetCFHtml(&read_html)); + EXPECT_TRUE(copy->GetHtml(&read_html, &url)); EXPECT_EQ(html, read_html); + + // Check the CF_HTML too. + std::string expected_cf_html( + "Version:0.9\r\nStartHTML:0000000138\r\nEndHTML:0000000291\r\n" + "StartFragment:0000000176\r\nEndFragment:0000000253\r\n" + "SourceURL:http://www.google.com/\r\n<html>\r\n<body>\r\n" + "<!--StartFragment-->\r\n"); + expected_cf_html += WideToUTF8(html); + expected_cf_html.append("\r\n<!--EndFragment-->\r\n</body>\r\n</html>"); + + STGMEDIUM medium; + EXPECT_EQ(S_OK, data->GetData(ClipboardUtil::GetHtmlFormat(), &medium)); + ScopedHGlobal<char> glob(medium.hGlobal); + std::string output(glob.get(), glob.Size()); + EXPECT_EQ(expected_cf_html, output); + ReleaseStgMedium(&medium); } TEST(OSExchangeDataTest, SetURLWithMaxPath) { diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 7c6f2c1..d74091a 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -1662,8 +1662,8 @@ struct ParamTraits<WebDropData> { WriteParam(m, p.url_title); WriteParam(m, p.filenames); WriteParam(m, p.plain_text); - WriteParam(m, p.cf_html); WriteParam(m, p.text_html); + WriteParam(m, p.html_base_url); WriteParam(m, p.file_description_filename); WriteParam(m, p.file_contents); } @@ -1673,8 +1673,8 @@ struct ParamTraits<WebDropData> { ReadParam(m, iter, &p->url_title) && ReadParam(m, iter, &p->filenames) && ReadParam(m, iter, &p->plain_text) && - ReadParam(m, iter, &p->cf_html) && ReadParam(m, iter, &p->text_html) && + ReadParam(m, iter, &p->html_base_url) && ReadParam(m, iter, &p->file_description_filename) && ReadParam(m, iter, &p->file_contents); } diff --git a/webkit/glue/clipboard_conversion.cc b/webkit/glue/clipboard_conversion.cc index 0c690c0..7bf8c51 100644 --- a/webkit/glue/clipboard_conversion.cc +++ b/webkit/glue/clipboard_conversion.cc @@ -16,114 +16,6 @@ #include "webkit/glue/glue_util.h" -namespace { - -// TODO(tc): CF_HTML logic should move into the browser process since it only -// makes sense on Windows. -#if defined(OS_WIN) -void append(WTF::Vector<char>& vector, const WebCore::CString& string) { - vector.append(string.data(), string.length()); -} -// Documentation for the CF_HTML format is available at -// http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp -void markupToCF_HTML(const WebCore::String& markup, - const WebCore::String& src_url, - WTF::Vector<char>& result) { - if (markup.isEmpty()) - return; - - #define MAX_DIGITS 10 - #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits) - #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u" - #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS) - - static const char* header = "Version:0.9\n" - "StartHTML:" NUMBER_FORMAT "\n" - "EndHTML:" NUMBER_FORMAT "\n" - "StartFragment:" NUMBER_FORMAT "\n" - "EndFragment:" NUMBER_FORMAT "\n"; - static const char* source_url_prefix = "SourceURL:"; - - static const char* start_markup = "<HTML>\n<BODY>\n<!--StartFragment-->\n"; - static const char* end_markup = "\n<!--EndFragment-->\n</BODY>\n</HTML>"; - - WebCore::CString source_url_utf8 = (src_url == WebCore::blankURL()) ? - "" : src_url.utf8(); - WebCore::CString markup_utf8 = markup.utf8(); - - // calculate offsets - size_t start_html_offset = strlen(header) - strlen(NUMBER_FORMAT) * 4 + - MAX_DIGITS * 4; - if (source_url_utf8.length()) { - start_html_offset += strlen(source_url_prefix) + - source_url_utf8.length() + 1; - } - size_t start_fragment_offset = start_html_offset + strlen(start_markup); - size_t end_fragment_offset = start_fragment_offset + markup_utf8.length(); - size_t end_html_offset = end_fragment_offset + strlen(end_markup); - - append(result, WebCore::String::format(header, start_html_offset, - end_html_offset, start_fragment_offset, end_fragment_offset).utf8()); - if (source_url_utf8.length()) { - append(result, source_url_prefix); - append(result, source_url_utf8); - result.append('\n'); - } - append(result, start_markup); - append(result, markup_utf8); - append(result, end_markup); - - #undef MAX_DIGITS - #undef MAKE_NUMBER_FORMAT_1 - #undef MAKE_NUMBER_FORMAT_2 - #undef NUMBER_FORMAT -} -#endif - -std::wstring HTMLToCFHTML(const WebCore::String& html, - const WebCore::KURL& url) { -#if defined(OS_WIN) - Vector<char> cf_html_data; - markupToCF_HTML(html, url, cf_html_data); - WebCore::String cf_html_str(cf_html_data.data(), cf_html_data.size()); - return webkit_glue::StringToStdWString(cf_html_str); -#else - return std::wstring(); -#endif -} - -WebCore::String CFHTMLToHTML(const std::wstring& cf_html_wstr) { -#if defined(OS_WIN) - WebCore::String cf_html = webkit_glue::StdWStringToString(cf_html_wstr); - // Obtain baseURL if present. - WebCore::String src_url_str("sourceURL:"); - WebCore::String src_url; - unsigned int line_start = cf_html.find(src_url_str, 0, false); - if (line_start != -1) { - unsigned int src_end = cf_html.find("\n", line_start, false); - unsigned int src_start = line_start + src_url_str.length(); - WebCore::String raw_src_url = cf_html.substring(src_start, src_end - src_start); - replaceNBSPWithSpace(raw_src_url); - src_url = raw_src_url.stripWhiteSpace(); - } - - // find the markup between "<!--StartFragment -->" and "<!--EndFragment - // -->", accounting for browser quirks - unsigned markup_start = cf_html.find("<html", 0, false); - unsigned tag_start = cf_html.find("startfragment", markup_start, false); - unsigned fragment_start = cf_html.find('>', tag_start) + 1; - unsigned tag_end = cf_html.find("endfragment", fragment_start, false); - unsigned fragment_end = cf_html.reverseFind('<', tag_end); - WebCore::String markup = cf_html.substring(fragment_start, - fragment_end - fragment_start).stripWhiteSpace(); - return markup; -#else - return WebCore::String(); -#endif -} - -} // namespace - namespace webkit_glue { WebDropData ChromiumDataObjectToWebDropData( @@ -139,9 +31,8 @@ WebDropData ChromiumDataObjectToWebDropData( drop_data.plain_text = StringToStdWString(data_object->plain_text); - drop_data.cf_html = HTMLToCFHTML(data_object->text_html, data_object->url); - drop_data.text_html = StringToStdWString(data_object->text_html); + drop_data.html_base_url = KURLToGURL(data_object->html_base_url); drop_data.file_description_filename = StringToStdWString( data_object->file_content_filename); @@ -167,10 +58,7 @@ PassRefPtr<WebCore::ChromiumDataObject> WebDropDataToChromiumDataObject( data_object->plain_text = StdWStringToString(drop_data.plain_text); data_object->text_html = StdWStringToString(drop_data.text_html); - if (data_object->text_html.isEmpty()) { - // Use CF_HTML only if there's no text/html data. - data_object->text_html = CFHTMLToHTML(drop_data.cf_html); - } + data_object->html_base_url = GURLToKURL(drop_data.html_base_url); data_object->file_content_filename = StdWStringToString( drop_data.file_description_filename); diff --git a/webkit/glue/webdropdata.cc b/webkit/glue/webdropdata.cc index 28ed52d..cd96169 100644 --- a/webkit/glue/webdropdata.cc +++ b/webkit/glue/webdropdata.cc @@ -20,8 +20,11 @@ void WebDropData::PopulateWebDropData(IDataObject* data_object, } ClipboardUtil::GetFilenames(data_object, &drop_data->filenames); ClipboardUtil::GetPlainText(data_object, &drop_data->plain_text); - ClipboardUtil::GetCFHtml(data_object, &drop_data->cf_html); - ClipboardUtil::GetTextHtml(data_object, &drop_data->text_html); + std::string base_url; + ClipboardUtil::GetHtml(data_object, &drop_data->text_html, &base_url); + if (!base_url.empty()) { + drop_data->html_base_url = GURL(base_url); + } ClipboardUtil::GetFileContents(data_object, &drop_data->file_description_filename, &drop_data->file_contents); } diff --git a/webkit/glue/webdropdata.h b/webkit/glue/webdropdata.h index 38d67b4..e6d51f4 100644 --- a/webkit/glue/webdropdata.h +++ b/webkit/glue/webdropdata.h @@ -26,14 +26,11 @@ struct WebDropData { // User is dragging plain text into the webview. std::wstring plain_text; - // User is dragging MS HTML into the webview (e.g., out of IE). - // TODO(tc): We should remove this from webdropdata because not all platforms - // have cf_html. On the browser side, we should do the necessary conversions - // so we still support cf_html. - std::wstring cf_html; - - // User is dragging text/html into the webview (e.g., out of Firefox). + // User is dragging text/html into the webview (e.g., out of Firefox). + // |html_base_url| is the URL that the html fragment is taken from (used to + // resolve relative links). It's ok for |html_base_url| to be empty. std::wstring text_html; + GURL html_base_url; // User is dragging data from the webview (e.g., an image). std::wstring file_description_filename; diff --git a/webkit/port/platform/chromium/ChromiumDataObject.cpp b/webkit/port/platform/chromium/ChromiumDataObject.cpp index ddf9cd9..54da838 100644 --- a/webkit/port/platform/chromium/ChromiumDataObject.cpp +++ b/webkit/port/platform/chromium/ChromiumDataObject.cpp @@ -39,6 +39,7 @@ void ChromiumDataObject::clear() filenames.clear(); plain_text = ""; text_html = ""; + html_base_url = KURL(); file_content_filename = ""; if (file_content) file_content->clear(); diff --git a/webkit/port/platform/chromium/ChromiumDataObject.h b/webkit/port/platform/chromium/ChromiumDataObject.h index f6178f3..bdbb62c 100644 --- a/webkit/port/platform/chromium/ChromiumDataObject.h +++ b/webkit/port/platform/chromium/ChromiumDataObject.h @@ -57,6 +57,7 @@ namespace WebCore { String plain_text; String text_html; + KURL html_base_url; String file_content_filename; RefPtr<SharedBuffer> file_content; diff --git a/webkit/port/platform/chromium/ClipboardChromium.cpp b/webkit/port/platform/chromium/ClipboardChromium.cpp index 663a341..5087cdf 100644 --- a/webkit/port/platform/chromium/ClipboardChromium.cpp +++ b/webkit/port/platform/chromium/ClipboardChromium.cpp @@ -331,6 +331,7 @@ void ClipboardChromium::writeURL(const KURL& url, const String& title, Frame*) // The URL can also be used as an HTML fragment. m_dataObject->text_html = urlToMarkup(url, title); + m_dataObject->html_base_url = url; } void ClipboardChromium::writeRange(Range* selectedRange, Frame* frame) @@ -341,6 +342,7 @@ void ClipboardChromium::writeRange(Range* selectedRange, Frame* frame) m_dataObject->text_html = createMarkup(selectedRange, 0, AnnotateForInterchange); + m_dataObject->html_base_url = frame->document()->url(); String str = frame->selectedText(); #if PLATFORM(WIN_OS) diff --git a/webkit/port/platform/chromium/DragDataChromium.cpp b/webkit/port/platform/chromium/DragDataChromium.cpp index 3507739..d615559 100644 --- a/webkit/port/platform/chromium/DragDataChromium.cpp +++ b/webkit/port/platform/chromium/DragDataChromium.cpp @@ -126,21 +126,21 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const * * PICT */ - // TODO(tc): Disabled because containsFilenames is hardcoded to return - // false. We need to implement fragmentFromFilenames when this is - // re-enabled in Apple's win port. - //if (containsFilenames()) - // if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(doc, m_platformDragData)) - // return fragment; - - if (!m_platformDragData->text_html.isEmpty()) { - String url; - RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(doc, - m_platformDragData->text_html, url); - return fragment; - } - - return 0; + if (containsFiles()) { + // TODO(tc): Implement this. Should be pretty simple to make some HTML + // and call createFragmentFromMarkup. + //if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(doc, + // ?, KURL())) + // return fragment; + } + + if (!m_platformDragData->text_html.isEmpty()) { + RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(doc, + m_platformDragData->text_html, m_platformDragData->html_base_url); + return fragment.release(); + } + + return 0; } Color DragData::asColor() const |