summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-27 03:33:59 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-27 03:33:59 +0000
commit562b222ad53049a87f695e450e8698d3cb2aa1d6 (patch)
tree7ed368560ed1137f330bf1b3d98df84e95107cc8 /chrome
parent7ff213014f83fc4066fb80f7c4ca3993d81a6b37 (diff)
downloadchromium_src-562b222ad53049a87f695e450e8698d3cb2aa1d6.zip
chromium_src-562b222ad53049a87f695e450e8698d3cb2aa1d6.tar.gz
chromium_src-562b222ad53049a87f695e450e8698d3cb2aa1d6.tar.bz2
Tweaks to copy/paste of omnibox on windows:
. Makes copy prefix the text with http if the user hasn't edited the text, and the scheme is http but the text doesn't include http. . Makes copying use the url as the text if the user hasn't edited the text and it's http/https. . Makes control-insert/shift-insert use our copy/paste. BUG=41639 41489 41493 TEST=make sure copy/paste from the omnibox work sanely. Seriously though, see the three bugs for specifics. Review URL: http://codereview.chromium.org/1761002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45667 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit.cc41
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit.h11
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_unittest.cc124
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.cc48
-rw-r--r--chrome/chrome_tests.gypi1
5 files changed, 194 insertions, 31 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit.cc b/chrome/browser/autocomplete/autocomplete_edit.cc
index 9b0aefb..5d68e59 100644
--- a/chrome/browser/autocomplete/autocomplete_edit.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit.cc
@@ -7,6 +7,7 @@
#include <string>
#include "base/basictypes.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/autocomplete/autocomplete_classifier.h"
@@ -21,6 +22,7 @@
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/common/notification_service.h"
+#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
#include "googleurl/src/url_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -165,6 +167,45 @@ bool AutocompleteEditModel::GetURLForText(const std::wstring& text,
return true;
}
+void AutocompleteEditModel::AdjustTextForCopy(int sel_start,
+ bool is_all_selected,
+ std::wstring* text,
+ GURL* url,
+ bool* write_url) {
+ *write_url = false;
+
+ if (sel_start != 0)
+ return;
+
+ // We can't use CurrentTextIsURL() or GetDataForURLExport() because right now
+ // the user is probably holding down control to cause the copy, which will
+ // screw up our calculation of the desired_tld.
+ if (!GetURLForText(*text, url))
+ return; // Can't be parsed as a url, no need to adjust text.
+
+ if (!user_input_in_progress() && is_all_selected) {
+ *text = UTF8ToWide(url->spec());
+ *write_url = true;
+ return;
+ }
+
+ // Prefix the text with 'http://' if the text doesn't start with 'http://',
+ // the text parses as a url with a scheme of http, the user selected the
+ // entire host, and the user hasn't edited the host or manually removed the
+ // scheme.
+ if (url->SchemeIs(chrome::kHttpScheme)) {
+ std::wstring http = ASCIIToWide(chrome::kHttpScheme) +
+ ASCIIToWide(chrome::kStandardSchemeSeparator);
+ std::wstring host = UTF8ToWide(url->host());
+ if (text->compare(0, http.length(), http) != 0 &&
+ text->length() >= host.length() &&
+ permanent_text_.compare(0, host.length(), host) == 0) {
+ *text = http + *text;
+ *write_url = true;
+ }
+ }
+}
+
void AutocompleteEditModel::SetInputInProgress(bool in_progress) {
if (user_input_in_progress_ == in_progress)
return;
diff --git a/chrome/browser/autocomplete/autocomplete_edit.h b/chrome/browser/autocomplete/autocomplete_edit.h
index 9f4e973..66d6b98 100644
--- a/chrome/browser/autocomplete/autocomplete_edit.h
+++ b/chrome/browser/autocomplete/autocomplete_edit.h
@@ -147,6 +147,17 @@ class AutocompleteEditModel : public NotificationObserver {
// copy.
bool GetURLForText(const std::wstring& text, GURL* url) const;
+ // Invoked to adjust the text before writting to the clipboard for a copy
+ // (e.g. by adding 'http' to the front). |sel_start| gives the start of the
+ // selection. |text| is the currently selected text. If |is_all_selected| is
+ // true all the text in the edit is selected. If the url should be copied to
+ // the clipboard |write_url| is set to true and |url| set to the url to write.
+ void AdjustTextForCopy(int sel_start,
+ bool is_all_selected,
+ std::wstring* text,
+ GURL* url,
+ bool* write_url);
+
bool user_input_in_progress() const { return user_input_in_progress_; }
// Sets the state of user_input_in_progress_, and notifies the observer if
diff --git a/chrome/browser/autocomplete/autocomplete_edit_unittest.cc b/chrome/browser/autocomplete/autocomplete_edit_unittest.cc
new file mode 100644
index 0000000..8affff1
--- /dev/null
+++ b/chrome/browser/autocomplete/autocomplete_edit_unittest.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/autocomplete/autocomplete_edit.h"
+#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
+#include "chrome/test/testing_profile.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class TestingAutocompleteEditView : public AutocompleteEditView {
+ public:
+ TestingAutocompleteEditView() {}
+
+ virtual AutocompleteEditModel* model() { return NULL; }
+ virtual const AutocompleteEditModel* model() const { return NULL; }
+ virtual void SaveStateToTab(TabContents* tab) {}
+ virtual void Update(const TabContents* tab_for_state_restoring) {}
+ virtual void OpenURL(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url,
+ size_t selected_line,
+ const std::wstring& keyword) {}
+ virtual std::wstring GetText() const { return std::wstring(); }
+ virtual bool IsEditingOrEmpty() const { return true; }
+ virtual int GetIcon() const { return 0; }
+ virtual void SetUserText(const std::wstring& text) {}
+ virtual void SetUserText(const std::wstring& text,
+ const std::wstring& display_text,
+ bool update_popup) {}
+ virtual void SetWindowTextAndCaretPos(const std::wstring& text,
+ size_t caret_pos) {}
+ virtual void SetForcedQuery() {}
+ virtual bool IsSelectAll() { return false; }
+ virtual void SelectAll(bool reversed) {}
+ virtual void RevertAll() {}
+ virtual void UpdatePopup() {}
+ virtual void ClosePopup() {}
+ virtual void SetFocus() {}
+ virtual void OnTemporaryTextMaybeChanged(const std::wstring& display_text,
+ bool save_original_selection) {}
+ virtual bool OnInlineAutocompleteTextMaybeChanged(
+ const std::wstring& display_text, size_t user_text_length) {
+ return false;
+ }
+ virtual void OnRevertTemporaryText() {}
+ virtual void OnBeforePossibleChange() {}
+ virtual bool OnAfterPossibleChange() { return false; }
+ virtual gfx::NativeView GetNativeView() const { return 0; }
+ virtual CommandUpdater* GetCommandUpdater() { return NULL; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestingAutocompleteEditView);
+};
+
+class TestingAutocompleteEditController : public AutocompleteEditController {
+ public:
+ TestingAutocompleteEditController() {}
+ virtual void OnAutocompleteAccept(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url) {}
+ virtual void OnChanged() {}
+ virtual void OnInputInProgress(bool in_progress) {}
+ virtual void OnKillFocus() {}
+ virtual void OnSetFocus() {}
+ virtual SkBitmap GetFavIcon() const { return SkBitmap(); }
+ virtual std::wstring GetTitle() const { return std::wstring(); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestingAutocompleteEditController);
+};
+
+}
+
+typedef testing::Test AutocompleteEditTest;
+
+// Tests various permutations of AutocompleteModel::AdjustTextForCopy.
+TEST(AutocompleteEditTest, AdjustTextForCopy) {
+ struct Data {
+ const int sel_start;
+ const bool is_all_selected;
+ const wchar_t* input;
+ const wchar_t* expected_output;
+ const bool write_url;
+ const char* expected_url;
+ } input[] = {
+ // Test that http:// is inserted if all text is selected.
+ { 0, true, L"a.b/c", L"http://a.b/c", true, "http://a.b/c" },
+
+ // Test that http:// is inserted if the host is selected.
+ { 0, false, L"a.b/", L"http://a.b/", true, "http://a.b/" },
+
+ // Tests that http:// is inserted if the path is modified.
+ { 0, false, L"a.b/d", L"http://a.b/d", true, "http://a.b/d" },
+
+ // Tests that http:// isn't inserted if the host is modified.
+ { 0, false, L"a.c/", L"a.c/", false, "" },
+
+ // Tests that http:// isn't inserted if the start of the selection is 1.
+ { 1, false, L"a.b/", L"a.b/", false, "" },
+ };
+ TestingAutocompleteEditView view;
+ TestingAutocompleteEditController controller;
+ TestingProfile profile;
+ AutocompleteEditModel model(&view, &controller, &profile);
+
+ model.UpdatePermanentText(L"a.b/c");
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input); ++i) {
+ std::wstring result(input[i].input);
+ GURL url;
+ bool write_url;
+ model.AdjustTextForCopy(input[i].sel_start, input[i].is_all_selected,
+ &result, &url, &write_url);
+ EXPECT_EQ(input[i].expected_output, result) << "@: " << i;
+ EXPECT_EQ(input[i].write_url, write_url) << " @" << i;
+ if (write_url)
+ EXPECT_EQ(input[i].expected_url, url.spec()) << " @" << i;
+ }
+}
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
index 5a0632f..153354c 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
@@ -1167,36 +1167,21 @@ void AutocompleteEditViewWin::OnContextMenu(HWND window, const CPoint& point) {
}
void AutocompleteEditViewWin::OnCopy() {
- const std::wstring text(GetSelectedText());
+ std::wstring text(GetSelectedText());
if (text.empty())
return;
+ CHARRANGE sel;
+ GURL url;
+ bool write_url = false;
+ GetSel(sel);
+ model_->AdjustTextForCopy(sel.cpMin, IsSelectAll(), &text, &url, &write_url);
ScopedClipboardWriter scw(g_browser_process->clipboard());
- // Check if the user is copying the whole address bar. If they are, we
- // assume they are trying to copy a URL and write this to the clipboard as a
- // hyperlink.
- if (static_cast<int>(text.length()) >= GetTextLength()) {
- // The entire control is selected. Let's see what the user typed. We
- // can't use model_->CurrentTextIsURL() or model_->GetDataForURLExport()
- // because right now the user is probably holding down control to cause the
- // copy, which will screw up our calculation of the desired_tld.
- GURL url;
- if (model_->GetURLForText(text, &url)) {
- // If the scheme is http or https and the user isn't editing,
- // we should copy the true URL instead of the (unescaped) display
- // string to avoid encoding and escaping issues when pasting this text
- // elsewhere.
- if ((url.SchemeIs("http") || url.SchemeIs("https")) &&
- !model_->user_input_in_progress())
- scw.WriteText(UTF8ToWide(url.spec()));
- else
- scw.WriteText(text);
- scw.WriteBookmark(text, url.spec());
- scw.WriteHyperlink(EscapeForHTML(UTF16ToUTF8(text)), url.spec());
- return;
- }
- }
scw.WriteText(text);
+ if (write_url) {
+ scw.WriteBookmark(text, url.spec());
+ scw.WriteHyperlink(EscapeForHTML(UTF16ToUTF8(text)), url.spec());
+ }
}
void AutocompleteEditViewWin::OnCut() {
@@ -1794,10 +1779,10 @@ bool AutocompleteEditViewWin::OnKeyDownOnlyWritable(TCHAR key,
// Cut: Shift-Delete and Ctrl-x are treated as cut. Ctrl-Shift-Delete and
// Ctrl-Shift-x are not treated as cut even though the underlying
// CRichTextEdit would treat them as such.
- // Copy: Ctrl-c is treated as copy. Shift-Ctrl-c is not. (This is handled
- // in OnKeyDownAllModes().)
- // Paste: Shift-Insert and Ctrl-v are tread as paste. Ctrl-Shift-Insert and
- // Ctrl-Shift-v are not.
+ // Copy: Ctrl-Insert and Ctrl-c is treated as copy. Shift-Ctrl-c is not.
+ // (This is handled in OnKeyDownAllModes().)
+ // Paste: Shift-Insert and Ctrl-v are treated as paste. Ctrl-Shift-Insert
+ // and Ctrl-Shift-v are not.
//
// This behavior matches most, but not all Windows programs, and largely
// conforms to what users expect.
@@ -1897,15 +1882,16 @@ bool AutocompleteEditViewWin::OnKeyDownOnlyWritable(TCHAR key,
bool AutocompleteEditViewWin::OnKeyDownAllModes(TCHAR key,
UINT repeat_count,
UINT flags) {
- // See KF_ALTDOWN comment atop OnKeyDownOnlyWriteable().
+ // See KF_ALTDOWN comment atop OnKeyDownOnlyWritable().
switch (key) {
case VK_CONTROL:
model_->OnControlKeyChanged(true);
return false;
+ case VK_INSERT:
case 'C':
- // See more detailed comments in OnKeyDownOnlyWriteable().
+ // See more detailed comments in OnKeyDownOnlyWritable().
if ((flags & KF_ALTDOWN) || (GetKeyState(VK_CONTROL) >= 0))
return false;
if (GetKeyState(VK_SHIFT) >= 0)
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index f8d15b3..ccfe83d 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -545,6 +545,7 @@
# All unittests in browser, common, and renderer.
'browser/app_controller_mac_unittest.mm',
'browser/app_menu_model_unittest.cc',
+ 'browser/autocomplete/autocomplete_edit_unittest.cc',
'browser/autocomplete/autocomplete_edit_view_mac_unittest.mm',
'browser/autocomplete/autocomplete_unittest.cc',
'browser/autocomplete/autocomplete_popup_view_mac_unittest.mm',