diff options
author | ericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-01 21:42:14 +0000 |
---|---|---|
committer | ericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-01 21:42:14 +0000 |
commit | 0c4c3884b89e0c5fb3adbbb0f3cdf092cda84a10 (patch) | |
tree | e942cc54be97b815ae60fdd7bbd65a2aa624d843 | |
parent | 2ef2712ec860306a843c0e18afbdc339da4917cd (diff) | |
download | chromium_src-0c4c3884b89e0c5fb3adbbb0f3cdf092cda84a10.zip chromium_src-0c4c3884b89e0c5fb3adbbb0f3cdf092cda84a10.tar.gz chromium_src-0c4c3884b89e0c5fb3adbbb0f3cdf092cda84a10.tar.bz2 |
The "Copy URL" link is always greyed out in the Chrome menu on popups [crbug.com/13488].
This turns out to be because it was never implemented.
Tested manually on Windows; I'll test on Linux before submitting.
BUG=13488
TEST=Tested manually on Windows and added a unit test for the new Clipboard function.
Review URL: http://codereview.chromium.org/210042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27772 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/clipboard.h | 9 | ||||
-rw-r--r-- | base/clipboard_linux.cc | 8 | ||||
-rw-r--r-- | base/clipboard_unittest.cc | 30 | ||||
-rw-r--r-- | base/scoped_clipboard_writer.cc | 36 | ||||
-rw-r--r-- | base/scoped_clipboard_writer.h | 12 | ||||
-rw-r--r-- | chrome/browser/browser.cc | 22 | ||||
-rw-r--r-- | chrome/browser/browser.h | 1 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.cc | 25 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.h | 5 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu_gtk.cc | 9 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu_gtk.h | 1 | ||||
-rw-r--r-- | net/base/net_util.cc | 18 | ||||
-rw-r--r-- | net/base/net_util.h | 6 |
13 files changed, 134 insertions, 48 deletions
diff --git a/base/clipboard.h b/base/clipboard.h index b960676..e5cc9c2 100644 --- a/base/clipboard.h +++ b/base/clipboard.h @@ -116,6 +116,14 @@ class Clipboard { // can use. void WriteObjects(const ObjectMap& objects, base::ProcessHandle process); + // On Linux, we need to know when the clipboard is set to a URL. Most + // platforms don't care. +#if !defined(OS_LINUX) + void DidWriteURL(const std::string& utf8_text) {} +#else // !defined(OS_LINUX) + void DidWriteURL(const std::string& utf8_text); +#endif + // Tests whether the clipboard contains a certain format bool IsFormatAvailable(const FormatType& format, Buffer buffer) const; @@ -190,6 +198,7 @@ class Clipboard { void WriteFiles(const char* file_data, size_t file_len); void WriteBitmap(const char* pixel_data, const char* size_data); + #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FREEBSD) // |format_name| is an ASCII string and should be NULL-terminated. // TODO(estade): port to mac. diff --git a/base/clipboard_linux.cc b/base/clipboard_linux.cc index 9a04d1c..f49da3f 100644 --- a/base/clipboard_linux.cc +++ b/base/clipboard_linux.cc @@ -119,6 +119,14 @@ void Clipboard::WriteObjects(const ObjectMap& objects) { SetGtkClipboard(); } +// When a URL is copied from a render view context menu (via "copy link +// location", for example), we additionally stick it in the X clipboard. This +// matches other linux browsers. +void Clipboard::DidWriteURL(const std::string& utf8_text) { + gtk_clipboard_set_text(primary_selection_, utf8_text.c_str(), + utf8_text.length()); +} + // Take ownership of the GTK clipboard and inform it of the targets we support. void Clipboard::SetGtkClipboard() { scoped_array<GtkTargetEntry> targets( diff --git a/base/clipboard_unittest.cc b/base/clipboard_unittest.cc index d26ba00..e6238ba 100644 --- a/base/clipboard_unittest.cc +++ b/base/clipboard_unittest.cc @@ -227,6 +227,36 @@ TEST_F(ClipboardTest, MultipleFilesTest) { } #endif // !defined(OS_LINUX) +TEST_F(ClipboardTest, URLTest) { + Clipboard clipboard; + + string16 url(ASCIIToUTF16("http://www.google.com/")); + + { + ScopedClipboardWriter clipboard_writer(&clipboard); + clipboard_writer.WriteURL(url); + } + + EXPECT_TRUE(clipboard.IsFormatAvailable( + Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD)); + EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetPlainTextFormatType(), + Clipboard::BUFFER_STANDARD)); + string16 text_result; + clipboard.ReadText(Clipboard::BUFFER_STANDARD, &text_result); + + EXPECT_EQ(text_result, url); + + std::string ascii_text; + clipboard.ReadAsciiText(Clipboard::BUFFER_STANDARD, &ascii_text); + EXPECT_EQ(UTF16ToUTF8(url), ascii_text); + +#if defined(OS_LINUX) + ascii_text.clear(); + clipboard.ReadAsciiText(Clipboard::BUFFER_SELECTION, &ascii_text); + EXPECT_EQ(UTF16ToUTF8(url), ascii_text); +#endif // defined(OS_LINUX) +} + #if defined(OS_WIN) || defined(OS_LINUX) TEST_F(ClipboardTest, DataTest) { Clipboard clipboard; diff --git a/base/scoped_clipboard_writer.cc b/base/scoped_clipboard_writer.cc index dff3321..e464628 100644 --- a/base/scoped_clipboard_writer.cc +++ b/base/scoped_clipboard_writer.cc @@ -18,20 +18,19 @@ ScopedClipboardWriter::ScopedClipboardWriter(Clipboard* clipboard) } ScopedClipboardWriter::~ScopedClipboardWriter() { - if (!objects_.empty() && clipboard_) + if (!objects_.empty() && clipboard_) { clipboard_->WriteObjects(objects_); + if (url_text_.length()) + clipboard_->DidWriteURL(url_text_); + } } void ScopedClipboardWriter::WriteText(const string16& text) { - if (text.empty()) - return; - - std::string utf8_text = UTF16ToUTF8(text); + WriteTextOrURL(text, false); +} - Clipboard::ObjectMapParams parameters; - parameters.push_back(Clipboard::ObjectMapParam(utf8_text.begin(), - utf8_text.end())); - objects_[Clipboard::CBF_TEXT] = parameters; +void ScopedClipboardWriter::WriteURL(const string16& text) { + WriteTextOrURL(text, true); } void ScopedClipboardWriter::WriteHTML(const string16& markup, @@ -156,3 +155,22 @@ void ScopedClipboardWriter::WritePickledData(const Pickle& pickle, parameters.push_back(data_parameter); objects_[Clipboard::CBF_DATA] = parameters; } + +void ScopedClipboardWriter::WriteTextOrURL(const string16& text, bool is_url) { + if (text.empty()) + return; + + std::string utf8_text = UTF16ToUTF8(text); + + Clipboard::ObjectMapParams parameters; + parameters.push_back(Clipboard::ObjectMapParam(utf8_text.begin(), + utf8_text.end())); + objects_[Clipboard::CBF_TEXT] = parameters; + + if (is_url) { + url_text_ = utf8_text; + } else { + url_text_.clear(); + } +} + diff --git a/base/scoped_clipboard_writer.h b/base/scoped_clipboard_writer.h index ed63050..feea7cd 100644 --- a/base/scoped_clipboard_writer.h +++ b/base/scoped_clipboard_writer.h @@ -33,6 +33,10 @@ class ScopedClipboardWriter { // Converts |text| to UTF-8 and adds it to the clipboard. void WriteText(const string16& text); + // Converts the text of the URL to UTF-8 and adds it to the clipboard, then + // notifies the Clipboard that we just wrote a URL. + void WriteURL(const string16& text); + // Adds HTML to the clipboard. The url parameter is optional, but especially // useful if the HTML fragment contains relative links. void WriteHTML(const string16& markup, const std::string& source_url); @@ -60,11 +64,19 @@ class ScopedClipboardWriter { void WritePickledData(const Pickle& pickle, Clipboard::FormatType format); protected: + // Converts |text| to UTF-8 and adds it to the clipboard. If it's a URL, we + // also notify the clipboard of that fact. + void WriteTextOrURL(const string16& text, bool is_url); + // We accumulate the data passed to the various targets in the |objects_| // vector, and pass it to Clipboard::WriteObjects() during object destruction. Clipboard::ObjectMap objects_; Clipboard* clipboard_; + // We keep around the UTF-8 text of the URL in order to pass it to + // Clipboard::DidWriteURL(). + std::string url_text_; + private: DISALLOW_COPY_AND_ASSIGN(ScopedClipboardWriter); }; diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 3df24ae..ae1b5538 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/keyboard_codes.h" #include "base/logging.h" +#include "base/scoped_clipboard_writer.h" #include "base/string_util.h" #include "base/thread.h" #include "chrome/app/chrome_dll_resource.h" @@ -856,6 +857,22 @@ void Browser::RestoreTab() { service->RestoreMostRecentEntry(this); } +void Browser::WriteCurrentURLToClipboard() { + // TODO(ericu): There isn't currently a metric for this. Should there be? + // We don't appear to track the action when it comes from the + // RenderContextViewMenu. + // UserMetrics::RecordAction(L"$Metric_Name_Goes_Here$", profile_); + + TabContents* contents = GetSelectedTabContents(); + if (!contents->ShouldDisplayURL()) + return; + + net::WriteURLToClipboard( + contents->GetURL(), + profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), + g_browser_process->clipboard()); +} + void Browser::ConvertPopupToTabbedBrowser() { UserMetrics::RecordAction(L"ShowAsTab", profile_); int tab_strip_index = tabstrip_model_.selected_index(); @@ -1347,6 +1364,7 @@ void Browser::ExecuteCommandWithDisposition( case IDC_SELECT_LAST_TAB: SelectLastTab(); break; case IDC_DUPLICATE_TAB: DuplicateTab(); break; case IDC_RESTORE_TAB: RestoreTab(); break; + case IDC_COPY_URL: WriteCurrentURLToClipboard(); break; case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break; case IDC_FULLSCREEN: ToggleFullscreenMode(); break; case IDC_EXIT: Exit(); break; @@ -2300,6 +2318,7 @@ void Browser::InitCommandState() { command_updater_.UpdateCommandEnabled(IDC_CUT, true); command_updater_.UpdateCommandEnabled(IDC_COPY, true); command_updater_.UpdateCommandEnabled(IDC_PASTE, true); + command_updater_.UpdateCommandEnabled(IDC_COPY_URL, true); // Find-in-page command_updater_.UpdateCommandEnabled(IDC_FIND, true); @@ -2367,9 +2386,6 @@ void Browser::InitCommandState() { // Page-related commands command_updater_.UpdateCommandEnabled(IDC_STAR, normal_window); - // Clipboard commands - command_updater_.UpdateCommandEnabled(IDC_COPY_URL, normal_window); - // Show various bits of UI command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window); diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index d881059..be4e1c2 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -325,6 +325,7 @@ class Browser : public TabStripModelDelegate, void SelectLastTab(); void DuplicateTab(); void RestoreTab(); + void WriteCurrentURLToClipboard(); void ConvertPopupToTabbedBrowser(); void ToggleFullscreenMode(); void Exit(); diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index f8f9dcd..ba62b06 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -801,28 +801,11 @@ void RenderViewContextMenu::Inspect(int x, int y) { source_tab_contents_->render_view_host(), x, y); } -void RenderViewContextMenu::WriteTextToClipboard(const string16& text) { - Clipboard* clipboard = g_browser_process->clipboard(); - - if (!clipboard) - return; - - ScopedClipboardWriter scw(clipboard); - scw.WriteText(text); -} - void RenderViewContextMenu::WriteURLToClipboard(const GURL& url) { - std::string utf8_text = url.SchemeIs(chrome::kMailToScheme) ? url.path() : - // Unescaping path and query is not a good idea because other - // applications may not enocode non-ASCII characters in UTF-8. - // So the 4th parameter of net::FormatUrl() should be false. - // See crbug.com/2820. - WideToUTF8(net::FormatUrl( - url, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), - false, UnescapeRule::NONE, NULL, NULL)); - - WriteTextToClipboard(UTF8ToUTF16(utf8_text)); - DidWriteURLToClipboard(utf8_text); + net::WriteURLToClipboard( + url, + profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), + g_browser_process->clipboard()); } void RenderViewContextMenu::MediaPlayerActionAt( diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h index 8e0f199..82a1778 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.h +++ b/chrome/browser/tab_contents/render_view_context_menu.h @@ -58,10 +58,6 @@ class RenderViewContextMenu { // Finish creating the submenu and attach it to the main menu. virtual void FinishSubMenu() = 0; - // For Linux, we want to know when we have written a URL to the clipboard. - // Most platforms won't care. - virtual void DidWriteURLToClipboard(const std::string& url) { } - // Delegate functions -------------------------------------------------------- bool IsItemCommandEnabled(int id) const; @@ -99,7 +95,6 @@ class RenderViewContextMenu { void Inspect(int x, int y); // Writes the specified text/url to the system clipboard - void WriteTextToClipboard(const string16& text); void WriteURLToClipboard(const GURL& url); void MediaPlayerActionAt(int x, int y, const MediaPlayerAction& action); diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc index dcfdb74..70381be 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc +++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc @@ -94,15 +94,6 @@ void RenderViewContextMenuGtk::FinishSubMenu() { making_submenu_ = false; } -// When a URL is copied from a render view context menu (via "copy link -// location", for example), we additionally stick it in the X clipboard. This -// matches other linux browsers. -void RenderViewContextMenuGtk::DidWriteURLToClipboard( - const std::string& url) { - GtkClipboard* x_clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text(x_clipboard, url.c_str(), url.length()); -} - void RenderViewContextMenuGtk::AppendItem( int id, const string16& label, MenuItemType type) { MenuCreateMaterial menu_create_material = { diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.h b/chrome/browser/tab_contents/render_view_context_menu_gtk.h index d4fca48..8d7a5d0 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_gtk.h +++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.h @@ -47,7 +47,6 @@ class RenderViewContextMenuGtk : public RenderViewContextMenu, virtual void AppendSeparator(); virtual void StartSubMenu(int id, const string16& label); virtual void FinishSubMenu(); - virtual void DidWriteURLToClipboard(const std::string& url); private: void AppendItem(int id, const string16& label, MenuItemType type); diff --git a/net/base/net_util.cc b/net/base/net_util.cc index b8c8add..51cfdf7 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -33,6 +33,7 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/path_service.h" +#include "base/scoped_clipboard_writer.h" #include "base/singleton.h" #include "base/stl_util-inl.h" #include "base/string_escape.h" @@ -1330,6 +1331,23 @@ std::wstring FormatUrl(const GURL& url, return url_string; } +void WriteURLToClipboard(const GURL& url, + const std::wstring& languages, + Clipboard *clipboard) { + if (url.is_empty() || !url.is_valid() || !clipboard) + return; + + string16 text = + // Unescaping path and query is not a good idea because other + // applications may not encode non-ASCII characters in UTF-8. + // See crbug.com/2820. + WideToUTF16(FormatUrl(url, languages, false, UnescapeRule::NONE, NULL, + NULL)); + + ScopedClipboardWriter scw(clipboard); + scw.WriteURL(text); +} + GURL SimplifyUrlForRequest(const GURL& url) { DCHECK(url.is_valid()); GURL::Replacements replacements; diff --git a/net/base/net_util.h b/net/base/net_util.h index 4d7e0aa..7d6cf81 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -19,6 +19,7 @@ #include "net/base/escape.h" struct addrinfo; +class Clipboard; class FilePath; class GURL; @@ -239,6 +240,11 @@ inline std::wstring FormatUrl(const GURL& url, const std::wstring& languages) { return FormatUrl(url, languages, true, UnescapeRule::SPACES, NULL, NULL); } +// Writes a string representation of |url| to the system clipboard. +void WriteURLToClipboard(const GURL& url, + const std::wstring& languages, + Clipboard *clipboard); + // Strip the portions of |url| that aren't core to the network request. // - user name / password // - reference section |