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