diff --git a/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc new file mode 100644 index 000000000000..2b957979d9f8 --- /dev/null +++ b/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc @@ -0,0 +1,39 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * you can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/views/tabs/tab.h" +#include "chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h" +#include "content/public/common/url_constants.h" +#include "ui/views/controls/label.h" + +#define TabHoverCardBubbleView TabHoverCardBubbleView_ChromiumImpl +#include "../../../../../../chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc" +#undef TabHoverCardBubbleView + +void TabHoverCardBubbleView_ChromiumImpl::BraveUpdateCardContent( + const Tab* tab) { + TabHoverCardBubbleView_ChromiumImpl::UpdateCardContent(tab); + const base::string16& domain = domain_label_->GetText(); + const base::string16 kChromeUISchemeU16 = + base::ASCIIToUTF16(content::kChromeUIScheme); + // Replace chrome:// with brave://. Since this is purely in the UI we can + // just do a sub-string replacement instead of parsing into GURL. + if (base::StartsWith(domain, kChromeUISchemeU16, + base::CompareCase::INSENSITIVE_ASCII)) { + base::string16 new_domain = domain; + base::ReplaceFirstSubstringAfterOffset( + &new_domain, 0ul, kChromeUISchemeU16, + base::ASCIIToUTF16(content::kBraveUIScheme)); + domain_label_->SetText(new_domain); + } +} + +void TabHoverCardBubbleView::UpdateCardContent(const Tab* tab) { + BraveUpdateCardContent(tab); +} diff --git a/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h new file mode 100644 index 000000000000..a1d6d6421d3c --- /dev/null +++ b/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * you can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_VIEWS_TABS_TAB_HOVER_CARD_BUBBLE_VIEW_H_ +#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_VIEWS_TABS_TAB_HOVER_CARD_BUBBLE_VIEW_H_ + +// Inject a protected method that will have access to the private members of the +// base class. Then, we can call this method from the subclass' override. +#define BRAVE_TAB_HOVER_CARD_BUBBLE_VIEW_H_ \ + protected: \ + void BraveUpdateCardContent(const Tab* tab); + +#define TabHoverCardBubbleView TabHoverCardBubbleView_ChromiumImpl +#define UpdateCardContent virtual UpdateCardContent +#include "../../../../../../chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h" +#undef UpdateCardContent +#undef TabHoverCardBubbleView +#undef BRAVE_TAB_HOVER_CARD_BUBBLE_VIEW_H_ + +class TabHoverCardBubbleView : public TabHoverCardBubbleView_ChromiumImpl { + public: + using TabHoverCardBubbleView_ChromiumImpl:: + TabHoverCardBubbleView_ChromiumImpl; + + private: + void UpdateCardContent(const Tab* tab) override; + + DISALLOW_COPY_AND_ASSIGN(TabHoverCardBubbleView); +}; + +#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_VIEWS_TABS_TAB_HOVER_CARD_BUBBLE_VIEW_H_ diff --git a/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc b/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc new file mode 100644 index 000000000000..cfb11c12f197 --- /dev/null +++ b/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc @@ -0,0 +1,129 @@ +/* Copyright (c) 2019 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "base/strings/string_util.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/test/test_browser_dialog.h" +#include "chrome/browser/ui/ui_features.h" +#include "chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h" +#include "chrome/browser/ui/views/tabs/tab_strip.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "ui/gfx/animation/animation_test_api.h" +#include "ui/views/controls/label.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_observer.h" + +using views::Widget; + +// Helper to wait until the hover card widget is visible. +class HoverCardVisibleWaiter : public views::WidgetObserver { + public: + explicit HoverCardVisibleWaiter(Widget* hover_card) + : hover_card_(hover_card) { + hover_card_->AddObserver(this); + } + ~HoverCardVisibleWaiter() override { hover_card_->RemoveObserver(this); } + + void Wait() { + if (hover_card_->IsVisible()) + return; + run_loop_.Run(); + } + + // WidgetObserver overrides: + void OnWidgetVisibilityChanged(Widget* widget, bool visible) override { + if (visible) + run_loop_.Quit(); + } + + private: + Widget* const hover_card_; + base::RunLoop run_loop_; +}; + +class TabHoverCardBubbleViewBrowserTest : public DialogBrowserTest { + public: + TabHoverCardBubbleViewBrowserTest() + : animation_mode_reset_(gfx::AnimationTestApi::SetRichAnimationRenderMode( + gfx::Animation::RichAnimationRenderMode::FORCE_DISABLED)) { + TabHoverCardBubbleView::disable_animations_for_testing_ = true; + } + ~TabHoverCardBubbleViewBrowserTest() override = default; + + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(features::kTabHoverCards); + DialogBrowserTest::SetUp(); + } + + static TabHoverCardBubbleView* GetHoverCard(const TabStrip* tabstrip) { + return tabstrip->hover_card_; + } + + static Widget* GetHoverCardWidget(const TabHoverCardBubbleView* hover_card) { + return hover_card->widget_; + } + + const base::string16& GetHoverCardTitle( + const TabHoverCardBubbleView* hover_card) { + return hover_card->title_label_->GetText(); + } + + const base::string16& GetHoverCardDomain( + const TabHoverCardBubbleView* hover_card) { + return hover_card->domain_label_->GetText(); + } + + void HoverMouseOverTabAt(int index) { + TabStrip* tab_strip = + BrowserView::GetBrowserViewForBrowser(browser())->tabstrip(); + Tab* tab = tab_strip->tab_at(index); + ui::MouseEvent hover_event(ui::ET_MOUSE_ENTERED, gfx::Point(), gfx::Point(), + base::TimeTicks(), ui::EF_NONE, 0); + tab->OnMouseEntered(hover_event); + } + + // DialogBrowserTest: + void ShowUi(const std::string& name) override { + TabStrip* tab_strip = + BrowserView::GetBrowserViewForBrowser(browser())->tabstrip(); + Tab* tab = tab_strip->tab_at(0); + ui::MouseEvent hover_event(ui::ET_MOUSE_ENTERED, gfx::Point(), gfx::Point(), + base::TimeTicks(), ui::EF_NONE, 0); + tab->OnMouseEntered(hover_event); + TabHoverCardBubbleView* hover_card = GetHoverCard(tab_strip); + Widget* widget = GetHoverCardWidget(hover_card); + HoverCardVisibleWaiter waiter(widget); + waiter.Wait(); + } + + private: + std::unique_ptr> + animation_mode_reset_; + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN(TabHoverCardBubbleViewBrowserTest); +}; + +IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, ChromeSchemeUrl) { + TabStrip* tab_strip = + BrowserView::GetBrowserViewForBrowser(browser())->tabstrip(); + TabRendererData new_tab_data = TabRendererData(); + new_tab_data.title = base::UTF8ToUTF16("Settings - Addresses and more"); + new_tab_data.last_committed_url = + GURL("chrome://settings/addresses"); + tab_strip->AddTabAt(1, new_tab_data, false); + + ShowUi("default"); + TabHoverCardBubbleView* hover_card = GetHoverCard(tab_strip); + Widget* widget = GetHoverCardWidget(hover_card); + EXPECT_TRUE(widget != nullptr); + EXPECT_TRUE(widget->IsVisible()); + HoverMouseOverTabAt(1); + EXPECT_EQ(GetHoverCardTitle(hover_card), + base::UTF8ToUTF16("Settings - Addresses and more")); + EXPECT_EQ(GetHoverCardDomain(hover_card), + base::UTF8ToUTF16("brave://settings")); +} diff --git a/patches/chrome-browser-ui-views-tabs-tab_hover_card_bubble_view.h.patch b/patches/chrome-browser-ui-views-tabs-tab_hover_card_bubble_view.h.patch new file mode 100644 index 000000000000..19c050e4d197 --- /dev/null +++ b/patches/chrome-browser-ui-views-tabs-tab_hover_card_bubble_view.h.patch @@ -0,0 +1,12 @@ +diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +index eaa40d8fdb646fe7ae39a2f363b3e8405519509b..b600a7bd9908b20bef9c42fcd18a83f838d42ec8 100644 +--- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h ++++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +@@ -61,6 +61,7 @@ class TabHoverCardBubbleView : public views::BubbleDialogDelegateView, + last_mouse_exit_timestamp_ = last_mouse_exit_timestamp; + } + ++ BRAVE_TAB_HOVER_CARD_BUBBLE_VIEW_H_ + private: + friend class TabHoverCardBubbleViewBrowserTest; + friend class TabHoverCardBubbleViewInteractiveUiTest; diff --git a/test/BUILD.gn b/test/BUILD.gn index 0d0ccc363082..f1ad49e4e90e 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -453,11 +453,6 @@ test("brave_browser_tests") { "//brave/app/brave_main_delegate_browsertest.cc", "//brave/browser/autocomplete/brave_autocomplete_provider_client_browsertest.cc", "//brave/browser/brave_scheme_load_browsertest.cc", - "//brave/chromium_src/chrome/browser/profiles/profile_window_browsertest.cc", - "//brave/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc", - "//brave/chromium_src/components/content_settings/core/browser/brave_content_settings_registry_browsertest.cc", - "//brave/chromium_src/third_party/blink/renderer/modules/battery/navigator_batterytest.cc", - "//brave/chromium_src/third_party/blink/renderer/modules/bluetooth/navigator_bluetoothtest.cc", "//brave/browser/autoplay/autoplay_permission_context_browsertest.cc", "//brave/browser/brave_content_browser_client_browsertest.cc", "//brave/browser/brave_features_browsertest.cc", @@ -468,12 +463,13 @@ test("brave_browser_tests") { "//brave/browser/brave_stats_updater_browsertest.cc", "//brave/browser/browsing_data/brave_clear_browsing_data_browsertest.cc", "//brave/browser/devtools/brave_devtools_ui_bindings_browsertest.cc", + "//brave/browser/extensions/api/brave_shields_api_browsertest.cc", + "//brave/browser/extensions/api/brave_theme_api_browsertest.cc", "//brave/browser/extensions/brave_base_local_data_files_browsertest.cc", "//brave/browser/extensions/brave_base_local_data_files_browsertest.h", "//brave/browser/extensions/brave_extension_functional_test.cc", "//brave/browser/extensions/brave_extension_functional_test.h", - "//brave/browser/extensions/api/brave_shields_api_browsertest.cc", - "//brave/browser/extensions/api/brave_theme_api_browsertest.cc", + "//brave/browser/extensions/brave_extension_provider_browsertest.cc", "//brave/browser/extensions/brave_theme_event_router_browsertest.cc", "//brave/browser/net/brave_network_delegate_browsertest.cc", "//brave/browser/net/brave_network_delegate_hsts_fingerprinting_browsertest.cc", @@ -482,6 +478,7 @@ test("brave_browser_tests") { "//brave/browser/renderer_context_menu/brave_mock_render_view_context_menu.h", "//brave/browser/renderer_context_menu/brave_spelling_menu_observer_browsertest.cc", "//brave/browser/search_engines/search_engine_provider_service_browsertest.cc", + "//brave/browser/themes/brave_theme_service_browsertest.cc", "//brave/browser/ui/bookmark/bookmark_tab_helper_browsertest.cc", "//brave/browser/ui/content_settings/brave_autoplay_blocked_image_model_browsertest.cc", "//brave/browser/ui/views/brave_actions/brave_actions_container_browsertest.cc", @@ -491,17 +488,21 @@ test("brave_browser_tests") { "//brave/browser/ui/webui/brave_welcome_ui_browsertest.cc", "//brave/browser/ui/toolbar/brave_app_menu_model_browsertest.cc", "//brave/chromium_src/chrome/browser/media/router/media_router_feature_browsertest.cc", + "//brave/chromium_src/chrome/browser/profiles/profile_window_browsertest.cc", + "//brave/chromium_src/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc", + "//brave/chromium_src/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc", + "//brave/chromium_src/components/content_settings/core/browser/brave_content_settings_registry_browsertest.cc", "//brave/chromium_src/third_party/blink/public/platform/disable_client_hints_browsertest.cc", + "//brave/chromium_src/third_party/blink/renderer/modules/battery/navigator_batterytest.cc", + "//brave/chromium_src/third_party/blink/renderer/modules/bluetooth/navigator_bluetoothtest.cc", "//brave/common/brave_channel_info_browsertest.cc", "//brave/components/brave_shields/browser/ad_block_service_browsertest.cc", "//brave/components/brave_shields/browser/https_everywhere_service_browsertest.cc", "//brave/components/brave_shields/browser/referrer_whitelist_service_browsertest.cc", "//brave/components/brave_shields/browser/tracking_protection_service_browsertest.cc", - "//brave/browser/extensions/brave_extension_provider_browsertest.cc", "//brave/renderer/brave_content_settings_observer_browsertest.cc", "//brave/renderer/brave_content_settings_observer_autoplay_browsertest.cc", "//brave/renderer/brave_content_settings_observer_flash_browsertest.cc", - "//brave/browser/themes/brave_theme_service_browsertest.cc", "//chrome/browser/extensions/browsertest_util.cc", "//chrome/browser/extensions/browsertest_util.h", "//chrome/browser/extensions/extension_browsertest.cc", @@ -510,6 +511,12 @@ test("brave_browser_tests") { "//chrome/browser/extensions/extension_function_test_utils.h", "//chrome/browser/extensions/updater/extension_cache_fake.cc", "//chrome/browser/extensions/updater/extension_cache_fake.h", + "//chrome/browser/ui/test/test_browser_dialog.cc", + "//chrome/browser/ui/test/test_browser_dialog.h", + "//chrome/browser/ui/test/test_browser_dialog_mac.h", + "//chrome/browser/ui/test/test_browser_dialog_mac.mm", + "//chrome/browser/ui/test/test_browser_ui.cc", + "//chrome/browser/ui/test/test_browser_ui.h", ] deps = []