summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 21:42:14 +0000
committerericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 21:42:14 +0000
commit0c4c3884b89e0c5fb3adbbb0f3cdf092cda84a10 (patch)
treee942cc54be97b815ae60fdd7bbd65a2aa624d843
parent2ef2712ec860306a843c0e18afbdc339da4917cd (diff)
downloadchromium_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.h9
-rw-r--r--base/clipboard_linux.cc8
-rw-r--r--base/clipboard_unittest.cc30
-rw-r--r--base/scoped_clipboard_writer.cc36
-rw-r--r--base/scoped_clipboard_writer.h12
-rw-r--r--chrome/browser/browser.cc22
-rw-r--r--chrome/browser/browser.h1
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc25
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.h5
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_gtk.cc9
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_gtk.h1
-rw-r--r--net/base/net_util.cc18
-rw-r--r--net/base/net_util.h6
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