/*
 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All
 * Rights Reserved.
 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "third_party/blink/renderer/core/page/page.h"

#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_layer_tree_view.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/visited_link_state.h"
#include "third_party/blink/renderer/core/editing/drag_caret.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/frame/browser_controls.h"
#include "third_party/blink/renderer/core/frame/dom_timer.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/frame_console.h"
#include "third_party/blink/renderer/core/frame/link_highlights.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/page_scale_constraints.h"
#include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/frame/remote_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/viewport_data.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/console_message_storage.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/page/autoscroll_controller.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/context_menu_controller.h"
#include "third_party/blink/renderer/core/page/drag_controller.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page_hidden_state.h"
#include "third_party/blink/renderer/core/page/plugins_changed_observer.h"
#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
#include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
#include "third_party/blink/renderer/core/page/scrolling/overscroll_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
#include "third_party/blink/renderer/core/page/spatial_navigation_controller.h"
#include "third_party/blink/renderer/core/page/validation_message_client_impl.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/plugins/plugin_data.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/skia/include/core/SkColor.h"

namespace blink {

// Wrapper function defined in WebKit.h
void ResetPluginCache(bool reload_pages) {
  // At this point we already know that the browser has refreshed its list, so
  // it is not necessary to force it to be regenerated.
  DCHECK(!reload_pages);
  Page::ResetPluginData();
}

// Set of all live pages; includes internal Page objects that are
// not observable from scripts.
static Page::PageSet& AllPages() {
  DEFINE_STATIC_LOCAL(Persistent<Page::PageSet>, pages,
                      (MakeGarbageCollected<Page::PageSet>()));
  return *pages;
}

Page::PageSet& Page::OrdinaryPages() {
  DEFINE_STATIC_LOCAL(Persistent<Page::PageSet>, pages,
                      (MakeGarbageCollected<Page::PageSet>()));
  return *pages;
}

void Page::InsertOrdinaryPageForTesting(Page* page) {
  OrdinaryPages().insert(page);
}

HeapVector<Member<Page>> Page::RelatedPages() {
  HeapVector<Member<Page>> result;
  Page* ptr = this->next_related_page_;
  while (ptr != this) {
    result.push_back(ptr);
    ptr = ptr->next_related_page_;
  }
  return result;
}

float DeviceScaleFactorDeprecated(LocalFrame* frame) {
  if (!frame)
    return 1;
  Page* page = frame->GetPage();
  if (!page)
    return 1;
  return page->DeviceScaleFactorDeprecated();
}

Page* Page::Create(PageClients& page_clients) {
  Page* page = MakeGarbageCollected<Page>(page_clients);
  page->SetPageScheduler(ThreadScheduler::Current()->CreatePageScheduler(page));
  return page;
}

Page* Page::CreateOrdinary(PageClients& page_clients, Page* opener) {
  Page* page = Create(page_clients);

  if (opener) {
    // Before: ... -> opener -> next -> ...
    // After: ... -> opener -> page -> next -> ...
    Page* next = opener->next_related_page_;
    opener->next_related_page_ = page;
    page->prev_related_page_ = opener;
    page->next_related_page_ = next;
    next->prev_related_page_ = page;
  }

  OrdinaryPages().insert(page);
  if (ScopedPagePauser::IsActive())
    page->SetPaused(true);
  return page;
}

Page::Page(PageClients& page_clients)
    : SettingsDelegate(Settings::Create()),
      main_frame_(nullptr),
      animator_(PageAnimator::Create(*this)),
      autoscroll_controller_(AutoscrollController::Create(*this)),
      chrome_client_(page_clients.chrome_client),
      drag_caret_(DragCaret::Create()),
      drag_controller_(DragController::Create(this)),
      focus_controller_(FocusController::Create(this)),
      context_menu_controller_(ContextMenuController::Create(this)),
      page_scale_constraints_set_(PageScaleConstraintsSet::Create(this)),
      pointer_lock_controller_(PointerLockController::Create(this)),
      browser_controls_(BrowserControls::Create(*this)),
      console_message_storage_(MakeGarbageCollected<ConsoleMessageStorage>()),
      global_root_scroller_controller_(
          TopDocumentRootScrollerController::Create(*this)),
      visual_viewport_(VisualViewport::Create(*this)),
      overscroll_controller_(
          OverscrollController::Create(GetVisualViewport(), GetChromeClient())),
      link_highlights_(LinkHighlights::Create(*this)),
      plugin_data_(nullptr),
      // TODO(pdr): Initialize |validation_message_client_| lazily.
      validation_message_client_(ValidationMessageClientImpl::Create(*this)),
      opened_by_dom_(false),
      tab_key_cycles_through_elements_(true),
      paused_(false),
      device_scale_factor_(1),
      is_hidden_(false),
      page_lifecycle_state_(kDefaultPageLifecycleState),
      is_cursor_visible_(true),
      subframe_count_(0),
      next_related_page_(this),
      prev_related_page_(this),
      autoplay_flags_(0) {
  DCHECK(!AllPages().Contains(this));
  AllPages().insert(this);
}

Page::~Page() {
  // willBeDestroyed() must be called before Page destruction.
  DCHECK(!main_frame_);
}

void Page::CloseSoon() {
  // Make sure this Page can no longer be found by JS.
  is_closing_ = true;

  // TODO(dcheng): Try to remove this in a followup, it's not obviously needed.
  if (main_frame_->IsLocalFrame())
    ToLocalFrame(main_frame_)->Loader().StopAllLoaders();

  GetChromeClient().CloseWindowSoon();
}

ViewportDescription Page::GetViewportDescription() const {
  return MainFrame() && MainFrame()->IsLocalFrame() &&
                 DeprecatedLocalMainFrame()->GetDocument()
             ? DeprecatedLocalMainFrame()
                   ->GetDocument()
                   ->GetViewportData()
                   .GetViewportDescription()
             : ViewportDescription();
}

ScrollingCoordinator* Page::GetScrollingCoordinator() {
  if (!scrolling_coordinator_ && settings_->GetAcceleratedCompositingEnabled())
    scrolling_coordinator_ = ScrollingCoordinator::Create(this);

  return scrolling_coordinator_.Get();
}

PageScaleConstraintsSet& Page::GetPageScaleConstraintsSet() {
  return *page_scale_constraints_set_;
}

const PageScaleConstraintsSet& Page::GetPageScaleConstraintsSet() const {
  return *page_scale_constraints_set_;
}

BrowserControls& Page::GetBrowserControls() {
  return *browser_controls_;
}

const BrowserControls& Page::GetBrowserControls() const {
  return *browser_controls_;
}

ConsoleMessageStorage& Page::GetConsoleMessageStorage() {
  return *console_message_storage_;
}

const ConsoleMessageStorage& Page::GetConsoleMessageStorage() const {
  return *console_message_storage_;
}

TopDocumentRootScrollerController& Page::GlobalRootScrollerController() const {
  return *global_root_scroller_controller_;
}

VisualViewport& Page::GetVisualViewport() {
  return *visual_viewport_;
}

const VisualViewport& Page::GetVisualViewport() const {
  return *visual_viewport_;
}

OverscrollController& Page::GetOverscrollController() {
  return *overscroll_controller_;
}

const OverscrollController& Page::GetOverscrollController() const {
  return *overscroll_controller_;
}

LinkHighlights& Page::GetLinkHighlights() {
  return *link_highlights_;
}

void Page::SetMainFrame(Frame* main_frame) {
  // Should only be called during initialization or swaps between local and
  // remote frames.
  // FIXME: Unfortunately we can't assert on this at the moment, because this
  // is called in the base constructor for both LocalFrame and RemoteFrame,
  // when the vtables for the derived classes have not yet been setup. Once this
  // is fixed, also call  page_scheduler_->SetIsMainFrameLocal() from here
  // instead of from the callers of this method.
  main_frame_ = main_frame;
}

LocalFrame* Page::DeprecatedLocalMainFrame() const {
  return ToLocalFrame(main_frame_);
}

void Page::DocumentDetached(Document* document) {
  pointer_lock_controller_->DocumentDetached(document);
  context_menu_controller_->DocumentDetached(document);
  if (validation_message_client_)
    validation_message_client_->DocumentDetached(*document);
  hosts_using_features_.DocumentDetached(*document);
}

bool Page::OpenedByDOM() const {
  return opened_by_dom_;
}

void Page::SetOpenedByDOM() {
  opened_by_dom_ = true;
}

SpatialNavigationController& Page::GetSpatialNavigationController() {
  DCHECK(GetSettings().GetSpatialNavigationEnabled());
  if (!spatial_navigation_controller_)
    spatial_navigation_controller_ = SpatialNavigationController::Create(*this);
  return *spatial_navigation_controller_;
}

void Page::PlatformColorsChanged() {
  for (const Page* page : AllPages())
    for (Frame* frame = page->MainFrame(); frame;
         frame = frame->Tree().TraverseNext()) {
      if (frame->IsLocalFrame())
        ToLocalFrame(frame)->GetDocument()->PlatformColorsChanged();
    }
}

void Page::InitialStyleChanged() {
  for (Frame* frame = MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    if (!frame->IsLocalFrame())
      continue;
    ToLocalFrame(frame)->GetDocument()->GetStyleEngine().InitialStyleChanged();
  }
}

PluginData* Page::GetPluginData(const SecurityOrigin* main_frame_origin) {
  if (!plugin_data_)
    plugin_data_ = PluginData::Create();

  if (!plugin_data_->Origin() ||
      !main_frame_origin->IsSameSchemeHostPort(plugin_data_->Origin()))
    plugin_data_->UpdatePluginList(main_frame_origin);

  return plugin_data_.Get();
}

void Page::ResetPluginData() {
  for (Page* page : AllPages()) {
    if (page->plugin_data_) {
      page->plugin_data_->ResetPluginData();
      page->NotifyPluginsChanged();
    }
  }
}

static void RestoreSVGImageAnimations() {
  for (const Page* page : AllPages()) {
    if (auto* svg_image_chrome_client =
            ToSVGImageChromeClientOrNull(page->GetChromeClient()))
      svg_image_chrome_client->RestoreAnimationIfNeeded();
  }
}

void Page::SetValidationMessageClientForTesting(
    ValidationMessageClient* client) {
  validation_message_client_ = client;
}

void Page::SetPaused(bool paused) {
  if (paused == paused_)
    return;

  paused_ = paused;
  for (Frame* frame = MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    if (!frame->IsLocalFrame())
      continue;
    LocalFrame* local_frame = ToLocalFrame(frame);
    local_frame->Loader().SetDefersLoading(paused);
    local_frame->GetFrameScheduler()->SetPaused(paused);
  }
}

void Page::SetDefaultPageScaleLimits(float min_scale, float max_scale) {
  PageScaleConstraints new_defaults =
      GetPageScaleConstraintsSet().DefaultConstraints();
  new_defaults.minimum_scale = min_scale;
  new_defaults.maximum_scale = max_scale;

  if (new_defaults == GetPageScaleConstraintsSet().DefaultConstraints())
    return;

  GetPageScaleConstraintsSet().SetDefaultConstraints(new_defaults);
  GetPageScaleConstraintsSet().ComputeFinalConstraints();
  GetPageScaleConstraintsSet().SetNeedsReset(true);

  if (!MainFrame() || !MainFrame()->IsLocalFrame())
    return;

  LocalFrameView* root_view = DeprecatedLocalMainFrame()->View();

  if (!root_view)
    return;

  root_view->SetNeedsLayout();
}

void Page::SetUserAgentPageScaleConstraints(
    const PageScaleConstraints& new_constraints) {
  if (new_constraints == GetPageScaleConstraintsSet().UserAgentConstraints())
    return;

  GetPageScaleConstraintsSet().SetUserAgentConstraints(new_constraints);

  if (!MainFrame() || !MainFrame()->IsLocalFrame())
    return;

  LocalFrameView* root_view = DeprecatedLocalMainFrame()->View();

  if (!root_view)
    return;

  root_view->SetNeedsLayout();
}

void Page::SetPageScaleFactor(float scale) {
  GetVisualViewport().SetScale(scale);
}

float Page::PageScaleFactor() const {
  return GetVisualViewport().Scale();
}

void Page::SetDeviceScaleFactorDeprecated(float scale_factor) {
  if (device_scale_factor_ == scale_factor)
    return;

  device_scale_factor_ = scale_factor;

  if (MainFrame() && MainFrame()->IsLocalFrame())
    DeprecatedLocalMainFrame()->DeviceScaleFactorChanged();
}

void Page::AllVisitedStateChanged(bool invalidate_visited_link_hashes) {
  for (const Page* page : OrdinaryPages()) {
    for (Frame* frame = page->main_frame_; frame;
         frame = frame->Tree().TraverseNext()) {
      if (frame->IsLocalFrame())
        ToLocalFrame(frame)
            ->GetDocument()
            ->GetVisitedLinkState()
            .InvalidateStyleForAllLinks(invalidate_visited_link_hashes);
    }
  }
}

void Page::VisitedStateChanged(LinkHash link_hash) {
  for (const Page* page : OrdinaryPages()) {
    for (Frame* frame = page->main_frame_; frame;
         frame = frame->Tree().TraverseNext()) {
      if (frame->IsLocalFrame())
        ToLocalFrame(frame)
            ->GetDocument()
            ->GetVisitedLinkState()
            .InvalidateStyleForLink(link_hash);
    }
  }
}

void Page::SetIsHidden(bool hidden, bool is_initial_state) {
  if (is_hidden_ == hidden)
    return;
  is_hidden_ = hidden;

  if (is_initial_state)
    return;

  NotifyPageVisibilityChanged();
  if (main_frame_) {
    if (IsPageVisible())
      RestoreSVGImageAnimations();
    main_frame_->DidChangeVisibilityState();
  }
}

bool Page::IsPageVisible() const {
  return !is_hidden_;
}

void Page::SetLifecycleState(PageLifecycleState state) {
  if (state == page_lifecycle_state_)
    return;
  DCHECK_NE(state, PageLifecycleState::kUnknown);

  if (RuntimeEnabledFeatures::PageLifecycleEnabled()) {
    if (state == PageLifecycleState::kFrozen) {
      for (Frame* frame = main_frame_.Get(); frame;
           frame = frame->Tree().TraverseNext()) {
        frame->DidFreeze();
      }
    } else if (page_lifecycle_state_ == PageLifecycleState::kFrozen) {
      // TODO(fmeawad): Only resume the page that just became visible, blocked
      // on task queues per frame.
      DCHECK(state == PageLifecycleState::kActive ||
             state == PageLifecycleState::kHiddenBackgrounded ||
             state == PageLifecycleState::kHiddenForegrounded);
      for (Frame* frame = main_frame_.Get(); frame;
           frame = frame->Tree().TraverseNext()) {
        frame->DidResume();
      }
    }
  }
  page_lifecycle_state_ = state;
}

PageLifecycleState Page::LifecycleState() const {
  return page_lifecycle_state_;
}

bool Page::IsCursorVisible() const {
  return is_cursor_visible_;
}

#if DCHECK_IS_ON()
void CheckFrameCountConsistency(int expected_frame_count, Frame* frame) {
  DCHECK_GE(expected_frame_count, 0);

  int actual_frame_count = 0;
  for (; frame; frame = frame->Tree().TraverseNext())
    ++actual_frame_count;

  DCHECK_EQ(expected_frame_count, actual_frame_count);
}
#endif

int Page::SubframeCount() const {
#if DCHECK_IS_ON()
  CheckFrameCountConsistency(subframe_count_ + 1, MainFrame());
#endif
  return subframe_count_;
}

void Page::SettingsChanged(SettingsDelegate::ChangeType change_type) {
  switch (change_type) {
    case SettingsDelegate::kStyleChange:
      InitialStyleChanged();
      break;
    case SettingsDelegate::kViewportDescriptionChange:
      if (MainFrame() && MainFrame()->IsLocalFrame()) {
        DeprecatedLocalMainFrame()
            ->GetDocument()
            ->GetViewportData()
            .UpdateViewportDescription();
        // The text autosizer has dependencies on the viewport.
        if (TextAutosizer* text_autosizer =
                DeprecatedLocalMainFrame()->GetDocument()->GetTextAutosizer())
          text_autosizer->UpdatePageInfoInAllFrames();
      }
      break;
    case SettingsDelegate::kViewportScrollbarChange:
      GetVisualViewport().InitializeScrollbars();
      break;
    case SettingsDelegate::kDNSPrefetchingChange:
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (frame->IsLocalFrame())
          ToLocalFrame(frame)->GetDocument()->InitDNSPrefetch();
      }
      break;
    case SettingsDelegate::kImageLoadingChange:
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (frame->IsLocalFrame()) {
          ToLocalFrame(frame)->GetDocument()->Fetcher()->SetImagesEnabled(
              GetSettings().GetImagesEnabled());
          ToLocalFrame(frame)->GetDocument()->Fetcher()->SetAutoLoadImages(
              GetSettings().GetLoadsImagesAutomatically());
        }
      }
      break;
    case SettingsDelegate::kTextAutosizingChange:
      if (!MainFrame() || !MainFrame()->IsLocalFrame())
        break;
      if (TextAutosizer* text_autosizer =
              DeprecatedLocalMainFrame()->GetDocument()->GetTextAutosizer())
        text_autosizer->UpdatePageInfoInAllFrames();
      break;
    case SettingsDelegate::kFontFamilyChange:
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (frame->IsLocalFrame())
          ToLocalFrame(frame)
              ->GetDocument()
              ->GetStyleEngine()
              .UpdateGenericFontFamilySettings();
      }
      break;
    case SettingsDelegate::kAcceleratedCompositingChange:
      UpdateAcceleratedCompositingSettings();
      break;
    case SettingsDelegate::kMediaQueryChange:
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (frame->IsLocalFrame())
          ToLocalFrame(frame)->GetDocument()->MediaQueryAffectingValueChanged();
      }
      break;
    case SettingsDelegate::kAccessibilityStateChange:
      if (!MainFrame() || !MainFrame()->IsLocalFrame())
        break;
      DeprecatedLocalMainFrame()
          ->GetDocument()
          ->AXObjectCacheOwner()
          .ClearAXObjectCache();
      break;
    case SettingsDelegate::kViewportRuleChange: {
      if (!MainFrame() || !MainFrame()->IsLocalFrame())
        break;
      if (Document* doc = ToLocalFrame(MainFrame())->GetDocument())
        doc->GetStyleEngine().ViewportRulesChanged();
      break;
    }
    case SettingsDelegate::kTextTrackKindUserPreferenceChange:
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (frame->IsLocalFrame()) {
          Document* doc = ToLocalFrame(frame)->GetDocument();
          if (doc)
            HTMLMediaElement::SetTextTrackKindUserPreferenceForAllMediaElements(
                doc);
        }
      }
      break;
    case SettingsDelegate::kDOMWorldsChange: {
      if (!GetSettings().GetForceMainWorldInitialization())
        break;
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (!frame->IsLocalFrame())
          continue;
        LocalFrame* local_frame = ToLocalFrame(frame);
        if (!local_frame->Loader()
                 .StateMachine()
                 ->CreatingInitialEmptyDocument()) {
          // Forcibly instantiate WindowProxy.
          local_frame->GetScriptController().WindowProxy(
              DOMWrapperWorld::MainWorld());
        }
      }
      break;
    }
    case SettingsDelegate::kMediaControlsChange:
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (!frame->IsLocalFrame())
          continue;
        Document* doc = ToLocalFrame(frame)->GetDocument();
        if (doc)
          HTMLMediaElement::OnMediaControlsEnabledChange(doc);
      }
      break;
    case SettingsDelegate::kPluginsChange: {
      NotifyPluginsChanged();
      break;
    }
    case SettingsDelegate::kHighlightAdsChange: {
      for (Frame* frame = MainFrame(); frame;
           frame = frame->Tree().TraverseNext()) {
        if (frame->IsLocalFrame())
          ToLocalFrame(frame)->UpdateAdHighlight();
      }
      break;
    }
  }
}

void Page::NotifyPluginsChanged() const {
  HeapVector<Member<PluginsChangedObserver>, 32> observers;
  CopyToVector(plugins_changed_observers_, observers);
  for (PluginsChangedObserver* observer : observers)
    observer->PluginsChanged();
}

void Page::UpdateAcceleratedCompositingSettings() {
  for (Frame* frame = MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    if (!frame->IsLocalFrame())
      continue;
    if (LocalFrameView* view = ToLocalFrame(frame)->View())
      view->UpdateAcceleratedCompositingSettings();
  }
}

void Page::DidCommitLoad(LocalFrame* frame) {
  if (main_frame_ == frame) {
    GetConsoleMessageStorage().Clear();
    // TODO(loonybear): Most of this doesn't appear to take into account that
    // each SVGImage gets it's own Page instance.
    GetDeprecation().ClearSuppression();
    GetVisualViewport().SendUMAMetrics();
    // Need to reset visual viewport position here since before commit load we
    // would update the previous history item, Page::didCommitLoad is called
    // after a new history item is created in FrameLoader.
    // See crbug.com/642279
    GetVisualViewport().SetScrollOffset(ScrollOffset(), kProgrammaticScroll);
    hosts_using_features_.UpdateMeasurementsAndClear();
  }
  GetLinkHighlights().ResetForPageNavigation();
}

void Page::AcceptLanguagesChanged() {
  HeapVector<Member<LocalFrame>> frames;

  // Even though we don't fire an event from here, the LocalDOMWindow's will
  // fire an event so we keep the frames alive until we are done.
  for (Frame* frame = MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    if (frame->IsLocalFrame())
      frames.push_back(ToLocalFrame(frame));
  }

  for (unsigned i = 0; i < frames.size(); ++i)
    frames[i]->DomWindow()->AcceptLanguagesChanged();
}

void Page::Trace(blink::Visitor* visitor) {
  visitor->Trace(animator_);
  visitor->Trace(autoscroll_controller_);
  visitor->Trace(chrome_client_);
  visitor->Trace(drag_caret_);
  visitor->Trace(drag_controller_);
  visitor->Trace(focus_controller_);
  visitor->Trace(context_menu_controller_);
  visitor->Trace(page_scale_constraints_set_);
  visitor->Trace(pointer_lock_controller_);
  visitor->Trace(scrolling_coordinator_);
  visitor->Trace(browser_controls_);
  visitor->Trace(console_message_storage_);
  visitor->Trace(global_root_scroller_controller_);
  visitor->Trace(visual_viewport_);
  visitor->Trace(overscroll_controller_);
  visitor->Trace(link_highlights_);
  visitor->Trace(spatial_navigation_controller_);
  visitor->Trace(main_frame_);
  visitor->Trace(plugin_data_);
  visitor->Trace(validation_message_client_);
  visitor->Trace(plugins_changed_observers_);
  visitor->Trace(next_related_page_);
  visitor->Trace(prev_related_page_);
  Supplementable<Page>::Trace(visitor);
  PageVisibilityNotifier::Trace(visitor);
}

void Page::LayerTreeViewInitialized(WebLayerTreeView& layer_tree_view,
                                    LocalFrameView* view) {
  if (GetScrollingCoordinator())
    GetScrollingCoordinator()->LayerTreeViewInitialized(layer_tree_view, view);
  GetLinkHighlights().LayerTreeViewInitialized(layer_tree_view);
}

void Page::WillCloseLayerTreeView(WebLayerTreeView& layer_tree_view,
                                  LocalFrameView* view) {
  if (scrolling_coordinator_)
    scrolling_coordinator_->WillCloseLayerTreeView(layer_tree_view, view);
  GetLinkHighlights().WillCloseLayerTreeView(layer_tree_view);
}

void Page::WillBeDestroyed() {
  Frame* main_frame = main_frame_;

  main_frame->Detach(FrameDetachType::kRemove);

  DCHECK(AllPages().Contains(this));
  AllPages().erase(this);
  OrdinaryPages().erase(this);

  {
    // Before: ... -> prev -> this -> next -> ...
    // After: ... -> prev -> next -> ...
    // (this is ok even if |this| is the only element on the list).
    Page* prev = this->prev_related_page_;
    Page* next = this->next_related_page_;
    next->prev_related_page_ = prev;
    prev->next_related_page_ = next;
    this->prev_related_page_ = nullptr;
    this->next_related_page_ = nullptr;
  }

  if (scrolling_coordinator_)
    scrolling_coordinator_->WillBeDestroyed();

  GetChromeClient().ChromeDestroyed();
  if (validation_message_client_)
    validation_message_client_->WillBeDestroyed();
  main_frame_ = nullptr;

  PageVisibilityNotifier::NotifyContextDestroyed();

  page_scheduler_.reset();
}

void Page::RegisterPluginsChangedObserver(PluginsChangedObserver* observer) {
  plugins_changed_observers_.insert(observer);
}

ScrollbarTheme& Page::GetScrollbarTheme() const {
  if (settings_->GetForceAndroidOverlayScrollbar())
    return ScrollbarThemeOverlay::MobileTheme();
  return ScrollbarTheme::DeprecatedStaticGetTheme();
}

PageScheduler* Page::GetPageScheduler() const {
  return page_scheduler_.get();
}

void Page::SetPageScheduler(std::unique_ptr<PageScheduler> page_scheduler) {
  page_scheduler_ = std::move(page_scheduler);
  // The scheduler should be set before the main frame.
  DCHECK(!main_frame_);
}

void Page::ReportIntervention(const String& text) {
  if (LocalFrame* local_frame = DeprecatedLocalMainFrame()) {
    ConsoleMessage* message =
        ConsoleMessage::Create(kOtherMessageSource, kWarningMessageLevel, text,
                               SourceLocation::Create(String(), 0, 0, nullptr));
    local_frame->GetDocument()->AddConsoleMessage(message);
  }
}

bool Page::RequestBeginMainFrameNotExpected(bool new_state) {
  if (!main_frame_ || !main_frame_->IsLocalFrame())
    return false;

  base::debug::StackTrace main_frame_created_trace =
      main_frame_->CreateStackForDebugging();
  base::debug::Alias(&main_frame_created_trace);
  base::debug::StackTrace main_frame_detached_trace =
      main_frame_->DetachStackForDebugging();
  base::debug::Alias(&main_frame_detached_trace);
  CHECK(main_frame_->IsAttached());
  if (LocalFrame* main_frame = DeprecatedLocalMainFrame()) {
    if (WebLayerTreeView* layer_tree_view =
            chrome_client_->GetWebLayerTreeView(main_frame)) {
      layer_tree_view->RequestBeginMainFrameNotExpected(new_state);
      return true;
    }
  }
  return false;
}

void Page::AddAutoplayFlags(int32_t value) {
  autoplay_flags_ |= value;
}

void Page::ClearAutoplayFlags() {
  autoplay_flags_ = 0;
}

int32_t Page::AutoplayFlags() const {
  return autoplay_flags_;
}

void Page::SetInsidePortal(bool inside_portal) {
  inside_portal_ = inside_portal;
}

bool Page::InsidePortal() const {
  return inside_portal_;
}

Page::PageClients::PageClients() : chrome_client(nullptr) {}

Page::PageClients::~PageClients() = default;

template class CORE_TEMPLATE_EXPORT Supplement<Page>;

}  // namespace blink
