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 /base | |
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
Diffstat (limited to 'base')
-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 |
5 files changed, 144 insertions, 134 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())); |