Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / location_bar / location_bar_view_mac.mm
blob3417aa77227ed47eeaa62d5e80332d1840949ade
1 // Copyright 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.
5 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/stl_util.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/sys_string_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/app/chrome_command_ids.h"
16 #import "chrome/browser/app_controller_mac.h"
17 #include "chrome/browser/command_updater.h"
18 #include "chrome/browser/defaults.h"
19 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
20 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
21 #include "chrome/browser/extensions/extension_action.h"
22 #include "chrome/browser/extensions/location_bar_controller.h"
23 #include "chrome/browser/extensions/tab_helper.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/search/instant_service.h"
26 #include "chrome/browser/search/instant_service_factory.h"
27 #include "chrome/browser/search/search.h"
28 #include "chrome/browser/search_engines/template_url_service_factory.h"
29 #include "chrome/browser/translate/chrome_translate_client.h"
30 #include "chrome/browser/translate/translate_service.h"
31 #include "chrome/browser/ui/browser_list.h"
32 #import "chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h"
33 #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
34 #import "chrome/browser/ui/cocoa/first_run_bubble_controller.h"
35 #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h"
36 #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell.h"
37 #import "chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h"
38 #import "chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h"
39 #import "chrome/browser/ui/cocoa/location_bar/keyword_hint_decoration.h"
40 #import "chrome/browser/ui/cocoa/location_bar/location_icon_decoration.h"
41 #import "chrome/browser/ui/cocoa/location_bar/manage_passwords_decoration.h"
42 #import "chrome/browser/ui/cocoa/location_bar/mic_search_decoration.h"
43 #import "chrome/browser/ui/cocoa/location_bar/page_action_decoration.h"
44 #import "chrome/browser/ui/cocoa/location_bar/selected_keyword_decoration.h"
45 #import "chrome/browser/ui/cocoa/location_bar/star_decoration.h"
46 #import "chrome/browser/ui/cocoa/location_bar/translate_decoration.h"
47 #import "chrome/browser/ui/cocoa/location_bar/zoom_decoration.h"
48 #import "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
49 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
50 #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
51 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
52 #include "chrome/browser/ui/tabs/tab_strip_model.h"
53 #include "chrome/browser/ui/toolbar/chrome_toolbar_model.h"
54 #include "chrome/common/chrome_switches.h"
55 #include "chrome/common/pref_names.h"
56 #import "components/omnibox/browser/omnibox_popup_model.h"
57 #include "components/search_engines/template_url.h"
58 #include "components/search_engines/template_url_service.h"
59 #include "components/translate/core/browser/language_state.h"
60 #include "components/ui/zoom/zoom_controller.h"
61 #include "components/ui/zoom/zoom_event_manager.h"
62 #include "content/public/browser/web_contents.h"
63 #include "extensions/browser/extension_system.h"
64 #include "extensions/common/extension.h"
65 #include "grit/components_scaled_resources.h"
66 #include "grit/theme_resources.h"
67 #include "net/base/net_util.h"
68 #include "skia/ext/skia_utils_mac.h"
69 #import "ui/base/cocoa/cocoa_base_utils.h"
70 #include "ui/base/l10n/l10n_util_mac.h"
71 #include "ui/gfx/image/image.h"
73 using content::WebContents;
75 namespace {
77 // Vertical space between the bottom edge of the location_bar and the first run
78 // bubble arrow point.
79 const static int kFirstRunBubbleYOffset = 1;
81 }  // namespace
83 // TODO(shess): This code is mostly copied from the gtk
84 // implementation.  Make sure it's all appropriate and flesh it out.
86 LocationBarViewMac::LocationBarViewMac(AutocompleteTextField* field,
87                                        CommandUpdater* command_updater,
88                                        Profile* profile,
89                                        Browser* browser)
90     : LocationBar(profile),
91       ChromeOmniboxEditController(command_updater),
92       omnibox_view_(new OmniboxViewMac(this, profile, command_updater, field)),
93       field_(field),
94       location_icon_decoration_(new LocationIconDecoration(this)),
95       selected_keyword_decoration_(new SelectedKeywordDecoration()),
96       ev_bubble_decoration_(
97           new EVBubbleDecoration(location_icon_decoration_.get())),
98       star_decoration_(new StarDecoration(command_updater)),
99       translate_decoration_(new TranslateDecoration(command_updater)),
100       zoom_decoration_(new ZoomDecoration(this)),
101       keyword_hint_decoration_(new KeywordHintDecoration()),
102       mic_search_decoration_(new MicSearchDecoration(command_updater)),
103       manage_passwords_decoration_(
104           new ManagePasswordsDecoration(command_updater, this)),
105       browser_(browser),
106       weak_ptr_factory_(this) {
107   for (ContentSettingsType type :
108        ContentSettingBubbleModel::GetSupportedBubbleTypes()) {
109     content_setting_decorations_.push_back(
110         new ContentSettingDecoration(type, this, profile));
111   }
113   edit_bookmarks_enabled_.Init(
114       bookmarks::prefs::kEditBookmarksEnabled, profile->GetPrefs(),
115       base::Bind(&LocationBarViewMac::OnEditBookmarksEnabledChanged,
116                  base::Unretained(this)));
118   browser_->search_model()->AddObserver(this);
120   ui_zoom::ZoomEventManager::GetForBrowserContext(profile)
121       ->AddZoomEventManagerObserver(this);
123   [[field_ cell] setIsPopupMode:
124       !browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)];
126   // Sets images for the decorations, and performs a layout. This call ensures
127   // that this class is in a consistent state after initialization.
128   OnChanged();
131 LocationBarViewMac::~LocationBarViewMac() {
132   // Disconnect from cell in case it outlives us.
133   [[field_ cell] clearDecorations];
135   browser_->search_model()->RemoveObserver(this);
136   ui_zoom::ZoomEventManager::GetForBrowserContext(profile())
137       ->RemoveZoomEventManagerObserver(this);
140 void LocationBarViewMac::ShowFirstRunBubble() {
141   // We need the browser window to be shown before we can show the bubble, but
142   // we get called before that's happened.
143   base::MessageLoop::current()->PostTask(
144       FROM_HERE, base::Bind(&LocationBarViewMac::ShowFirstRunBubbleInternal,
145                             weak_ptr_factory_.GetWeakPtr()));
148 GURL LocationBarViewMac::GetDestinationURL() const {
149   return destination_url();
152 WindowOpenDisposition LocationBarViewMac::GetWindowOpenDisposition() const {
153   return disposition();
156 ui::PageTransition LocationBarViewMac::GetPageTransition() const {
157   return transition();
160 void LocationBarViewMac::AcceptInput() {
161   WindowOpenDisposition disposition =
162       ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
163   omnibox_view_->model()->AcceptInput(disposition, false);
166 void LocationBarViewMac::FocusLocation(bool select_all) {
167   omnibox_view_->FocusLocation(select_all);
170 void LocationBarViewMac::FocusSearch() {
171   omnibox_view_->SetForcedQuery();
174 void LocationBarViewMac::UpdateContentSettingsIcons() {
175   if (RefreshContentSettingsDecorations())
176     OnDecorationsChanged();
179 void LocationBarViewMac::UpdateManagePasswordsIconAndBubble() {
180   WebContents* web_contents = GetWebContents();
181   if (!web_contents)
182     return;
183   ManagePasswordsUIController::FromWebContents(web_contents)
184       ->UpdateIconAndBubbleState(manage_passwords_decoration_->icon());
185   OnDecorationsChanged();
188 void LocationBarViewMac::UpdatePageActions() {
189   RefreshPageActionDecorations();
190   Layout();
192   [field_ updateMouseTracking];
193   [field_ setNeedsDisplay:YES];
196 void LocationBarViewMac::UpdateBookmarkStarVisibility() {
197   star_decoration_->SetVisible(IsStarEnabled());
200 void LocationBarViewMac::UpdateLocationBarVisibility(bool visible,
201                                                      bool animate) {
202   // Not implemented on Mac.
205 bool LocationBarViewMac::ShowPageActionPopup(
206     const extensions::Extension* extension, bool grant_active_tab) {
207   for (ScopedVector<PageActionDecoration>::iterator iter =
208            page_action_decorations_.begin();
209        iter != page_action_decorations_.end(); ++iter) {
210     if ((*iter)->GetExtension() == extension)
211       return (*iter)->ActivatePageAction(grant_active_tab);
212   }
213   return false;
216 void LocationBarViewMac::UpdateOpenPDFInReaderPrompt() {
217   // Not implemented on Mac.
220 void LocationBarViewMac::SaveStateToContents(WebContents* contents) {
221   // TODO(shess): Why SaveStateToContents vs SaveStateToTab?
222   omnibox_view_->SaveStateToTab(contents);
225 void LocationBarViewMac::Revert() {
226   omnibox_view_->RevertAll();
229 const OmniboxView* LocationBarViewMac::GetOmniboxView() const {
230   return omnibox_view_.get();
233 OmniboxView* LocationBarViewMac::GetOmniboxView() {
234   return omnibox_view_.get();
237 LocationBarTesting* LocationBarViewMac::GetLocationBarForTesting() {
238   return this;
241 // TODO(pamg): Change all these, here and for other platforms, to size_t.
242 int LocationBarViewMac::PageActionCount() {
243   return static_cast<int>(page_action_decorations_.size());
246 int LocationBarViewMac::PageActionVisibleCount() {
247   int result = 0;
248   for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
249     if (page_action_decorations_[i]->IsVisible())
250       ++result;
251   }
252   return result;
255 ExtensionAction* LocationBarViewMac::GetPageAction(size_t index) {
256   if (index < page_action_decorations_.size())
257     return page_action_decorations_[index]->GetPageAction();
258   NOTREACHED();
259   return NULL;
262 ExtensionAction* LocationBarViewMac::GetVisiblePageAction(size_t index) {
263   size_t current = 0;
264   for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
265     if (page_action_decorations_[i]->IsVisible()) {
266       if (current == index)
267         return page_action_decorations_[i]->GetPageAction();
269       ++current;
270     }
271   }
273   NOTREACHED();
274   return NULL;
277 void LocationBarViewMac::TestPageActionPressed(size_t index) {
278   DCHECK_LT(index, static_cast<size_t>(PageActionVisibleCount()));
279   size_t current = 0;
280   for (PageActionDecoration* decoration : page_action_decorations_) {
281     if (decoration->IsVisible()) {
282       if (current == index) {
283         decoration->OnMousePressed(NSZeroRect, NSZeroPoint);
284         return;
285       }
286       ++current;
287     }
288   }
291 bool LocationBarViewMac::GetBookmarkStarVisibility() {
292   DCHECK(star_decoration_.get());
293   return star_decoration_->IsVisible();
296 void LocationBarViewMac::SetEditable(bool editable) {
297   [field_ setEditable:editable ? YES : NO];
298   UpdateBookmarkStarVisibility();
299   UpdateZoomDecoration(/*default_zoom_changed=*/false);
300   UpdatePageActions();
301   Layout();
304 bool LocationBarViewMac::IsEditable() {
305   return [field_ isEditable] ? true : false;
308 void LocationBarViewMac::SetStarred(bool starred) {
309   if (star_decoration_->starred() == starred)
310     return;
312   star_decoration_->SetStarred(starred);
313   UpdateBookmarkStarVisibility();
314   OnDecorationsChanged();
317 void LocationBarViewMac::SetTranslateIconLit(bool on) {
318   translate_decoration_->SetLit(on);
319   OnDecorationsChanged();
322 void LocationBarViewMac::ZoomChangedForActiveTab(bool can_show_bubble) {
323   bool changed = UpdateZoomDecoration(/*default_zoom_changed=*/false);
324   if (changed)
325     OnDecorationsChanged();
327   if (can_show_bubble && zoom_decoration_->IsVisible())
328     zoom_decoration_->ShowBubble(YES);
331 bool LocationBarViewMac::IsStarEnabled() const {
332   return browser_defaults::bookmarks_enabled &&
333          [field_ isEditable] &&
334          !GetToolbarModel()->input_in_progress() &&
335          edit_bookmarks_enabled_.GetValue() &&
336          !IsBookmarkStarHiddenByExtension();
339 NSPoint LocationBarViewMac::GetBookmarkBubblePoint() const {
340   DCHECK(IsStarEnabled());
341   return [field_ bubblePointForDecoration:star_decoration_.get()];
344 NSPoint LocationBarViewMac::GetTranslateBubblePoint() const {
345   return [field_ bubblePointForDecoration:translate_decoration_.get()];
348 NSPoint LocationBarViewMac::GetManagePasswordsBubblePoint() const {
349   return [field_ bubblePointForDecoration:manage_passwords_decoration_.get()];
352 NSPoint LocationBarViewMac::GetPageInfoBubblePoint() const {
353   if (ev_bubble_decoration_->IsVisible()) {
354     return [field_ bubblePointForDecoration:ev_bubble_decoration_.get()];
355   } else {
356     return [field_ bubblePointForDecoration:location_icon_decoration_.get()];
357   }
360 void LocationBarViewMac::OnDecorationsChanged() {
361   // TODO(shess): The field-editor frame and cursor rects should not
362   // change, here.
363   [field_ updateMouseTracking];
364   [field_ resetFieldEditorFrameIfNeeded];
365   [field_ setNeedsDisplay:YES];
368 // TODO(shess): This function should over time grow to closely match
369 // the views Layout() function.
370 void LocationBarViewMac::Layout() {
371   AutocompleteTextFieldCell* cell = [field_ cell];
373   // Reset the left-hand decorations.
374   // TODO(shess): Shortly, this code will live somewhere else, like in
375   // the constructor.  I am still wrestling with how best to deal with
376   // right-hand decorations, which are not a static set.
377   [cell clearDecorations];
378   [cell addLeftDecoration:location_icon_decoration_.get()];
379   [cell addLeftDecoration:selected_keyword_decoration_.get()];
380   [cell addLeftDecoration:ev_bubble_decoration_.get()];
381   [cell addRightDecoration:star_decoration_.get()];
382   [cell addRightDecoration:translate_decoration_.get()];
383   [cell addRightDecoration:zoom_decoration_.get()];
384   [cell addRightDecoration:manage_passwords_decoration_.get()];
386   // Note that display order is right to left.
387   for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
388     [cell addRightDecoration:page_action_decorations_[i]];
389   }
391   for (ScopedVector<ContentSettingDecoration>::iterator i =
392        content_setting_decorations_.begin();
393        i != content_setting_decorations_.end(); ++i) {
394     [cell addRightDecoration:*i];
395   }
397   [cell addRightDecoration:keyword_hint_decoration_.get()];
398   [cell addRightDecoration:mic_search_decoration_.get()];
400   // By default only the location icon is visible.
401   location_icon_decoration_->SetVisible(true);
402   selected_keyword_decoration_->SetVisible(false);
403   ev_bubble_decoration_->SetVisible(false);
404   keyword_hint_decoration_->SetVisible(false);
406   // Get the keyword to use for keyword-search and hinting.
407   const base::string16 keyword = omnibox_view_->model()->keyword();
408   base::string16 short_name;
409   bool is_extension_keyword = false;
410   if (!keyword.empty()) {
411     short_name = TemplateURLServiceFactory::GetForProfile(profile())->
412         GetKeywordShortName(keyword, &is_extension_keyword);
413   }
415   const bool is_keyword_hint = omnibox_view_->model()->is_keyword_hint();
416   ChromeToolbarModel* chrome_toolbar_model =
417       static_cast<ChromeToolbarModel*>(GetToolbarModel());
418   if (!keyword.empty() && !is_keyword_hint) {
419     // Switch from location icon to keyword mode.
420     location_icon_decoration_->SetVisible(false);
421     selected_keyword_decoration_->SetVisible(true);
422     selected_keyword_decoration_->SetKeyword(short_name, is_extension_keyword);
423     selected_keyword_decoration_->SetImage(GetKeywordImage(keyword));
424   } else if (chrome_toolbar_model->GetSecurityLevel(false) ==
425              SecurityStateModel::EV_SECURE) {
426     // Switch from location icon to show the EV bubble instead.
427     location_icon_decoration_->SetVisible(false);
428     ev_bubble_decoration_->SetVisible(true);
430     base::string16 label(GetToolbarModel()->GetEVCertName());
431     ev_bubble_decoration_->SetFullLabel(base::SysUTF16ToNSString(label));
432   } else if (!keyword.empty() && is_keyword_hint) {
433     keyword_hint_decoration_->SetKeyword(short_name,
434                                          is_extension_keyword);
435     keyword_hint_decoration_->SetVisible(true);
436   }
438   // These need to change anytime the layout changes.
439   // TODO(shess): Anytime the field editor might have changed, the
440   // cursor rects almost certainly should have changed.  The tooltips
441   // might change even when the rects don't change.
442   OnDecorationsChanged();
445 void LocationBarViewMac::RedrawDecoration(LocationBarDecoration* decoration) {
446   AutocompleteTextFieldCell* cell = [field_ cell];
447   NSRect frame = [cell frameForDecoration:decoration
448                                   inFrame:[field_ bounds]];
449   if (!NSIsEmptyRect(frame))
450     [field_ setNeedsDisplayInRect:frame];
453 void LocationBarViewMac::SetPreviewEnabledPageAction(
454     ExtensionAction* page_action, bool preview_enabled) {
455   DCHECK(page_action);
456   WebContents* contents = GetWebContents();
457   if (!contents)
458     return;
459   RefreshPageActionDecorations();
460   Layout();
462   PageActionDecoration* decoration = GetPageActionDecoration(page_action);
463   DCHECK(decoration);
464   if (!decoration)
465     return;
467   decoration->set_preview_enabled(preview_enabled);
468   decoration->UpdateVisibility(contents);
471 NSRect LocationBarViewMac::GetPageActionFrame(ExtensionAction* page_action) {
472   PageActionDecoration* decoration = GetPageActionDecoration(page_action);
473   if (!decoration)
474     return NSZeroRect;
476   AutocompleteTextFieldCell* cell = [field_ cell];
477   NSRect frame = [cell frameForDecoration:decoration inFrame:[field_ bounds]];
478   return frame;
481 NSPoint LocationBarViewMac::GetPageActionBubblePoint(
482     ExtensionAction* page_action) {
483   PageActionDecoration* decoration = GetPageActionDecoration(page_action);
484   if (!decoration)
485     return NSZeroPoint;
487   NSRect frame = GetPageActionFrame(page_action);
488   if (NSIsEmptyRect(frame)) {
489     // The bubble point positioning assumes that the page action is visible. If
490     // not, something else needs to be done otherwise the bubble will appear
491     // near the top left corner (unanchored).
492     NOTREACHED();
493     return NSZeroPoint;
494   }
496   NSPoint bubble_point = decoration->GetBubblePointInFrame(frame);
497   return [field_ convertPoint:bubble_point toView:nil];
500 void LocationBarViewMac::ResetTabState(WebContents* contents) {
501   omnibox_view_->ResetTabState(contents);
504 void LocationBarViewMac::Update(const WebContents* contents) {
505   UpdateManagePasswordsIconAndBubble();
506   UpdateBookmarkStarVisibility();
507   UpdateTranslateDecoration();
508   UpdateZoomDecoration(/*default_zoom_changed=*/false);
509   RefreshPageActionDecorations();
510   RefreshContentSettingsDecorations();
511   UpdateMicSearchDecorationVisibility();
512   if (contents)
513     omnibox_view_->OnTabChanged(contents);
514   else
515     omnibox_view_->Update();
516   OnChanged();
519 void LocationBarViewMac::UpdateWithoutTabRestore() {
520   Update(nullptr);
523 void LocationBarViewMac::OnChanged() {
524   // Update the location-bar icon.
525   const int resource_id = omnibox_view_->GetIcon();
526   NSImage* image = OmniboxViewMac::ImageForResource(resource_id);
527   location_icon_decoration_->SetImage(image);
528   ev_bubble_decoration_->SetImage(image);
529   Layout();
531   InstantService* instant_service =
532       InstantServiceFactory::GetForProfile(profile());
533   if (instant_service) {
534     gfx::Rect bounds(NSRectToCGRect([field_ frame]));
535     instant_service->OnOmniboxStartMarginChanged(bounds.x());
536   }
539 void LocationBarViewMac::OnSetFocus() {
540   // Update the keyword and search hint states.
541   OnChanged();
544 void LocationBarViewMac::ShowURL() {
545   omnibox_view_->ShowURL();
548 ToolbarModel* LocationBarViewMac::GetToolbarModel() {
549   return browser_->toolbar_model();
552 const ToolbarModel* LocationBarViewMac::GetToolbarModel() const {
553   return browser_->toolbar_model();
556 WebContents* LocationBarViewMac::GetWebContents() {
557   return browser_->tab_strip_model()->GetActiveWebContents();
560 NSImage* LocationBarViewMac::GetKeywordImage(const base::string16& keyword) {
561   const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(
562       profile())->GetTemplateURLForKeyword(keyword);
563   if (template_url &&
564       (template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION)) {
565     return extensions::OmniboxAPI::Get(profile())->
566         GetOmniboxIcon(template_url->GetExtensionId()).AsNSImage();
567   }
569   return OmniboxViewMac::ImageForResource(IDR_OMNIBOX_SEARCH);
572 void LocationBarViewMac::ModelChanged(const SearchModel::State& old_state,
573                                       const SearchModel::State& new_state) {
574   if (UpdateMicSearchDecorationVisibility())
575     Layout();
578 void LocationBarViewMac::PostNotification(NSString* notification) {
579   [[NSNotificationCenter defaultCenter] postNotificationName:notification
580                                         object:[NSValue valueWithPointer:this]];
583 PageActionDecoration* LocationBarViewMac::GetPageActionDecoration(
584     ExtensionAction* page_action) {
585   DCHECK(page_action);
586   for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
587     if (page_action_decorations_[i]->GetPageAction() == page_action)
588       return page_action_decorations_[i];
589   }
590   // If |page_action| is the browser action of an extension, no element in
591   // |page_action_decorations_| will match.
592   NOTREACHED();
593   return NULL;
596 void LocationBarViewMac::DeletePageActionDecorations() {
597   // TODO(shess): Deleting these decorations could result in the cell
598   // refering to them before things are laid out again.  Meanwhile, at
599   // least fail safe.
600   [[field_ cell] clearDecorations];
602   page_action_decorations_.clear();
605 void LocationBarViewMac::OnEditBookmarksEnabledChanged() {
606   UpdateBookmarkStarVisibility();
607   OnChanged();
610 void LocationBarViewMac::RefreshPageActionDecorations() {
611   if (!IsEditable()) {
612     DeletePageActionDecorations();
613     return;
614   }
616   WebContents* web_contents = GetWebContents();
617   if (!web_contents) {
618     DeletePageActionDecorations();
619     return;
620   }
622   std::vector<ExtensionAction*> new_page_actions =
623       extensions::TabHelper::FromWebContents(web_contents)->
624           location_bar_controller()->GetCurrentActions();
626   if (PageActionsDiffer(new_page_actions)) {
627     DeletePageActionDecorations();
628     for (size_t i = 0; i < new_page_actions.size(); ++i) {
629       page_action_decorations_.push_back(
630           new PageActionDecoration(this, browser_, new_page_actions[i]));
631     }
632   }
634   GURL url = GetToolbarModel()->GetURL();
635   for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
636     page_action_decorations_[i]->UpdateVisibility(
637         GetToolbarModel()->input_in_progress() ? NULL : web_contents);
638   }
641 bool LocationBarViewMac::PageActionsDiffer(
642     const std::vector<ExtensionAction*>& page_actions) const {
643   if (page_action_decorations_.size() != page_actions.size())
644     return true;
646   for (size_t index = 0; index < page_actions.size(); ++index) {
647     PageActionDecoration* decoration = page_action_decorations_[index];
648     if (decoration->GetPageAction() != page_actions[index])
649       return true;
650   }
652   return false;
655 bool LocationBarViewMac::RefreshContentSettingsDecorations() {
656   const bool input_in_progress = GetToolbarModel()->input_in_progress();
657   WebContents* web_contents = input_in_progress ?
658       NULL : browser_->tab_strip_model()->GetActiveWebContents();
659   bool icons_updated = false;
660   for (size_t i = 0; i < content_setting_decorations_.size(); ++i) {
661     icons_updated |=
662         content_setting_decorations_[i]->UpdateFromWebContents(web_contents);
663   }
664   return icons_updated;
667 void LocationBarViewMac::ShowFirstRunBubbleInternal() {
668   if (!field_ || ![field_ window])
669     return;
671   // The first run bubble's left edge should line up with the left edge of the
672   // omnibox. This is different from other bubbles, which line up at a point
673   // set by their top arrow. Because the BaseBubbleController adjusts the
674   // window origin left to account for the arrow spacing, the first run bubble
675   // moves the window origin right by this spacing, so that the
676   // BaseBubbleController will move it back to the correct position.
677   const NSPoint kOffset = NSMakePoint(
678       info_bubble::kBubbleArrowXOffset + info_bubble::kBubbleArrowWidth/2.0,
679       kFirstRunBubbleYOffset);
680   [FirstRunBubbleController showForView:field_
681                                  offset:kOffset
682                                 browser:browser_
683                                 profile:profile()];
686 void LocationBarViewMac::UpdateTranslateDecoration() {
687   if (!TranslateService::IsTranslateBubbleEnabled())
688     return;
690   WebContents* web_contents = GetWebContents();
691   if (!web_contents)
692     return;
693   translate::LanguageState& language_state =
694       ChromeTranslateClient::FromWebContents(web_contents)->GetLanguageState();
695   bool enabled = language_state.translate_enabled();
696   command_updater()->UpdateCommandEnabled(IDC_TRANSLATE_PAGE, enabled);
697   translate_decoration_->SetVisible(enabled);
698   translate_decoration_->SetLit(language_state.IsPageTranslated());
701 bool LocationBarViewMac::UpdateZoomDecoration(bool default_zoom_changed) {
702   WebContents* web_contents = GetWebContents();
703   if (!web_contents)
704     return false;
706   return zoom_decoration_->UpdateIfNecessary(
707       ui_zoom::ZoomController::FromWebContents(web_contents),
708       default_zoom_changed);
711 void LocationBarViewMac::OnDefaultZoomLevelChanged() {
712   if (UpdateZoomDecoration(/*default_zoom_changed=*/true))
713     OnDecorationsChanged();
716 bool LocationBarViewMac::UpdateMicSearchDecorationVisibility() {
717   bool is_visible = !GetToolbarModel()->input_in_progress() &&
718                     browser_->search_model()->voice_search_supported();
719   if (mic_search_decoration_->IsVisible() == is_visible)
720     return false;
721   mic_search_decoration_->SetVisible(is_visible);
722   return true;