OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-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 // Many of these functions are based on those found in | 5 // Many of these functions are based on those found in |
6 // webkit/port/platform/PasteboardWin.cpp | 6 // webkit/port/platform/PasteboardWin.cpp |
7 | 7 |
8 #include <shlobj.h> | 8 #include <shlobj.h> |
9 #include <shellapi.h> | 9 #include <shellapi.h> |
10 | 10 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 UTF8ToWide(text_data, text_len, &text); | 171 UTF8ToWide(text_data, text_len, &text); |
172 HGLOBAL glob = CreateGlobalData(text); | 172 HGLOBAL glob = CreateGlobalData(text); |
173 | 173 |
174 WriteToClipboard(CF_UNICODETEXT, glob); | 174 WriteToClipboard(CF_UNICODETEXT, glob); |
175 } | 175 } |
176 | 176 |
177 void Clipboard::WriteHTML(const char* markup_data, | 177 void Clipboard::WriteHTML(const char* markup_data, |
178 size_t markup_len, | 178 size_t markup_len, |
179 const char* url_data, | 179 const char* url_data, |
180 size_t url_len) { | 180 size_t url_len) { |
181 std::string html_fragment, | 181 std::string markup(markup_data, markup_len); |
182 markup(markup_data, markup_len), | 182 std::string url; |
183 url; | |
184 | 183 |
185 if (url_len > 0) | 184 if (url_len > 0) |
186 url.assign(url_data, url_len); | 185 url.assign(url_data, url_len); |
187 | 186 |
188 MarkupToHTMLClipboardFormat(markup, url, &html_fragment); | 187 std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); |
189 HGLOBAL glob = CreateGlobalData(html_fragment); | 188 HGLOBAL glob = CreateGlobalData(html_fragment); |
190 | 189 |
191 WriteToClipboard(GetHtmlFormatType(), glob); | 190 WriteToClipboard(GetHtmlFormatType(), glob); |
192 } | 191 } |
193 | 192 |
194 void Clipboard::WriteBookmark(const char* title_data, | 193 void Clipboard::WriteBookmark(const char* title_data, |
195 size_t title_len, | 194 size_t title_len, |
196 const char* url_data, | 195 const char* url_data, |
197 size_t url_len) { | 196 size_t url_len) { |
198 std::string bookmark(title_data, title_len); | 197 std::string bookmark(title_data, title_len); |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 if (!clipboard.Acquire(clipboard_owner_)) | 429 if (!clipboard.Acquire(clipboard_owner_)) |
431 return; | 430 return; |
432 | 431 |
433 HANDLE data = ::GetClipboardData(GetHtmlFormatType()); | 432 HANDLE data = ::GetClipboardData(GetHtmlFormatType()); |
434 if (!data) | 433 if (!data) |
435 return; | 434 return; |
436 | 435 |
437 std::string html_fragment(static_cast<const char*>(::GlobalLock(data))); | 436 std::string html_fragment(static_cast<const char*>(::GlobalLock(data))); |
438 ::GlobalUnlock(data); | 437 ::GlobalUnlock(data); |
439 | 438 |
440 ParseHTMLClipboardFormat(html_fragment, markup, src_url); | 439 std::string markup_utf8; |
| 440 ClipboardUtil::CFHtmlToHtml(html_fragment, &markup_utf8, src_url); |
| 441 markup->assign(UTF8ToWide(markup_utf8)); |
441 } | 442 } |
442 | 443 |
443 void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const { | 444 void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const { |
444 if (title) | 445 if (title) |
445 title->clear(); | 446 title->clear(); |
446 | 447 |
447 if (url) | 448 if (url) |
448 url->clear(); | 449 url->clear(); |
449 | 450 |
450 // Acquire the clipboard. | 451 // Acquire the clipboard. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 for (int i = 0; i < count; ++i) { | 503 for (int i = 0; i < count; ++i) { |
503 int size = ::DragQueryFile(drop, i, NULL, 0) + 1; | 504 int size = ::DragQueryFile(drop, i, NULL, 0) + 1; |
504 std::wstring file; | 505 std::wstring file; |
505 ::DragQueryFile(drop, i, WriteInto(&file, size), size); | 506 ::DragQueryFile(drop, i, WriteInto(&file, size), size); |
506 files->push_back(file); | 507 files->push_back(file); |
507 } | 508 } |
508 } | 509 } |
509 } | 510 } |
510 | 511 |
511 // static | 512 // static |
512 void Clipboard::MarkupToHTMLClipboardFormat(const std::string& markup, | |
513 const std::string& src_url, | |
514 std::string* html_fragment) { | |
515 DCHECK(html_fragment); | |
516 // Documentation for the CF_HTML format is available at | |
517 // http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp | |
518 | |
519 if (markup.empty()) { | |
520 html_fragment->clear(); | |
521 return; | |
522 } | |
523 | |
524 html_fragment->assign("Version:0.9"); | |
525 | |
526 std::string start_html("\nStartHTML:"); | |
527 std::string end_html("\nEndHTML:"); | |
528 std::string start_fragment("\nStartFragment:"); | |
529 std::string end_fragment("\nEndFragment:"); | |
530 std::string source_url("\nSourceURL:"); | |
531 | |
532 bool has_source_url = !src_url.empty() && | |
533 !StartsWithASCII(src_url, "about:", false); | |
534 if (has_source_url) | |
535 source_url.append(src_url); | |
536 | |
537 std::string start_markup("\n<HTML>\n<BODY>\n<!--StartFragment-->\n"); | |
538 std::string end_markup("\n<!--EndFragment-->\n</BODY>\n</HTML>"); | |
539 | |
540 // calculate offsets | |
541 const size_t kMaxDigits = 10; // number of digits in UINT_MAX in base 10 | |
542 | |
543 size_t start_html_offset, start_fragment_offset; | |
544 size_t end_fragment_offset, end_html_offset; | |
545 | |
546 start_html_offset = html_fragment->length() + | |
547 start_html.length() + end_html.length() + | |
548 start_fragment.length() + end_fragment.length() + | |
549 (has_source_url ? source_url.length() : 0) + | |
550 (4*kMaxDigits); | |
551 | |
552 start_fragment_offset = start_html_offset + start_markup.length(); | |
553 end_fragment_offset = start_fragment_offset + markup.length(); | |
554 end_html_offset = end_fragment_offset + end_markup.length(); | |
555 | |
556 // fill in needed data | |
557 start_html.append(StringPrintf("%010u", start_html_offset)); | |
558 end_html.append(StringPrintf("%010u", end_html_offset)); | |
559 start_fragment.append(StringPrintf("%010u", start_fragment_offset)); | |
560 end_fragment.append(StringPrintf("%010u", end_fragment_offset)); | |
561 start_markup.append(markup); | |
562 | |
563 // create full html_fragment string from the fragments | |
564 html_fragment->append(start_html); | |
565 html_fragment->append(end_html); | |
566 html_fragment->append(start_fragment); | |
567 html_fragment->append(end_fragment); | |
568 if (has_source_url) | |
569 html_fragment->append(source_url); | |
570 html_fragment->append(start_markup); | |
571 html_fragment->append(end_markup); | |
572 } | |
573 | |
574 // static | |
575 void Clipboard::ParseHTMLClipboardFormat(const std::string& html_frag, | |
576 std::wstring* markup, | |
577 std::string* src_url) { | |
578 if (src_url) { | |
579 // Obtain SourceURL, if present | |
580 std::string src_url_str("SourceURL:"); | |
581 size_t line_start = html_frag.find(src_url_str, 0); | |
582 if (line_start != std::string::npos) { | |
583 size_t src_start = line_start+src_url_str.length(); | |
584 size_t src_end = html_frag.find("\n", line_start); | |
585 | |
586 if (src_end != std::string::npos) | |
587 *src_url = html_frag.substr(src_start, src_end - src_start); | |
588 } | |
589 } | |
590 | |
591 if (markup) { | |
592 // Find the markup between "<!--StartFragment -->" and | |
593 // "<!--EndFragment -->", accounting for browser quirks | |
594 size_t markup_start = html_frag.find('<', 0); | |
595 size_t tag_start = html_frag.find("StartFragment", markup_start); | |
596 size_t frag_start = html_frag.find('>', tag_start) + 1; | |
597 // Here we do something slightly differently than WebKit. Webkit does a | |
598 // forward find for EndFragment, but that seems to be a bug if the html | |
599 // fragment actually includes the string "EndFragment" | |
600 size_t tag_end = html_frag.rfind("EndFragment", std::string::npos); | |
601 size_t frag_end = html_frag.rfind('<', tag_end); | |
602 | |
603 TrimWhitespace(UTF8ToWide(html_frag.substr(frag_start, | |
604 frag_end - frag_start)), | |
605 TRIM_ALL, markup); | |
606 } | |
607 } | |
608 | |
609 // static | |
610 void Clipboard::ParseBookmarkClipboardFormat(const std::wstring& bookmark, | 513 void Clipboard::ParseBookmarkClipboardFormat(const std::wstring& bookmark, |
611 std::wstring* title, | 514 std::wstring* title, |
612 std::string* url) { | 515 std::string* url) { |
613 const wchar_t* const kDelim = L"\r\n"; | 516 const wchar_t* const kDelim = L"\r\n"; |
614 | 517 |
615 const size_t title_end = bookmark.find_first_of(kDelim); | 518 const size_t title_end = bookmark.find_first_of(kDelim); |
616 if (title) | 519 if (title) |
617 title->assign(bookmark.substr(0, title_end)); | 520 title->assign(bookmark.substr(0, title_end)); |
618 | 521 |
619 if (url) { | 522 if (url) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat; | 598 return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat; |
696 } | 599 } |
697 | 600 |
698 // static | 601 // static |
699 void Clipboard::FreeData(FormatType format, HANDLE data) { | 602 void Clipboard::FreeData(FormatType format, HANDLE data) { |
700 if (format == CF_BITMAP) | 603 if (format == CF_BITMAP) |
701 ::DeleteObject(static_cast<HBITMAP>(data)); | 604 ::DeleteObject(static_cast<HBITMAP>(data)); |
702 else | 605 else |
703 ::GlobalFree(data); | 606 ::GlobalFree(data); |
704 } | 607 } |
OLD | NEW |