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"
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/chrome_notification_types.h"
18 #include "chrome/browser/command_updater.h"
19 #include "chrome/browser/defaults.h"
20 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
21 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
22 #include "chrome/browser/extensions/extension_action.h"
23 #include "chrome/browser/extensions/extension_service.h"
24 #include "chrome/browser/extensions/location_bar_controller.h"
25 #include "chrome/browser/extensions/tab_helper.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/search/instant_service.h"
28 #include "chrome/browser/search/instant_service_factory.h"
29 #include "chrome/browser/search/search.h"
30 #include "chrome/browser/search_engines/template_url.h"
31 #include "chrome/browser/search_engines/template_url_service.h"
32 #include "chrome/browser/search_engines/template_url_service_factory.h"
33 #include "chrome/browser/translate/translate_service.h"
34 #include "chrome/browser/translate/translate_tab_helper.h"
35 #include "chrome/browser/ui/browser_instant_controller.h"
36 #include "chrome/browser/ui/browser_list.h"
37 #import "chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.h"
38 #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
39 #import "chrome/browser/ui/cocoa/first_run_bubble_controller.h"
40 #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h"
41 #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell.h"
42 #import "chrome/browser/ui/cocoa/location_bar/content_setting_decoration.h"
43 #import "chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h"
44 #import "chrome/browser/ui/cocoa/location_bar/generated_credit_card_decoration.h"
45 #import "chrome/browser/ui/cocoa/location_bar/keyword_hint_decoration.h"
46 #import "chrome/browser/ui/cocoa/location_bar/location_icon_decoration.h"
47 #import "chrome/browser/ui/cocoa/location_bar/mic_search_decoration.h"
48 #import "chrome/browser/ui/cocoa/location_bar/origin_chip_decoration.h"
49 #import "chrome/browser/ui/cocoa/location_bar/page_action_decoration.h"
50 #import "chrome/browser/ui/cocoa/location_bar/search_button_decoration.h"
51 #import "chrome/browser/ui/cocoa/location_bar/selected_keyword_decoration.h"
52 #import "chrome/browser/ui/cocoa/location_bar/star_decoration.h"
53 #import "chrome/browser/ui/cocoa/location_bar/translate_decoration.h"
54 #import "chrome/browser/ui/cocoa/location_bar/zoom_decoration.h"
55 #import "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
56 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
57 #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
58 #include "chrome/browser/ui/omnibox/location_bar_util.h"
59 #import "chrome/browser/ui/omnibox/omnibox_popup_model.h"
60 #include "chrome/browser/ui/tabs/tab_strip_model.h"
61 #include "chrome/browser/ui/toolbar/toolbar_model.h"
62 #include "chrome/browser/ui/zoom/zoom_controller.h"
63 #include "chrome/common/chrome_switches.h"
64 #include "chrome/common/pref_names.h"
65 #include "components/translate/core/browser/language_state.h"
66 #include "content/public/browser/notification_service.h"
67 #include "content/public/browser/web_contents.h"
68 #include "extensions/browser/extension_system.h"
69 #include "extensions/common/extension.h"
70 #include "extensions/common/permissions/permissions_data.h"
71 #include "grit/generated_resources.h"
72 #include "grit/theme_resources.h"
73 #include "net/base/net_util.h"
74 #include "skia/ext/skia_utils_mac.h"
75 #import "ui/base/cocoa/cocoa_base_utils.h"
76 #include "ui/base/l10n/l10n_util_mac.h"
77 #include "ui/base/resource/resource_bundle.h"
78 #include "ui/gfx/image/image.h"
80 using content::WebContents;
84 // Vertical space between the bottom edge of the location_bar and the first run
85 // bubble arrow point.
86 const static int kFirstRunBubbleYOffset = 1;
88 // Functor for moving BookmarkManagerPrivate page actions to the right via
90 class IsPageActionViewRightAligned {
92 explicit IsPageActionViewRightAligned(ExtensionService* extension_service)
93 : extension_service_(extension_service) {}
95 bool operator()(PageActionDecoration* page_action_decoration) {
96 return extensions::PermissionsData::HasAPIPermission(
97 extension_service_->GetExtensionById(
98 page_action_decoration->page_action()->extension_id(),
100 extensions::APIPermission::kBookmarkManagerPrivate);
104 ExtensionService* extension_service_;
106 // NOTE: Can't DISALLOW_COPY_AND_ASSIGN as we pass this object by value to
107 // std::stable_partition().
112 // TODO(shess): This code is mostly copied from the gtk
113 // implementation. Make sure it's all appropriate and flesh it out.
115 LocationBarViewMac::LocationBarViewMac(AutocompleteTextField* field,
116 CommandUpdater* command_updater,
119 : LocationBar(profile),
120 OmniboxEditController(command_updater),
121 omnibox_view_(new OmniboxViewMac(this, profile, command_updater, field)),
123 location_icon_decoration_(new LocationIconDecoration(this)),
124 selected_keyword_decoration_(new SelectedKeywordDecoration()),
125 ev_bubble_decoration_(
126 new EVBubbleDecoration(location_icon_decoration_.get())),
127 star_decoration_(new StarDecoration(command_updater)),
128 translate_decoration_(new TranslateDecoration(command_updater)),
129 zoom_decoration_(new ZoomDecoration(this)),
130 keyword_hint_decoration_(new KeywordHintDecoration()),
131 mic_search_decoration_(new MicSearchDecoration(command_updater)),
132 generated_credit_card_decoration_(
133 new GeneratedCreditCardDecoration(this)),
134 search_button_decoration_(new SearchButtonDecoration(this)),
136 weak_ptr_factory_(this) {
138 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
139 DCHECK_EQ(i, content_setting_decorations_.size());
140 ContentSettingsType type = static_cast<ContentSettingsType>(i);
141 content_setting_decorations_.push_back(
142 new ContentSettingDecoration(type, this, profile));
146 this, chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
147 content::NotificationService::AllSources());
148 content::Source<Profile> profile_source = content::Source<Profile>(profile);
149 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
152 this, chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, profile_source);
153 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
156 edit_bookmarks_enabled_.Init(
157 prefs::kEditBookmarksEnabled, profile->GetPrefs(),
158 base::Bind(&LocationBarViewMac::OnEditBookmarksEnabledChanged,
159 base::Unretained(this)));
161 browser_->search_model()->AddObserver(this);
163 [[field_ cell] setIsPopupMode:
164 !browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)];
166 if (chrome::ShouldDisplayOriginChipV2())
167 origin_chip_decoration_.reset(new OriginChipDecoration(this));
170 LocationBarViewMac::~LocationBarViewMac() {
171 // Disconnect from cell in case it outlives us.
172 [[field_ cell] clearDecorations];
174 browser_->search_model()->RemoveObserver(this);
177 void LocationBarViewMac::ShowFirstRunBubble() {
178 // We need the browser window to be shown before we can show the bubble, but
179 // we get called before that's happened.
180 base::MessageLoop::current()->PostTask(
181 FROM_HERE, base::Bind(&LocationBarViewMac::ShowFirstRunBubbleInternal,
182 weak_ptr_factory_.GetWeakPtr()));
185 GURL LocationBarViewMac::GetDestinationURL() const {
186 return destination_url();
189 WindowOpenDisposition LocationBarViewMac::GetWindowOpenDisposition() const {
190 return disposition();
193 content::PageTransition LocationBarViewMac::GetPageTransition() const {
197 void LocationBarViewMac::AcceptInput() {
198 WindowOpenDisposition disposition =
199 ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
200 omnibox_view_->model()->AcceptInput(disposition, false);
203 void LocationBarViewMac::FocusLocation(bool select_all) {
204 omnibox_view_->FocusLocation(select_all);
207 void LocationBarViewMac::FocusSearch() {
208 omnibox_view_->SetForcedQuery();
211 void LocationBarViewMac::UpdateContentSettingsIcons() {
212 if (RefreshContentSettingsDecorations())
213 OnDecorationsChanged();
216 void LocationBarViewMac::UpdatePageActions() {
217 size_t count_before = page_action_decorations_.size();
218 RefreshPageActionDecorations();
220 if (page_action_decorations_.size() != count_before) {
221 content::NotificationService::current()->Notify(
222 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED,
223 content::Source<LocationBar>(this),
224 content::NotificationService::NoDetails());
228 void LocationBarViewMac::InvalidatePageActions() {
229 size_t count_before = page_action_decorations_.size();
230 DeletePageActionDecorations();
232 if (page_action_decorations_.size() != count_before) {
233 content::NotificationService::current()->Notify(
234 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_COUNT_CHANGED,
235 content::Source<LocationBar>(this),
236 content::NotificationService::NoDetails());
240 void LocationBarViewMac::UpdateOpenPDFInReaderPrompt() {
241 // Not implemented on Mac.
244 void LocationBarViewMac::UpdateGeneratedCreditCardView() {
245 generated_credit_card_decoration_->Update();
248 void LocationBarViewMac::SaveStateToContents(WebContents* contents) {
249 // TODO(shess): Why SaveStateToContents vs SaveStateToTab?
250 omnibox_view_->SaveStateToTab(contents);
253 void LocationBarViewMac::Revert() {
254 omnibox_view_->RevertAll();
257 const OmniboxView* LocationBarViewMac::GetOmniboxView() const {
258 return omnibox_view_.get();
261 OmniboxView* LocationBarViewMac::GetOmniboxView() {
262 return omnibox_view_.get();
265 LocationBarTesting* LocationBarViewMac::GetLocationBarForTesting() {
269 // TODO(pamg): Change all these, here and for other platforms, to size_t.
270 int LocationBarViewMac::PageActionCount() {
271 return static_cast<int>(page_action_decorations_.size());
274 int LocationBarViewMac::PageActionVisibleCount() {
276 for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
277 if (page_action_decorations_[i]->IsVisible())
283 ExtensionAction* LocationBarViewMac::GetPageAction(size_t index) {
284 if (index < page_action_decorations_.size())
285 return page_action_decorations_[index]->page_action();
290 ExtensionAction* LocationBarViewMac::GetVisiblePageAction(size_t index) {
292 for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
293 if (page_action_decorations_[i]->IsVisible()) {
294 if (current == index)
295 return page_action_decorations_[i]->page_action();
305 void LocationBarViewMac::TestPageActionPressed(size_t index) {
306 DCHECK_LT(index, page_action_decorations_.size());
307 if (index < page_action_decorations_.size())
308 page_action_decorations_[index]->OnMousePressed(NSZeroRect);
311 bool LocationBarViewMac::GetBookmarkStarVisibility() {
312 DCHECK(star_decoration_.get());
313 return star_decoration_->IsVisible();
316 void LocationBarViewMac::SetEditable(bool editable) {
317 [field_ setEditable:editable ? YES : NO];
318 UpdateStarDecorationVisibility();
319 UpdateZoomDecoration();
324 bool LocationBarViewMac::IsEditable() {
325 return [field_ isEditable] ? true : false;
328 void LocationBarViewMac::SetStarred(bool starred) {
329 star_decoration_->SetStarred(starred);
330 UpdateStarDecorationVisibility();
331 OnDecorationsChanged();
334 void LocationBarViewMac::SetTranslateIconLit(bool on) {
335 translate_decoration_->SetLit(on);
336 OnDecorationsChanged();
339 void LocationBarViewMac::ZoomChangedForActiveTab(bool can_show_bubble) {
340 UpdateZoomDecoration();
341 OnDecorationsChanged();
343 if (can_show_bubble && zoom_decoration_->IsVisible())
344 zoom_decoration_->ShowBubble(YES);
347 bool LocationBarViewMac::IsStarEnabled() const {
348 return browser_defaults::bookmarks_enabled &&
349 [field_ isEditable] &&
350 !GetToolbarModel()->input_in_progress() &&
351 edit_bookmarks_enabled_.GetValue() &&
352 !IsBookmarkStarHiddenByExtension();
355 NSPoint LocationBarViewMac::GetBookmarkBubblePoint() const {
356 DCHECK(IsStarEnabled());
357 return [field_ bubblePointForDecoration:star_decoration_.get()];
360 NSPoint LocationBarViewMac::GetTranslateBubblePoint() const {
361 return [field_ bubblePointForDecoration:translate_decoration_.get()];
364 NSPoint LocationBarViewMac::GetPageInfoBubblePoint() const {
365 if (ev_bubble_decoration_->IsVisible()) {
366 return [field_ bubblePointForDecoration:ev_bubble_decoration_.get()];
368 return [field_ bubblePointForDecoration:location_icon_decoration_.get()];
372 NSPoint LocationBarViewMac::GetGeneratedCreditCardBubblePoint() const {
374 [field_ bubblePointForDecoration:generated_credit_card_decoration_.get()];
377 void LocationBarViewMac::OnDecorationsChanged() {
378 // TODO(shess): The field-editor frame and cursor rects should not
380 [field_ updateMouseTracking];
381 [field_ resetFieldEditorFrameIfNeeded];
382 [field_ setNeedsDisplay:YES];
385 // TODO(shess): This function should over time grow to closely match
386 // the views Layout() function.
387 void LocationBarViewMac::Layout() {
388 AutocompleteTextFieldCell* cell = [field_ cell];
390 // Reset the left-hand decorations.
391 // TODO(shess): Shortly, this code will live somewhere else, like in
392 // the constructor. I am still wrestling with how best to deal with
393 // right-hand decorations, which are not a static set.
394 [cell clearDecorations];
395 if (origin_chip_decoration_.get())
396 [cell addLeftDecoration:origin_chip_decoration_.get()];
397 [cell addLeftDecoration:location_icon_decoration_.get()];
398 [cell addLeftDecoration:selected_keyword_decoration_.get()];
399 if (!origin_chip_decoration_.get())
400 [cell addLeftDecoration:ev_bubble_decoration_.get()];
401 [cell addRightDecoration:search_button_decoration_.get()];
402 [cell addRightDecoration:star_decoration_.get()];
403 [cell addRightDecoration:translate_decoration_.get()];
404 [cell addRightDecoration:zoom_decoration_.get()];
405 [cell addRightDecoration:generated_credit_card_decoration_.get()];
407 // Note that display order is right to left.
408 for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
409 [cell addRightDecoration:page_action_decorations_[i]];
412 for (ScopedVector<ContentSettingDecoration>::iterator i =
413 content_setting_decorations_.begin();
414 i != content_setting_decorations_.end(); ++i) {
415 [cell addRightDecoration:*i];
418 [cell addRightDecoration:keyword_hint_decoration_.get()];
419 [cell addRightDecoration:mic_search_decoration_.get()];
421 // By default only the location icon is visible.
422 location_icon_decoration_->SetVisible(!origin_chip_decoration_.get() ||
423 !origin_chip_decoration_->IsVisible());
424 selected_keyword_decoration_->SetVisible(false);
425 ev_bubble_decoration_->SetVisible(false);
426 keyword_hint_decoration_->SetVisible(false);
428 // Get the keyword to use for keyword-search and hinting.
429 const base::string16 keyword = omnibox_view_->model()->keyword();
430 base::string16 short_name;
431 bool is_extension_keyword = false;
432 if (!keyword.empty()) {
433 short_name = TemplateURLServiceFactory::GetForProfile(profile())->
434 GetKeywordShortName(keyword, &is_extension_keyword);
437 const bool is_keyword_hint = omnibox_view_->model()->is_keyword_hint();
438 if (!keyword.empty() && !is_keyword_hint) {
439 // Switch from location icon to keyword mode.
440 location_icon_decoration_->SetVisible(false);
441 selected_keyword_decoration_->SetVisible(true);
442 selected_keyword_decoration_->SetKeyword(short_name, is_extension_keyword);
443 selected_keyword_decoration_->SetImage(GetKeywordImage(keyword));
444 } else if ((GetToolbarModel()->GetSecurityLevel(false) ==
445 ToolbarModel::EV_SECURE) && !origin_chip_decoration_.get()) {
446 // Switch from location icon to show the EV bubble instead.
447 location_icon_decoration_->SetVisible(false);
448 ev_bubble_decoration_->SetVisible(true);
450 base::string16 label(GetToolbarModel()->GetEVCertName());
451 ev_bubble_decoration_->SetFullLabel(base::SysUTF16ToNSString(label));
452 } else if (!keyword.empty() && is_keyword_hint) {
453 keyword_hint_decoration_->SetKeyword(short_name,
454 is_extension_keyword);
455 keyword_hint_decoration_->SetVisible(true);
458 // These need to change anytime the layout changes.
459 // TODO(shess): Anytime the field editor might have changed, the
460 // cursor rects almost certainly should have changed. The tooltips
461 // might change even when the rects don't change.
462 OnDecorationsChanged();
465 void LocationBarViewMac::RedrawDecoration(LocationBarDecoration* decoration) {
466 AutocompleteTextFieldCell* cell = [field_ cell];
467 NSRect frame = [cell frameForDecoration:decoration
468 inFrame:[field_ bounds]];
469 if (!NSIsEmptyRect(frame))
470 [field_ setNeedsDisplayInRect:frame];
473 void LocationBarViewMac::SetPreviewEnabledPageAction(
474 ExtensionAction* page_action, bool preview_enabled) {
476 WebContents* contents = GetWebContents();
479 RefreshPageActionDecorations();
482 PageActionDecoration* decoration = GetPageActionDecoration(page_action);
487 decoration->set_preview_enabled(preview_enabled);
488 decoration->UpdateVisibility(contents, GetToolbarModel()->GetURL());
491 NSRect LocationBarViewMac::GetPageActionFrame(ExtensionAction* page_action) {
492 PageActionDecoration* decoration = GetPageActionDecoration(page_action);
496 AutocompleteTextFieldCell* cell = [field_ cell];
497 NSRect frame = [cell frameForDecoration:decoration inFrame:[field_ bounds]];
501 NSPoint LocationBarViewMac::GetPageActionBubblePoint(
502 ExtensionAction* page_action) {
503 PageActionDecoration* decoration = GetPageActionDecoration(page_action);
507 NSRect frame = GetPageActionFrame(page_action);
508 if (NSIsEmptyRect(frame)) {
509 // The bubble point positioning assumes that the page action is visible. If
510 // not, something else needs to be done otherwise the bubble will appear
511 // near the top left corner (unanchored).
516 NSPoint bubble_point = decoration->GetBubblePointInFrame(frame);
517 return [field_ convertPoint:bubble_point toView:nil];
520 void LocationBarViewMac::Update(const WebContents* contents) {
521 UpdateStarDecorationVisibility();
522 UpdateTranslateDecoration();
523 UpdateZoomDecoration();
524 RefreshPageActionDecorations();
525 RefreshContentSettingsDecorations();
526 UpdateMicSearchDecorationVisibility();
527 UpdateGeneratedCreditCardView();
529 omnibox_view_->OnTabChanged(contents);
531 omnibox_view_->Update();
535 void LocationBarViewMac::OnChanged() {
536 // Update the location-bar icon.
537 const int resource_id = omnibox_view_->GetIcon();
538 NSImage* image = OmniboxViewMac::ImageForResource(resource_id);
539 location_icon_decoration_->SetImage(image);
540 ev_bubble_decoration_->SetImage(image);
542 if (origin_chip_decoration_.get())
543 origin_chip_decoration_->Update();
545 ToolbarModel* toolbar_model = GetToolbarModel();
546 const chrome::DisplaySearchButtonConditions conditions =
547 chrome::GetDisplaySearchButtonConditions();
548 const bool meets_conditions =
549 (conditions == chrome::DISPLAY_SEARCH_BUTTON_ALWAYS) ||
550 ((conditions != chrome::DISPLAY_SEARCH_BUTTON_NEVER) &&
551 (toolbar_model->WouldPerformSearchTermReplacement(true) ||
552 ((conditions == chrome::DISPLAY_SEARCH_BUTTON_FOR_STR_OR_IIP) &&
553 toolbar_model->input_in_progress())));
554 search_button_decoration_->SetVisible(
555 ![[field_ cell] isPopupMode] && meets_conditions);
556 search_button_decoration_->SetIcon(
557 (resource_id == IDR_OMNIBOX_SEARCH) ?
558 IDR_OMNIBOX_SEARCH_BUTTON_LOUPE : IDR_OMNIBOX_SEARCH_BUTTON_ARROW);
562 InstantService* instant_service =
563 InstantServiceFactory::GetForProfile(profile());
564 if (instant_service) {
565 gfx::Rect bounds(NSRectToCGRect([field_ frame]));
566 instant_service->OnOmniboxStartMarginChanged(bounds.x());
570 void LocationBarViewMac::OnSetFocus() {
571 // Update the keyword and search hint states.
575 void LocationBarViewMac::ShowURL() {
576 omnibox_view_->ShowURL();
579 void LocationBarViewMac::HideURL() {
580 omnibox_view_->HideURL();
583 InstantController* LocationBarViewMac::GetInstant() {
584 return browser_->instant_controller() ?
585 browser_->instant_controller()->instant() : NULL;
588 WebContents* LocationBarViewMac::GetWebContents() {
589 return browser_->tab_strip_model()->GetActiveWebContents();
592 ToolbarModel* LocationBarViewMac::GetToolbarModel() {
593 return browser_->toolbar_model();
596 const ToolbarModel* LocationBarViewMac::GetToolbarModel() const {
597 return browser_->toolbar_model();
600 NSImage* LocationBarViewMac::GetKeywordImage(const base::string16& keyword) {
601 const TemplateURL* template_url = TemplateURLServiceFactory::GetForProfile(
602 profile())->GetTemplateURLForKeyword(keyword);
604 (template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION)) {
605 return extensions::OmniboxAPI::Get(profile())->
606 GetOmniboxIcon(template_url->GetExtensionId()).AsNSImage();
609 return OmniboxViewMac::ImageForResource(IDR_OMNIBOX_SEARCH);
612 void LocationBarViewMac::Observe(int type,
613 const content::NotificationSource& source,
614 const content::NotificationDetails& details) {
616 case chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED: {
617 WebContents* contents = GetWebContents();
618 if (content::Details<WebContents>(contents) != details)
621 [field_ updateMouseTracking];
622 [field_ setNeedsDisplay:YES];
626 case chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED: {
627 // Only update if the updated action box was for the active tab contents.
628 WebContents* target_tab = content::Details<WebContents>(details).ptr();
629 if (target_tab == GetWebContents())
634 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED:
635 case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED:
640 NOTREACHED() << "Unexpected notification";
645 void LocationBarViewMac::ModelChanged(const SearchModel::State& old_state,
646 const SearchModel::State& new_state) {
647 if (UpdateMicSearchDecorationVisibility())
651 void LocationBarViewMac::ActivatePageAction(const std::string& extension_id) {
652 for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
653 if (page_action_decorations_[i]->page_action()->extension_id() ==
655 page_action_decorations_[i]->ActivatePageAction();
661 void LocationBarViewMac::PostNotification(NSString* notification) {
662 [[NSNotificationCenter defaultCenter] postNotificationName:notification
663 object:[NSValue valueWithPointer:this]];
666 PageActionDecoration* LocationBarViewMac::GetPageActionDecoration(
667 ExtensionAction* page_action) {
669 for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
670 if (page_action_decorations_[i]->page_action() == page_action)
671 return page_action_decorations_[i];
673 // If |page_action| is the browser action of an extension, no element in
674 // |page_action_decorations_| will match.
680 void LocationBarViewMac::DeletePageActionDecorations() {
681 // TODO(shess): Deleting these decorations could result in the cell
682 // refering to them before things are laid out again. Meanwhile, at
684 [[field_ cell] clearDecorations];
686 page_action_decorations_.clear();
689 void LocationBarViewMac::OnEditBookmarksEnabledChanged() {
690 UpdateStarDecorationVisibility();
694 void LocationBarViewMac::RefreshPageActionDecorations() {
696 DeletePageActionDecorations();
700 WebContents* web_contents = GetWebContents();
702 DeletePageActionDecorations(); // Necessary?
706 std::vector<ExtensionAction*> new_page_actions =
707 extensions::TabHelper::FromWebContents(web_contents)->
708 location_bar_controller()->GetCurrentActions();
710 if (new_page_actions != page_actions_) {
711 page_actions_.swap(new_page_actions);
712 DeletePageActionDecorations();
713 for (size_t i = 0; i < page_actions_.size(); ++i) {
714 page_action_decorations_.push_back(
715 new PageActionDecoration(this, browser_, page_actions_[i]));
718 // Move rightmost extensions to the start.
719 std::stable_partition(
720 page_action_decorations_.begin(),
721 page_action_decorations_.end(),
722 IsPageActionViewRightAligned(
723 extensions::ExtensionSystem::Get(profile())->extension_service()));
726 GURL url = GetToolbarModel()->GetURL();
727 for (size_t i = 0; i < page_action_decorations_.size(); ++i) {
728 page_action_decorations_[i]->UpdateVisibility(
729 GetToolbarModel()->input_in_progress() ? NULL : web_contents, url);
733 bool LocationBarViewMac::RefreshContentSettingsDecorations() {
734 const bool input_in_progress = GetToolbarModel()->input_in_progress();
735 WebContents* web_contents = input_in_progress ?
736 NULL : browser_->tab_strip_model()->GetActiveWebContents();
737 bool icons_updated = false;
738 for (size_t i = 0; i < content_setting_decorations_.size(); ++i) {
740 content_setting_decorations_[i]->UpdateFromWebContents(web_contents);
742 return icons_updated;
745 void LocationBarViewMac::ShowFirstRunBubbleInternal() {
746 if (!field_ || ![field_ window])
749 // The first run bubble's left edge should line up with the left edge of the
750 // omnibox. This is different from other bubbles, which line up at a point
751 // set by their top arrow. Because the BaseBubbleController adjusts the
752 // window origin left to account for the arrow spacing, the first run bubble
753 // moves the window origin right by this spacing, so that the
754 // BaseBubbleController will move it back to the correct position.
755 const NSPoint kOffset = NSMakePoint(
756 info_bubble::kBubbleArrowXOffset + info_bubble::kBubbleArrowWidth/2.0,
757 kFirstRunBubbleYOffset);
758 [FirstRunBubbleController showForView:field_
764 void LocationBarViewMac::UpdateTranslateDecoration() {
765 if (!TranslateService::IsTranslateBubbleEnabled())
768 WebContents* web_contents = GetWebContents();
771 LanguageState& language_state =
772 TranslateTabHelper::FromWebContents(web_contents)->GetLanguageState();
773 bool enabled = language_state.translate_enabled();
774 command_updater()->UpdateCommandEnabled(IDC_TRANSLATE_PAGE, enabled);
775 translate_decoration_->SetVisible(enabled);
776 translate_decoration_->SetLit(language_state.IsPageTranslated());
779 void LocationBarViewMac::UpdateZoomDecoration() {
780 WebContents* web_contents = GetWebContents();
784 zoom_decoration_->Update(ZoomController::FromWebContents(web_contents));
787 void LocationBarViewMac::UpdateStarDecorationVisibility() {
788 star_decoration_->SetVisible(IsStarEnabled());
791 bool LocationBarViewMac::UpdateMicSearchDecorationVisibility() {
792 bool is_visible = !GetToolbarModel()->input_in_progress() &&
793 browser_->search_model()->voice_search_supported();
794 if (mic_search_decoration_->IsVisible() == is_visible)
796 mic_search_decoration_->SetVisible(is_visible);