diff options
-rw-r--r-- | chrome/app/generated_resources.grd | 9 | ||||
-rw-r--r-- | chrome/browser/extensions/tab_helper.cc | 51 | ||||
-rw-r--r-- | chrome/browser/ui/browser_window.h | 11 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/browser_window_cocoa.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/browser_window_cocoa.mm | 6 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/browser_window_gtk.cc | 6 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/browser_window_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc | 224 | ||||
-rw-r--r-- | chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h | 95 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.cc | 10 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.h | 3 | ||||
-rw-r--r-- | chrome/chrome_browser_ui.gypi | 2 | ||||
-rw-r--r-- | chrome/test/base/test_browser_window.h | 3 | ||||
-rw-r--r-- | extensions/common/extension.h | 5 |
14 files changed, 398 insertions, 33 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a930513..1221b56 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -2152,6 +2152,15 @@ Even if you have downloaded files from this website before, the website might ha No </message> + <!-- Bookmark app bubble --> + <message name="IDS_BOOKMARK_APP_BUBBLE_TITLE" desc="Title of the bubble to add a bookmark app."> + Add shortcut? + </message> + + <message name="IDS_BOOKMARK_APP_BUBBLE_OPEN_AS_TAB" desc="Checkbox text for opening the bookmark app as a tab."> + Open as tab + </message> + <!-- "Create application shortcuts" menu item --> <if expr="not pp_ifdef('use_titlecase')"> <message name="IDS_CREATE_SHORTCUTS" desc="Default installation menu label"> diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index ffe9606..1638928 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc @@ -27,11 +27,10 @@ #include "chrome/browser/sessions/session_id.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/shell_integration.h" -#include "chrome/browser/ui/app_list/app_list_service.h" -#include "chrome/browser/ui/app_list/app_list_util.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/browser/web_applications/web_app.h" @@ -66,6 +65,10 @@ #include "ui/gfx/color_analysis.h" #include "ui/gfx/image/image.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#endif + using content::NavigationController; using content::NavigationEntry; using content::RenderViewHost; @@ -413,14 +416,13 @@ void TabHelper::FinishCreateHostedApp( return; } - WebApplicationInfo install_info(web_app_info_); - if (install_info.app_url.is_empty()) - install_info.app_url = web_contents()->GetURL(); + if (web_app_info_.app_url.is_empty()) + web_app_info_.app_url = web_contents()->GetURL(); - if (install_info.title.empty()) - install_info.title = web_contents()->GetTitle(); - if (install_info.title.empty()) - install_info.title = base::UTF8ToUTF16(install_info.app_url.spec()); + if (web_app_info_.title.empty()) + web_app_info_.title = web_contents()->GetTitle(); + if (web_app_info_.title.empty()) + web_app_info_.title = base::UTF8ToUTF16(web_app_info_.app_url.spec()); // Add the downloaded icons. Extensions only allow certain icon sizes. First // populate icons that match the allowed sizes exactly and then downscale @@ -481,7 +483,7 @@ void TabHelper::FinishCreateHostedApp( icon_info.data = resized_bitmaps_it->second; icon_info.width = icon_info.data.width(); icon_info.height = icon_info.data.height(); - install_info.icons.push_back(icon_info); + web_app_info_.icons.push_back(icon_info); } // Install the app. @@ -490,7 +492,7 @@ void TabHelper::FinishCreateHostedApp( scoped_refptr<extensions::CrxInstaller> installer( extensions::CrxInstaller::CreateSilent(profile->GetExtensionService())); installer->set_error_on_unsupported_requirements(true); - installer->InstallWebApp(install_info); + installer->InstallWebApp(web_app_info_); favicon_downloader_.reset(); } @@ -734,34 +736,21 @@ void TabHelper::Observe(int type, const Extension* extension = content::Details<const Extension>(details).ptr(); - if (!extension || !extension->from_bookmark()) + if (!extension || + AppLaunchInfo::GetLaunchWebURL(extension) != web_app_info_.app_url) return; - // If enabled, launch the app launcher and highlight the new app. - // Otherwise, open the chrome://apps page in a new foreground tab. - if (IsAppLauncherEnabled()) { - AppListService::Get(chrome::GetHostDesktopTypeForNativeView( - web_contents()->GetView()->GetNativeView()))-> - ShowForProfile(profile_); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST, - content::Source<Profile>(profile_), - content::Details<const std::string>(&extension->id())); - return; - } +#if defined(OS_CHROMEOS) + ChromeLauncherController::instance()->PinAppWithID(extension->id()); +#endif // Android does not implement browser_finder.cc. #if !defined(OS_ANDROID) Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); if (browser) { - browser->OpenURL( - content::OpenURLParams(GURL(chrome::kChromeUIAppsURL), - content::Referrer(), - NEW_FOREGROUND_TAB, - content::PAGE_TRANSITION_LINK, - false)); + browser->window()->ShowBookmarkAppBubble(web_app_info_, + extension->id()); } #endif } diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index be23fd4..6a23b11 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -32,6 +32,8 @@ class TemplateURL; class ToolbarView; #endif +struct WebApplicationInfo; + namespace autofill { class PasswordGenerator; struct PasswordForm; @@ -214,6 +216,15 @@ class BrowserWindow : public ui::BaseWindow { // |already_bookmarked| is true if the url is already bookmarked. virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) = 0; + // Shows the Bookmark App bubble. + // See Extension::InitFromValueFlags::FROM_BOOKMARK for a description of + // bookmark apps. + // + // |web_app_info| is the WebApplicationInfo being converted into an app. + // |extension_id| is the id of the bookmark app. + virtual void ShowBookmarkAppBubble(const WebApplicationInfo& web_app_info, + const std::string& extension_id) = 0; + // Shows the bookmark prompt. // TODO(yosin): Make ShowBookmarkPrompt pure virtual. virtual void ShowBookmarkPrompt() {} diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index 4091953..24c7bbc 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h @@ -101,6 +101,9 @@ class BrowserWindowCocoa : virtual void ShowUpdateChromeDialog() OVERRIDE; virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) OVERRIDE; + virtual void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const std::string& extension_id) OVERRIDE; virtual void ShowTranslateBubble( content::WebContents* contents, TranslateBubbleModel::ViewState view_state, diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index 4287c00..439a15e 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm @@ -478,6 +478,12 @@ void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url, alreadyBookmarked:(already_bookmarked ? YES : NO)]; } +void BrowserWindowCocoa::ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const std::string& extension_id) { + NOTIMPLEMENTED(); +} + void BrowserWindowCocoa::ShowTranslateBubble( content::WebContents* contents, TranslateBubbleModel::ViewState view_state, diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc index c038e11..7130452 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.cc +++ b/chrome/browser/ui/gtk/browser_window_gtk.cc @@ -1027,6 +1027,12 @@ void BrowserWindowGtk::ShowBookmarkBubble(const GURL& url, toolbar_->GetLocationBarView()->ShowStarBubble(url, !already_bookmarked); } +void BrowserWindowGtk::ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const std::string& extension_id) { + NOTIMPLEMENTED(); +} + void BrowserWindowGtk::ShowTranslateBubble( content::WebContents* contents, TranslateBubbleModel::ViewState view_state, diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h index 6185654..fe5382a4 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.h +++ b/chrome/browser/ui/gtk/browser_window_gtk.h @@ -137,6 +137,9 @@ class BrowserWindowGtk virtual void ShowUpdateChromeDialog() OVERRIDE; virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) OVERRIDE; + virtual void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const std::string& extension_id) OVERRIDE; virtual void ShowTranslateBubble( content::WebContents* contents, TranslateBubbleModel::ViewState view_state, diff --git a/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc new file mode 100644 index 0000000..013dec4 --- /dev/null +++ b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.cc @@ -0,0 +1,224 @@ +// Copyright 2014 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/ui/views/extensions/bookmark_app_bubble_view.h" + +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/extensions/crx_installer.h" +#include "chrome/browser/extensions/launch_util.h" +#include "chrome/browser/profiles/profile.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/views/controls/button/checkbox.h" +#include "ui/views/controls/button/label_button.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/layout/layout_constants.h" +#include "ui/views/widget/widget.h" + +using views::ColumnSet; +using views::GridLayout; + +namespace { + +// Minimum width of the the bubble. +const int kMinBubbleWidth = 300; + +} // namespace + +BookmarkAppBubbleView* BookmarkAppBubbleView::bookmark_app_bubble_ = NULL; + +BookmarkAppBubbleView::~BookmarkAppBubbleView() { +} + +// static +void BookmarkAppBubbleView::ShowBubble(views::View* anchor_view, + Profile* profile, + const WebApplicationInfo& web_app_info, + const std::string& extension_id) { + if (bookmark_app_bubble_ != NULL) + return; + + bookmark_app_bubble_ = new BookmarkAppBubbleView( + anchor_view, profile, web_app_info, extension_id); + views::BubbleDelegateView::CreateBubble(bookmark_app_bubble_)->Show(); + // Select the entire title textfield contents when the bubble is first shown. + bookmark_app_bubble_->title_tf_->SelectAll(true); + bookmark_app_bubble_->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); +} + +BookmarkAppBubbleView::BookmarkAppBubbleView( + views::View* anchor_view, + Profile* profile, + const WebApplicationInfo& web_app_info, + const std::string& extension_id) + : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), + profile_(profile), + web_app_info_(web_app_info), + extension_id_(extension_id), + add_button_(NULL), + cancel_button_(NULL), + open_as_tab_checkbox_(NULL), + title_tf_(NULL), + remove_app_(true) { + const SkColor background_color = GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_DialogBackground); + set_color(background_color); + set_background(views::Background::CreateSolidBackground(background_color)); + set_margins(gfx::Insets(views::kPanelVertMargin, 0, 0, 0)); +} + +void BookmarkAppBubbleView::Init() { + views::Label* title_label = new views::Label( + l10n_util::GetStringUTF16(IDS_BOOKMARK_APP_BUBBLE_TITLE)); + ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); + title_label->SetFontList(rb->GetFontList(ui::ResourceBundle::MediumFont)); + title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + + add_button_ = + new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_ADD)); + add_button_->SetStyle(views::Button::STYLE_BUTTON); + add_button_->SetIsDefault(true); + + cancel_button_ = + new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_CANCEL)); + cancel_button_->SetStyle(views::Button::STYLE_BUTTON); + + GridLayout* layout = new GridLayout(this); + SetLayoutManager(layout); + + // Column sets used in the layout of the bubble. + enum ColumnSetID { + TITLE_COLUMN_SET_ID, + TITLE_TEXT_COLUMN_SET_ID, + CONTENT_COLUMN_SET_ID + }; + + // The column layout used for the title and checkbox. + ColumnSet* cs = layout->AddColumnSet(TITLE_COLUMN_SET_ID); + cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew); + cs->AddColumn( + GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0); + cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew); + + // The column layout used for the text box. + cs = layout->AddColumnSet(TITLE_TEXT_COLUMN_SET_ID); + cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew); + cs->AddColumn( + GridLayout::FILL, GridLayout::FILL, 1, GridLayout::USE_PREF, 0, 0); + cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew); + + // The column layout used for the row with buttons. + cs = layout->AddColumnSet(CONTENT_COLUMN_SET_ID); + cs->AddPaddingColumn(1, views::kButtonHEdgeMarginNew); + + cs->AddColumn( + GridLayout::LEADING, GridLayout::TRAILING, 0, GridLayout::USE_PREF, 0, 0); + cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); + cs->AddColumn( + GridLayout::LEADING, GridLayout::TRAILING, 0, GridLayout::USE_PREF, 0, 0); + cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew); + + layout->StartRow(0, TITLE_COLUMN_SET_ID); + layout->AddView(title_label); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + + layout->StartRow(0, TITLE_TEXT_COLUMN_SET_ID); + title_tf_ = new views::Textfield(); + const extensions::Extension* extension = + profile_->GetExtensionService()->GetInstalledExtension(extension_id_); + title_tf_->SetText(extension ? base::UTF8ToUTF16(extension->name()) + : web_app_info_.title); + layout->AddView(title_tf_); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + + layout->StartRow(0, TITLE_COLUMN_SET_ID); + open_as_tab_checkbox_ = new views::Checkbox( + l10n_util::GetStringUTF16(IDS_BOOKMARK_APP_BUBBLE_OPEN_AS_TAB)); + layout->AddView(open_as_tab_checkbox_); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + + layout->StartRow(0, CONTENT_COLUMN_SET_ID); + layout->AddView(add_button_); + layout->AddView(cancel_button_); + layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); + + AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); +} + +views::View* BookmarkAppBubbleView::GetInitiallyFocusedView() { + return title_tf_; +} + +void BookmarkAppBubbleView::WindowClosing() { + // We have to reset |bookmark_app_bubble_| here, not in our destructor, + // because we'll be destroyed asynchronously and the shown state will be + // checked before then. + DCHECK_EQ(bookmark_app_bubble_, this); + bookmark_app_bubble_ = NULL; + + if (remove_app_) { + profile_->GetExtensionService()->UninstallExtension( + extension_id_, false, NULL); + } else { + ApplyEdits(); + } +} + +bool BookmarkAppBubbleView::AcceleratorPressed( + const ui::Accelerator& accelerator) { + if (accelerator.key_code() == ui::VKEY_RETURN) { + HandleButtonPressed(add_button_); + } + + return BubbleDelegateView::AcceleratorPressed(accelerator); +} + +gfx::Size BookmarkAppBubbleView::GetMinimumSize() { + gfx::Size size(views::BubbleDelegateView::GetPreferredSize()); + size.SetToMax(gfx::Size(kMinBubbleWidth, 0)); + return size; +} + +void BookmarkAppBubbleView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + HandleButtonPressed(sender); +} + +void BookmarkAppBubbleView::HandleButtonPressed(views::Button* sender) { + // Unset |remove_app_| so we don't delete the bookmark after the window + // closes. + if (sender == add_button_) + remove_app_ = false; + + StartFade(false); +} + +void BookmarkAppBubbleView::ApplyEdits() { + // Set the launch type based on the checkbox. + extensions::SetLaunchType(profile_->GetExtensionService(), + extension_id_, + open_as_tab_checkbox_->checked() + ? extensions::LAUNCH_TYPE_REGULAR + : extensions::LAUNCH_TYPE_WINDOW); + + const extensions::Extension* extension = + profile_->GetExtensionService()->GetInstalledExtension(extension_id_); + if (extension && base::UTF8ToUTF16(extension->name()) == title_tf_->text()) + return; + + // Reinstall the app with an updated name. + WebApplicationInfo install_info(web_app_info_); + install_info.title = title_tf_->text(); + + scoped_refptr<extensions::CrxInstaller> installer( + extensions::CrxInstaller::CreateSilent(profile_->GetExtensionService())); + installer->set_error_on_unsupported_requirements(true); + installer->InstallWebApp(install_info); +} diff --git a/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h new file mode 100644 index 0000000..0a07228 --- /dev/null +++ b/chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h @@ -0,0 +1,95 @@ +// Copyright 2014 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. + +#ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_BOOKMARK_APP_BUBBLE_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_BOOKMARK_APP_BUBBLE_VIEW_H_ + +#include "base/basictypes.h" +#include "base/strings/string16.h" +#include "chrome/common/web_application_info.h" +#include "ui/views/bubble/bubble_delegate.h" +#include "ui/views/controls/button/button.h" + +class Profile; + +namespace views { +class Checkbox; +class LabelButton; +class Textfield; +} + +// BookmarkAppBubbleView is a view intended to be used as the content of a +// Bubble. BookmarkAppBubbleView provides views for editing the bookmark app it +// is created with. Don't create a BookmarkAppBubbleView directly, instead use +// the static ShowBubble method. +class BookmarkAppBubbleView : public views::BubbleDelegateView, + public views::ButtonListener { + public: + virtual ~BookmarkAppBubbleView(); + + static void ShowBubble(views::View* anchor_view, + Profile* profile, + const WebApplicationInfo& web_app_info, + const std::string& extension_id); + + private: + // Creates a BookmarkAppBubbleView. + BookmarkAppBubbleView(views::View* anchor_view, + Profile* profile, + const WebApplicationInfo& web_app_info, + const std::string& extension_id); + + // Overriden from views::BubbleDelegateView: + virtual void Init() OVERRIDE; + virtual views::View* GetInitiallyFocusedView() OVERRIDE; + + // Overridden from views::WidgetDelegate: + virtual void WindowClosing() OVERRIDE; + + // Overridden from views::View: + virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; + virtual gfx::Size GetMinimumSize() OVERRIDE; + + // Overridden from views::ButtonListener: + // Closes the bubble or opens the edit dialog. + virtual void ButtonPressed(views::Button* sender, + const ui::Event& event) OVERRIDE; + + // Handle the message when the user presses a button. + void HandleButtonPressed(views::Button* sender); + + // Sets the title and launch type of the app. + void ApplyEdits(); + + // The bookmark app bubble, if we're showing one. + static BookmarkAppBubbleView* bookmark_app_bubble_; + + // The profile. + Profile* profile_; + + // The WebApplicationInfo being used to create the app. + const WebApplicationInfo web_app_info_; + + // The extension id of the bookmark app. + const std::string extension_id_; + + // Button for removing the bookmark. + views::LabelButton* add_button_; + + // Button to close the window. + views::LabelButton* cancel_button_; + + // Checkbox to launch as a tab. + views::Checkbox* open_as_tab_checkbox_; + + // Textfield showing the title of the app. + views::Textfield* title_tf_; + + // When the destructor is invoked should the app be removed? + bool remove_app_; + + DISALLOW_COPY_AND_ASSIGN(BookmarkAppBubbleView); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_BOOKMARK_APP_BUBBLE_VIEW_H_ diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index b86e848..655d51a 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -66,6 +66,7 @@ #include "chrome/browser/ui/views/browser_dialogs.h" #include "chrome/browser/ui/views/download/download_in_progress_dialog_view.h" #include "chrome/browser/ui/views/download/download_shelf_view.h" +#include "chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h" #include "chrome/browser/ui/views/frame/browser_view_layout.h" #include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h" #include "chrome/browser/ui/views/frame/contents_layout_manager.h" @@ -1196,6 +1197,15 @@ void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) { !already_bookmarked); } +void BrowserView::ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const std::string& extension_id) { + BookmarkAppBubbleView::ShowBubble(GetToolbarView(), + browser_->profile(), + web_app_info, + extension_id); +} + void BrowserView::ShowBookmarkPrompt() { GetLocationBarView()->ShowBookmarkPrompt(); } diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 06fcb0a..6a8c617 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -323,6 +323,9 @@ class BrowserView : public BrowserWindow, virtual void ShowUpdateChromeDialog() OVERRIDE; virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) OVERRIDE; + virtual void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const std::string& extension_id) OVERRIDE; virtual void ShowBookmarkPrompt() OVERRIDE; virtual void ShowTranslateBubble( content::WebContents* contents, diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index d0a8a5f..6ef0aa7 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -1819,6 +1819,8 @@ 'browser/ui/views/dropdown_bar_view.h', 'browser/ui/views/edit_search_engine_dialog.cc', 'browser/ui/views/edit_search_engine_dialog.h', + 'browser/ui/views/extensions/bookmark_app_bubble_view.cc', + 'browser/ui/views/extensions/bookmark_app_bubble_view.h', 'browser/ui/views/extensions/browser_action_drag_data.cc', 'browser/ui/views/extensions/browser_action_drag_data.h', 'browser/ui/views/extensions/browser_action_overflow_menu_controller.cc', diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 6a462a4..3a5072c 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h @@ -102,6 +102,9 @@ class TestBrowserWindow : public BrowserWindow { virtual void ShowUpdateChromeDialog() OVERRIDE {} virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) OVERRIDE {} + virtual void ShowBookmarkAppBubble( + const WebApplicationInfo& web_app_info, + const std::string& extension_id) OVERRIDE {} virtual void ShowTranslateBubble( content::WebContents* contents, TranslateBubbleModel::ViewState view_state, diff --git a/extensions/common/extension.h b/extensions/common/extension.h index ead3dd0..4ea11b4 100644 --- a/extensions/common/extension.h +++ b/extensions/common/extension.h @@ -133,8 +133,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> { // Chrome Web Store. FROM_WEBSTORE = 1 << 3, - // |FROM_BOOKMARK| indicates the extension was created using a mock App - // created from a bookmark. + // |FROM_BOOKMARK| indicates the extension is a bookmark app which has been + // generated from a web page. Bookmark apps have no permissions or extent + // and launch the web page they are created from when run. FROM_BOOKMARK = 1 << 4, // |FOLLOW_SYMLINKS_ANYWHERE| means that resources can be symlinks to |