Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: ios/chrome/browser/ui/omnibox/location_bar_view_ios.mm

Issue 2589803002: Upstream Chrome on iOS source code [6/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include <UIKit/UIKit.h>
6
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/macros.h"
10 #include "base/strings/string16.h"
11 #include "components/omnibox/browser/omnibox_edit_model.h"
12 #include "components/strings/grit/components_strings.h"
13 #include "components/toolbar/toolbar_model.h"
14 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
15 #include "ios/chrome/browser/chrome_url_constants.h"
16 #include "ios/chrome/browser/experimental_flags.h"
17 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
18 #include "ios/chrome/browser/ui/omnibox/location_bar_view_ios.h"
19 #import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
20 #include "ios/chrome/browser/ui/omnibox/omnibox_view_ios.h"
21 #include "ios/chrome/browser/ui/ui_util.h"
22 #import "ios/chrome/browser/ui/uikit_ui_util.h"
23 #include "ios/chrome/grit/ios_strings.h"
24 #include "ios/chrome/grit/ios_theme_resources.h"
25 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoF ontLoader.h"
26 #include "ios/web/public/navigation_item.h"
27 #include "ios/web/public/navigation_manager.h"
28 #include "ios/web/public/ssl_status.h"
29 #include "ios/web/public/web_state/web_state.h"
30 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/base/resource/resource_bundle.h"
32 #include "ui/gfx/geometry/rect.h"
33 #include "ui/gfx/image/image.h"
34
35 namespace {
36 const CGFloat kClearTextButtonWidth = 28;
37 const CGFloat kClearTextButtonHeight = 28;
38
39 // Workaround for https://crbug.com/527084 . If there is connection
40 // information, always show the icon. Remove this once connection info
41 // is available via other UI: https://crbug.com/533581
42 bool DoesCurrentPageHaveCertInfo(web::WebState* webState) {
43 if (!webState)
44 return false;
45 web::NavigationManager* navigationMangager = webState->GetNavigationManager();
46 if (!navigationMangager)
47 return false;
48 web::NavigationItem* visibleItem = navigationMangager->GetVisibleItem();
49 if (!visibleItem)
50 return false;
51
52 const web::SSLStatus& SSLStatus = visibleItem->GetSSL();
53 // Evaluation of |security_style| SSLStatus field in WKWebView based app is an
54 // asynchronous operation, so for a short period of time SSLStatus may have
55 // non-null certificate and SECURITY_STYLE_UNKNOWN |security_style|.
56 return SSLStatus.certificate &&
57 SSLStatus.security_style != web::SECURITY_STYLE_UNKNOWN;
58 }
59
60 // Returns whether the |webState| is presenting an offline page.
61 bool IsCurrentPageOffline(web::WebState* webState) {
62 if (!webState)
63 return false;
64 auto navigationManager = webState->GetNavigationManager();
65 auto visibleItem = navigationManager->GetVisibleItem();
66 if (!visibleItem)
67 return false;
68 const GURL& url = visibleItem->GetURL();
69 return url.SchemeIs(kChromeUIScheme) && url.host() == kChromeUIOfflineHost;
70 }
71
72 } // namespace
73
74 // An ObjC bridge class to allow taps on the clear button to be sent to a C++
75 // class.
76 @interface OmniboxClearButtonBridge : NSObject
77
78 - (instancetype)initWithOmniboxView:(OmniboxViewIOS*)omniboxView
79 NS_DESIGNATED_INITIALIZER;
80
81 - (instancetype)init NS_UNAVAILABLE;
82
83 - (void)clearText;
84
85 @end
86
87 @implementation OmniboxClearButtonBridge {
88 OmniboxViewIOS* _omniboxView;
89 }
90
91 - (instancetype)initWithOmniboxView:(OmniboxViewIOS*)omniboxView {
92 self = [super init];
93 if (self) {
94 _omniboxView = omniboxView;
95 }
96 return self;
97 }
98
99 - (instancetype)init {
100 NOTREACHED();
101 return nil;
102 }
103
104 - (void)clearText {
105 _omniboxView->ClearText();
106 }
107
108 @end
109
110 LocationBarViewIOS::LocationBarViewIOS(OmniboxTextFieldIOS* field,
111 ios::ChromeBrowserState* browser_state,
112 id<PreloadProvider> preloader,
113 id<OmniboxPopupPositioner> positioner,
114 id<LocationBarDelegate> delegate)
115 : edit_view_(new OmniboxViewIOS(field,
116 this,
117 browser_state,
118 preloader,
119 positioner)),
120 field_(field),
121 delegate_(delegate) {
122 DCHECK([delegate_ toolbarModel]);
123 show_hint_text_ = true;
124
125 InstallLocationIcon();
126 CreateClearTextIcon(browser_state->IsOffTheRecord());
127 }
128
129 LocationBarViewIOS::~LocationBarViewIOS() {}
130
131 void LocationBarViewIOS::HideKeyboardAndEndEditing() {
132 edit_view_->HideKeyboardAndEndEditing();
133 }
134
135 void LocationBarViewIOS::SetShouldShowHintText(bool show_hint_text) {
136 show_hint_text_ = show_hint_text;
137 }
138
139 const OmniboxView* LocationBarViewIOS::GetLocationEntry() const {
140 return edit_view_.get();
141 }
142
143 OmniboxView* LocationBarViewIOS::GetLocationEntry() {
144 return edit_view_.get();
145 }
146
147 void LocationBarViewIOS::OnToolbarUpdated() {
148 edit_view_->UpdateAppearance();
149 OnChanged();
150 }
151
152 void LocationBarViewIOS::OnAutocompleteAccept(
153 const GURL& gurl,
154 WindowOpenDisposition disposition,
155 ui::PageTransition transition,
156 AutocompleteMatchType::Type type) {
157 if (gurl.is_valid()) {
158 transition = ui::PageTransitionFromInt(
159 transition | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
160 [delegate_ loadGURLFromLocationBar:gurl transition:transition];
161 }
162 }
163
164 void LocationBarViewIOS::OnChanged() {
165 const bool page_is_offline = IsCurrentPageOffline(GetWebState());
166 const int resource_id = edit_view_->GetIcon(page_is_offline);
167 [field_ setPlaceholderImage:resource_id];
168
169 // TODO(rohitrao): Can we get focus information from somewhere other than the
170 // model?
171 if (!IsIPadIdiom() && !edit_view_->model()->has_focus()) {
172 ToolbarModel* toolbarModel = [delegate_ toolbarModel];
173 if (toolbarModel) {
174 bool page_is_secure =
175 toolbarModel->GetSecurityLevel(false) != security_state::NONE;
176 bool page_has_downgraded_HTTPS =
177 experimental_flags::IsPageIconForDowngradedHTTPSEnabled() &&
178 DoesCurrentPageHaveCertInfo(GetWebState());
179 if (page_is_secure || page_has_downgraded_HTTPS || page_is_offline) {
180 [field_ showPlaceholderImage];
181 is_showing_placeholder_while_collapsed_ = true;
182 } else {
183 [field_ hidePlaceholderImage];
184 is_showing_placeholder_while_collapsed_ = false;
185 }
186 }
187 }
188 UpdateRightDecorations();
189 [delegate_ locationBarChanged];
190
191 NSString* placeholderText =
192 show_hint_text_ ? l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT) : nil;
193 [field_ setPlaceholder:placeholderText];
194 }
195
196 bool LocationBarViewIOS::IsShowingPlaceholderWhileCollapsed() {
197 return is_showing_placeholder_while_collapsed_;
198 }
199
200 void LocationBarViewIOS::OnInputInProgress(bool in_progress) {
201 if ([delegate_ toolbarModel])
202 [delegate_ toolbarModel]->set_input_in_progress(in_progress);
203 if (in_progress)
204 [delegate_ locationBarBeganEdit];
205 }
206
207 void LocationBarViewIOS::OnKillFocus() {
208 // Hide the location icon on phone. A subsequent call to OnChanged() will
209 // bring the icon back if needed.
210 if (!IsIPadIdiom()) {
211 [field_ hidePlaceholderImage];
212 is_showing_placeholder_while_collapsed_ = false;
213 }
214
215 // Update the placeholder icon.
216 const int resource_id =
217 edit_view_->GetIcon(IsCurrentPageOffline(GetWebState()));
218 [field_ setPlaceholderImage:resource_id];
219
220 // Show the placeholder text on iPad.
221 if (IsIPadIdiom()) {
222 NSString* placeholderText = l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT);
223 [field_ setPlaceholder:placeholderText];
224 }
225
226 UpdateRightDecorations();
227 [delegate_ locationBarHasResignedFirstResponder];
228 }
229
230 void LocationBarViewIOS::OnSetFocus() {
231 // Show the location icon on phone.
232 if (!IsIPadIdiom())
233 [field_ showPlaceholderImage];
234
235 // Update the placeholder icon.
236 const int resource_id =
237 edit_view_->GetIcon(IsCurrentPageOffline(GetWebState()));
238 [field_ setPlaceholderImage:resource_id];
239
240 // Hide the placeholder text on iPad.
241 if (IsIPadIdiom()) {
242 [field_ setPlaceholder:nil];
243 }
244 UpdateRightDecorations();
245 [delegate_ locationBarHasBecomeFirstResponder];
246 }
247
248 const ToolbarModel* LocationBarViewIOS::GetToolbarModel() const {
249 return [delegate_ toolbarModel];
250 }
251
252 ToolbarModel* LocationBarViewIOS::GetToolbarModel() {
253 return [delegate_ toolbarModel];
254 }
255
256 web::WebState* LocationBarViewIOS::GetWebState() {
257 return [delegate_ getWebState];
258 }
259
260 void LocationBarViewIOS::InstallLocationIcon() {
261 // Set the placeholder for empty omnibox.
262 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
263 gfx::Image magImage = rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_SEARCH);
264 UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
265 UIImage* image = magImage.ToUIImage();
266 [button setImage:image forState:UIControlStateNormal];
267 [button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
268 [button addTarget:nil
269 action:@selector(chromeExecuteCommand:)
270 forControlEvents:UIControlEventTouchUpInside];
271 [button setTag:IDC_SHOW_PAGE_INFO];
272 SetA11yLabelAndUiAutomationName(
273 button, IDS_IOS_PAGE_INFO_SECURITY_BUTTON_ACCESSIBILITY_LABEL,
274 @"Page Security Info");
275 [button setIsAccessibilityElement:YES];
276
277 // Set chip text options.
278 [button setTitleColor:[UIColor colorWithWhite:0.631 alpha:1]
279 forState:UIControlStateNormal];
280 [button titleLabel].font =
281 [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:12];
282 [field_ setLeftView:button];
283
284 // The placeholder image is only shown when in edit mode on iPhone, and always
285 // shown on iPad.
286 if (IsIPadIdiom())
287 [field_ setLeftViewMode:UITextFieldViewModeAlways];
288 else
289 [field_ setLeftViewMode:UITextFieldViewModeNever];
290 }
291
292 void LocationBarViewIOS::CreateClearTextIcon(bool is_incognito) {
293 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
294 UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
295 UIImage* omniBoxClearImage =
296 is_incognito
297 ? rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_CLEAR_OTR).ToUIImage()
298 : rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_CLEAR).ToUIImage();
299 UIImage* omniBoxClearPressedImage =
300 is_incognito
301 ? rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_CLEAR_OTR_PRESSED)
302 .ToUIImage()
303 : rb.GetNativeImageNamed(IDR_IOS_OMNIBOX_CLEAR_PRESSED).ToUIImage();
304 [button setImage:omniBoxClearImage forState:UIControlStateNormal];
305 [button setImage:omniBoxClearPressedImage forState:UIControlStateHighlighted];
306
307 CGRect frame = CGRectZero;
308 frame.size = CGSizeMake(kClearTextButtonWidth, kClearTextButtonHeight);
309 [button setFrame:frame];
310
311 clear_button_bridge_.reset(
312 [[OmniboxClearButtonBridge alloc] initWithOmniboxView:edit_view_.get()]);
313 [button addTarget:clear_button_bridge_
314 action:@selector(clearText)
315 forControlEvents:UIControlEventTouchUpInside];
316 clear_text_button_.reset([button retain]);
317
318 SetA11yLabelAndUiAutomationName(clear_text_button_,
319 IDS_IOS_ACCNAME_CLEAR_TEXT, @"Clear Text");
320 }
321
322 void LocationBarViewIOS::UpdateRightDecorations() {
323 DCHECK(clear_text_button_);
324 if (!edit_view_->model()->has_focus()) {
325 // Do nothing for iPhone. The right view will be set to nil after the
326 // omnibox animation is completed.
327 if (IsIPadIdiom())
328 [field_ setRightView:nil];
329 } else if ([field_ displayedText].empty() &&
330 ![field_ isShowingQueryRefinementChip]) {
331 [field_ setRightView:nil];
332 } else {
333 [field_ setRightView:clear_text_button_];
334 [clear_text_button_ setAlpha:1];
335 }
336 }
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/omnibox/location_bar_view_ios.h ('k') | ios/chrome/browser/ui/omnibox/omnibox_popup_material_row.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698