Address post-review feedback after r238438
[WebKit-https.git] / Source / WebCore / page / Page.cpp
1 /*
2  * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "Page.h"
22
23 #include "ActivityStateChangeObserver.h"
24 #include "AlternativeTextClient.h"
25 #include "ApplicationCacheStorage.h"
26 #include "ApplicationStateChangeListener.h"
27 #include "AuthenticatorCoordinator.h"
28 #include "BackForwardClient.h"
29 #include "BackForwardController.h"
30 #include "CSSAnimationController.h"
31 #include "CacheStorageProvider.h"
32 #include "Chrome.h"
33 #include "ChromeClient.h"
34 #include "ConstantPropertyMap.h"
35 #include "ContextMenuClient.h"
36 #include "ContextMenuController.h"
37 #include "DOMRect.h"
38 #include "DOMRectList.h"
39 #include "DatabaseProvider.h"
40 #include "DiagnosticLoggingClient.h"
41 #include "DiagnosticLoggingKeys.h"
42 #include "DocumentLoader.h"
43 #include "DocumentMarkerController.h"
44 #include "DocumentTimeline.h"
45 #include "DragController.h"
46 #include "Editing.h"
47 #include "Editor.h"
48 #include "EditorClient.h"
49 #include "EmptyClients.h"
50 #include "Event.h"
51 #include "EventNames.h"
52 #include "ExtensionStyleSheets.h"
53 #include "FileSystem.h"
54 #include "FocusController.h"
55 #include "FrameLoader.h"
56 #include "FrameLoaderClient.h"
57 #include "FrameSelection.h"
58 #include "FrameTree.h"
59 #include "FrameView.h"
60 #include "HTMLElement.h"
61 #include "HTMLMediaElement.h"
62 #include "HistoryController.h"
63 #include "HistoryItem.h"
64 #include "InspectorClient.h"
65 #include "InspectorController.h"
66 #include "InspectorInstrumentation.h"
67 #include "LibWebRTCProvider.h"
68 #include "LoaderStrategy.h"
69 #include "Logging.h"
70 #include "LowPowerModeNotifier.h"
71 #include "MediaCanStartListener.h"
72 #include "Navigator.h"
73 #include "PageCache.h"
74 #include "PageConfiguration.h"
75 #include "PageConsoleClient.h"
76 #include "PageDebuggable.h"
77 #include "PageGroup.h"
78 #include "PageOverlayController.h"
79 #include "PaymentCoordinator.h"
80 #include "PerformanceLogging.h"
81 #include "PerformanceLoggingClient.h"
82 #include "PerformanceMonitor.h"
83 #include "PlatformMediaSessionManager.h"
84 #include "PlatformStrategies.h"
85 #include "PlugInClient.h"
86 #include "PluginData.h"
87 #include "PluginInfoProvider.h"
88 #include "PluginViewBase.h"
89 #include "PointerLockController.h"
90 #include "ProgressTracker.h"
91 #include "PublicSuffix.h"
92 #include "RenderLayerCompositor.h"
93 #include "RenderTheme.h"
94 #include "RenderView.h"
95 #include "RenderWidget.h"
96 #include "ResourceUsageOverlay.h"
97 #include "RuntimeEnabledFeatures.h"
98 #include "SVGDocumentExtensions.h"
99 #include "SchemeRegistry.h"
100 #include "ScriptController.h"
101 #include "ScriptedAnimationController.h"
102 #include "ScrollLatchingState.h"
103 #include "ScrollingCoordinator.h"
104 #include "Settings.h"
105 #include "SharedBuffer.h"
106 #include "SocketProvider.h"
107 #include "StorageArea.h"
108 #include "StorageNamespace.h"
109 #include "StorageNamespaceProvider.h"
110 #include "StyleResolver.h"
111 #include "StyleScope.h"
112 #include "SubframeLoader.h"
113 #include "TextIterator.h"
114 #include "TextResourceDecoder.h"
115 #include "UserContentProvider.h"
116 #include "UserInputBridge.h"
117 #include "ValidationMessageClient.h"
118 #include "VisitedLinkState.h"
119 #include "VisitedLinkStore.h"
120 #include "VoidCallback.h"
121 #include "WebGLStateTracker.h"
122 #include "WheelEventDeltaFilter.h"
123 #include "Widget.h"
124 #include <wtf/RefCountedLeakCounter.h>
125 #include <wtf/StdLibExtras.h>
126 #include <wtf/text/Base64.h>
127 #include <wtf/text/StringHash.h>
128
129 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
130 #include "HTMLVideoElement.h"
131 #include "MediaPlaybackTarget.h"
132 #endif
133
134 #if PLATFORM(MAC)
135 #include "ServicesOverlayController.h"
136 #endif
137
138 #if ENABLE(MEDIA_SESSION)
139 #include "MediaSessionManager.h"
140 #endif
141
142 #if ENABLE(INDEXED_DATABASE)
143 #include "IDBConnectionToServer.h"
144 #include "InProcessIDBServer.h"
145 #endif
146
147 #if ENABLE(DATA_INTERACTION)
148 #include "SelectionRect.h"
149 #endif
150
151 namespace WebCore {
152
153 static HashSet<Page*>& allPages()
154 {
155     static NeverDestroyed<HashSet<Page*>> set;
156     return set;
157 }
158
159 static unsigned nonUtilityPageCount { 0 };
160
161 static inline bool isUtilityPageChromeClient(ChromeClient& chromeClient)
162 {
163     return chromeClient.isEmptyChromeClient() || chromeClient.isSVGImageChromeClient();
164 }
165
166 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
167
168 void Page::forEachPage(const WTF::Function<void(Page&)>& function)
169 {
170     for (auto* page : allPages())
171         function(*page);
172 }
173
174 void Page::updateValidationBubbleStateIfNeeded()
175 {
176     if (auto* client = validationMessageClient())
177         client->updateValidationBubbleStateIfNeeded();
178 }
179
180 static void networkStateChanged(bool isOnLine)
181 {
182     Vector<Ref<Frame>> frames;
183
184     // Get all the frames of all the pages in all the page groups
185     for (auto* page : allPages()) {
186         for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext())
187             frames.append(*frame);
188         InspectorInstrumentation::networkStateChanged(*page);
189     }
190
191     auto& eventName = isOnLine ? eventNames().onlineEvent : eventNames().offlineEvent;
192     for (auto& frame : frames) {
193         if (!frame->document())
194             continue;
195         frame->document()->dispatchWindowEvent(Event::create(eventName, Event::CanBubble::No, Event::IsCancelable::No));
196     }
197 }
198
199 static constexpr OptionSet<ActivityState::Flag> pageInitialActivityState()
200 {
201     return { ActivityState::IsVisible, ActivityState::IsInWindow };
202 }
203
204 Page::Page(PageConfiguration&& pageConfiguration)
205     : m_chrome(std::make_unique<Chrome>(*this, *pageConfiguration.chromeClient))
206     , m_dragCaretController(std::make_unique<DragCaretController>())
207 #if ENABLE(DRAG_SUPPORT)
208     , m_dragController(std::make_unique<DragController>(*this, *pageConfiguration.dragClient))
209 #endif
210     , m_focusController(std::make_unique<FocusController>(*this, pageInitialActivityState()))
211 #if ENABLE(CONTEXT_MENUS)
212     , m_contextMenuController(std::make_unique<ContextMenuController>(*this, *pageConfiguration.contextMenuClient))
213 #endif
214     , m_userInputBridge(std::make_unique<UserInputBridge>(*this))
215     , m_inspectorController(std::make_unique<InspectorController>(*this, pageConfiguration.inspectorClient))
216 #if ENABLE(POINTER_LOCK)
217     , m_pointerLockController(std::make_unique<PointerLockController>(*this))
218 #endif
219     , m_settings(Settings::create(this))
220     , m_progress(std::make_unique<ProgressTracker>(*pageConfiguration.progressTrackerClient))
221     , m_backForwardController(std::make_unique<BackForwardController>(*this, WTFMove(pageConfiguration.backForwardClient)))
222     , m_mainFrame(Frame::create(this, nullptr, pageConfiguration.loaderClientForMainFrame))
223     , m_editorClient(WTFMove(pageConfiguration.editorClient))
224     , m_plugInClient(pageConfiguration.plugInClient)
225     , m_validationMessageClient(WTFMove(pageConfiguration.validationMessageClient))
226     , m_diagnosticLoggingClient(WTFMove(pageConfiguration.diagnosticLoggingClient))
227     , m_performanceLoggingClient(WTFMove(pageConfiguration.performanceLoggingClient))
228     , m_webGLStateTracker(WTFMove(pageConfiguration.webGLStateTracker))
229     , m_libWebRTCProvider(WTFMove(pageConfiguration.libWebRTCProvider))
230     , m_verticalScrollElasticity(ScrollElasticityAllowed)
231     , m_horizontalScrollElasticity(ScrollElasticityAllowed)
232     , m_domTimerAlignmentInterval(DOMTimer::defaultAlignmentInterval())
233     , m_domTimerAlignmentIntervalIncreaseTimer(*this, &Page::domTimerAlignmentIntervalIncreaseTimerFired)
234     , m_activityState(pageInitialActivityState())
235     , m_alternativeTextClient(pageConfiguration.alternativeTextClient)
236     , m_consoleClient(std::make_unique<PageConsoleClient>(*this))
237 #if ENABLE(REMOTE_INSPECTOR)
238     , m_inspectorDebuggable(std::make_unique<PageDebuggable>(*this))
239 #endif
240     , m_socketProvider(WTFMove(pageConfiguration.socketProvider))
241     , m_applicationCacheStorage(*WTFMove(pageConfiguration.applicationCacheStorage))
242     , m_cacheStorageProvider(WTFMove(pageConfiguration.cacheStorageProvider))
243     , m_databaseProvider(*WTFMove(pageConfiguration.databaseProvider))
244     , m_pluginInfoProvider(*WTFMove(pageConfiguration.pluginInfoProvider))
245     , m_storageNamespaceProvider(*WTFMove(pageConfiguration.storageNamespaceProvider))
246     , m_userContentProvider(*WTFMove(pageConfiguration.userContentProvider))
247     , m_visitedLinkStore(*WTFMove(pageConfiguration.visitedLinkStore))
248 #if ENABLE(INTERSECTION_OBSERVER)
249     , m_intersectionObservationUpdateTimer(*this, &Page::updateIntersectionObservations)
250 #endif
251     , m_sessionID(PAL::SessionID::defaultSessionID())
252 #if ENABLE(VIDEO)
253     , m_playbackControlsManagerUpdateTimer(*this, &Page::playbackControlsManagerUpdateTimerFired)
254 #endif
255     , m_isUtilityPage(isUtilityPageChromeClient(chrome().client()))
256     , m_performanceMonitor(isUtilityPage() ? nullptr : std::make_unique<PerformanceMonitor>(*this))
257     , m_lowPowerModeNotifier(std::make_unique<LowPowerModeNotifier>([this](bool isLowPowerModeEnabled) { handleLowModePowerChange(isLowPowerModeEnabled); }))
258     , m_performanceLogging(std::make_unique<PerformanceLogging>(*this))
259 #if PLATFORM(MAC) && (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION))
260     , m_servicesOverlayController(std::make_unique<ServicesOverlayController>(*this))
261 #endif
262     , m_recentWheelEventDeltaFilter(WheelEventDeltaFilter::create())
263     , m_pageOverlayController(std::make_unique<PageOverlayController>(*this))
264 #if ENABLE(APPLE_PAY)
265     , m_paymentCoordinator(std::make_unique<PaymentCoordinator>(*pageConfiguration.paymentCoordinatorClient))
266 #endif
267 #if ENABLE(WEB_AUTHN)
268     , m_authenticatorCoordinator(makeUniqueRef<AuthenticatorCoordinator>(WTFMove(pageConfiguration.authenticatorCoordinatorClient)))
269 #endif
270 #if ENABLE(APPLICATION_MANIFEST)
271     , m_applicationManifest(pageConfiguration.applicationManifest)
272 #endif
273 {
274     updateTimerThrottlingState();
275
276     m_pluginInfoProvider->addPage(*this);
277     m_storageNamespaceProvider->addPage(*this);
278     m_userContentProvider->addPage(*this);
279     m_visitedLinkStore->addPage(*this);
280
281     static bool addedListener;
282     if (!addedListener) {
283         platformStrategies()->loaderStrategy()->addOnlineStateChangeListener(&networkStateChanged);
284         addedListener = true;
285     }
286
287     ASSERT(!allPages().contains(this));
288     allPages().add(this);
289
290     if (!isUtilityPage()) {
291         ++nonUtilityPageCount;
292         MemoryPressureHandler::setPageCount(nonUtilityPageCount);
293     }
294
295 #ifndef NDEBUG
296     pageCounter.increment();
297 #endif
298
299 #if ENABLE(REMOTE_INSPECTOR)
300     if (m_inspectorController->inspectorClient() && m_inspectorController->inspectorClient()->allowRemoteInspectionToPageDirectly())
301         m_inspectorDebuggable->init();
302 #endif
303
304 #if PLATFORM(COCOA)
305     platformInitialize();
306 #endif
307 }
308
309 Page::~Page()
310 {
311     ASSERT(!m_nestedRunLoopCount);
312     ASSERT(!m_unnestCallback);
313
314     m_validationMessageClient = nullptr;
315     m_diagnosticLoggingClient = nullptr;
316     m_performanceLoggingClient = nullptr;
317     m_mainFrame->setView(nullptr);
318     setGroupName(String());
319     allPages().remove(this);
320     if (!isUtilityPage()) {
321         --nonUtilityPageCount;
322         MemoryPressureHandler::setPageCount(nonUtilityPageCount);
323     }
324     
325     m_settings->pageDestroyed();
326
327     m_inspectorController->inspectedPageDestroyed();
328
329     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
330         frame->willDetachPage();
331         frame->detachFromPage();
332     }
333
334     if (m_plugInClient)
335         m_plugInClient->pageDestroyed();
336     if (m_alternativeTextClient)
337         m_alternativeTextClient->pageDestroyed();
338
339     if (m_scrollingCoordinator)
340         m_scrollingCoordinator->pageDestroyed();
341
342     backForward().close();
343     if (!isUtilityPage())
344         PageCache::singleton().removeAllItemsForPage(*this);
345
346 #ifndef NDEBUG
347     pageCounter.decrement();
348 #endif
349
350     m_pluginInfoProvider->removePage(*this);
351     m_storageNamespaceProvider->removePage(*this);
352     m_userContentProvider->removePage(*this);
353     m_visitedLinkStore->removePage(*this);
354 }
355
356 void Page::clearPreviousItemFromAllPages(HistoryItem* item)
357 {
358     for (auto* page : allPages()) {
359         auto& controller = page->mainFrame().loader().history();
360         if (item == controller.previousItem()) {
361             controller.clearPreviousItem();
362             return;
363         }
364     }
365 }
366
367 uint64_t Page::renderTreeSize() const
368 {
369     uint64_t total = 0;
370     for (const Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
371         if (!frame->document() || !frame->document()->renderView())
372             continue;
373         total += frame->document()->renderView()->rendererCount();
374     }
375     return total;
376 }
377
378 OptionSet<DisabledAdaptations> Page::disabledAdaptations() const
379 {
380     if (mainFrame().document())
381         return mainFrame().document()->disabledAdaptations();
382
383     return { };
384 }
385
386 ViewportArguments Page::viewportArguments() const
387 {
388     return mainFrame().document() ? mainFrame().document()->viewportArguments() : ViewportArguments();
389 }
390
391 ScrollingCoordinator* Page::scrollingCoordinator()
392 {
393     if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) {
394         m_scrollingCoordinator = chrome().client().createScrollingCoordinator(*this);
395         if (!m_scrollingCoordinator)
396             m_scrollingCoordinator = ScrollingCoordinator::create(this);
397     }
398
399     return m_scrollingCoordinator.get();
400 }
401
402 String Page::scrollingStateTreeAsText()
403 {
404     if (Document* document = m_mainFrame->document())
405         document->updateLayout();
406
407     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
408         return scrollingCoordinator->scrollingStateTreeAsText();
409
410     return String();
411 }
412
413 String Page::synchronousScrollingReasonsAsText()
414 {
415     if (Document* document = m_mainFrame->document())
416         document->updateLayout();
417
418     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
419         return scrollingCoordinator->synchronousScrollingReasonsAsText();
420
421     return String();
422 }
423
424 Ref<DOMRectList> Page::nonFastScrollableRects()
425 {
426     if (Document* document = m_mainFrame->document())
427         document->updateLayout();
428
429     Vector<IntRect> rects;
430     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
431         const EventTrackingRegions& eventTrackingRegions = scrollingCoordinator->absoluteEventTrackingRegions();
432         for (const auto& synchronousEventRegion : eventTrackingRegions.eventSpecificSynchronousDispatchRegions)
433             rects.appendVector(synchronousEventRegion.value.rects());
434     }
435
436     Vector<FloatQuad> quads(rects.size());
437     for (size_t i = 0; i < rects.size(); ++i)
438         quads[i] = FloatRect(rects[i]);
439
440     return DOMRectList::create(quads);
441 }
442
443 Ref<DOMRectList> Page::touchEventRectsForEvent(const String& eventName)
444 {
445     if (Document* document = m_mainFrame->document()) {
446         document->updateLayout();
447 #if ENABLE(IOS_TOUCH_EVENTS)
448         document->updateTouchEventRegions();
449 #endif
450     }
451
452     Vector<IntRect> rects;
453     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
454         const EventTrackingRegions& eventTrackingRegions = scrollingCoordinator->absoluteEventTrackingRegions();
455         const auto& region = eventTrackingRegions.eventSpecificSynchronousDispatchRegions.get(eventName);
456         rects.appendVector(region.rects());
457     }
458
459     Vector<FloatQuad> quads(rects.size());
460     for (size_t i = 0; i < rects.size(); ++i)
461         quads[i] = FloatRect(rects[i]);
462
463     return DOMRectList::create(quads);
464 }
465
466 Ref<DOMRectList> Page::passiveTouchEventListenerRects()
467 {
468     if (Document* document = m_mainFrame->document()) {
469         document->updateLayout();
470 #if ENABLE(IOS_TOUCH_EVENTS)
471         document->updateTouchEventRegions();
472 #endif  
473     }
474
475     Vector<IntRect> rects;
476     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
477         rects.appendVector(scrollingCoordinator->absoluteEventTrackingRegions().asynchronousDispatchRegion.rects());
478
479     Vector<FloatQuad> quads(rects.size());
480     for (size_t i = 0; i < rects.size(); ++i)
481         quads[i] = FloatRect(rects[i]);
482
483     return DOMRectList::create(quads);
484 }
485
486 bool Page::openedByDOM() const
487 {
488     return m_openedByDOM;
489 }
490
491 void Page::setOpenedByDOM()
492 {
493     m_openedByDOM = true;
494 }
495
496 void Page::goToItem(HistoryItem& item, FrameLoadType type, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad)
497 {
498     // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem
499     // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later.
500     Ref<HistoryItem> protector(item);
501
502     auto& frameLoader = m_mainFrame->loader();
503     if (frameLoader.history().shouldStopLoadingForHistoryItem(item))
504         m_mainFrame->loader().stopAllLoadersAndCheckCompleteness();
505
506     m_mainFrame->loader().history().goToItem(item, type, shouldTreatAsContinuingLoad);
507 }
508
509 void Page::setGroupName(const String& name)
510 {
511     if (m_group && !m_group->name().isEmpty()) {
512         ASSERT(m_group != m_singlePageGroup.get());
513         ASSERT(!m_singlePageGroup);
514         m_group->removePage(*this);
515     }
516
517     if (name.isEmpty())
518         m_group = m_singlePageGroup.get();
519     else {
520         m_singlePageGroup = nullptr;
521         m_group = PageGroup::pageGroup(name);
522         m_group->addPage(*this);
523     }
524 }
525
526 const String& Page::groupName() const
527 {
528     return m_group ? m_group->name() : nullAtom().string();
529 }
530
531 void Page::initGroup()
532 {
533     ASSERT(!m_singlePageGroup);
534     ASSERT(!m_group);
535     m_singlePageGroup = std::make_unique<PageGroup>(*this);
536     m_group = m_singlePageGroup.get();
537 }
538
539 void Page::updateStyleAfterChangeInEnvironment()
540 {
541     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
542         // If a change in the global environment has occurred, we need to
543         // make sure all the properties a recomputed, therefore we invalidate
544         // the properties cache.
545         auto* document = frame->document();
546         if (!document)
547             continue;
548
549         if (StyleResolver* styleResolver = document->styleScope().resolverIfExists())
550             styleResolver->invalidateMatchedPropertiesCache();
551         document->scheduleForcedStyleRecalc();
552         document->styleScope().didChangeStyleSheetEnvironment();
553     }
554 }
555
556 void Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment()
557 {
558     for (auto* page : allPages())
559         page->updateStyleAfterChangeInEnvironment();
560 }
561
562 void Page::setNeedsRecalcStyleInAllFrames()
563 {
564     // FIXME: Figure out what this function is actually trying to add in different call sites.
565     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
566         if (Document* document = frame->document())
567             document->styleScope().didChangeStyleSheetEnvironment();
568     }
569 }
570
571 void Page::refreshPlugins(bool reload)
572 {
573     HashSet<PluginInfoProvider*> pluginInfoProviders;
574
575     for (auto* page : allPages())
576         pluginInfoProviders.add(&page->pluginInfoProvider());
577
578     for (auto& pluginInfoProvider : pluginInfoProviders)
579         pluginInfoProvider->refresh(reload);
580 }
581
582 PluginData& Page::pluginData()
583 {
584     if (!m_pluginData)
585         m_pluginData = PluginData::create(*this);
586     return *m_pluginData;
587 }
588
589 void Page::clearPluginData()
590 {
591     m_pluginData = nullptr;
592 }
593
594 bool Page::showAllPlugins() const
595 {
596     if (m_showAllPlugins)
597         return true;
598
599     if (Document* document = mainFrame().document())
600         return document->securityOrigin().isLocal();
601
602     return false;
603 }
604
605 inline std::optional<std::pair<MediaCanStartListener&, Document&>>  Page::takeAnyMediaCanStartListener()
606 {
607     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
608         if (!frame->document())
609             continue;
610         if (MediaCanStartListener* listener = frame->document()->takeAnyMediaCanStartListener())
611             return { { *listener, *frame->document() } };
612     }
613     return std::nullopt;
614 }
615
616 void Page::setCanStartMedia(bool canStartMedia)
617 {
618     if (m_canStartMedia == canStartMedia)
619         return;
620
621     m_canStartMedia = canStartMedia;
622
623     while (m_canStartMedia) {
624         auto listener = takeAnyMediaCanStartListener();
625         if (!listener)
626             break;
627         listener->first.mediaCanStart(listener->second);
628     }
629 }
630
631 static Frame* incrementFrame(Frame* curr, bool forward, CanWrap canWrap, DidWrap* didWrap = nullptr)
632 {
633     return forward
634         ? curr->tree().traverseNext(canWrap, didWrap)
635         : curr->tree().traversePrevious(canWrap, didWrap);
636 }
637
638 bool Page::findString(const String& target, FindOptions options, DidWrap* didWrap)
639 {
640     if (target.isEmpty())
641         return false;
642
643     CanWrap canWrap = options.contains(WrapAround) ? CanWrap::Yes : CanWrap::No;
644     Frame* frame = &focusController().focusedOrMainFrame();
645     Frame* startFrame = frame;
646     do {
647         if (frame->editor().findString(target, (options - WrapAround) | StartInSelection)) {
648             if (frame != startFrame)
649                 startFrame->selection().clear();
650             focusController().setFocusedFrame(frame);
651             return true;
652         }
653         frame = incrementFrame(frame, !options.contains(Backwards), canWrap, didWrap);
654     } while (frame && frame != startFrame);
655
656     // Search contents of startFrame, on the other side of the selection that we did earlier.
657     // We cheat a bit and just research with wrap on
658     if (canWrap == CanWrap::Yes && !startFrame->selection().isNone()) {
659         if (didWrap)
660             *didWrap = DidWrap::Yes;
661         bool found = startFrame->editor().findString(target, options | WrapAround | StartInSelection);
662         focusController().setFocusedFrame(frame);
663         return found;
664     }
665
666     return false;
667 }
668
669 void Page::findStringMatchingRanges(const String& target, FindOptions options, int limit, Vector<RefPtr<Range>>& matchRanges, int& indexForSelection)
670 {
671     indexForSelection = 0;
672
673     Frame* frame = &mainFrame();
674     Frame* frameWithSelection = nullptr;
675     do {
676         frame->editor().countMatchesForText(target, 0, options, limit ? (limit - matchRanges.size()) : 0, true, &matchRanges);
677         if (frame->selection().isRange())
678             frameWithSelection = frame;
679         frame = incrementFrame(frame, true, CanWrap::No);
680     } while (frame);
681
682     if (matchRanges.isEmpty())
683         return;
684
685     if (frameWithSelection) {
686         indexForSelection = NoMatchAfterUserSelection;
687         RefPtr<Range> selectedRange = frameWithSelection->selection().selection().firstRange();
688         if (options.contains(Backwards)) {
689             for (size_t i = matchRanges.size(); i > 0; --i) {
690                 auto result = selectedRange->compareBoundaryPoints(Range::END_TO_START, *matchRanges[i - 1]);
691                 if (!result.hasException() && result.releaseReturnValue() > 0) {
692                     indexForSelection = i - 1;
693                     break;
694                 }
695             }
696         } else {
697             for (size_t i = 0, size = matchRanges.size(); i < size; ++i) {
698                 auto result = selectedRange->compareBoundaryPoints(Range::START_TO_END, *matchRanges[i]);
699                 if (!result.hasException() && result.releaseReturnValue() < 0) {
700                     indexForSelection = i;
701                     break;
702                 }
703             }
704         }
705     } else {
706         if (options.contains(Backwards))
707             indexForSelection = matchRanges.size() - 1;
708         else
709             indexForSelection = 0;
710     }
711 }
712
713 RefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
714 {
715     if (target.isEmpty())
716         return nullptr;
717
718     if (referenceRange && referenceRange->ownerDocument().page() != this)
719         return nullptr;
720
721     CanWrap canWrap = options.contains(WrapAround) ? CanWrap::Yes : CanWrap::No;
722     Frame* frame = referenceRange ? referenceRange->ownerDocument().frame() : &mainFrame();
723     Frame* startFrame = frame;
724     do {
725         if (RefPtr<Range> resultRange = frame->editor().rangeOfString(target, frame == startFrame ? referenceRange : 0, options - WrapAround))
726             return resultRange;
727
728         frame = incrementFrame(frame, !options.contains(Backwards), canWrap);
729     } while (frame && frame != startFrame);
730
731     // Search contents of startFrame, on the other side of the reference range that we did earlier.
732     // We cheat a bit and just search again with wrap on.
733     if (canWrap == CanWrap::Yes && referenceRange) {
734         if (RefPtr<Range> resultRange = startFrame->editor().rangeOfString(target, referenceRange, options | WrapAround | StartInSelection))
735             return resultRange;
736     }
737
738     return nullptr;
739 }
740
741 unsigned Page::findMatchesForText(const String& target, FindOptions options, unsigned maxMatchCount, ShouldHighlightMatches shouldHighlightMatches, ShouldMarkMatches shouldMarkMatches)
742 {
743     if (target.isEmpty())
744         return 0;
745
746     unsigned matchCount = 0;
747
748     Frame* frame = &mainFrame();
749     do {
750         if (shouldMarkMatches == MarkMatches)
751             frame->editor().setMarkedTextMatchesAreHighlighted(shouldHighlightMatches == HighlightMatches);
752         matchCount += frame->editor().countMatchesForText(target, 0, options, maxMatchCount ? (maxMatchCount - matchCount) : 0, shouldMarkMatches == MarkMatches, 0);
753         frame = incrementFrame(frame, true, CanWrap::No);
754     } while (frame);
755
756     return matchCount;
757 }
758
759 unsigned Page::markAllMatchesForText(const String& target, FindOptions options, bool shouldHighlight, unsigned maxMatchCount)
760 {
761     return findMatchesForText(target, options, maxMatchCount, shouldHighlight ? HighlightMatches : DoNotHighlightMatches, MarkMatches);
762 }
763
764 unsigned Page::countFindMatches(const String& target, FindOptions options, unsigned maxMatchCount)
765 {
766     return findMatchesForText(target, options, maxMatchCount, DoNotHighlightMatches, DoNotMarkMatches);
767 }
768
769 struct FindReplacementRange {
770     RefPtr<ContainerNode> root;
771     size_t location { notFound };
772     size_t length { 0 };
773 };
774
775 static void replaceRanges(Page& page, const Vector<FindReplacementRange>& ranges, const String& replacementText)
776 {
777     HashMap<RefPtr<ContainerNode>, Vector<FindReplacementRange>> rangesByContainerNode;
778     for (auto& range : ranges) {
779         auto& rangeList = rangesByContainerNode.ensure(range.root, [] {
780             return Vector<FindReplacementRange> { };
781         }).iterator->value;
782
783         // Ensure that ranges are sorted by their end offsets, per editing container.
784         auto endOffsetForRange = range.location + range.length;
785         auto insertionIndex = rangeList.size();
786         for (auto iterator = rangeList.rbegin(); iterator != rangeList.rend(); ++iterator) {
787             auto endOffsetBeforeInsertionIndex = iterator->location + iterator->length;
788             if (endOffsetForRange >= endOffsetBeforeInsertionIndex)
789                 break;
790             insertionIndex--;
791         }
792         rangeList.insert(insertionIndex, range);
793     }
794
795     HashMap<RefPtr<Frame>, unsigned> frameToTraversalIndexMap;
796     unsigned currentFrameTraversalIndex = 0;
797     for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext())
798         frameToTraversalIndexMap.set(frame, currentFrameTraversalIndex++);
799
800     // Likewise, iterate backwards (in document and frame order) through editing containers that contain text matches,
801     // so that we're consistent with our backwards iteration behavior per editing container when replacing text.
802     auto containerNodesInOrderOfReplacement = copyToVector(rangesByContainerNode.keys());
803     std::sort(containerNodesInOrderOfReplacement.begin(), containerNodesInOrderOfReplacement.end(), [frameToTraversalIndexMap] (auto& firstNode, auto& secondNode) {
804         if (firstNode == secondNode)
805             return false;
806
807         auto firstFrame = makeRefPtr(firstNode->document().frame());
808         if (!firstFrame)
809             return true;
810
811         auto secondFrame = makeRefPtr(secondNode->document().frame());
812         if (!secondFrame)
813             return false;
814
815         if (firstFrame == secondFrame) {
816             // comparePositions is used here instead of Node::compareDocumentPosition because some editing roots may exist inside shadow roots.
817             return comparePositions({ firstNode.get(), Position::PositionIsBeforeChildren }, { secondNode.get(), Position::PositionIsBeforeChildren }) > 0;
818         }
819         return frameToTraversalIndexMap.get(firstFrame) > frameToTraversalIndexMap.get(secondFrame);
820     });
821
822     for (auto& container : containerNodesInOrderOfReplacement) {
823         auto frame = makeRefPtr(container->document().frame());
824         if (!frame)
825             continue;
826
827         // Iterate backwards through ranges when replacing text, such that earlier text replacements don't clobber replacement ranges later on.
828         auto& ranges = rangesByContainerNode.find(container)->value;
829         for (auto iterator = ranges.rbegin(); iterator != ranges.rend(); ++iterator) {
830             auto range = TextIterator::rangeFromLocationAndLength(container.get(), iterator->location, iterator->length);
831             if (!range || range->collapsed())
832                 continue;
833
834             frame->selection().setSelectedRange(range.get(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes);
835             frame->editor().replaceSelectionWithText(replacementText, Editor::SelectReplacement::Yes, Editor::SmartReplace::No, EditAction::InsertReplacement);
836         }
837     }
838 }
839
840 uint32_t Page::replaceRangesWithText(const Vector<Ref<Range>>& rangesToReplace, const String& replacementText, bool selectionOnly)
841 {
842     // FIXME: In the future, we should respect the `selectionOnly` flag by checking whether each range being replaced is
843     // contained within its frame's selection.
844     UNUSED_PARAM(selectionOnly);
845
846     Vector<FindReplacementRange> replacementRanges;
847     replacementRanges.reserveInitialCapacity(rangesToReplace.size());
848
849     for (auto& range : rangesToReplace) {
850         auto highestRoot = makeRefPtr(highestEditableRoot(range->startPosition()));
851         if (!highestRoot || highestRoot != highestEditableRoot(range->endPosition()))
852             continue;
853
854         auto frame = makeRefPtr(highestRoot->document().frame());
855         if (!frame)
856             continue;
857
858         size_t replacementLocation = notFound;
859         size_t replacementLength = 0;
860         if (!TextIterator::getLocationAndLengthFromRange(highestRoot.get(), range.ptr(), replacementLocation, replacementLength))
861             continue;
862
863         if (replacementLocation == notFound || !replacementLength)
864             continue;
865
866         replacementRanges.append({ WTFMove(highestRoot), replacementLocation, replacementLength });
867     }
868
869     replaceRanges(*this, replacementRanges, replacementText);
870     return rangesToReplace.size();
871 }
872
873 uint32_t Page::replaceSelectionWithText(const String& replacementText)
874 {
875     auto frame = makeRef(focusController().focusedOrMainFrame());
876     auto selection = frame->selection().selection();
877     if (!selection.isContentEditable())
878         return 0;
879
880     auto editAction = selection.isRange() ? EditAction::InsertReplacement : EditAction::Insert;
881     frame->editor().replaceSelectionWithText(replacementText, Editor::SelectReplacement::Yes, Editor::SmartReplace::No, editAction);
882     return 1;
883 }
884
885 void Page::unmarkAllTextMatches()
886 {
887     Frame* frame = &mainFrame();
888     do {
889         frame->document()->markers().removeMarkers(DocumentMarker::TextMatch);
890         frame = incrementFrame(frame, true, CanWrap::No);
891     } while (frame);
892 }
893
894 const VisibleSelection& Page::selection() const
895 {
896     return focusController().focusedOrMainFrame().selection().selection();
897 }
898
899 void Page::setDefersLoading(bool defers)
900 {
901     if (!m_settings->loadDeferringEnabled())
902         return;
903
904     if (m_settings->wantsBalancedSetDefersLoadingBehavior()) {
905         ASSERT(defers || m_defersLoadingCallCount);
906         if (defers && ++m_defersLoadingCallCount > 1)
907             return;
908         if (!defers && --m_defersLoadingCallCount)
909             return;
910     } else {
911         ASSERT(!m_defersLoadingCallCount);
912         if (defers == m_defersLoading)
913             return;
914     }
915
916     m_defersLoading = defers;
917     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
918         frame->loader().setDefersLoading(defers);
919 }
920
921 void Page::clearUndoRedoOperations()
922 {
923     m_editorClient->clearUndoRedoOperations();
924 }
925
926 bool Page::inLowQualityImageInterpolationMode() const
927 {
928     return m_inLowQualityInterpolationMode;
929 }
930
931 void Page::setInLowQualityImageInterpolationMode(bool mode)
932 {
933     m_inLowQualityInterpolationMode = mode;
934 }
935
936 DiagnosticLoggingClient& Page::diagnosticLoggingClient() const
937 {
938     if (!settings().diagnosticLoggingEnabled() || !m_diagnosticLoggingClient)
939         return emptyDiagnosticLoggingClient();
940     return *m_diagnosticLoggingClient;
941 }
942
943 void Page::setMediaVolume(float volume)
944 {
945     if (volume < 0 || volume > 1)
946         return;
947
948     if (m_mediaVolume == volume)
949         return;
950
951     m_mediaVolume = volume;
952     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
953         if (!frame->document())
954             continue;
955         frame->document()->mediaVolumeDidChange();
956     }
957 }
958
959 void Page::setZoomedOutPageScaleFactor(float scale)
960 {
961     if (m_zoomedOutPageScaleFactor == scale)
962         return;
963     m_zoomedOutPageScaleFactor = scale;
964
965     mainFrame().deviceOrPageScaleFactorChanged();
966 }
967
968 void Page::setPageScaleFactor(float scale, const IntPoint& origin, bool inStableState)
969 {
970     LOG(Viewports, "Page::setPageScaleFactor %.2f - inStableState %d", scale, inStableState);
971
972     Document* document = mainFrame().document();
973     FrameView* view = document->view();
974
975     if (scale == m_pageScaleFactor) {
976         if (view && view->scrollPosition() != origin) {
977             if (!m_settings->delegatesPageScaling())
978                 document->updateLayoutIgnorePendingStylesheets();
979
980             if (!view->delegatesScrolling())
981                 view->setScrollPosition(origin);
982 #if USE(COORDINATED_GRAPHICS)
983             else
984                 view->requestScrollPositionUpdate(origin);
985 #endif
986         }
987 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
988         if (inStableState) {
989             for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
990                 if (!frame->document())
991                     continue;
992                 frame->document()->pageScaleFactorChangedAndStable();
993             }
994         }
995 #endif
996         return;
997     }
998
999     m_pageScaleFactor = scale;
1000
1001     if (!m_settings->delegatesPageScaling()) {
1002         if (auto* renderView = document->renderView()) {
1003             renderView->setNeedsLayout();
1004             if (renderView->hasLayer() && renderView->layer()->isComposited())
1005                 renderView->layer()->setNeedsCompositingGeometryUpdate();
1006         }
1007
1008         document->resolveStyle(Document::ResolveStyleType::Rebuild);
1009
1010         // Transform change on RenderView doesn't trigger repaint on non-composited contents.
1011         mainFrame().view()->invalidateRect(IntRect(LayoutRect::infiniteRect()));
1012     }
1013
1014     mainFrame().deviceOrPageScaleFactorChanged();
1015
1016     if (view && view->fixedElementsLayoutRelativeToFrame())
1017         view->setViewportConstrainedObjectsNeedLayout();
1018
1019     if (view && view->scrollPosition() != origin) {
1020         if (!m_settings->delegatesPageScaling() && document->renderView() && document->renderView()->needsLayout() && view->didFirstLayout())
1021             view->layoutContext().layout();
1022
1023         if (!view->delegatesScrolling())
1024             view->setScrollPosition(origin);
1025 #if USE(COORDINATED_GRAPHICS)
1026         else
1027             view->requestScrollPositionUpdate(origin);
1028 #endif
1029     }
1030
1031 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1032     if (inStableState) {
1033         for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1034             if (!frame->document())
1035                 continue;
1036             frame->document()->pageScaleFactorChangedAndStable();
1037         }
1038     }
1039 #else
1040     UNUSED_PARAM(inStableState);
1041 #endif
1042 }
1043
1044 void Page::setViewScaleFactor(float scale)
1045 {
1046     if (m_viewScaleFactor == scale)
1047         return;
1048
1049     m_viewScaleFactor = scale;
1050     PageCache::singleton().markPagesForDeviceOrPageScaleChanged(*this);
1051 }
1052
1053 void Page::setDeviceScaleFactor(float scaleFactor)
1054 {
1055     ASSERT(scaleFactor > 0);
1056     if (scaleFactor <= 0)
1057         return;
1058     
1059     if (m_deviceScaleFactor == scaleFactor)
1060         return;
1061
1062     m_deviceScaleFactor = scaleFactor;
1063     setNeedsRecalcStyleInAllFrames();
1064
1065     mainFrame().deviceOrPageScaleFactorChanged();
1066     PageCache::singleton().markPagesForDeviceOrPageScaleChanged(*this);
1067
1068     pageOverlayController().didChangeDeviceScaleFactor();
1069 }
1070
1071 void Page::setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection userInterfaceLayoutDirection)
1072 {
1073     if (m_userInterfaceLayoutDirection == userInterfaceLayoutDirection)
1074         return;
1075
1076     m_userInterfaceLayoutDirection = userInterfaceLayoutDirection;
1077 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1078     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1079         if (!frame->document())
1080             continue;
1081         frame->document()->userInterfaceLayoutDirectionChanged();
1082     }
1083 #endif
1084 }
1085
1086 #if ENABLE(VIDEO)
1087 void Page::updateMediaElementRateChangeRestrictions()
1088 {
1089     for (auto* mediaElement : HTMLMediaElement::allMediaElements())
1090         mediaElement->updateRateChangeRestrictions();
1091 }
1092 #endif
1093
1094 void Page::didStartProvisionalLoad()
1095 {
1096     if (m_performanceMonitor)
1097         m_performanceMonitor->didStartProvisionalLoad();
1098 }
1099
1100 void Page::didFinishLoad()
1101 {
1102     resetRelevantPaintedObjectCounter();
1103
1104     if (m_performanceMonitor)
1105         m_performanceMonitor->didFinishLoad();
1106 }
1107
1108 void Page::willDisplayPage()
1109 {
1110 #if ENABLE(INTERSECTION_OBSERVER)
1111     updateIntersectionObservations();
1112 #endif
1113 }
1114
1115 bool Page::isOnlyNonUtilityPage() const
1116 {
1117     return !isUtilityPage() && nonUtilityPageCount == 1;
1118 }
1119
1120 bool Page::isLowPowerModeEnabled() const
1121 {
1122     if (m_lowPowerModeEnabledOverrideForTesting)
1123         return m_lowPowerModeEnabledOverrideForTesting.value();
1124
1125     return m_lowPowerModeNotifier->isLowPowerModeEnabled();
1126 }
1127
1128 void Page::setLowPowerModeEnabledOverrideForTesting(std::optional<bool> isEnabled)
1129 {
1130     m_lowPowerModeEnabledOverrideForTesting = isEnabled;
1131     handleLowModePowerChange(m_lowPowerModeEnabledOverrideForTesting.value_or(false));
1132 }
1133
1134 void Page::setTopContentInset(float contentInset)
1135 {
1136     if (m_topContentInset == contentInset)
1137         return;
1138     
1139     m_topContentInset = contentInset;
1140     
1141     if (FrameView* view = mainFrame().view())
1142         view->topContentInsetDidChange(m_topContentInset);
1143 }
1144
1145 void Page::setShouldSuppressScrollbarAnimations(bool suppressAnimations)
1146 {
1147     if (suppressAnimations == m_suppressScrollbarAnimations)
1148         return;
1149
1150     lockAllOverlayScrollbarsToHidden(suppressAnimations);
1151     m_suppressScrollbarAnimations = suppressAnimations;
1152 }
1153
1154 void Page::lockAllOverlayScrollbarsToHidden(bool lockOverlayScrollbars)
1155 {
1156     FrameView* view = mainFrame().view();
1157     if (!view)
1158         return;
1159
1160     view->lockOverlayScrollbarStateToHidden(lockOverlayScrollbars);
1161     
1162     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1163         FrameView* frameView = frame->view();
1164         if (!frameView)
1165             continue;
1166
1167         const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
1168         if (!scrollableAreas)
1169             continue;
1170
1171         for (auto& scrollableArea : *scrollableAreas)
1172             scrollableArea->lockOverlayScrollbarStateToHidden(lockOverlayScrollbars);
1173     }
1174 }
1175     
1176 void Page::setVerticalScrollElasticity(ScrollElasticity elasticity)
1177 {
1178     if (m_verticalScrollElasticity == elasticity)
1179         return;
1180     
1181     m_verticalScrollElasticity = elasticity;
1182     
1183     if (FrameView* view = mainFrame().view())
1184         view->setVerticalScrollElasticity(elasticity);
1185 }
1186     
1187 void Page::setHorizontalScrollElasticity(ScrollElasticity elasticity)
1188 {
1189     if (m_horizontalScrollElasticity == elasticity)
1190         return;
1191     
1192     m_horizontalScrollElasticity = elasticity;
1193     
1194     if (FrameView* view = mainFrame().view())
1195         view->setHorizontalScrollElasticity(elasticity);
1196 }
1197
1198 void Page::setPagination(const Pagination& pagination)
1199 {
1200     if (m_pagination == pagination)
1201         return;
1202
1203     m_pagination = pagination;
1204
1205     setNeedsRecalcStyleInAllFrames();
1206 }
1207
1208 void Page::setPaginationLineGridEnabled(bool enabled)
1209 {
1210     if (m_paginationLineGridEnabled == enabled)
1211         return;
1212     
1213     m_paginationLineGridEnabled = enabled;
1214     
1215     setNeedsRecalcStyleInAllFrames();
1216 }
1217
1218 unsigned Page::pageCount() const
1219 {
1220     if (m_pagination.mode == Pagination::Unpaginated)
1221         return 0;
1222
1223     if (Document* document = mainFrame().document())
1224         document->updateLayoutIgnorePendingStylesheets();
1225
1226     RenderView* contentRenderer = mainFrame().contentRenderer();
1227     return contentRenderer ? contentRenderer->pageCount() : 0;
1228 }
1229
1230 void Page::setIsInWindow(bool isInWindow)
1231 {
1232     setActivityState(isInWindow ? m_activityState | ActivityState::IsInWindow : m_activityState - ActivityState::IsInWindow);
1233 }
1234
1235 void Page::setIsInWindowInternal(bool isInWindow)
1236 {
1237     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1238         if (FrameView* frameView = frame->view())
1239             frameView->setIsInWindow(isInWindow);
1240     }
1241
1242     if (isInWindow)
1243         resumeAnimatingImages();
1244 }
1245
1246 void Page::addActivityStateChangeObserver(ActivityStateChangeObserver& observer)
1247 {
1248     m_activityStateChangeObservers.add(&observer);
1249 }
1250
1251 void Page::removeActivityStateChangeObserver(ActivityStateChangeObserver& observer)
1252 {
1253     m_activityStateChangeObservers.remove(&observer);
1254 }
1255
1256 #if ENABLE(INTERSECTION_OBSERVER)
1257 void Page::addDocumentNeedingIntersectionObservationUpdate(Document& document)
1258 {
1259     if (m_documentsNeedingIntersectionObservationUpdate.find(&document) == notFound)
1260         m_documentsNeedingIntersectionObservationUpdate.append(makeWeakPtr(document));
1261 }
1262
1263 void Page::updateIntersectionObservations()
1264 {
1265     m_intersectionObservationUpdateTimer.stop();
1266     for (auto document : m_documentsNeedingIntersectionObservationUpdate) {
1267         if (document)
1268             document->updateIntersectionObservations();
1269     }
1270     m_documentsNeedingIntersectionObservationUpdate.clear();
1271 }
1272
1273 void Page::scheduleForcedIntersectionObservationUpdate(Document& document)
1274 {
1275     addDocumentNeedingIntersectionObservationUpdate(document);
1276     if (m_intersectionObservationUpdateTimer.isActive())
1277         return;
1278     m_intersectionObservationUpdateTimer.startOneShot(0_s);
1279 }
1280 #endif
1281
1282 void Page::suspendScriptedAnimations()
1283 {
1284     m_scriptedAnimationsSuspended = true;
1285     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1286         if (frame->document())
1287             frame->document()->suspendScriptedAnimationControllerCallbacks();
1288     }
1289 }
1290
1291 void Page::resumeScriptedAnimations()
1292 {
1293     m_scriptedAnimationsSuspended = false;
1294     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1295         if (frame->document())
1296             frame->document()->resumeScriptedAnimationControllerCallbacks();
1297     }
1298 }
1299
1300 enum class ThrottlingReasonOperation { Add, Remove };
1301 static void updateScriptedAnimationsThrottlingReason(Page& page, ThrottlingReasonOperation operation, ScriptedAnimationController::ThrottlingReason reason)
1302 {
1303     for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
1304         auto* document = frame->document();
1305         if (!document)
1306             continue;
1307         auto* scriptedAnimationController = document->scriptedAnimationController();
1308         if (!scriptedAnimationController)
1309             continue;
1310
1311         if (operation == ThrottlingReasonOperation::Add)
1312             scriptedAnimationController->addThrottlingReason(reason);
1313         else
1314             scriptedAnimationController->removeThrottlingReason(reason);
1315     }
1316 }
1317
1318 void Page::setIsVisuallyIdleInternal(bool isVisuallyIdle)
1319 {
1320     updateScriptedAnimationsThrottlingReason(*this, isVisuallyIdle ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::VisuallyIdle);
1321 }
1322
1323 void Page::handleLowModePowerChange(bool isLowPowerModeEnabled)
1324 {
1325     updateScriptedAnimationsThrottlingReason(*this, isLowPowerModeEnabled ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::LowPowerMode);
1326     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1327         forEachDocument([&] (Document& document) {
1328             if (auto timeline = document.existingTimeline())
1329                 timeline->updateThrottlingState();
1330         });
1331     } else
1332         mainFrame().animation().updateThrottlingState();
1333     updateDOMTimerAlignmentInterval();
1334 }
1335
1336 void Page::userStyleSheetLocationChanged()
1337 {
1338     // FIXME: Eventually we will move to a model of just being handed the sheet
1339     // text instead of loading the URL ourselves.
1340     URL url = m_settings->userStyleSheetLocation();
1341     
1342     // Allow any local file URL scheme to be loaded.
1343     if (SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol().toStringWithoutCopying()))
1344         m_userStyleSheetPath = url.fileSystemPath();
1345     else
1346         m_userStyleSheetPath = String();
1347
1348     m_didLoadUserStyleSheet = false;
1349     m_userStyleSheet = String();
1350     m_userStyleSheetModificationTime = 0;
1351
1352     // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them
1353     // synchronously and avoid using a loader. 
1354     if (url.protocolIsData() && url.string().startsWith("data:text/css;charset=utf-8;base64,")) {
1355         m_didLoadUserStyleSheet = true;
1356
1357         Vector<char> styleSheetAsUTF8;
1358         if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, Base64IgnoreSpacesAndNewLines))
1359             m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size());
1360     }
1361
1362     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1363         if (frame->document())
1364             frame->document()->extensionStyleSheets().updatePageUserSheet();
1365     }
1366 }
1367
1368 const String& Page::userStyleSheet() const
1369 {
1370     if (m_userStyleSheetPath.isEmpty())
1371         return m_userStyleSheet;
1372
1373     time_t modTime;
1374     if (!FileSystem::getFileModificationTime(m_userStyleSheetPath, modTime)) {
1375         // The stylesheet either doesn't exist, was just deleted, or is
1376         // otherwise unreadable. If we've read the stylesheet before, we should
1377         // throw away that data now as it no longer represents what's on disk.
1378         m_userStyleSheet = String();
1379         return m_userStyleSheet;
1380     }
1381
1382     // If the stylesheet hasn't changed since the last time we read it, we can
1383     // just return the old data.
1384     if (m_didLoadUserStyleSheet && modTime <= m_userStyleSheetModificationTime)
1385         return m_userStyleSheet;
1386
1387     m_didLoadUserStyleSheet = true;
1388     m_userStyleSheet = String();
1389     m_userStyleSheetModificationTime = modTime;
1390
1391     // FIXME: It would be better to load this asynchronously to avoid blocking
1392     // the process, but we will first need to create an asynchronous loading
1393     // mechanism that is not tied to a particular Frame. We will also have to
1394     // determine what our behavior should be before the stylesheet is loaded
1395     // and what should happen when it finishes loading, especially with respect
1396     // to when the load event fires, when Document::close is called, and when
1397     // layout/paint are allowed to happen.
1398     RefPtr<SharedBuffer> data = SharedBuffer::createWithContentsOfFile(m_userStyleSheetPath);
1399     if (!data)
1400         return m_userStyleSheet;
1401
1402     m_userStyleSheet = TextResourceDecoder::create("text/css")->decodeAndFlush(data->data(), data->size());
1403
1404     return m_userStyleSheet;
1405 }
1406
1407 void Page::userAgentChanged()
1408 {
1409     for (auto* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1410         auto* window = frame->window();
1411         if (!window)
1412             continue;
1413         if (auto* navigator = window->optionalNavigator())
1414             navigator->userAgentChanged();
1415     }
1416 }
1417
1418 void Page::invalidateStylesForAllLinks()
1419 {
1420     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1421         if (!frame->document())
1422             continue;
1423         frame->document()->visitedLinkState().invalidateStyleForAllLinks();
1424     }
1425 }
1426
1427 void Page::invalidateStylesForLink(SharedStringHash linkHash)
1428 {
1429     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1430         if (!frame->document())
1431             continue;
1432         frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
1433     }
1434 }
1435
1436 void Page::invalidateInjectedStyleSheetCacheInAllFrames()
1437 {
1438     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1439         Document* document = frame->document();
1440         if (!document)
1441             continue;
1442         document->extensionStyleSheets().invalidateInjectedStyleSheetCache();
1443     }
1444 }
1445
1446 void Page::setDebugger(JSC::Debugger* debugger)
1447 {
1448     if (m_debugger == debugger)
1449         return;
1450
1451     m_debugger = debugger;
1452
1453     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
1454         frame->windowProxy().attachDebugger(m_debugger);
1455 }
1456
1457 StorageNamespace* Page::sessionStorage(bool optionalCreate)
1458 {
1459     if (!m_sessionStorage && optionalCreate)
1460         m_sessionStorage = m_storageNamespaceProvider->createSessionStorageNamespace(*this, m_settings->sessionStorageQuota());
1461
1462     return m_sessionStorage.get();
1463 }
1464
1465 void Page::setSessionStorage(RefPtr<StorageNamespace>&& newStorage)
1466 {
1467     m_sessionStorage = WTFMove(newStorage);
1468 }
1469
1470 StorageNamespace* Page::ephemeralLocalStorage(bool optionalCreate)
1471 {
1472     if (!m_ephemeralLocalStorage && optionalCreate)
1473         m_ephemeralLocalStorage = m_storageNamespaceProvider->createEphemeralLocalStorageNamespace(*this, m_settings->sessionStorageQuota());
1474
1475     return m_ephemeralLocalStorage.get();
1476 }
1477
1478 void Page::setEphemeralLocalStorage(RefPtr<StorageNamespace>&& newStorage)
1479 {
1480     m_ephemeralLocalStorage = WTFMove(newStorage);
1481 }
1482
1483 bool Page::hasCustomHTMLTokenizerTimeDelay() const
1484 {
1485     return m_settings->maxParseDuration() != -1;
1486 }
1487
1488 double Page::customHTMLTokenizerTimeDelay() const
1489 {
1490     ASSERT(m_settings->maxParseDuration() != -1);
1491     return m_settings->maxParseDuration();
1492 }
1493
1494 void Page::setMemoryCacheClientCallsEnabled(bool enabled)
1495 {
1496     if (m_areMemoryCacheClientCallsEnabled == enabled)
1497         return;
1498
1499     m_areMemoryCacheClientCallsEnabled = enabled;
1500     if (!enabled)
1501         return;
1502
1503     for (RefPtr<Frame> frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
1504         frame->loader().tellClientAboutPastMemoryCacheLoads();
1505 }
1506
1507 void Page::hiddenPageDOMTimerThrottlingStateChanged()
1508 {
1509     // Disable & reengage to ensure state is updated.
1510     setTimerThrottlingState(TimerThrottlingState::Disabled);
1511     updateTimerThrottlingState();
1512 }
1513
1514 void Page::updateTimerThrottlingState()
1515 {
1516     // Timer throttling disabled if page is visually active, or disabled by setting.
1517     if (!m_settings->hiddenPageDOMTimerThrottlingEnabled() || !(m_activityState & ActivityState::IsVisuallyIdle)) {
1518         setTimerThrottlingState(TimerThrottlingState::Disabled);
1519         return;
1520     }
1521
1522     // If the page is visible (but idle), there is any activity (loading, media playing, etc), or per setting,
1523     // we allow timer throttling, but not increasing timer throttling.
1524     if (!m_settings->hiddenPageDOMTimerThrottlingAutoIncreases()
1525         || m_activityState.containsAny({ActivityState::IsVisible, ActivityState::IsAudible, ActivityState::IsLoading, ActivityState::IsCapturingMedia })) {
1526         setTimerThrottlingState(TimerThrottlingState::Enabled);
1527         return;
1528     }
1529
1530     // If we get here increasing timer throttling is enabled.
1531     setTimerThrottlingState(TimerThrottlingState::EnabledIncreasing);
1532 }
1533
1534 void Page::setTimerThrottlingState(TimerThrottlingState state)
1535 {
1536     if (state == m_timerThrottlingState)
1537         return;
1538
1539     m_timerThrottlingState = state;
1540     m_timerThrottlingStateLastChangedTime = MonotonicTime::now();
1541
1542     updateDOMTimerAlignmentInterval();
1543
1544     // When throttling is disabled, release all throttled timers.
1545     if (state == TimerThrottlingState::Disabled) {
1546         for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1547             if (auto* document = frame->document())
1548                 document->didChangeTimerAlignmentInterval();
1549         }
1550     }
1551 }
1552
1553 void Page::setDOMTimerAlignmentIntervalIncreaseLimit(Seconds limit)
1554 {
1555     m_domTimerAlignmentIntervalIncreaseLimit = limit;
1556
1557     // If (m_domTimerAlignmentIntervalIncreaseLimit < m_domTimerAlignmentInterval) then we need
1558     // to update m_domTimerAlignmentInterval, if greater then need to restart the increase timer.
1559     if (m_timerThrottlingState == TimerThrottlingState::EnabledIncreasing)
1560         updateDOMTimerAlignmentInterval();
1561 }
1562
1563 void Page::updateDOMTimerAlignmentInterval()
1564 {
1565     bool needsIncreaseTimer = false;
1566
1567     switch (m_timerThrottlingState) {
1568     case TimerThrottlingState::Disabled:
1569         m_domTimerAlignmentInterval = isLowPowerModeEnabled() ? DOMTimer::defaultAlignmentIntervalInLowPowerMode() : DOMTimer::defaultAlignmentInterval();
1570         break;
1571
1572     case TimerThrottlingState::Enabled:
1573         m_domTimerAlignmentInterval = DOMTimer::hiddenPageAlignmentInterval();
1574         break;
1575
1576     case TimerThrottlingState::EnabledIncreasing:
1577         // For pages in prerender state maximum throttling kicks in immediately.
1578         if (m_isPrerender)
1579             m_domTimerAlignmentInterval = m_domTimerAlignmentIntervalIncreaseLimit;
1580         else {
1581             ASSERT(!!m_timerThrottlingStateLastChangedTime);
1582             m_domTimerAlignmentInterval = MonotonicTime::now() - m_timerThrottlingStateLastChangedTime;
1583             // If we're below the limit, set the timer. If above, clamp to limit.
1584             if (m_domTimerAlignmentInterval < m_domTimerAlignmentIntervalIncreaseLimit)
1585                 needsIncreaseTimer = true;
1586             else
1587                 m_domTimerAlignmentInterval = m_domTimerAlignmentIntervalIncreaseLimit;
1588         }
1589         // Alignment interval should not be less than DOMTimer::hiddenPageAlignmentInterval().
1590         m_domTimerAlignmentInterval = std::max(m_domTimerAlignmentInterval, DOMTimer::hiddenPageAlignmentInterval());
1591     }
1592
1593     // If throttling is enabled, auto-increasing of throttling is enabled, and the auto-increase
1594     // limit has not yet been reached, and then arm the timer to consider an increase. Time to wait
1595     // between increases is equal to the current throttle time. Since alinment interval increases
1596     // exponentially, time between steps is exponential too.
1597     if (!needsIncreaseTimer)
1598         m_domTimerAlignmentIntervalIncreaseTimer.stop();
1599     else if (!m_domTimerAlignmentIntervalIncreaseTimer.isActive())
1600         m_domTimerAlignmentIntervalIncreaseTimer.startOneShot(m_domTimerAlignmentInterval);
1601 }
1602
1603 void Page::domTimerAlignmentIntervalIncreaseTimerFired()
1604 {
1605     ASSERT(m_settings->hiddenPageDOMTimerThrottlingAutoIncreases());
1606     ASSERT(m_timerThrottlingState == TimerThrottlingState::EnabledIncreasing);
1607     ASSERT(m_domTimerAlignmentInterval < m_domTimerAlignmentIntervalIncreaseLimit);
1608     
1609     // Alignment interval is increased to equal the time the page has been throttled, to a limit.
1610     updateDOMTimerAlignmentInterval();
1611 }
1612
1613 void Page::dnsPrefetchingStateChanged()
1614 {
1615     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1616         if (!frame->document())
1617             continue;
1618         frame->document()->initDNSPrefetch();
1619     }
1620 }
1621
1622 Vector<Ref<PluginViewBase>> Page::pluginViews()
1623 {
1624     Vector<Ref<PluginViewBase>> views;
1625     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1626         auto* view = frame->view();
1627         if (!view)
1628             break;
1629         for (auto& widget : view->children()) {
1630             if (is<PluginViewBase>(widget))
1631                 views.append(downcast<PluginViewBase>(widget.get()));
1632         }
1633     }
1634     return views;
1635 }
1636
1637 void Page::storageBlockingStateChanged()
1638 {
1639     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1640         if (!frame->document())
1641             continue;
1642         frame->document()->storageBlockingStateDidChange();
1643     }
1644
1645     // Collect the PluginViews in to a vector to ensure that action the plug-in takes
1646     // from below storageBlockingStateChanged does not affect their lifetime.
1647     for (auto& view : pluginViews())
1648         view->storageBlockingStateChanged();
1649 }
1650
1651 void Page::enableLegacyPrivateBrowsing(bool privateBrowsingEnabled)
1652 {
1653     // Don't allow changing the legacy private browsing state if we have set a session ID.
1654     ASSERT(m_sessionID == PAL::SessionID::defaultSessionID() || m_sessionID == PAL::SessionID::legacyPrivateSessionID());
1655
1656     setSessionID(privateBrowsingEnabled ? PAL::SessionID::legacyPrivateSessionID() : PAL::SessionID::defaultSessionID());
1657 }
1658
1659 void Page::updateIsPlayingMedia(uint64_t sourceElementID)
1660 {
1661     MediaProducer::MediaStateFlags state = MediaProducer::IsNotPlaying;
1662     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1663         if (Document* document = frame->document())
1664             state |= document->mediaState();
1665     }
1666
1667     if (state == m_mediaState)
1668         return;
1669
1670     m_mediaState = state;
1671
1672     chrome().client().isPlayingMediaDidChange(state, sourceElementID);
1673 }
1674
1675 void Page::schedulePlaybackControlsManagerUpdate()
1676 {
1677 #if ENABLE(VIDEO)
1678     if (!m_playbackControlsManagerUpdateTimer.isActive())
1679         m_playbackControlsManagerUpdateTimer.startOneShot(0_s);
1680 #endif
1681 }
1682
1683 #if ENABLE(VIDEO)
1684 void Page::playbackControlsManagerUpdateTimerFired()
1685 {
1686     if (auto bestMediaElement = HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::ControlsManager))
1687         chrome().client().setUpPlaybackControlsManager(*bestMediaElement);
1688     else
1689         chrome().client().clearPlaybackControlsManager();
1690 }
1691 #endif
1692
1693 void Page::setMuted(MediaProducer::MutedStateFlags muted)
1694 {
1695     if (m_mutedState == muted)
1696         return;
1697
1698     m_mutedState = muted;
1699
1700     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1701         if (!frame->document())
1702             continue;
1703         frame->document()->pageMutedStateDidChange();
1704     }
1705 }
1706
1707 void Page::stopMediaCapture()
1708 {
1709 #if ENABLE(MEDIA_STREAM)
1710     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1711         if (!frame->document())
1712             continue;
1713
1714         frame->document()->stopMediaCapture();
1715     }
1716 #endif
1717 }
1718
1719 #if ENABLE(MEDIA_SESSION)
1720 void Page::handleMediaEvent(MediaEventType eventType)
1721 {
1722     switch (eventType) {
1723     case MediaEventType::PlayPause:
1724         MediaSessionManager::singleton().togglePlayback();
1725         break;
1726     case MediaEventType::TrackNext:
1727         MediaSessionManager::singleton().skipToNextTrack();
1728         break;
1729     case MediaEventType::TrackPrevious:
1730         MediaSessionManager::singleton().skipToPreviousTrack();
1731         break;
1732     }
1733 }
1734
1735 void Page::setVolumeOfMediaElement(double volume, uint64_t elementID)
1736 {
1737     if (HTMLMediaElement* element = HTMLMediaElement::elementWithID(elementID))
1738         element->setVolume(volume, ASSERT_NO_EXCEPTION);
1739 }
1740 #endif
1741
1742 #if !ASSERT_DISABLED
1743 void Page::checkSubframeCountConsistency() const
1744 {
1745     ASSERT(m_subframeCount >= 0);
1746
1747     int subframeCount = 0;
1748     for (const Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
1749         ++subframeCount;
1750
1751     ASSERT(m_subframeCount + 1 == subframeCount);
1752 }
1753 #endif
1754
1755 void Page::resumeAnimatingImages()
1756 {
1757     // Drawing models which cache painted content while out-of-window (WebKit2's composited drawing areas, etc.)
1758     // require that we repaint animated images to kickstart the animation loop.
1759     if (FrameView* view = mainFrame().view())
1760         view->resumeVisibleImageAnimationsIncludingSubframes();
1761 }
1762
1763 void Page::setActivityState(OptionSet<ActivityState::Flag> activityState)
1764 {
1765     auto changed = m_activityState ^ activityState;
1766     if (!changed)
1767         return;
1768
1769     auto oldActivityState = m_activityState;
1770
1771     bool wasVisibleAndActive = isVisibleAndActive();
1772     m_activityState = activityState;
1773
1774     m_focusController->setActivityState(activityState);
1775
1776     if (changed & ActivityState::IsVisible)
1777         setIsVisibleInternal(activityState.contains(ActivityState::IsVisible));
1778     if (changed & ActivityState::IsInWindow)
1779         setIsInWindowInternal(activityState.contains(ActivityState::IsInWindow));
1780     if (changed & ActivityState::IsVisuallyIdle)
1781         setIsVisuallyIdleInternal(activityState.contains(ActivityState::IsVisuallyIdle));
1782     if (changed & ActivityState::WindowIsActive) {
1783         if (auto* view = m_mainFrame->view())
1784             view->updateTiledBackingAdaptiveSizing();
1785     }
1786
1787     if (changed.containsAny({ActivityState::IsVisible, ActivityState::IsVisuallyIdle, ActivityState::IsAudible, ActivityState::IsLoading, ActivityState::IsCapturingMedia }))
1788         updateTimerThrottlingState();
1789
1790     for (auto* observer : m_activityStateChangeObservers)
1791         observer->activityStateDidChange(oldActivityState, m_activityState);
1792
1793     if (wasVisibleAndActive != isVisibleAndActive())
1794         PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary();
1795
1796     if (m_performanceMonitor)
1797         m_performanceMonitor->activityStateChanged(oldActivityState, activityState);
1798 }
1799
1800 bool Page::isVisibleAndActive() const
1801 {
1802     return m_activityState.contains(ActivityState::IsVisible) && m_activityState.contains(ActivityState::WindowIsActive);
1803 }
1804
1805 bool Page::isWindowActive() const
1806 {
1807     return m_activityState.contains(ActivityState::WindowIsActive);
1808 }
1809
1810 void Page::setIsVisible(bool isVisible)
1811 {
1812     auto state = m_activityState;
1813
1814     if (isVisible) {
1815         state.remove(ActivityState::IsVisuallyIdle);
1816         state.add({ ActivityState::IsVisible, ActivityState::IsVisibleOrOccluded });
1817     } else {
1818         state.add(ActivityState::IsVisuallyIdle);
1819         state.remove({ ActivityState::IsVisible, ActivityState::IsVisibleOrOccluded });
1820     }
1821     setActivityState(state);
1822 }
1823
1824 enum class SVGAnimationsState { Paused, Resumed };
1825 static inline void setSVGAnimationsState(Page& page, SVGAnimationsState state)
1826 {
1827     for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
1828         auto* document = frame->document();
1829         if (!document)
1830             continue;
1831
1832         if (!document->svgExtensions())
1833             continue;
1834
1835         if (state == SVGAnimationsState::Paused)
1836             document->accessSVGExtensions().pauseAnimations();
1837         else
1838             document->accessSVGExtensions().unpauseAnimations();
1839     }
1840 }
1841
1842 void Page::setIsVisibleInternal(bool isVisible)
1843 {
1844     // FIXME: The visibility state should be stored on the top-level document.
1845     // https://bugs.webkit.org/show_bug.cgi?id=116769
1846
1847     if (isVisible) {
1848         m_isPrerender = false;
1849
1850         resumeScriptedAnimations();
1851 #if PLATFORM(IOS_FAMILY)
1852         resumeDeviceMotionAndOrientationUpdates();
1853 #endif
1854
1855         if (FrameView* view = mainFrame().view())
1856             view->show();
1857
1858         if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) {
1859             if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1860                 forEachDocument([&] (Document& document) {
1861                     if (auto* timeline = document.existingTimeline())
1862                         timeline->resumeAnimations();
1863                 });
1864             } else
1865                 mainFrame().animation().resumeAnimations();
1866         }
1867
1868         setSVGAnimationsState(*this, SVGAnimationsState::Resumed);
1869
1870         resumeAnimatingImages();
1871
1872         if (m_navigationToLogWhenVisible) {
1873             logNavigation(m_navigationToLogWhenVisible.value());
1874             m_navigationToLogWhenVisible = std::nullopt;
1875         }
1876     }
1877
1878     if (!isVisible) {
1879         if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) {
1880             if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1881                 forEachDocument([&] (Document& document) {
1882                     if (auto* timeline = document.existingTimeline())
1883                         timeline->suspendAnimations();
1884                 });
1885             } else
1886                 mainFrame().animation().suspendAnimations();
1887         }
1888
1889         setSVGAnimationsState(*this, SVGAnimationsState::Paused);
1890
1891 #if PLATFORM(IOS_FAMILY)
1892         suspendDeviceMotionAndOrientationUpdates();
1893 #endif
1894
1895         suspendScriptedAnimations();
1896
1897         if (FrameView* view = mainFrame().view())
1898             view->hide();
1899     }
1900
1901     Vector<Ref<Document>> documents;
1902     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
1903         documents.append(*frame->document());
1904
1905     for (auto& document : documents)
1906         document->visibilityStateChanged();
1907 }
1908
1909 void Page::setIsPrerender()
1910 {
1911     m_isPrerender = true;
1912     updateDOMTimerAlignmentInterval();
1913 }
1914
1915 VisibilityState Page::visibilityState() const
1916 {
1917     if (isVisible())
1918         return VisibilityState::Visible;
1919     if (m_isPrerender)
1920         return VisibilityState::Prerender;
1921     return VisibilityState::Hidden;
1922 }
1923
1924 #if ENABLE(RUBBER_BANDING)
1925 void Page::addHeaderWithHeight(int headerHeight)
1926 {
1927     m_headerHeight = headerHeight;
1928
1929     FrameView* frameView = mainFrame().view();
1930     if (!frameView)
1931         return;
1932
1933     RenderView* renderView = frameView->renderView();
1934     if (!renderView)
1935         return;
1936
1937     frameView->setHeaderHeight(m_headerHeight);
1938     renderView->compositor().updateLayerForHeader(m_headerHeight);
1939 }
1940
1941 void Page::addFooterWithHeight(int footerHeight)
1942 {
1943     m_footerHeight = footerHeight;
1944
1945     FrameView* frameView = mainFrame().view();
1946     if (!frameView)
1947         return;
1948
1949     RenderView* renderView = frameView->renderView();
1950     if (!renderView)
1951         return;
1952
1953     frameView->setFooterHeight(m_footerHeight);
1954     renderView->compositor().updateLayerForFooter(m_footerHeight);
1955 }
1956 #endif
1957
1958 void Page::incrementNestedRunLoopCount()
1959 {
1960     m_nestedRunLoopCount++;
1961 }
1962
1963 void Page::decrementNestedRunLoopCount()
1964 {
1965     ASSERT(m_nestedRunLoopCount);
1966     if (m_nestedRunLoopCount <= 0)
1967         return;
1968
1969     m_nestedRunLoopCount--;
1970
1971     if (!m_nestedRunLoopCount && m_unnestCallback) {
1972         callOnMainThread([this] {
1973             if (insideNestedRunLoop())
1974                 return;
1975
1976             // This callback may destruct the Page.
1977             if (m_unnestCallback) {
1978                 auto callback = WTFMove(m_unnestCallback);
1979                 callback();
1980             }
1981         });
1982     }
1983 }
1984
1985 void Page::whenUnnested(WTF::Function<void()>&& callback)
1986 {
1987     ASSERT(!m_unnestCallback);
1988
1989     m_unnestCallback = WTFMove(callback);
1990 }
1991
1992 #if ENABLE(REMOTE_INSPECTOR)
1993 bool Page::remoteInspectionAllowed() const
1994 {
1995     return m_inspectorDebuggable->remoteDebuggingAllowed();
1996 }
1997
1998 void Page::setRemoteInspectionAllowed(bool allowed)
1999 {
2000     m_inspectorDebuggable->setRemoteDebuggingAllowed(allowed);
2001 }
2002
2003 String Page::remoteInspectionNameOverride() const
2004 {
2005     return m_inspectorDebuggable->nameOverride();
2006 }
2007
2008 void Page::setRemoteInspectionNameOverride(const String& name)
2009 {
2010     m_inspectorDebuggable->setNameOverride(name);
2011 }
2012
2013 void Page::remoteInspectorInformationDidChange() const
2014 {
2015     m_inspectorDebuggable->update();
2016 }
2017 #endif
2018
2019 void Page::addLayoutMilestones(OptionSet<LayoutMilestone> milestones)
2020 {
2021     // In the future, we may want a function that replaces m_layoutMilestones instead of just adding to it.
2022     m_requestedLayoutMilestones.add(milestones);
2023 }
2024
2025 void Page::removeLayoutMilestones(OptionSet<LayoutMilestone> milestones)
2026 {
2027     m_requestedLayoutMilestones.remove(milestones);
2028 }
2029
2030 Color Page::pageExtendedBackgroundColor() const
2031 {
2032     FrameView* frameView = mainFrame().view();
2033     if (!frameView)
2034         return Color();
2035
2036     RenderView* renderView = frameView->renderView();
2037     if (!renderView)
2038         return Color();
2039
2040     return renderView->compositor().rootExtendedBackgroundColor();
2041 }
2042
2043 // These are magical constants that might be tweaked over time.
2044 static const double gMinimumPaintedAreaRatio = 0.1;
2045 static const double gMaximumUnpaintedAreaRatio = 0.04;
2046
2047 bool Page::isCountingRelevantRepaintedObjects() const
2048 {
2049     return m_isCountingRelevantRepaintedObjects && m_requestedLayoutMilestones.contains(DidHitRelevantRepaintedObjectsAreaThreshold);
2050 }
2051
2052 void Page::startCountingRelevantRepaintedObjects()
2053 {
2054     // Reset everything in case we didn't hit the threshold last time.
2055     resetRelevantPaintedObjectCounter();
2056
2057     m_isCountingRelevantRepaintedObjects = true;
2058 }
2059
2060 void Page::resetRelevantPaintedObjectCounter()
2061 {
2062     m_isCountingRelevantRepaintedObjects = false;
2063     m_relevantUnpaintedRenderObjects.clear();
2064     m_topRelevantPaintedRegion = Region();
2065     m_bottomRelevantPaintedRegion = Region();
2066     m_relevantUnpaintedRegion = Region();
2067 }
2068
2069 static LayoutRect relevantViewRect(RenderView* view)
2070 {
2071     LayoutRect viewRect = view->viewRect();
2072
2073     float relevantViewRectWidth = 980;
2074 #if PLATFORM(WATCHOS)
2075     // FIXME(186051): Consider limiting the relevant rect width to the view width everywhere.
2076     relevantViewRectWidth = std::min<float>(viewRect.width().toFloat(), relevantViewRectWidth);
2077 #endif
2078
2079     // DidHitRelevantRepaintedObjectsAreaThreshold is a LayoutMilestone intended to indicate that
2080     // a certain relevant amount of content has been drawn to the screen. This is the rect that
2081     // has been determined to be relevant in the context of this goal. We may choose to tweak
2082     // the rect over time, much like we may choose to tweak gMinimumPaintedAreaRatio and
2083     // gMaximumUnpaintedAreaRatio. But this seems to work well right now.
2084     LayoutRect relevantViewRect { 0, 0, relevantViewRectWidth, 1300 };
2085     // If the viewRect is wider than the relevantViewRect, center the relevantViewRect.
2086     if (viewRect.width() > relevantViewRect.width())
2087         relevantViewRect.setX((viewRect.width() - relevantViewRect.width()) / 2);
2088
2089     return relevantViewRect;
2090 }
2091
2092 void Page::addRelevantRepaintedObject(RenderObject* object, const LayoutRect& objectPaintRect)
2093 {
2094     if (!isCountingRelevantRepaintedObjects())
2095         return;
2096
2097     // Objects inside sub-frames are not considered to be relevant.
2098     if (&object->frame() != &mainFrame())
2099         return;
2100
2101     LayoutRect relevantRect = relevantViewRect(&object->view());
2102
2103     // The objects are only relevant if they are being painted within the viewRect().
2104     if (!objectPaintRect.intersects(snappedIntRect(relevantRect)))
2105         return;
2106
2107     IntRect snappedPaintRect = snappedIntRect(objectPaintRect);
2108
2109     // If this object was previously counted as an unpainted object, remove it from that HashSet
2110     // and corresponding Region. FIXME: This doesn't do the right thing if the objects overlap.
2111     if (m_relevantUnpaintedRenderObjects.remove(object))
2112         m_relevantUnpaintedRegion.subtract(snappedPaintRect);
2113
2114     // Split the relevantRect into a top half and a bottom half. Making sure we have coverage in
2115     // both halves helps to prevent cases where we have a fully loaded menu bar or masthead with
2116     // no content beneath that.
2117     LayoutRect topRelevantRect = relevantRect;
2118     topRelevantRect.contract(LayoutSize(0, relevantRect.height() / 2));
2119     LayoutRect bottomRelevantRect = topRelevantRect;
2120     bottomRelevantRect.setY(relevantRect.height() / 2);
2121
2122     // If the rect straddles both Regions, split it appropriately.
2123     if (topRelevantRect.intersects(snappedPaintRect) && bottomRelevantRect.intersects(snappedPaintRect)) {
2124         IntRect topIntersection = snappedPaintRect;
2125         topIntersection.intersect(snappedIntRect(topRelevantRect));
2126         m_topRelevantPaintedRegion.unite(topIntersection);
2127
2128         IntRect bottomIntersection = snappedPaintRect;
2129         bottomIntersection.intersect(snappedIntRect(bottomRelevantRect));
2130         m_bottomRelevantPaintedRegion.unite(bottomIntersection);
2131     } else if (topRelevantRect.intersects(snappedPaintRect))
2132         m_topRelevantPaintedRegion.unite(snappedPaintRect);
2133     else
2134         m_bottomRelevantPaintedRegion.unite(snappedPaintRect);
2135
2136     float topPaintedArea = m_topRelevantPaintedRegion.totalArea();
2137     float bottomPaintedArea = m_bottomRelevantPaintedRegion.totalArea();
2138     float viewArea = relevantRect.width() * relevantRect.height();
2139
2140     float ratioThatIsPaintedOnTop = topPaintedArea / viewArea;
2141     float ratioThatIsPaintedOnBottom = bottomPaintedArea / viewArea;
2142     float ratioOfViewThatIsUnpainted = m_relevantUnpaintedRegion.totalArea() / viewArea;
2143
2144     if (ratioThatIsPaintedOnTop > (gMinimumPaintedAreaRatio / 2) && ratioThatIsPaintedOnBottom > (gMinimumPaintedAreaRatio / 2)
2145         && ratioOfViewThatIsUnpainted < gMaximumUnpaintedAreaRatio) {
2146         m_isCountingRelevantRepaintedObjects = false;
2147         resetRelevantPaintedObjectCounter();
2148         if (Frame* frame = &mainFrame())
2149             frame->loader().didReachLayoutMilestone(DidHitRelevantRepaintedObjectsAreaThreshold);
2150     }
2151 }
2152
2153 void Page::addRelevantUnpaintedObject(RenderObject* object, const LayoutRect& objectPaintRect)
2154 {
2155     if (!isCountingRelevantRepaintedObjects())
2156         return;
2157
2158     // The objects are only relevant if they are being painted within the relevantViewRect().
2159     if (!objectPaintRect.intersects(snappedIntRect(relevantViewRect(&object->view()))))
2160         return;
2161
2162     m_relevantUnpaintedRenderObjects.add(object);
2163     m_relevantUnpaintedRegion.unite(snappedIntRect(objectPaintRect));
2164 }
2165
2166 void Page::suspendDeviceMotionAndOrientationUpdates()
2167 {
2168     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2169         if (Document* document = frame->document())
2170             document->suspendDeviceMotionAndOrientationUpdates();
2171     }
2172 }
2173
2174 void Page::resumeDeviceMotionAndOrientationUpdates()
2175 {
2176     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2177         if (Document* document = frame->document())
2178             document->resumeDeviceMotionAndOrientationUpdates();
2179     }
2180 }
2181
2182 void Page::suspendActiveDOMObjectsAndAnimations()
2183 {
2184     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
2185         frame->suspendActiveDOMObjectsAndAnimations();
2186 }
2187
2188 void Page::resumeActiveDOMObjectsAndAnimations()
2189 {
2190     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
2191         frame->resumeActiveDOMObjectsAndAnimations();
2192
2193     resumeAnimatingImages();
2194 }
2195
2196 bool Page::hasSeenAnyPlugin() const
2197 {
2198     return !m_seenPlugins.isEmpty();
2199 }
2200
2201 bool Page::hasSeenPlugin(const String& serviceType) const
2202 {
2203     return m_seenPlugins.contains(serviceType);
2204 }
2205
2206 void Page::sawPlugin(const String& serviceType)
2207 {
2208     m_seenPlugins.add(serviceType);
2209 }
2210
2211 void Page::resetSeenPlugins()
2212 {
2213     m_seenPlugins.clear();
2214 }
2215
2216 bool Page::hasSeenAnyMediaEngine() const
2217 {
2218     return !m_seenMediaEngines.isEmpty();
2219 }
2220
2221 bool Page::hasSeenMediaEngine(const String& engineDescription) const
2222 {
2223     return m_seenMediaEngines.contains(engineDescription);
2224 }
2225
2226 void Page::sawMediaEngine(const String& engineDescription)
2227 {
2228     m_seenMediaEngines.add(engineDescription);
2229 }
2230
2231 void Page::resetSeenMediaEngines()
2232 {
2233     m_seenMediaEngines.clear();
2234 }
2235
2236 void Page::hiddenPageCSSAnimationSuspensionStateChanged()
2237 {
2238     if (!isVisible()) {
2239         if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
2240             forEachDocument([&] (Document& document) {
2241                 if (auto* timeline = document.existingTimeline()) {
2242                     if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
2243                         timeline->suspendAnimations();
2244                     else
2245                         timeline->resumeAnimations();
2246                 }
2247             });
2248         } else {
2249             if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
2250                 mainFrame().animation().suspendAnimations();
2251             else
2252                 mainFrame().animation().resumeAnimations();
2253         }
2254     }
2255 }
2256
2257 #if ENABLE(VIDEO_TRACK)
2258 void Page::captionPreferencesChanged()
2259 {
2260     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2261         if (!frame->document())
2262             continue;
2263         frame->document()->captionPreferencesChanged();
2264     }
2265 }
2266 #endif
2267
2268 void Page::forbidPrompts()
2269 {
2270     ++m_forbidPromptsDepth;
2271 }
2272
2273 void Page::allowPrompts()
2274 {
2275     ASSERT(m_forbidPromptsDepth);
2276     --m_forbidPromptsDepth;
2277 }
2278
2279 bool Page::arePromptsAllowed()
2280 {
2281     return !m_forbidPromptsDepth;
2282 }
2283
2284 void Page::logNavigation(const Navigation& navigation)
2285 {
2286     String navigationDescription;
2287     switch (navigation.type) {
2288     case FrameLoadType::Standard:
2289         navigationDescription = "standard"_s;
2290         break;
2291     case FrameLoadType::Back:
2292         navigationDescription = "back"_s;
2293         break;
2294     case FrameLoadType::Forward:
2295         navigationDescription = "forward"_s;
2296         break;
2297     case FrameLoadType::IndexedBackForward:
2298         navigationDescription = "indexedBackForward"_s;
2299         break;
2300     case FrameLoadType::Reload:
2301         navigationDescription = "reload"_s;
2302         break;
2303     case FrameLoadType::Same:
2304         navigationDescription = "same"_s;
2305         break;
2306     case FrameLoadType::ReloadFromOrigin:
2307         navigationDescription = "reloadFromOrigin"_s;
2308         break;
2309     case FrameLoadType::ReloadExpiredOnly:
2310         navigationDescription = "reloadRevalidatingExpired"_s;
2311         break;
2312     case FrameLoadType::Replace:
2313     case FrameLoadType::RedirectWithLockedBackForwardList:
2314         // Not logging those for now.
2315         return;
2316     }
2317     diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::navigationKey(), navigationDescription, ShouldSample::No);
2318
2319     if (!navigation.domain.isEmpty())
2320         diagnosticLoggingClient().logDiagnosticMessageWithEnhancedPrivacy(DiagnosticLoggingKeys::domainVisitedKey(), navigation.domain, ShouldSample::No);
2321 }
2322
2323 void Page::mainFrameLoadStarted(const URL& destinationURL, FrameLoadType type)
2324 {
2325     String domain;
2326 #if ENABLE(PUBLIC_SUFFIX_LIST)
2327     domain = topPrivatelyControlledDomain(destinationURL.host().toString());
2328 #else
2329     UNUSED_PARAM(destinationURL);
2330 #endif
2331
2332     Navigation navigation = { domain, type };
2333
2334     // To avoid being too verbose, we only log navigations if the page is or becomes visible. This avoids logging non-user observable loads.
2335     if (!isVisible()) {
2336         m_navigationToLogWhenVisible = navigation;
2337         return;
2338     }
2339
2340     m_navigationToLogWhenVisible = std::nullopt;
2341     logNavigation(navigation);
2342 }
2343
2344 PluginInfoProvider& Page::pluginInfoProvider()
2345 {
2346     return m_pluginInfoProvider;
2347 }
2348
2349 UserContentProvider& Page::userContentProvider()
2350 {
2351     return m_userContentProvider;
2352 }
2353
2354 void Page::setUserContentProvider(Ref<UserContentProvider>&& userContentProvider)
2355 {
2356     m_userContentProvider->removePage(*this);
2357     m_userContentProvider = WTFMove(userContentProvider);
2358     m_userContentProvider->addPage(*this);
2359
2360     invalidateInjectedStyleSheetCacheInAllFrames();
2361 }
2362
2363 void Page::setStorageNamespaceProvider(Ref<StorageNamespaceProvider>&& storageNamespaceProvider)
2364 {
2365     m_storageNamespaceProvider->removePage(*this);
2366     m_storageNamespaceProvider = WTFMove(storageNamespaceProvider);
2367     m_storageNamespaceProvider->addPage(*this);
2368
2369     // This needs to reset all the local storage namespaces of all the pages.
2370 }
2371
2372 VisitedLinkStore& Page::visitedLinkStore()
2373 {
2374     return m_visitedLinkStore;
2375 }
2376
2377 void Page::setVisitedLinkStore(Ref<VisitedLinkStore>&& visitedLinkStore)
2378 {
2379     m_visitedLinkStore->removePage(*this);
2380     m_visitedLinkStore = WTFMove(visitedLinkStore);
2381     m_visitedLinkStore->addPage(*this);
2382
2383     invalidateStylesForAllLinks();
2384 }
2385
2386 PAL::SessionID Page::sessionID() const
2387 {
2388     return m_sessionID;
2389 }
2390
2391 void Page::setSessionID(PAL::SessionID sessionID)
2392 {
2393     ASSERT(sessionID.isValid());
2394
2395 #if ENABLE(INDEXED_DATABASE)
2396     if (sessionID != m_sessionID)
2397         m_idbConnectionToServer = nullptr;
2398 #endif
2399
2400     bool privateBrowsingStateChanged = (sessionID.isEphemeral() != m_sessionID.isEphemeral());
2401
2402     m_sessionID = sessionID;
2403
2404     if (!privateBrowsingStateChanged)
2405         return;
2406
2407     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2408         if (!frame->document())
2409             continue;
2410         frame->document()->privateBrowsingStateDidChange();
2411     }
2412
2413     // Collect the PluginViews in to a vector to ensure that action the plug-in takes
2414     // from below privateBrowsingStateChanged does not affect their lifetime.
2415
2416     for (auto& view : pluginViews())
2417         view->privateBrowsingStateChanged(sessionID.isEphemeral());
2418 }
2419
2420 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
2421 void Page::addPlaybackTargetPickerClient(uint64_t contextId)
2422 {
2423     chrome().client().addPlaybackTargetPickerClient(contextId);
2424 }
2425
2426 void Page::removePlaybackTargetPickerClient(uint64_t contextId)
2427 {
2428     chrome().client().removePlaybackTargetPickerClient(contextId);
2429 }
2430
2431 void Page::showPlaybackTargetPicker(uint64_t contextId, const WebCore::IntPoint& location, bool isVideo, RouteSharingPolicy routeSharingPolicy, const String& routingContextUID)
2432 {
2433 #if PLATFORM(IOS_FAMILY)
2434     // FIXME: refactor iOS implementation.
2435     UNUSED_PARAM(contextId);
2436     UNUSED_PARAM(location);
2437     chrome().client().showPlaybackTargetPicker(isVideo, routeSharingPolicy, routingContextUID);
2438 #else
2439     UNUSED_PARAM(routeSharingPolicy);
2440     UNUSED_PARAM(routingContextUID);
2441     chrome().client().showPlaybackTargetPicker(contextId, location, isVideo);
2442 #endif
2443 }
2444
2445 void Page::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state)
2446 {
2447     chrome().client().playbackTargetPickerClientStateDidChange(contextId, state);
2448 }
2449
2450 void Page::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
2451 {
2452     chrome().client().setMockMediaPlaybackTargetPickerEnabled(enabled);
2453 }
2454
2455 void Page::setMockMediaPlaybackTargetPickerState(const String& name, MediaPlaybackTargetContext::State state)
2456 {
2457     chrome().client().setMockMediaPlaybackTargetPickerState(name, state);
2458 }
2459
2460 void Page::setPlaybackTarget(uint64_t contextId, Ref<MediaPlaybackTarget>&& target)
2461 {
2462     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2463         if (!frame->document())
2464             continue;
2465         frame->document()->setPlaybackTarget(contextId, target.copyRef());
2466     }
2467 }
2468
2469 void Page::playbackTargetAvailabilityDidChange(uint64_t contextId, bool available)
2470 {
2471     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2472         if (!frame->document())
2473             continue;
2474         frame->document()->playbackTargetAvailabilityDidChange(contextId, available);
2475     }
2476 }
2477
2478 void Page::setShouldPlayToPlaybackTarget(uint64_t clientId, bool shouldPlay)
2479 {
2480     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2481         if (!frame->document())
2482             continue;
2483         frame->document()->setShouldPlayToPlaybackTarget(clientId, shouldPlay);
2484     }
2485 }
2486 #endif
2487
2488 WheelEventTestTrigger& Page::ensureTestTrigger()
2489 {
2490     if (!m_testTrigger) {
2491         m_testTrigger = adoptRef(new WheelEventTestTrigger());
2492         // We need to update the scrolling coordinator so that the mainframe scrolling node can expect wheel event test triggers.
2493         if (auto* frameView = mainFrame().view()) {
2494             if (m_scrollingCoordinator)
2495                 m_scrollingCoordinator->updateExpectsWheelEventTestTriggerWithFrameView(*frameView);
2496         }
2497     }
2498
2499     return *m_testTrigger;
2500 }
2501
2502 #if ENABLE(VIDEO)
2503 void Page::setAllowsMediaDocumentInlinePlayback(bool flag)
2504 {
2505     if (m_allowsMediaDocumentInlinePlayback == flag)
2506         return;
2507     m_allowsMediaDocumentInlinePlayback = flag;
2508
2509     Vector<Ref<Document>> documents;
2510     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
2511         documents.append(*frame->document());
2512
2513     for (auto& document : documents)
2514         document->allowsMediaDocumentInlinePlaybackChanged();
2515 }
2516 #endif
2517
2518 #if ENABLE(INDEXED_DATABASE)
2519 IDBClient::IDBConnectionToServer& Page::idbConnection()
2520 {
2521     if (!m_idbConnectionToServer)
2522         m_idbConnectionToServer = &databaseProvider().idbConnectionToServerForSession(m_sessionID);
2523     
2524     return *m_idbConnectionToServer;
2525 }
2526
2527 IDBClient::IDBConnectionToServer* Page::optionalIDBConnection()
2528 {
2529     return m_idbConnectionToServer.get();
2530 }
2531
2532 void Page::clearIDBConnection()
2533 {
2534     m_idbConnectionToServer = nullptr;
2535 }
2536 #endif
2537
2538 #if ENABLE(RESOURCE_USAGE)
2539 void Page::setResourceUsageOverlayVisible(bool visible)
2540 {
2541     if (!visible) {
2542         m_resourceUsageOverlay = nullptr;
2543         return;
2544     }
2545
2546     if (!m_resourceUsageOverlay && m_settings->acceleratedCompositingEnabled())
2547         m_resourceUsageOverlay = std::make_unique<ResourceUsageOverlay>(*this);
2548 }
2549 #endif
2550
2551 bool Page::isAlwaysOnLoggingAllowed() const
2552 {
2553     return m_sessionID.isAlwaysOnLoggingAllowed();
2554 }
2555
2556 String Page::captionUserPreferencesStyleSheet()
2557 {
2558     return m_captionUserPreferencesStyleSheet;
2559 }
2560
2561 void Page::setCaptionUserPreferencesStyleSheet(const String& styleSheet)
2562 {
2563     if (m_captionUserPreferencesStyleSheet == styleSheet)
2564         return;
2565
2566     m_captionUserPreferencesStyleSheet = styleSheet;
2567     
2568     invalidateInjectedStyleSheetCacheInAllFrames();
2569 }
2570
2571 void Page::accessibilitySettingsDidChange()
2572 {
2573     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2574         if (auto* document = frame->document()) {
2575             document->styleScope().evaluateMediaQueriesForAccessibilitySettingsChange();
2576             document->evaluateMediaQueryList();
2577         }
2578     }
2579 }
2580
2581 void Page::appearanceDidChange()
2582 {
2583     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2584         auto* document = frame->document();
2585         if (!document)
2586             continue;
2587
2588         document->styleScope().didChangeStyleSheetEnvironment();
2589         document->styleScope().evaluateMediaQueriesForAppearanceChange();
2590         document->evaluateMediaQueryList();
2591     }
2592 }
2593
2594 void Page::setUnobscuredSafeAreaInsets(const FloatBoxExtent& insets)
2595 {
2596     if (m_unobscuredSafeAreaInsets == insets)
2597         return;
2598
2599     m_unobscuredSafeAreaInsets = insets;
2600
2601     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2602         if (!frame->document())
2603             continue;
2604         frame->document()->constantProperties().didChangeSafeAreaInsets();
2605     }
2606 }
2607
2608 void Page::setUseSystemAppearance(bool value)
2609 {
2610     if (m_useSystemAppearance == value)
2611         return;
2612
2613     m_useSystemAppearance = value;
2614
2615     appearanceDidChange();
2616
2617     for (auto* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2618         auto* document = frame->document();
2619         if (!document)
2620             continue;
2621
2622         // System apperance change may affect stylesheet parsing. We need to reparse.
2623         document->extensionStyleSheets().clearPageUserSheet();
2624         document->extensionStyleSheets().invalidateInjectedStyleSheetCache();
2625     }
2626 }
2627
2628 void Page::setUseDarkAppearance(bool value)
2629 {
2630     if (m_useDarkAppearance == value)
2631         return;
2632
2633     m_useDarkAppearance = value;
2634
2635     appearanceDidChange();
2636 }
2637
2638 bool Page::useDarkAppearance() const
2639 {
2640     FrameView* view = mainFrame().view();
2641     if (!view || !equalLettersIgnoringASCIICase(view->mediaType(), "screen"))
2642         return false;
2643     return m_useDarkAppearance;
2644 }
2645
2646 void Page::setFullscreenInsets(const FloatBoxExtent& insets)
2647 {
2648     if (insets == m_fullscreenInsets)
2649         return;
2650     m_fullscreenInsets = insets;
2651
2652     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2653         if (!frame->document())
2654             continue;
2655         frame->document()->constantProperties().didChangeFullscreenInsets();
2656     }
2657 }
2658
2659 void Page::setFullscreenAutoHideDuration(Seconds duration)
2660 {
2661     if (duration == m_fullscreenAutoHideDuration)
2662         return;
2663     m_fullscreenAutoHideDuration = duration;
2664     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2665         if (!frame->document())
2666             continue;
2667         frame->document()->constantProperties().setFullscreenAutoHideDuration(duration);
2668     }
2669 }
2670
2671 void Page::setFullscreenControlsHidden(bool hidden)
2672 {
2673 #if ENABLE(FULLSCREEN_API)
2674     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2675         if (!frame->document())
2676             continue;
2677         frame->document()->setFullscreenControlsHidden(hidden);
2678     }
2679 #else
2680     UNUSED_PARAM(hidden);
2681 #endif
2682 }
2683
2684 #if ENABLE(DATA_INTERACTION)
2685
2686 bool Page::hasSelectionAtPosition(const FloatPoint& position) const
2687 {
2688     auto currentSelection = m_mainFrame->selection().selection();
2689     if (!currentSelection.isRange())
2690         return false;
2691
2692     if (auto selectedRange = currentSelection.toNormalizedRange()) {
2693         Vector<SelectionRect> selectionRects;
2694         selectedRange->collectSelectionRects(selectionRects);
2695         for (auto selectionRect : selectionRects) {
2696             if (FloatRect(selectionRect.rect()).contains(position))
2697                 return true;
2698         }
2699     }
2700
2701     return false;
2702 }
2703
2704 #endif
2705
2706 void Page::disableICECandidateFiltering()
2707 {
2708     m_shouldEnableICECandidateFilteringByDefault = false;
2709 #if ENABLE(WEB_RTC)
2710     m_rtcController.disableICECandidateFilteringForAllOrigins();
2711 #endif
2712 }
2713
2714 void Page::enableICECandidateFiltering()
2715 {
2716     m_shouldEnableICECandidateFilteringByDefault = true;
2717 #if ENABLE(WEB_RTC)
2718     m_rtcController.enableICECandidateFiltering();
2719 #endif
2720 }
2721
2722 void Page::didChangeMainDocument()
2723 {
2724 #if ENABLE(WEB_RTC)
2725     m_rtcController.reset(m_shouldEnableICECandidateFilteringByDefault);
2726 #endif
2727 }
2728
2729 void Page::forEachDocument(const Function<void(Document&)>& functor)
2730 {
2731     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2732         if (!frame->document())
2733             continue;
2734
2735         functor(*frame->document());
2736     }
2737 }
2738
2739 void Page::applicationWillResignActive()
2740 {
2741     forEachDocument([&] (Document& document) {
2742         document.forEachApplicationStateChangeListener([&] (ApplicationStateChangeListener& listener) {
2743             listener.applicationWillResignActive();
2744         });
2745     });
2746 }
2747
2748 void Page::applicationDidEnterBackground()
2749 {
2750     m_libWebRTCProvider->setActive(false);
2751 }
2752
2753 void Page::applicationWillEnterForeground()
2754 {
2755     m_libWebRTCProvider->setActive(true);
2756 }
2757
2758 void Page::applicationDidBecomeActive()
2759 {
2760     forEachDocument([&] (Document& document) {
2761         document.forEachApplicationStateChangeListener([&] (ApplicationStateChangeListener& listener) {
2762             listener.applicationDidBecomeActive();
2763         });
2764     });
2765 }
2766
2767 #if PLATFORM(MAC)
2768 ScrollLatchingState* Page::latchingState()
2769 {
2770     if (m_latchingState.isEmpty())
2771         return nullptr;
2772
2773     return &m_latchingState.last();
2774 }
2775
2776 void Page::pushNewLatchingState()
2777 {
2778     m_latchingState.append(ScrollLatchingState());
2779 }
2780
2781 void Page::resetLatchingState()
2782 {
2783     m_latchingState.clear();
2784 }
2785
2786 void Page::popLatchingState()
2787 {
2788     m_latchingState.removeLast();
2789 }
2790
2791 void Page::removeLatchingStateForTarget(Element& targetNode)
2792 {
2793     if (m_latchingState.isEmpty())
2794         return;
2795
2796     m_latchingState.removeAllMatching([&targetNode] (ScrollLatchingState& state) {
2797         auto* wheelElement = state.wheelEventElement();
2798         if (!wheelElement)
2799             return false;
2800
2801         return targetNode.isEqualNode(wheelElement);
2802     });
2803 }
2804 #endif // PLATFORM(MAC)
2805
2806 #if ENABLE(APPLE_PAY)
2807 void Page::setPaymentCoordinator(std::unique_ptr<PaymentCoordinator>&& paymentCoordinator)
2808 {
2809     m_paymentCoordinator = WTFMove(paymentCoordinator);
2810 }
2811 #endif
2812
2813 } // namespace WebCore