ba4259a9a7cafb56549f07a01b2a7fb88a60075e
[platform/framework/web/chromium-efl.git] / third_party / blink / renderer / core / page / page.cc
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All
3  * Rights Reserved.
4  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved.
5  * (http://www.torchmobile.com/)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #include "third_party/blink/renderer/core/page/page.h"
23
24 #include "base/compiler_specific.h"
25 #include "base/feature_list.h"
26 #include "third_party/blink/public/common/features.h"
27 #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
28 #include "third_party/blink/public/platform/platform.h"
29
30 #if BUILDFLAG(IS_EFL)
31 #include "third_party/blink/public/platform/web_runtime_features.h"
32 #endif
33
34 #include "third_party/blink/public/web/blink.h"
35 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
36 #include "third_party/blink/renderer/core/core_export.h"
37 #include "third_party/blink/renderer/core/css/media_feature_overrides.h"
38 #include "third_party/blink/renderer/core/css/style_change_reason.h"
39 #include "third_party/blink/renderer/core/css/style_engine.h"
40 #include "third_party/blink/renderer/core/css/vision_deficiency.h"
41 #include "third_party/blink/renderer/core/dom/events/event.h"
42 #include "third_party/blink/renderer/core/dom/node_rare_data.h"
43 #include "third_party/blink/renderer/core/dom/visited_link_state.h"
44 #include "third_party/blink/renderer/core/editing/drag_caret.h"
45 #include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
46 #include "third_party/blink/renderer/core/frame/browser_controls.h"
47 #include "third_party/blink/renderer/core/frame/event_handler_registry.h"
48 #include "third_party/blink/renderer/core/frame/frame_console.h"
49 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
50 #include "third_party/blink/renderer/core/frame/local_frame.h"
51 #include "third_party/blink/renderer/core/frame/local_frame_client.h"
52 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
53 #include "third_party/blink/renderer/core/frame/page_scale_constraints.h"
54 #include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
55 #include "third_party/blink/renderer/core/frame/remote_frame.h"
56 #include "third_party/blink/renderer/core/frame/remote_frame_view.h"
57 #include "third_party/blink/renderer/core/frame/settings.h"
58 #include "third_party/blink/renderer/core/frame/viewport_data.h"
59 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
60 #include "third_party/blink/renderer/core/html/fenced_frame/document_fenced_frames.h"
61 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
62 #include "third_party/blink/renderer/core/html/portal/document_portals.h"
63 #include "third_party/blink/renderer/core/inspector/console_message.h"
64 #include "third_party/blink/renderer/core/inspector/console_message_storage.h"
65 #include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
66 #include "third_party/blink/renderer/core/layout/layout_view.h"
67 #include "third_party/blink/renderer/core/layout/text_autosizer.h"
68 #include "third_party/blink/renderer/core/loader/idleness_detector.h"
69 #include "third_party/blink/renderer/core/page/autoscroll_controller.h"
70 #include "third_party/blink/renderer/core/page/chrome_client.h"
71 #include "third_party/blink/renderer/core/page/context_menu_controller.h"
72 #include "third_party/blink/renderer/core/page/drag_controller.h"
73 #include "third_party/blink/renderer/core/page/focus_controller.h"
74 #include "third_party/blink/renderer/core/page/link_highlight.h"
75 #include "third_party/blink/renderer/core/page/page_animator.h"
76 #include "third_party/blink/renderer/core/page/page_hidden_state.h"
77 #include "third_party/blink/renderer/core/page/plugin_data.h"
78 #include "third_party/blink/renderer/core/page/plugins_changed_observer.h"
79 #include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
80 #include "third_party/blink/renderer/core/page/scoped_browsing_context_group_pauser.h"
81 #include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
82 #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
83 #include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
84 #include "third_party/blink/renderer/core/page/spatial_navigation_controller.h"
85 #include "third_party/blink/renderer/core/page/validation_message_client_impl.h"
86 #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
87 #include "third_party/blink/renderer/core/preferences/preference_overrides.h"
88 #include "third_party/blink/renderer/core/probe/core_probes.h"
89 #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
90 #include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mobile.h"
91 #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
92 #include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h"
93 #include "third_party/blink/renderer/platform/bindings/source_location.h"
94 #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
95 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
96 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
97 #include "third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h"
98 #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
99 #include "third_party/skia/include/core/SkColor.h"
100
101 namespace blink {
102
103 namespace {
104 // This seems like a reasonable upper bound, and otherwise mutually
105 // recursive frameset pages can quickly bring the program to its knees
106 // with exponential growth in the number of frames.
107 const int kMaxNumberOfFrames = 1000;
108
109 // It is possible to use a reduced frame limit for testing, but only two values
110 // are permitted, the default or reduced limit.
111 const int kTenFrames = 10;
112
113 bool g_limit_max_frames_to_ten_for_testing = false;
114
115 }  // namespace
116
117 // Function defined in third_party/blink/public/web/blink.h.
118 void ResetPluginCache(bool reload_pages) {
119   // At this point we already know that the browser has refreshed its list, so
120   // it is not necessary to force it to be regenerated.
121   DCHECK(!reload_pages);
122   Page::ResetPluginData();
123 }
124
125 // Set of all live pages; includes internal Page objects that are
126 // not observable from scripts.
127 static Page::PageSet& AllPages() {
128   DEFINE_STATIC_LOCAL(Persistent<Page::PageSet>, pages,
129                       (MakeGarbageCollected<Page::PageSet>()));
130   return *pages;
131 }
132
133 Page::PageSet& Page::OrdinaryPages() {
134   DEFINE_STATIC_LOCAL(Persistent<Page::PageSet>, pages,
135                       (MakeGarbageCollected<Page::PageSet>()));
136   return *pages;
137 }
138
139 void Page::InsertOrdinaryPageForTesting(Page* page) {
140   OrdinaryPages().insert(page);
141 }
142
143 HeapVector<Member<Page>> Page::RelatedPages() {
144   HeapVector<Member<Page>> result;
145   Page* ptr = next_related_page_;
146   while (ptr != this) {
147     result.push_back(ptr);
148     ptr = ptr->next_related_page_;
149   }
150   return result;
151 }
152
153 Page* Page::CreateNonOrdinary(ChromeClient& chrome_client,
154                               AgentGroupScheduler& agent_group_scheduler) {
155   return MakeGarbageCollected<Page>(
156       base::PassKey<Page>(), chrome_client, agent_group_scheduler,
157       BrowsingContextGroupInfo::CreateUnique(), /*is_ordinary=*/false);
158 }
159
160 Page* Page::CreateOrdinary(
161     ChromeClient& chrome_client,
162     Page* opener,
163     AgentGroupScheduler& agent_group_scheduler,
164     const BrowsingContextGroupInfo& browsing_context_group_info) {
165   Page* page = MakeGarbageCollected<Page>(
166       base::PassKey<Page>(), chrome_client, agent_group_scheduler,
167       browsing_context_group_info, /*is_ordinary=*/true);
168
169   if (opener) {
170     // Before: ... -> opener -> next -> ...
171     // After: ... -> opener -> page -> next -> ...
172     Page* next = opener->next_related_page_;
173     opener->next_related_page_ = page;
174     page->prev_related_page_ = opener;
175     page->next_related_page_ = next;
176     next->prev_related_page_ = page;
177   }
178
179   OrdinaryPages().insert(page);
180
181   bool should_pause = false;
182   if (base::FeatureList::IsEnabled(
183           features::kPausePagesPerBrowsingContextGroup)) {
184     should_pause = ScopedBrowsingContextGroupPauser::IsActive(*page);
185   } else {
186     should_pause = ScopedPagePauser::IsActive();
187   }
188   if (should_pause) {
189     page->SetPaused(true);
190   }
191
192   return page;
193 }
194
195 Page::Page(base::PassKey<Page>,
196            ChromeClient& chrome_client,
197            AgentGroupScheduler& agent_group_scheduler,
198            const BrowsingContextGroupInfo& browsing_context_group_info,
199            bool is_ordinary)
200     : SettingsDelegate(std::make_unique<Settings>()),
201       main_frame_(nullptr),
202       agent_group_scheduler_(agent_group_scheduler),
203       animator_(MakeGarbageCollected<PageAnimator>(*this)),
204       autoscroll_controller_(MakeGarbageCollected<AutoscrollController>(*this)),
205       chrome_client_(&chrome_client),
206       drag_caret_(MakeGarbageCollected<DragCaret>()),
207       drag_controller_(MakeGarbageCollected<DragController>(this)),
208       focus_controller_(MakeGarbageCollected<FocusController>(this)),
209       context_menu_controller_(
210           MakeGarbageCollected<ContextMenuController>(this)),
211       page_scale_constraints_set_(
212           MakeGarbageCollected<PageScaleConstraintsSet>(this)),
213       pointer_lock_controller_(
214           MakeGarbageCollected<PointerLockController>(this)),
215       browser_controls_(MakeGarbageCollected<BrowserControls>(*this)),
216       console_message_storage_(MakeGarbageCollected<ConsoleMessageStorage>()),
217       global_root_scroller_controller_(
218           MakeGarbageCollected<TopDocumentRootScrollerController>(*this)),
219       visual_viewport_(MakeGarbageCollected<VisualViewport>(*this)),
220       link_highlight_(MakeGarbageCollected<LinkHighlight>(*this)),
221       plugin_data_(nullptr),
222       // TODO(pdr): Initialize |validation_message_client_| lazily.
223       validation_message_client_(
224           MakeGarbageCollected<ValidationMessageClientImpl>(*this)),
225       opened_by_dom_(false),
226       tab_key_cycles_through_elements_(true),
227       inspector_device_scale_factor_override_(1),
228       lifecycle_state_(mojom::blink::PageLifecycleState::New()),
229       is_ordinary_(is_ordinary),
230       is_cursor_visible_(true),
231       subframe_count_(0),
232       next_related_page_(this),
233       prev_related_page_(this),
234       autoplay_flags_(0),
235 #if BUILDFLAG(IS_TIZEN)
236       m_isSuspended(false),
237 #endif
238       web_text_autosizer_page_info_({0, 0, 1.f}),
239       v8_compile_hints_producer_(
240           MakeGarbageCollected<
241               v8_compile_hints::V8CrowdsourcedCompileHintsProducer>(this)),
242       v8_compile_hints_consumer_(
243           MakeGarbageCollected<
244               v8_compile_hints::V8CrowdsourcedCompileHintsConsumer>()),
245       browsing_context_group_info_(browsing_context_group_info) {
246   DCHECK(!AllPages().Contains(this));
247   AllPages().insert(this);
248
249   page_scheduler_ = agent_group_scheduler_->CreatePageScheduler(this);
250   // The scheduler should be set before the main frame.
251   DCHECK(!main_frame_);
252   if (auto* virtual_time_controller =
253           page_scheduler_->GetVirtualTimeController()) {
254     history_navigation_virtual_time_pauser_ =
255         virtual_time_controller->CreateWebScopedVirtualTimePauser(
256             "HistoryNavigation",
257             WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant);
258   }
259 }
260
261 Page::~Page() {
262   // WillBeDestroyed() must be called before Page destruction.
263   DCHECK(!main_frame_);
264 }
265
266 void Page::CloseSoon() {
267   // Make sure this Page can no longer be found by JS.
268   is_closing_ = true;
269
270   // TODO(dcheng): Try to remove this in a followup, it's not obviously needed.
271   if (auto* main_local_frame = DynamicTo<LocalFrame>(main_frame_.Get()))
272     main_local_frame->Loader().StopAllLoaders(/*abort_client=*/true);
273
274   GetChromeClient().CloseWindowSoon();
275 }
276
277 ViewportDescription Page::GetViewportDescription() const {
278   return MainFrame() && MainFrame()->IsLocalFrame() &&
279                  DeprecatedLocalMainFrame()->GetDocument()
280              ? DeprecatedLocalMainFrame()
281                    ->GetDocument()
282                    ->GetViewportData()
283                    .GetViewportDescription()
284              : ViewportDescription();
285 }
286
287 ScrollingCoordinator* Page::GetScrollingCoordinator() {
288   if (!scrolling_coordinator_ && settings_->GetAcceleratedCompositingEnabled())
289     scrolling_coordinator_ = MakeGarbageCollected<ScrollingCoordinator>(this);
290
291   return scrolling_coordinator_.Get();
292 }
293
294 PageScaleConstraintsSet& Page::GetPageScaleConstraintsSet() {
295   return *page_scale_constraints_set_;
296 }
297
298 const PageScaleConstraintsSet& Page::GetPageScaleConstraintsSet() const {
299   return *page_scale_constraints_set_;
300 }
301
302 BrowserControls& Page::GetBrowserControls() {
303   return *browser_controls_;
304 }
305
306 const BrowserControls& Page::GetBrowserControls() const {
307   return *browser_controls_;
308 }
309
310 ConsoleMessageStorage& Page::GetConsoleMessageStorage() {
311   return *console_message_storage_;
312 }
313
314 const ConsoleMessageStorage& Page::GetConsoleMessageStorage() const {
315   return *console_message_storage_;
316 }
317
318 InspectorIssueStorage& Page::GetInspectorIssueStorage() {
319   return inspector_issue_storage_;
320 }
321
322 const InspectorIssueStorage& Page::GetInspectorIssueStorage() const {
323   return inspector_issue_storage_;
324 }
325
326 TopDocumentRootScrollerController& Page::GlobalRootScrollerController() const {
327   return *global_root_scroller_controller_;
328 }
329
330 VisualViewport& Page::GetVisualViewport() {
331   return *visual_viewport_;
332 }
333
334 const VisualViewport& Page::GetVisualViewport() const {
335   return *visual_viewport_;
336 }
337
338 LinkHighlight& Page::GetLinkHighlight() {
339   return *link_highlight_;
340 }
341
342 void Page::SetMainFrame(Frame* main_frame) {
343   // TODO(https://crbug.com/952836): Assert that this is only called during
344   // initialization or swaps between local and remote frames.
345   main_frame_ = main_frame;
346
347   page_scheduler_->SetIsMainFrameLocal(main_frame->IsLocalFrame());
348 }
349
350 LocalFrame* Page::DeprecatedLocalMainFrame() const {
351   return To<LocalFrame>(main_frame_.Get());
352 }
353
354 void Page::DocumentDetached(Document* document) {
355   pointer_lock_controller_->DocumentDetached(document);
356   context_menu_controller_->DocumentDetached(document);
357   if (validation_message_client_)
358     validation_message_client_->DocumentDetached(*document);
359
360   GetChromeClient().DocumentDetached(*document);
361 }
362
363 bool Page::OpenedByDOM() const {
364   return opened_by_dom_;
365 }
366
367 void Page::SetOpenedByDOM() {
368   opened_by_dom_ = true;
369 }
370
371 SpatialNavigationController& Page::GetSpatialNavigationController() {
372   if (!spatial_navigation_controller_) {
373     spatial_navigation_controller_ =
374         MakeGarbageCollected<SpatialNavigationController>(*this);
375   }
376   return *spatial_navigation_controller_;
377 }
378
379 void Page::UsesOverlayScrollbarsChanged() {
380   for (Page* page : AllPages()) {
381     for (Frame* frame = page->MainFrame(); frame;
382          frame = frame->Tree().TraverseNext()) {
383       if (auto* local_frame = DynamicTo<LocalFrame>(frame))
384         local_frame->View()->UsesOverlayScrollbarsChanged();
385     }
386   }
387 }
388
389 void Page::PlatformColorsChanged() {
390   for (const Page* page : AllPages()) {
391     for (Frame* frame = page->MainFrame(); frame;
392          frame = frame->Tree().TraverseNext()) {
393       if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
394         local_frame->GetDocument()->PlatformColorsChanged();
395         if (LayoutView* view = local_frame->ContentLayoutObject())
396           view->InvalidatePaintForViewAndDescendants();
397       }
398     }
399   }
400 }
401
402 void Page::ColorSchemeChanged() {
403   for (const Page* page : AllPages())
404     for (Frame* frame = page->MainFrame(); frame;
405          frame = frame->Tree().TraverseNext()) {
406       if (auto* local_frame = DynamicTo<LocalFrame>(frame))
407         local_frame->GetDocument()->ColorSchemeChanged();
408     }
409 }
410
411 void Page::ColorProvidersChanged() {
412   for (Page* page : AllPages())
413     page->InvalidatePaint();
414 }
415
416 void Page::InitialStyleChanged() {
417   for (Frame* frame = MainFrame(); frame;
418        frame = frame->Tree().TraverseNext()) {
419     auto* local_frame = DynamicTo<LocalFrame>(frame);
420     if (!local_frame)
421       continue;
422     local_frame->GetDocument()->GetStyleEngine().InitialStyleChanged();
423   }
424 }
425
426 PluginData* Page::GetPluginData() {
427   if (!plugin_data_)
428     plugin_data_ = MakeGarbageCollected<PluginData>();
429
430   plugin_data_->UpdatePluginList();
431   return plugin_data_.Get();
432 }
433
434 void Page::ResetPluginData() {
435   for (Page* page : AllPages()) {
436     if (page->plugin_data_) {
437       page->plugin_data_->ResetPluginData();
438       page->NotifyPluginsChanged();
439     }
440   }
441 }
442
443 static void RestoreSVGImageAnimations() {
444   for (const Page* page : AllPages()) {
445     if (auto* svg_image_chrome_client =
446             DynamicTo<SVGImageChromeClient>(page->GetChromeClient()))
447       svg_image_chrome_client->RestoreAnimationIfNeeded();
448   }
449 }
450
451 void Page::SetValidationMessageClientForTesting(
452     ValidationMessageClient* client) {
453   validation_message_client_ = client;
454 }
455
456 void Page::SetPaused(bool paused) {
457   if (paused == paused_)
458     return;
459
460   paused_ = paused;
461   for (Frame* frame = MainFrame(); frame;
462        frame = frame->Tree().TraverseNext()) {
463     if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
464       local_frame->OnPageLifecycleStateUpdated();
465     }
466   }
467 }
468
469 void Page::SetDefaultPageScaleLimits(float min_scale, float max_scale) {
470   PageScaleConstraints new_defaults =
471       GetPageScaleConstraintsSet().DefaultConstraints();
472   new_defaults.minimum_scale = min_scale;
473   new_defaults.maximum_scale = max_scale;
474
475   if (new_defaults == GetPageScaleConstraintsSet().DefaultConstraints())
476     return;
477
478   GetPageScaleConstraintsSet().SetDefaultConstraints(new_defaults);
479   GetPageScaleConstraintsSet().ComputeFinalConstraints();
480   GetPageScaleConstraintsSet().SetNeedsReset(true);
481
482   if (!MainFrame() || !MainFrame()->IsLocalFrame())
483     return;
484
485   LocalFrameView* root_view = DeprecatedLocalMainFrame()->View();
486
487   if (!root_view)
488     return;
489
490   root_view->SetNeedsLayout();
491 }
492
493 void Page::SetUserAgentPageScaleConstraints(
494     const PageScaleConstraints& new_constraints) {
495   if (new_constraints == GetPageScaleConstraintsSet().UserAgentConstraints())
496     return;
497
498   GetPageScaleConstraintsSet().SetUserAgentConstraints(new_constraints);
499
500   if (!MainFrame() || !MainFrame()->IsLocalFrame())
501     return;
502
503   LocalFrameView* root_view = DeprecatedLocalMainFrame()->View();
504
505   if (!root_view)
506     return;
507
508   root_view->SetNeedsLayout();
509 }
510
511 void Page::SetPageScaleFactor(float scale) {
512   GetVisualViewport().SetScale(scale);
513 }
514
515 float Page::PageScaleFactor() const {
516   return GetVisualViewport().Scale();
517 }
518
519 void Page::AllVisitedStateChanged(bool invalidate_visited_link_hashes) {
520   for (const Page* page : OrdinaryPages()) {
521     for (Frame* frame = page->main_frame_; frame;
522          frame = frame->Tree().TraverseNext()) {
523       if (auto* main_local_frame = DynamicTo<LocalFrame>(frame))
524         main_local_frame->GetDocument()
525             ->GetVisitedLinkState()
526             .InvalidateStyleForAllLinks(invalidate_visited_link_hashes);
527     }
528   }
529 }
530
531 void Page::VisitedStateChanged(LinkHash link_hash) {
532   for (const Page* page : OrdinaryPages()) {
533     for (Frame* frame = page->main_frame_; frame;
534          frame = frame->Tree().TraverseNext()) {
535       if (auto* main_local_frame = DynamicTo<LocalFrame>(frame))
536         main_local_frame->GetDocument()
537             ->GetVisitedLinkState()
538             .InvalidateStyleForLink(link_hash);
539     }
540   }
541 }
542
543 void Page::SetVisibilityState(
544     mojom::blink::PageVisibilityState visibility_state,
545     bool is_initial_state) {
546   if (lifecycle_state_->visibility == visibility_state)
547     return;
548
549   // Are we entering / leaving a state that would map to the "visible" state, in
550   // the `document.visibilityState` sense?
551   const bool was_visible = lifecycle_state_->visibility ==
552                            mojom::blink::PageVisibilityState::kVisible;
553   const bool is_visible =
554       visibility_state == mojom::blink::PageVisibilityState::kVisible;
555
556   lifecycle_state_->visibility = visibility_state;
557
558   if (is_initial_state)
559     return;
560
561   for (auto observer : page_visibility_observer_set_) {
562     observer->PageVisibilityChanged();
563   }
564
565   if (main_frame_) {
566     if (lifecycle_state_->visibility ==
567         mojom::blink::PageVisibilityState::kVisible) {
568       RestoreSVGImageAnimations();
569     }
570     // If we're eliding visibility transitions between the two `kHidden*`
571     // states, then we never get here unless one state was `kVisible` and the
572     // other was not.  However, if we aren't eliding those transitions, then we
573     // need to do so now; from the Frame's point of view, nothing is changing if
574     // this is a change between the two `kHidden*` states.  Both map to "hidden"
575     // in the sense of `document.visibilityState`, and dispatching an event when
576     // the web-exposed state hasn't changed is confusing.
577     //
578     // This check could be enabled for both cases, and the result in the
579     // "eliding" case shouldn't change.  It's not, just to be safe, since this
580     // is intended as a fall-back to previous behavior.
581     if (!RuntimeEnabledFeatures::DispatchHiddenVisibilityTransitionsEnabled() ||
582         was_visible || is_visible) {
583       main_frame_->DidChangeVisibilityState();
584     }
585   }
586 }
587
588 mojom::blink::PageVisibilityState Page::GetVisibilityState() const {
589   return lifecycle_state_->visibility;
590 }
591
592 bool Page::IsPageVisible() const {
593   return lifecycle_state_->visibility ==
594          mojom::blink::PageVisibilityState::kVisible;
595 }
596
597 bool Page::DispatchedPagehideAndStillHidden() {
598   return lifecycle_state_->pagehide_dispatch !=
599          mojom::blink::PagehideDispatch::kNotDispatched;
600 }
601
602 bool Page::DispatchedPagehidePersistedAndStillHidden() {
603   return lifecycle_state_->pagehide_dispatch ==
604          mojom::blink::PagehideDispatch::kDispatchedPersisted;
605 }
606
607 void Page::OnSetPageFrozen(bool frozen) {
608   if (frozen_ == frozen)
609     return;
610   frozen_ = frozen;
611
612   for (Frame* frame = main_frame_.Get(); frame;
613        frame = frame->Tree().TraverseNext()) {
614     if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
615       local_frame->OnPageLifecycleStateUpdated();
616     }
617   }
618 }
619
620 bool Page::IsCursorVisible() const {
621   return is_cursor_visible_;
622 }
623
624 // static
625 int Page::MaxNumberOfFrames() {
626   if (UNLIKELY(g_limit_max_frames_to_ten_for_testing))
627     return kTenFrames;
628   return kMaxNumberOfFrames;
629 }
630
631 // static
632 void Page::SetMaxNumberOfFramesToTenForTesting(bool enabled) {
633   g_limit_max_frames_to_ten_for_testing = enabled;
634 }
635
636 #if DCHECK_IS_ON()
637 void CheckFrameCountConsistency(int expected_frame_count, Frame* frame) {
638   DCHECK_GE(expected_frame_count, 0);
639
640   int actual_frame_count = 0;
641
642   if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
643     if (auto* portals = DocumentPortals::Get(*local_frame->GetDocument())) {
644       actual_frame_count += static_cast<int>(portals->GetPortals().size());
645     }
646   }
647
648   for (; frame; frame = frame->Tree().TraverseNext()) {
649     ++actual_frame_count;
650
651     // Check the ``DocumentFencedFrames`` on every local frame beneath
652     // the ``frame`` to get an accurate count (i.e. if an iframe embeds
653     // a fenced frame and creates a new ``DocumentFencedFrames`` object).
654     if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
655       if (auto* fenced_frames =
656               DocumentFencedFrames::Get(*local_frame->GetDocument())) {
657         actual_frame_count +=
658             static_cast<int>(fenced_frames->GetFencedFrames().size());
659       }
660     }
661   }
662
663   DCHECK_EQ(expected_frame_count, actual_frame_count);
664 }
665 #endif
666
667 int Page::SubframeCount() const {
668 #if DCHECK_IS_ON()
669   CheckFrameCountConsistency(subframe_count_ + 1, MainFrame());
670 #endif
671   return subframe_count_;
672 }
673
674 void Page::SettingsChanged(ChangeType change_type) {
675   switch (change_type) {
676     case ChangeType::kStyle:
677       InitialStyleChanged();
678       break;
679     case ChangeType::kViewportDescription:
680       if (MainFrame() && MainFrame()->IsLocalFrame()) {
681         DeprecatedLocalMainFrame()
682             ->GetDocument()
683             ->GetViewportData()
684             .UpdateViewportDescription();
685         // The text autosizer has dependencies on the viewport. Viewport
686         // description only applies to the main frame. On a viewport description
687         // change; any changes will be calculated starting from the local main
688         // frame renderer and propagated to the OOPIF renderers.
689         TextAutosizer::UpdatePageInfoInAllFrames(MainFrame());
690       }
691       break;
692     case ChangeType::kViewportPaintProperties:
693       if (GetVisualViewport().IsActiveViewport()) {
694         GetVisualViewport().SetNeedsPaintPropertyUpdate();
695         GetVisualViewport().InitializeScrollbars();
696       }
697       if (auto* local_frame = DynamicTo<LocalFrame>(MainFrame())) {
698         if (LocalFrameView* view = local_frame->View())
699           view->SetNeedsPaintPropertyUpdate();
700       }
701       break;
702     case ChangeType::kDNSPrefetching:
703       for (Frame* frame = MainFrame(); frame;
704            frame = frame->Tree().TraverseNext()) {
705         if (auto* local_frame = DynamicTo<LocalFrame>(frame))
706           local_frame->GetDocument()->InitDNSPrefetch();
707       }
708       break;
709     case ChangeType::kImageLoading:
710       for (Frame* frame = MainFrame(); frame;
711            frame = frame->Tree().TraverseNext()) {
712         if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
713           local_frame->GetDocument()->Fetcher()->SetImagesEnabled(
714               GetSettings().GetImagesEnabled());
715           local_frame->GetDocument()->Fetcher()->SetAutoLoadImages(
716               GetSettings().GetLoadsImagesAutomatically());
717         }
718       }
719       break;
720     case ChangeType::kTextAutosizing:
721       if (!MainFrame())
722         break;
723       // We need to update even for remote main frames since this setting
724       // could be changed via InternalSettings.
725       TextAutosizer::UpdatePageInfoInAllFrames(MainFrame());
726       break;
727     case ChangeType::kFontFamily:
728       for (Frame* frame = MainFrame(); frame;
729            frame = frame->Tree().TraverseNext()) {
730         if (auto* local_frame = DynamicTo<LocalFrame>(frame))
731           local_frame->GetDocument()
732               ->GetStyleEngine()
733               .UpdateGenericFontFamilySettings();
734       }
735       break;
736     case ChangeType::kAcceleratedCompositing:
737       UpdateAcceleratedCompositingSettings();
738       break;
739     case ChangeType::kMediaQuery:
740       for (Frame* frame = MainFrame(); frame;
741            frame = frame->Tree().TraverseNext()) {
742         if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
743           local_frame->GetDocument()->MediaQueryAffectingValueChanged(
744               MediaValueChange::kOther);
745         }
746       }
747       break;
748     case ChangeType::kAccessibilityState:
749       if (!MainFrame() || !MainFrame()->IsLocalFrame()) {
750         break;
751       }
752       DeprecatedLocalMainFrame()->GetDocument()->RefreshAccessibilityTree();
753       break;
754     case ChangeType::kViewportStyle: {
755       auto* main_local_frame = DynamicTo<LocalFrame>(MainFrame());
756       if (!main_local_frame)
757         break;
758       if (Document* doc = main_local_frame->GetDocument())
759         doc->GetStyleEngine().ViewportStyleSettingChanged();
760       break;
761     }
762     case ChangeType::kTextTrackKindUserPreference:
763       for (Frame* frame = MainFrame(); frame;
764            frame = frame->Tree().TraverseNext()) {
765         if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
766           Document* doc = local_frame->GetDocument();
767           if (doc)
768             HTMLMediaElement::SetTextTrackKindUserPreferenceForAllMediaElements(
769                 doc);
770         }
771       }
772       break;
773     case ChangeType::kDOMWorlds: {
774       if (!GetSettings().GetForceMainWorldInitialization())
775         break;
776       for (Frame* frame = MainFrame(); frame;
777            frame = frame->Tree().TraverseNext()) {
778         if (auto* window = DynamicTo<LocalDOMWindow>(frame->DomWindow())) {
779           // Forcibly instantiate WindowProxy.
780           window->GetScriptController().WindowProxy(
781               DOMWrapperWorld::MainWorld());
782         }
783       }
784       break;
785     }
786     case ChangeType::kMediaControls:
787       for (Frame* frame = MainFrame(); frame;
788            frame = frame->Tree().TraverseNext()) {
789         auto* local_frame = DynamicTo<LocalFrame>(frame);
790         if (!local_frame)
791           continue;
792         Document* doc = local_frame->GetDocument();
793         if (doc)
794           HTMLMediaElement::OnMediaControlsEnabledChange(doc);
795       }
796       break;
797     case ChangeType::kPlugins: {
798       NotifyPluginsChanged();
799       break;
800     }
801     case ChangeType::kHighlightAds: {
802       for (Frame* frame = MainFrame(); frame;
803            frame = frame->Tree().TraverseNext()) {
804         if (auto* local_frame = DynamicTo<LocalFrame>(frame))
805           local_frame->UpdateAdHighlight();
806       }
807       break;
808     }
809     case ChangeType::kPaint: {
810       InvalidatePaint();
811       break;
812     }
813     case ChangeType::kScrollbarLayout: {
814       for (Frame* frame = MainFrame(); frame;
815            frame = frame->Tree().TraverseNext()) {
816         auto* local_frame = DynamicTo<LocalFrame>(frame);
817         if (!local_frame)
818           continue;
819         // Iterate through all of the scrollable areas and mark their layout
820         // objects for layout.
821         if (LocalFrameView* view = local_frame->View()) {
822           if (const auto* scrollable_areas = view->UserScrollableAreas()) {
823             for (const auto& scrollable_area : *scrollable_areas) {
824               if (scrollable_area->ScrollsOverflow()) {
825                 if (auto* layout_box = scrollable_area->GetLayoutBox()) {
826                   layout_box->SetNeedsLayout(
827                       layout_invalidation_reason::kScrollbarChanged);
828                 }
829               }
830             }
831           }
832         }
833       }
834       break;
835     }
836     case ChangeType::kColorScheme:
837       InvalidateColorScheme();
838       break;
839     case ChangeType::kSpatialNavigation:
840       if (spatial_navigation_controller_ ||
841           GetSettings().GetSpatialNavigationEnabled()) {
842         GetSpatialNavigationController().OnSpatialNavigationSettingChanged();
843       }
844       break;
845     case ChangeType::kUniversalAccess: {
846       if (!GetSettings().GetAllowUniversalAccessFromFileURLs())
847         break;
848       for (Frame* frame = MainFrame(); frame;
849            frame = frame->Tree().TraverseNext()) {
850         // If we got granted universal access from file urls we need to grant
851         // any outstanding security origin cross agent cluster access since
852         // newly allocated agent clusters will be the universal agent.
853         if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
854           auto* window = local_frame->DomWindow();
855           window->GetMutableSecurityOrigin()->GrantCrossAgentClusterAccess();
856         }
857       }
858       break;
859     }
860     case ChangeType::kVisionDeficiency: {
861       if (auto* main_local_frame = DynamicTo<LocalFrame>(MainFrame()))
862         main_local_frame->GetDocument()->VisionDeficiencyChanged();
863       break;
864     }
865 #if BUILDFLAG(IS_EFL)
866     case ChangeType::kTizenVersionChange: {
867       WebRuntimeFeatures::SetTizenCompatibilityModeEnabled(
868           GetSettings().TizenCompatibilityModeEnabled());
869       break;
870     }
871 #endif
872   }
873 }
874
875 void Page::InvalidateColorScheme() {
876   for (Frame* frame = MainFrame(); frame;
877        frame = frame->Tree().TraverseNext()) {
878     if (auto* local_frame = DynamicTo<LocalFrame>(frame))
879       local_frame->GetDocument()->ColorSchemeChanged();
880   }
881 }
882
883 void Page::InvalidatePaint() {
884   for (Frame* frame = MainFrame(); frame;
885        frame = frame->Tree().TraverseNext()) {
886     auto* local_frame = DynamicTo<LocalFrame>(frame);
887     if (!local_frame)
888       continue;
889     if (LayoutView* view = local_frame->ContentLayoutObject())
890       view->InvalidatePaintForViewAndDescendants();
891   }
892 }
893
894 void Page::NotifyPluginsChanged() const {
895   HeapVector<Member<PluginsChangedObserver>, 32> observers(
896       plugins_changed_observers_);
897   for (PluginsChangedObserver* observer : observers)
898     observer->PluginsChanged();
899 }
900
901 void Page::UpdateAcceleratedCompositingSettings() {
902   for (Frame* frame = MainFrame(); frame;
903        frame = frame->Tree().TraverseNext()) {
904     auto* local_frame = DynamicTo<LocalFrame>(frame);
905     if (!local_frame)
906       continue;
907     // Mark all scrollable areas as needing a paint property update because the
908     // compositing reasons may have changed.
909     if (const auto* areas = local_frame->View()->UserScrollableAreas()) {
910       for (const auto& scrollable_area : *areas) {
911         if (scrollable_area->ScrollsOverflow()) {
912           if (auto* layout_box = scrollable_area->GetLayoutBox())
913             layout_box->SetNeedsPaintPropertyUpdate();
914         }
915       }
916     }
917   }
918 }
919
920 void Page::DidCommitLoad(LocalFrame* frame) {
921   if (main_frame_ == frame) {
922     GetConsoleMessageStorage().Clear();
923     GetInspectorIssueStorage().Clear();
924     // TODO(loonybear): Most of this doesn't appear to take into account that
925     // each SVGImage gets it's own Page instance.
926     GetDeprecation().ClearSuppression();
927     // Need to reset visual viewport position here since before commit load we
928     // would update the previous history item, Page::didCommitLoad is called
929     // after a new history item is created in FrameLoader.
930     // See crbug.com/642279
931     GetVisualViewport().SetScrollOffset(ScrollOffset(),
932                                         mojom::blink::ScrollType::kProgrammatic,
933                                         mojom::blink::ScrollBehavior::kInstant,
934                                         ScrollableArea::ScrollCallback());
935   }
936   // crbug/1312107: If DevTools has "Highlight ad frames" checked when the
937   // main frame is refreshed or the ad frame is navigated to a different
938   // process, DevTools calls `Settings::SetHighlightAds` so early that the
939   // local frame is still in provisional state (not swapped in). Explicitly
940   // invalidate the settings here as `Page::DidCommitLoad` is only fired after
941   // the navigation is committed, at which point the local frame must already
942   // be swapped-in.
943   //
944   // This explicit update is placed outside the above if-block to accommodate
945   // iframes. The iframes share the same Page (frame tree) as the main frame,
946   // but local frame swap can happen to any of the iframes.
947   //
948   // TODO(crbug/1357763): Properly apply the settings when the local frame
949   // becomes the main frame of the page (i.e. when the navigation is
950   // committed).
951   frame->UpdateAdHighlight();
952   GetLinkHighlight().ResetForPageNavigation();
953 }
954
955 void Page::AcceptLanguagesChanged() {
956   HeapVector<Member<LocalFrame>> frames;
957
958   // Even though we don't fire an event from here, the LocalDOMWindow's will
959   // fire an event so we keep the frames alive until we are done.
960   for (Frame* frame = MainFrame(); frame;
961        frame = frame->Tree().TraverseNext()) {
962     if (auto* local_frame = DynamicTo<LocalFrame>(frame))
963       frames.push_back(local_frame);
964   }
965
966   for (unsigned i = 0; i < frames.size(); ++i)
967     frames[i]->DomWindow()->AcceptLanguagesChanged();
968 }
969
970 void Page::Trace(Visitor* visitor) const {
971   visitor->Trace(animator_);
972   visitor->Trace(autoscroll_controller_);
973   visitor->Trace(chrome_client_);
974   visitor->Trace(drag_caret_);
975   visitor->Trace(drag_controller_);
976   visitor->Trace(focus_controller_);
977   visitor->Trace(context_menu_controller_);
978   visitor->Trace(page_scale_constraints_set_);
979   visitor->Trace(page_visibility_observer_set_);
980   visitor->Trace(pointer_lock_controller_);
981   visitor->Trace(scrolling_coordinator_);
982   visitor->Trace(browser_controls_);
983   visitor->Trace(console_message_storage_);
984   visitor->Trace(global_root_scroller_controller_);
985   visitor->Trace(visual_viewport_);
986   visitor->Trace(link_highlight_);
987   visitor->Trace(spatial_navigation_controller_);
988   visitor->Trace(main_frame_);
989   visitor->Trace(previous_main_frame_for_local_swap_);
990   visitor->Trace(plugin_data_);
991   visitor->Trace(validation_message_client_);
992   visitor->Trace(plugins_changed_observers_);
993   visitor->Trace(next_related_page_);
994   visitor->Trace(prev_related_page_);
995   visitor->Trace(agent_group_scheduler_);
996   visitor->Trace(v8_compile_hints_producer_);
997   visitor->Trace(v8_compile_hints_consumer_);
998   Supplementable<Page>::Trace(visitor);
999 }
1000
1001 void Page::DidInitializeCompositing(cc::AnimationHost& host) {
1002   GetLinkHighlight().AnimationHostInitialized(host);
1003 }
1004
1005 void Page::WillStopCompositing() {
1006   GetLinkHighlight().WillCloseAnimationHost();
1007   // We may have disconnected the associated LayerTreeHost during
1008   // the frame lifecycle so ensure the PageAnimator is reset to the
1009   // default state.
1010   animator_->SetSuppressFrameRequestsWorkaroundFor704763Only(false);
1011 }
1012
1013 void Page::WillBeDestroyed() {
1014   Frame* main_frame = main_frame_;
1015
1016   // TODO(https://crbug.com/838348): Sadly, there are situations where Blink may
1017   // attempt to detach a main frame twice due to a bug. That rewinds
1018   // FrameLifecycle from kDetached to kDetaching, but GetPage() will already be
1019   // null. Since Detach() has already happened, just skip the actual Detach()
1020   // call to try to limit the side effects of this bug on the rest of frame
1021   // detach.
1022   if (main_frame->GetPage()) {
1023     main_frame->Detach(FrameDetachType::kRemove);
1024   }
1025
1026   DCHECK(AllPages().Contains(this));
1027   AllPages().erase(this);
1028   OrdinaryPages().erase(this);
1029
1030   {
1031     // Before: ... -> prev -> this -> next -> ...
1032     // After: ... -> prev -> next -> ...
1033     // (this is ok even if |this| is the only element on the list).
1034     Page* prev = prev_related_page_;
1035     Page* next = next_related_page_;
1036     next->prev_related_page_ = prev;
1037     prev->next_related_page_ = next;
1038     prev_related_page_ = nullptr;
1039     next_related_page_ = nullptr;
1040   }
1041
1042   if (scrolling_coordinator_)
1043     scrolling_coordinator_->WillBeDestroyed();
1044
1045   GetChromeClient().ChromeDestroyed();
1046   if (validation_message_client_)
1047     validation_message_client_->WillBeDestroyed();
1048   main_frame_ = nullptr;
1049
1050   for (auto observer : page_visibility_observer_set_) {
1051     observer->ObserverSetWillBeCleared();
1052   }
1053   page_visibility_observer_set_.clear();
1054
1055   page_scheduler_ = nullptr;
1056 }
1057
1058 void Page::RegisterPluginsChangedObserver(PluginsChangedObserver* observer) {
1059   plugins_changed_observers_.insert(observer);
1060 }
1061
1062 ScrollbarTheme& Page::GetScrollbarTheme() const {
1063   if (settings_->GetForceAndroidOverlayScrollbar())
1064     return ScrollbarThemeOverlayMobile::GetInstance();
1065
1066   // Ensures that renderer preferences are set.
1067   DCHECK(main_frame_);
1068   return ScrollbarTheme::GetTheme();
1069 }
1070
1071 AgentGroupScheduler& Page::GetAgentGroupScheduler() const {
1072   return *agent_group_scheduler_;
1073 }
1074
1075 PageScheduler* Page::GetPageScheduler() const {
1076   DCHECK(page_scheduler_);
1077   return page_scheduler_.get();
1078 }
1079
1080 bool Page::IsOrdinary() const {
1081   return is_ordinary_;
1082 }
1083
1084 void Page::ReportIntervention(const String& text) {
1085   if (LocalFrame* local_frame = DeprecatedLocalMainFrame()) {
1086     auto* message = MakeGarbageCollected<ConsoleMessage>(
1087         mojom::ConsoleMessageSource::kOther,
1088         mojom::ConsoleMessageLevel::kWarning, text,
1089         std::make_unique<SourceLocation>(String(), String(), 0, 0, nullptr));
1090     local_frame->GetDocument()->AddConsoleMessage(message);
1091   }
1092 }
1093
1094 bool Page::RequestBeginMainFrameNotExpected(bool new_state) {
1095   if (!main_frame_ || !main_frame_->IsLocalFrame())
1096     return false;
1097
1098   chrome_client_->RequestBeginMainFrameNotExpected(*DeprecatedLocalMainFrame(),
1099                                                    new_state);
1100   return true;
1101 }
1102
1103 void Page::AddAutoplayFlags(int32_t value) {
1104   autoplay_flags_ |= value;
1105 }
1106
1107 void Page::ClearAutoplayFlags() {
1108   autoplay_flags_ = 0;
1109 }
1110
1111 int32_t Page::AutoplayFlags() const {
1112   return autoplay_flags_;
1113 }
1114
1115 void Page::SetInsidePortal(bool inside_portal) {
1116   if (inside_portal_ == inside_portal)
1117     return;
1118
1119   inside_portal_ = inside_portal;
1120
1121   if (MainFrame() && MainFrame()->IsLocalFrame())
1122     DeprecatedLocalMainFrame()->PortalStateChanged();
1123 }
1124
1125 bool Page::InsidePortal() const {
1126   return inside_portal_;
1127 }
1128
1129 void Page::SetIsMainFrameFencedFrameRoot() {
1130   is_fenced_frame_tree_ = true;
1131 }
1132
1133 bool Page::IsMainFrameFencedFrameRoot() const {
1134   return is_fenced_frame_tree_;
1135 }
1136
1137 void Page::SetMediaFeatureOverride(const AtomicString& media_feature,
1138                                    const String& value) {
1139   if (!media_feature_overrides_) {
1140     if (value.empty())
1141       return;
1142     media_feature_overrides_ = std::make_unique<MediaFeatureOverrides>();
1143   }
1144   media_feature_overrides_->SetOverride(media_feature, value);
1145   if (media_feature == "prefers-color-scheme" ||
1146       media_feature == "forced-colors")
1147     SettingsChanged(ChangeType::kColorScheme);
1148   else
1149     SettingsChanged(ChangeType::kMediaQuery);
1150 }
1151
1152 void Page::ClearMediaFeatureOverrides() {
1153   media_feature_overrides_.reset();
1154   SettingsChanged(ChangeType::kMediaQuery);
1155   SettingsChanged(ChangeType::kColorScheme);
1156 }
1157
1158 void Page::SetPreferenceOverride(const AtomicString& media_feature,
1159                                  const String& value) {
1160   if (!preference_overrides_) {
1161     if (value.empty()) {
1162       return;
1163     }
1164     preference_overrides_ = std::make_unique<PreferenceOverrides>();
1165   }
1166   preference_overrides_->SetOverride(media_feature, value);
1167   if (media_feature == "prefers-color-scheme") {
1168     SettingsChanged(ChangeType::kColorScheme);
1169   } else {
1170     SettingsChanged(ChangeType::kMediaQuery);
1171   }
1172 }
1173
1174 void Page::ClearPreferenceOverrides() {
1175   preference_overrides_.reset();
1176   SettingsChanged(ChangeType::kMediaQuery);
1177   SettingsChanged(ChangeType::kColorScheme);
1178 }
1179
1180 void Page::SetVisionDeficiency(VisionDeficiency new_vision_deficiency) {
1181   if (new_vision_deficiency != vision_deficiency_) {
1182     vision_deficiency_ = new_vision_deficiency;
1183     SettingsChanged(ChangeType::kVisionDeficiency);
1184   }
1185 }
1186
1187 #if BUILDFLAG(IS_TIZEN)
1188 void Page::SetIsSuspended(bool isSuspended) {
1189   m_isSuspended = isSuspended;
1190 }
1191 #endif
1192
1193 void Page::Animate(base::TimeTicks monotonic_frame_begin_time) {
1194   GetAutoscrollController().Animate();
1195   Animator().ServiceScriptedAnimations(monotonic_frame_begin_time);
1196   // The ValidationMessage overlay manages its own internal Page that isn't
1197   // hooked up the normal BeginMainFrame flow, so we manually tick its
1198   // animations here.
1199   GetValidationMessageClient().ServiceScriptedAnimations(
1200       monotonic_frame_begin_time);
1201 }
1202
1203 void Page::UpdateLifecycle(LocalFrame& root,
1204                            WebLifecycleUpdate requested_update,
1205                            DocumentUpdateReason reason) {
1206   if (requested_update == WebLifecycleUpdate::kLayout) {
1207     Animator().UpdateLifecycleToLayoutClean(root, reason);
1208   } else if (requested_update == WebLifecycleUpdate::kPrePaint) {
1209     Animator().UpdateLifecycleToPrePaintClean(root, reason);
1210   } else {
1211     Animator().UpdateAllLifecyclePhases(root, reason);
1212   }
1213 }
1214
1215 #if BUILDFLAG(IS_EFL)
1216 void Page::SetLongPollingGlobalTimeout(uint64_t timeout) {
1217   long_polling_global_timeout_ = timeout;
1218 }
1219 #endif
1220
1221 const base::UnguessableToken& Page::BrowsingContextGroupToken() {
1222   return browsing_context_group_info_.browsing_context_group_token;
1223 }
1224
1225 const base::UnguessableToken& Page::CoopRelatedGroupToken() {
1226   return browsing_context_group_info_.coop_related_group_token;
1227 }
1228
1229 void Page::UpdateBrowsingContextGroup(
1230     const blink::BrowsingContextGroupInfo& browsing_context_group_info) {
1231   if (browsing_context_group_info_ == browsing_context_group_info) {
1232     return;
1233   }
1234
1235   if (base::FeatureList::IsEnabled(
1236           features::kPausePagesPerBrowsingContextGroup) &&
1237       ScopedBrowsingContextGroupPauser::IsActive(*this)) {
1238     CHECK(paused_);
1239     SetPaused(false);
1240   }
1241
1242   browsing_context_group_info_ = browsing_context_group_info;
1243
1244   if (base::FeatureList::IsEnabled(
1245           features::kPausePagesPerBrowsingContextGroup) &&
1246       ScopedBrowsingContextGroupPauser::IsActive(*this)) {
1247     SetPaused(true);
1248   }
1249 }
1250
1251 void Page::SetAttributionSupport(
1252     network::mojom::AttributionSupport attribution_support) {
1253   attribution_support_ = attribution_support;
1254 }
1255
1256 template class CORE_TEMPLATE_EXPORT Supplement<Page>;
1257
1258 const char InternalSettingsPageSupplementBase::kSupplementName[] =
1259     "InternalSettings";
1260
1261 // static
1262 void Page::PrepareForLeakDetection() {
1263   // Internal settings are ScriptWrappable and thus may retain documents
1264   // depending on whether the garbage collector(s) are able to find the settings
1265   // object through the Page supplement. Prepares for leak detection by removing
1266   // all InternalSetting objects from Pages.
1267   for (Page* page : OrdinaryPages()) {
1268     page->RemoveSupplement<InternalSettingsPageSupplementBase>();
1269
1270     // V8CrowdsourcedCompileHintsProducer keeps v8::Script objects alive until
1271     // the page becomes interactive. Give it a chance to clean up.
1272     page->v8_compile_hints_producer_->ClearData();
1273   }
1274 }
1275
1276 // Ensure the 10 bits reserved for connected frame count in NodeRareData are
1277 // sufficient.
1278 static_assert(kMaxNumberOfFrames <
1279                   (1 << NodeRareData::kConnectedFrameCountBits),
1280               "Frame limit should fit in rare data count");
1281 static_assert(kTenFrames < kMaxNumberOfFrames,
1282               "Reduced frame limit for testing should actually be lower");
1283
1284 }  // namespace blink