diff options
Diffstat (limited to 'chromium/components/infobars/content')
4 files changed, 225 insertions, 0 deletions
diff --git a/chromium/components/infobars/content/BUILD.gn b/chromium/components/infobars/content/BUILD.gn new file mode 100644 index 00000000000..6be0c41535c --- /dev/null +++ b/chromium/components/infobars/content/BUILD.gn @@ -0,0 +1,18 @@ +# Copyright 2020 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. + +static_library("content") { + sources = [ + "content_infobar_manager.cc", + "content_infobar_manager.h", + ] + + public_deps = [ + "//base", + "//components/infobars/core", + "//content/public/browser", + "//content/public/common", + "//ui/base", + ] +} diff --git a/chromium/components/infobars/content/DEPS b/chromium/components/infobars/content/DEPS new file mode 100644 index 00000000000..c24130ef510 --- /dev/null +++ b/chromium/components/infobars/content/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+content/public/browser", + "+content/public/common", +] diff --git a/chromium/components/infobars/content/content_infobar_manager.cc b/chromium/components/infobars/content/content_infobar_manager.cc new file mode 100644 index 00000000000..d93801b6c63 --- /dev/null +++ b/chromium/components/infobars/content/content_infobar_manager.cc @@ -0,0 +1,115 @@ +// Copyright (c) 2013 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 "components/infobars/content/content_infobar_manager.h" + +#include "base/command_line.h" +#include "components/infobars/core/confirm_infobar_delegate.h" +#include "components/infobars/core/infobar.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" +#include "ui/base/page_transition_types.h" + +namespace infobars { + +// static +InfoBarDelegate::NavigationDetails +ContentInfoBarManager::NavigationDetailsFromLoadCommittedDetails( + const content::LoadCommittedDetails& details) { + InfoBarDelegate::NavigationDetails navigation_details; + navigation_details.entry_id = details.entry->GetUniqueID(); + navigation_details.is_navigation_to_different_page = + details.is_navigation_to_different_page(); + navigation_details.did_replace_entry = details.did_replace_entry; + const ui::PageTransition transition = details.entry->GetTransitionType(); + navigation_details.is_reload = + ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD); + navigation_details.is_redirect = ui::PageTransitionIsRedirect(transition); + return navigation_details; +} + +// static +content::WebContents* ContentInfoBarManager::WebContentsFromInfoBar( + InfoBar* infobar) { + if (!infobar || !infobar->owner()) + return nullptr; + ContentInfoBarManager* infobar_manager = + static_cast<ContentInfoBarManager*>(infobar->owner()); + return infobar_manager->web_contents(); +} + +ContentInfoBarManager::ContentInfoBarManager(content::WebContents* web_contents) + : content::WebContentsObserver(web_contents), ignore_next_reload_(false) { + DCHECK(web_contents); + // Infobar animations cause viewport resizes. Disable them for automated + // tests, since they could lead to flakiness. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableAutomation)) + set_animations_enabled(false); +} + +ContentInfoBarManager::~ContentInfoBarManager() { + ShutDown(); +} + +int ContentInfoBarManager::GetActiveEntryID() { + content::NavigationEntry* active_entry = + web_contents()->GetController().GetActiveEntry(); + return active_entry ? active_entry->GetUniqueID() : 0; +} + +std::unique_ptr<InfoBar> ContentInfoBarManager::CreateConfirmInfoBar( + std::unique_ptr<ConfirmInfoBarDelegate> delegate) { + NOTREACHED(); + return nullptr; +} + +void ContentInfoBarManager::RenderProcessGone(base::TerminationStatus status) { + RemoveAllInfoBars(true); +} + +void ContentInfoBarManager::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame() || + navigation_handle->IsSameDocument()) { + return; + } + + ignore_next_reload_ = false; +} + +void ContentInfoBarManager::NavigationEntryCommitted( + const content::LoadCommittedDetails& load_details) { + const bool ignore = + ignore_next_reload_ && + ui::PageTransitionCoreTypeIs(load_details.entry->GetTransitionType(), + ui::PAGE_TRANSITION_RELOAD); + ignore_next_reload_ = false; + if (!ignore) + OnNavigation(NavigationDetailsFromLoadCommittedDetails(load_details)); +} + +void ContentInfoBarManager::WebContentsDestroyed() { + // Subclasses may override this method to destroy this object, so don't do + // anything here. +} + +void ContentInfoBarManager::OpenURL(const GURL& url, + WindowOpenDisposition disposition) { + // A normal user click on an infobar URL will result in a CURRENT_TAB + // disposition; turn that into a NEW_FOREGROUND_TAB so that we don't end up + // smashing the page the user is looking at. + web_contents()->OpenURL( + content::OpenURLParams(url, content::Referrer(), + (disposition == WindowOpenDisposition::CURRENT_TAB) + ? WindowOpenDisposition::NEW_FOREGROUND_TAB + : disposition, + ui::PAGE_TRANSITION_LINK, false)); + +} // namespace infobars + +} // namespace infobars diff --git a/chromium/components/infobars/content/content_infobar_manager.h b/chromium/components/infobars/content/content_infobar_manager.h new file mode 100644 index 00000000000..f9c123445ed --- /dev/null +++ b/chromium/components/infobars/content/content_infobar_manager.h @@ -0,0 +1,88 @@ +// Copyright 2020 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 COMPONENTS_INFOBARS_CONTENT_CONTENT_INFOBAR_MANAGER_H_ +#define COMPONENTS_INFOBARS_CONTENT_CONTENT_INFOBAR_MANAGER_H_ + +#include <memory> +#include <vector> + +#include "base/macros.h" +#include "build/build_config.h" +#include "components/infobars/core/infobar_manager.h" +#include "content/public/browser/reload_type.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" +#include "ui/base/window_open_disposition.h" + +namespace content { +struct LoadCommittedDetails; +class WebContents; +} // namespace content + +namespace infobars { + +class InfoBar; + +// Associates a WebContents to an InfoBarManager. +// It manages the infobar notifications and responds to navigation events. +// By default the creation of confirm infobars is not supported. If embedders +// wish to add such support, they should create a custom subclass of +// ContentInfoBarManager that overrides CreateConfirmInfoBar(). +// This class is not itself a WebContentsUserData in order to support such +// subclassing; it is expected that embedders will either have an instance of +// this class as a member of their "Tab" objects or create a custom subclass +// that is a WCUD. +class ContentInfoBarManager : public InfoBarManager, + public content::WebContentsObserver { + public: + explicit ContentInfoBarManager(content::WebContents* web_contents); + ~ContentInfoBarManager() override; + + static InfoBarDelegate::NavigationDetails + NavigationDetailsFromLoadCommittedDetails( + const content::LoadCommittedDetails& details); + + // This function must only be called on infobars that are owned by a + // ContentInfoBarManager instance (or not owned at all, in which case this + // returns nullptr). + static content::WebContents* WebContentsFromInfoBar(InfoBar* infobar); + + // Makes it so the next reload is ignored. That is, if the next commit is a + // reload then it is treated as if nothing happened and no infobars are + // attempted to be closed. + // This is useful for non-user triggered reloads that should not dismiss + // infobars. For example, instant may trigger a reload when the google URL + // changes. + void set_ignore_next_reload() { ignore_next_reload_ = true; } + + // InfoBarManager: + // NOTE: By default this method is NOTREACHED() and returns nullptr. + // TODO(sdefresne): Change clients to invoke this on InfoBarManager + // and turn the method override private. + std::unique_ptr<InfoBar> CreateConfirmInfoBar( + std::unique_ptr<ConfirmInfoBarDelegate> delegate) override; + void OpenURL(const GURL& url, WindowOpenDisposition disposition) override; + + private: + // InfoBarManager: + int GetActiveEntryID() override; + + // content::WebContentsObserver: + void RenderProcessGone(base::TerminationStatus status) override; + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; + void NavigationEntryCommitted( + const content::LoadCommittedDetails& load_details) override; + void WebContentsDestroyed() override; + + // See description in set_ignore_next_reload(). + bool ignore_next_reload_; + + DISALLOW_COPY_AND_ASSIGN(ContentInfoBarManager); +}; + +} // namespace infobars + +#endif // COMPONENTS_INFOBARS_CONTENT_CONTENT_INFOBAR_MANAGER_H_ |