blob: 8801133c43fd9bb148c63e37d6e85dc97d135dd0 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// 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/toolbar/back_forward_button.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/chained_back_navigation_tracker.h"
#include "chrome/browser/preloading/chrome_preloading.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_element_identifiers.h"
#include "chrome/browser/ui/toolbar/back_forward_menu_model.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/grit/generated_resources.h"
#include "components/strings/grit/components_strings.h"
#include "components/vector_icons/vector_icons.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/window_open_disposition_utils.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/view_class_properties.h"
BackForwardButton::BackForwardButton(Direction direction,
PressedCallback callback,
Browser* browser)
: ToolbarButton(std::move(callback),
std::make_unique<BackForwardMenuModel>(
browser,
direction == Direction::kBack
? BackForwardMenuModel::ModelType::kBackward
: BackForwardMenuModel::ModelType::kForward),
browser->tab_strip_model()),
browser_(browser),
direction_(direction) {
SetHideInkDropWhenShowingContextMenu(false);
SetTriggerableEventFlags(ui::EF_LEFT_MOUSE_BUTTON |
ui::EF_MIDDLE_MOUSE_BUTTON);
if (direction == Direction::kBack) {
SetVectorIcons(vector_icons::kBackArrowChromeRefreshIcon,
kBackArrowTouchIcon);
SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_BACK));
GetViewAccessibility().SetName(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK));
GetViewAccessibility().SetDescription(
l10n_util::GetStringUTF8(IDS_ACCDESCRIPTION_BACK));
SetID(VIEW_ID_BACK_BUTTON);
SetProperty(views::kElementIdentifierKey, kToolbarBackButtonElementId);
set_menu_identifier(kToolbarBackButtonMenuElementId);
} else {
SetVectorIcons(vector_icons::kForwardArrowChromeRefreshIcon,
kForwardArrowTouchIcon);
SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_FORWARD));
GetViewAccessibility().SetName(
l10n_util::GetStringUTF16(IDS_ACCNAME_FORWARD));
GetViewAccessibility().SetDescription(
l10n_util::GetStringUTF8(IDS_ACCDESCRIPTION_FORWARD));
SetID(VIEW_ID_FORWARD_BUTTON);
SetProperty(views::kElementIdentifierKey, kToolbarForwardButtonElementId);
set_menu_identifier(kToolbarForwardButtonMenuElementId);
}
}
BackForwardButton::~BackForwardButton() = default;
const std::u16string BackForwardButton::GetAccessiblePageLoadingMessage() {
// If we don't have a model, there is no menu from which to obtain the title
// of the page that is about to be loaded.
if (!menu_model()) {
return std::u16string();
}
// The title of the page which is about to be loaded should be at the top of
// the menu.
return l10n_util::GetStringFUTF16(IDS_PAGE_LOADING_AX_TITLE_FORMAT,
menu_model()->GetLabelAt(0));
}
void BackForwardButton::NotifyClick(const ui::Event& event) {
// If the focus is on web content the screen reader will announce the page
// load; if not we want to make sure that something is still announced.
if (GetFocusManager()->GetFocusedView() !=
BrowserView::GetBrowserViewForBrowser(browser_)->contents_web_view()) {
const std::u16string message = GetAccessiblePageLoadingMessage();
if (!message.empty()) {
GetViewAccessibility().AnnounceText(message);
}
}
content::WebContents* web_contents =
browser_->tab_strip_model()->GetActiveWebContents();
ChainedBackNavigationTracker* tracker =
ChainedBackNavigationTracker::FromWebContents(web_contents);
CHECK(tracker);
tracker->RecordBackButtonClickForChainedBackNavigation();
// Do this last because upon activation the MenuModel gets updated, removing
// the label for the page about to be loaded. However, the title associated
// with the ContentsWebView has not yet been updated.
ToolbarButton::NotifyClick(event);
}
void BackForwardButton::StateChanged(ButtonState old_state) {
ToolbarButton::StateChanged(old_state);
if (direction_ != Direction::kBack) {
return;
}
if (old_state == ButtonState::STATE_NORMAL &&
GetState() == ButtonState::STATE_HOVERED) {
content::WebContents* active_contents =
browser_->tab_strip_model()->GetActiveWebContents();
if (active_contents) {
active_contents->BackNavigationLikely(
chrome_preloading_predictor::kBackButtonHover,
last_back_assumed_disposition_);
}
}
}
void BackForwardButton::OnMouseEntered(const ui::MouseEvent& event) {
if (direction_ == Direction::kBack) {
// Record this before the event triggers `StateChanged` via
// `ToolbarButton::OnMouseEntered`.
last_back_assumed_disposition_ = ui::DispositionFromEventFlags(
event.flags(), WindowOpenDisposition::CURRENT_TAB);
}
ToolbarButton::OnMouseEntered(event);
}
bool BackForwardButton::ShouldShowInkdropAfterIphInteraction() {
return false;
}
BEGIN_METADATA(BackForwardButton)
END_METADATA