chromium/ios/chrome/browser/web/model/blocked_popup_tab_helper.h

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IOS_CHROME_BROWSER_WEB_MODEL_BLOCKED_POPUP_TAB_HELPER_H_
#define IOS_CHROME_BROWSER_WEB_MODEL_BLOCKED_POPUP_TAB_HELPER_H_

#import <vector>

#import "base/memory/raw_ptr.h"
#import "base/scoped_observation.h"
#import "components/infobars/core/infobar_manager.h"
#import "ios/chrome/browser/shared/model/profile/profile_ios_forward.h"
#import "ios/web/public/lazy_web_state_user_data.h"
#import "ios/web/public/navigation/referrer.h"
#import "url/gurl.h"

namespace infobars {
class InfoBar;
}  // namespace infobars

namespace web {
class WebState;
}  // namespace web

// Handles blocked popups. Will display an infobar informing the user and
// allowing the user to add an exception and navigate to the site.
class BlockedPopupTabHelper
    : public infobars::InfoBarManager::Observer,
      public web::LazyWebStateUserData<BlockedPopupTabHelper> {
 public:
  explicit BlockedPopupTabHelper(web::WebState* web_state);

  BlockedPopupTabHelper(const BlockedPopupTabHelper&) = delete;
  BlockedPopupTabHelper& operator=(const BlockedPopupTabHelper&) = delete;

  ~BlockedPopupTabHelper() override;

  // Returns true if popup requested by the page with the given `source_url`
  // should be blocked.
  bool ShouldBlockPopup(const GURL& source_url);

  // Shows the popup blocker infobar for the popup with given popup_url.
  // `referrer` represents the frame which requested this popup.
  void HandlePopup(const GURL& popup_url, const web::Referrer& referrer);

  // infobars::InfoBarManager::Observer implementation.
  void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override;
  void OnManagerShuttingDown(
      infobars::InfoBarManager* infobar_manager) override;

  // Encapsulates information about popup.
  struct Popup {
    Popup(const GURL& popup_url, const web::Referrer& referrer)
        : popup_url(popup_url), referrer(referrer) {}
    // URL of the popup window.
    const GURL popup_url;
    // Referrer which requested this popup.
    const web::Referrer referrer;
  };

 private:
  friend class web::LazyWebStateUserData<BlockedPopupTabHelper>;

  friend class BlockedPopupTabHelperTest;

  // Shows the infobar for the current popups. Will also handle replacing an
  // existing infobar with the updated count.
  void ShowInfoBar();

  // Returns BrowserState for the WebState that this object is attached to.
  ChromeBrowserState* GetBrowserState() const;

  // Registers this object as an observer for the InfoBarManager associated with
  // `web_state_`.  Does nothing if already registered.
  void RegisterAsInfoBarManagerObserverIfNeeded(
      infobars::InfoBarManager* infobar_manager);

  // The WebState that this object is attached to.
  raw_ptr<web::WebState> web_state_;
  // The currently displayed infobar.
  raw_ptr<infobars::InfoBar> infobar_;
  // The popups to open.
  std::vector<Popup> popups_;
  // For management of infobars::InfoBarManager::Observer registration.  This
  // object will not start observing the InfoBarManager until ShowInfoBars() is
  // called.
  base::ScopedObservation<infobars::InfoBarManager,
                          infobars::InfoBarManager::Observer>
      scoped_observation_{this};

  WEB_STATE_USER_DATA_KEY_DECL();
};

#endif  // IOS_CHROME_BROWSER_WEB_MODEL_BLOCKED_POPUP_TAB_HELPER_H_