| /* |
| * 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/layout_view.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; |
| mojom::FrameLifecycleState state = paused |
| ? mojom::FrameLifecycleState::kPaused |
| : mojom::FrameLifecycleState::kRunning; |
| for (Frame* frame = MainFrame(); frame; |
| frame = frame->Tree().TraverseNext()) { |
| if (!frame->IsLocalFrame()) |
| continue; |
| ToLocalFrame(frame)->SetLifecycleState(state); |
| } |
| } |
| |
| 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; |
| } |
| case SettingsDelegate::kPaintChange: |
| for (Frame* frame = MainFrame(); frame; |
| frame = frame->Tree().TraverseNext()) { |
| if (!frame->IsLocalFrame()) |
| continue; |
| if (LayoutView* view = ToLocalFrame(frame)->ContentLayoutObject()) |
| view->InvalidatePaintForViewAndCompositedLayers(); |
| } |
| 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, |
| cc::AnimationHost& animation_host, |
| LocalFrameView* view) { |
| if (GetScrollingCoordinator()) { |
| GetScrollingCoordinator()->LayerTreeViewInitialized(layer_tree_view, |
| animation_host, view); |
| } |
| GetLinkHighlights().LayerTreeViewInitialized(layer_tree_view, animation_host); |
| } |
| |
| 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 |