summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authortc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-19 01:20:01 +0000
committertc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-19 01:20:01 +0000
commit22cf8687fe6c4fc4dbb2b9b2ac41d7d45f656d83 (patch)
treedf838980effe3721bdc41b6acea356bf6352df8e /base
parent234ebdecf98582ca141b9066b1e5f4f74d3bdbff (diff)
downloadchromium_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.h8
-rw-r--r--base/clipboard_util.cc147
-rw-r--r--base/clipboard_util.h12
-rw-r--r--base/clipboard_win.cc109
-rw-r--r--base/scoped_clipboard_writer.cc2
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()));