Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / omnibox / omnibox_view.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This file defines helper functions shared by the various implementations
6 // of OmniboxView.
7
8 #include "chrome/browser/ui/omnibox/omnibox_view.h"
9
10 #include "base/strings/string16.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/search/search.h"
14 #include "chrome/browser/search_engines/template_url_service_factory.h"
15 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
16 #include "chrome/browser/ui/toolbar/toolbar_model.h"
17 #include "chrome/grit/generated_resources.h"
18 #include "components/omnibox/autocomplete_match.h"
19 #include "components/search_engines/template_url.h"
20 #include "components/search_engines/template_url_service.h"
21 #include "grit/components_scaled_resources.h"
22 #include "grit/theme_resources.h"
23 #include "ui/base/clipboard/clipboard.h"
24 #include "ui/base/l10n/l10n_util.h"
25
26 // static
27 base::string16 OmniboxView::StripJavascriptSchemas(const base::string16& text) {
28   const base::string16 kJsPrefix(
29       base::ASCIIToUTF16(url::kJavaScriptScheme) + base::ASCIIToUTF16(":"));
30   base::string16 out(text);
31   while (StartsWith(out, kJsPrefix, false)) {
32     base::TrimWhitespace(out.substr(kJsPrefix.length()), base::TRIM_LEADING,
33                          &out);
34   }
35   return out;
36 }
37
38 // static
39 base::string16 OmniboxView::SanitizeTextForPaste(const base::string16& text) {
40   // Check for non-newline whitespace; if found, collapse whitespace runs down
41   // to single spaces.
42   // TODO(shess): It may also make sense to ignore leading or
43   // trailing whitespace when making this determination.
44   for (size_t i = 0; i < text.size(); ++i) {
45     if (IsWhitespace(text[i]) && text[i] != '\n' && text[i] != '\r') {
46       const base::string16 collapsed = base::CollapseWhitespace(text, false);
47       // If the user is pasting all-whitespace, paste a single space
48       // rather than nothing, since pasting nothing feels broken.
49       return collapsed.empty() ?
50           base::ASCIIToUTF16(" ") : StripJavascriptSchemas(collapsed);
51     }
52   }
53
54   // Otherwise, all whitespace is newlines; remove it entirely.
55   return StripJavascriptSchemas(base::CollapseWhitespace(text, true));
56 }
57
58 // static
59 base::string16 OmniboxView::GetClipboardText() {
60   // Try text format.
61   ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
62   if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
63                                    ui::CLIPBOARD_TYPE_COPY_PASTE)) {
64     base::string16 text;
65     clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &text);
66     return SanitizeTextForPaste(text);
67   }
68
69   // Try bookmark format.
70   //
71   // It is tempting to try bookmark format first, but the URL we get out of a
72   // bookmark has been cannonicalized via GURL.  This means if a user copies
73   // and pastes from the URL bar to itself, the text will get fixed up and
74   // cannonicalized, which is not what the user expects.  By pasting in this
75   // order, we are sure to paste what the user copied.
76   if (clipboard->IsFormatAvailable(ui::Clipboard::GetUrlWFormatType(),
77                                    ui::CLIPBOARD_TYPE_COPY_PASTE)) {
78     std::string url_str;
79     clipboard->ReadBookmark(NULL, &url_str);
80     // pass resulting url string through GURL to normalize
81     GURL url(url_str);
82     if (url.is_valid())
83       return StripJavascriptSchemas(base::UTF8ToUTF16(url.spec()));
84   }
85
86   return base::string16();
87 }
88
89 OmniboxView::~OmniboxView() {
90 }
91
92 void OmniboxView::HandleOriginChipMouseRelease() {
93   // Only hide if there isn't any current text in the Omnibox (e.g. search
94   // terms).
95   if (controller()->GetToolbarModel()->GetText().empty())
96     controller()->HideOriginChip();
97 }
98
99 void OmniboxView::OnDidKillFocus() {
100   if (chrome::ShouldDisplayOriginChip() && !model()->user_input_in_progress())
101     controller()->ShowOriginChip();
102 }
103
104 void OmniboxView::OpenMatch(const AutocompleteMatch& match,
105                             WindowOpenDisposition disposition,
106                             const GURL& alternate_nav_url,
107                             const base::string16& pasted_text,
108                             size_t selected_line) {
109   // Invalid URLs such as chrome://history can end up here.
110   if (!match.destination_url.is_valid() || !model_)
111     return;
112   model_->OpenMatch(
113       match, disposition, alternate_nav_url, pasted_text, selected_line);
114   OnMatchOpened(match, controller_->GetWebContents());
115 }
116
117 bool OmniboxView::IsEditingOrEmpty() const {
118   return (model_.get() && model_->user_input_in_progress()) ||
119       (GetOmniboxTextLength() == 0);
120 }
121
122 int OmniboxView::GetIcon() const {
123   if (!IsEditingOrEmpty())
124     return controller_->GetToolbarModel()->GetIcon();
125   int id = AutocompleteMatch::TypeToIcon(model_.get() ?
126       model_->CurrentTextType() : AutocompleteMatchType::URL_WHAT_YOU_TYPED);
127   return (id == IDR_OMNIBOX_HTTP) ? IDR_LOCATION_BAR_HTTP : id;
128 }
129
130 base::string16 OmniboxView::GetHintText() const {
131   // If the user is in keyword mode (the "Search <some site>:" chip is showing)
132   // then it doesn't make sense to show the "Search <default search engine>"
133   // hint text.
134   if (model_->is_keyword_selected())
135     return base::string16();
136
137   // Attempt to determine the default search provider and use that in the hint
138   // text.
139   TemplateURLService* template_url_service =
140       TemplateURLServiceFactory::GetForProfile(model_->profile());
141   if (template_url_service) {
142     TemplateURL* template_url =
143         template_url_service->GetDefaultSearchProvider();
144     if (template_url)
145       return l10n_util::GetStringFUTF16(
146           IDS_OMNIBOX_EMPTY_HINT_WITH_DEFAULT_SEARCH_PROVIDER,
147           template_url->AdjustedShortNameForLocaleDirection());
148   }
149
150   // Otherwise return a hint based on there being no default search provider.
151   return l10n_util::GetStringUTF16(
152       IDS_OMNIBOX_EMPTY_HINT_NO_DEFAULT_SEARCH_PROVIDER);
153 }
154
155 void OmniboxView::SetUserText(const base::string16& text) {
156   SetUserText(text, text, true);
157 }
158
159 void OmniboxView::SetUserText(const base::string16& text,
160                               const base::string16& display_text,
161                               bool update_popup) {
162   if (model_.get())
163     model_->SetUserText(text);
164   SetWindowTextAndCaretPos(display_text, display_text.length(), update_popup,
165                            true);
166 }
167
168 void OmniboxView::ShowURL() {
169   SetFocus();
170   controller_->GetToolbarModel()->set_origin_chip_enabled(false);
171   controller_->GetToolbarModel()->set_url_replacement_enabled(false);
172   model_->UpdatePermanentText();
173   RevertWithoutResettingSearchTermReplacement();
174   SelectAll(true);
175 }
176
177 void OmniboxView::HideURL() {
178   controller_->GetToolbarModel()->set_origin_chip_enabled(true);
179   controller_->GetToolbarModel()->set_url_replacement_enabled(true);
180   model_->UpdatePermanentText();
181   RevertWithoutResettingSearchTermReplacement();
182 }
183
184 void OmniboxView::RevertAll() {
185   controller_->GetToolbarModel()->set_origin_chip_enabled(true);
186   controller_->GetToolbarModel()->set_url_replacement_enabled(true);
187   RevertWithoutResettingSearchTermReplacement();
188 }
189
190 void OmniboxView::RevertWithoutResettingSearchTermReplacement() {
191   CloseOmniboxPopup();
192   if (model_.get())
193     model_->Revert();
194   TextChanged();
195 }
196
197 void OmniboxView::CloseOmniboxPopup() {
198   if (model_.get())
199     model_->StopAutocomplete();
200 }
201
202 bool OmniboxView::IsImeShowingPopup() const {
203   // Default to claiming that the IME is not showing a popup, since hiding the
204   // omnibox dropdown is a bad user experience when we don't know for sure that
205   // we have to.
206   return false;
207 }
208
209 void OmniboxView::ShowImeIfNeeded() {
210 }
211
212 bool OmniboxView::IsIndicatingQueryRefinement() const {
213   // The default implementation always returns false.  Mobile ports can override
214   // this method and implement as needed.
215   return false;
216 }
217
218 void OmniboxView::OnMatchOpened(const AutocompleteMatch& match,
219                                 content::WebContents* web_contents) {
220 }
221
222 OmniboxView::OmniboxView(Profile* profile,
223                          OmniboxEditController* controller,
224                          CommandUpdater* command_updater)
225     : controller_(controller),
226       command_updater_(command_updater) {
227   // |profile| can be NULL in tests.
228   if (profile)
229     model_.reset(new OmniboxEditModel(this, controller, profile));
230 }
231
232 void OmniboxView::TextChanged() {
233   EmphasizeURLComponents();
234   if (model_.get())
235     model_->OnChanged();
236 }