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