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