Source/WebCore:
[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 "LegacySchemeRegistry.h"
70 #include "LibWebRTCProvider.h"
71 #include "LoaderStrategy.h"
72 #include "Logging.h"
73 #include "LowPowerModeNotifier.h"
74 #include "MediaCanStartListener.h"
75 #include "Navigator.h"
76 #include "PageCache.h"
77 #include "PageConfiguration.h"
78 #include "PageConsoleClient.h"
79 #include "PageDebuggable.h"
80 #include "PageGroup.h"
81 #include "PageOverlayController.h"
82 #include "PaymentCoordinator.h"
83 #include "PerformanceLogging.h"
84 #include "PerformanceLoggingClient.h"
85 #include "PerformanceMonitor.h"
86 #include "PlatformMediaSessionManager.h"
87 #include "PlatformStrategies.h"
88 #include "PlugInClient.h"
89 #include "PluginData.h"
90 #include "PluginInfoProvider.h"
91 #include "PluginViewBase.h"
92 #include "PointerCaptureController.h"
93 #include "PointerLockController.h"
94 #include "ProgressTracker.h"
95 #include "RenderDescendantIterator.h"
96 #include "RenderLayerCompositor.h"
97 #include "RenderTheme.h"
98 #include "RenderView.h"
99 #include "RenderWidget.h"
100 #include "ResizeObserver.h"
101 #include "ResourceUsageOverlay.h"
102 #include "RuntimeEnabledFeatures.h"
103 #include "SVGDocumentExtensions.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(pageConfiguration.sessionID)
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 // https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering
1285 void Page::updateRendering()
1286 {
1287     // This function is not reentrant, e.g. a rAF callback may force repaint.
1288     if (m_inUpdateRendering) {
1289         layoutIfNeeded();
1290         return;
1291     }
1292
1293     TraceScope traceScope(RenderingUpdateStart, RenderingUpdateEnd);
1294
1295     SetForScope<bool> change(m_inUpdateRendering, true);
1296
1297     Vector<RefPtr<Document>> documents;
1298
1299     // The requestAnimationFrame callbacks may change the frame hierarchy of the page
1300     forEachDocument([&documents] (Document& document) {
1301         documents.append(&document);
1302     });
1303
1304     // FIXME: Run the resize steps
1305
1306     // FIXME: Run the scroll steps
1307
1308     // FIXME: Evaluate media queries and report changes.
1309
1310     for (auto& document : documents) {
1311         DOMHighResTimeStamp timestamp = document->domWindow()->nowTimestamp();
1312         document->updateAnimationsAndSendEvents(timestamp);
1313         // FIXME: Run the fullscreen steps.
1314         document->serviceRequestAnimationFrameCallbacks(timestamp);
1315     }
1316
1317     layoutIfNeeded();
1318
1319 #if ENABLE(INTERSECTION_OBSERVER)
1320     for (auto& document : documents)
1321         document->updateIntersectionObservations();
1322 #endif
1323 #if ENABLE(RESIZE_OBSERVER)
1324     for (auto& document : documents)
1325         document->updateResizeObservations(*this);
1326 #endif
1327
1328     // FIXME: Flush autofocus candidates
1329     // https://github.com/whatwg/html/issues/4992
1330
1331     layoutIfNeeded();
1332 }
1333
1334 void Page::suspendScriptedAnimations()
1335 {
1336     m_scriptedAnimationsSuspended = true;
1337     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1338         if (frame->document())
1339             frame->document()->suspendScriptedAnimationControllerCallbacks();
1340     }
1341 }
1342
1343 void Page::resumeScriptedAnimations()
1344 {
1345     m_scriptedAnimationsSuspended = false;
1346     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1347         if (frame->document())
1348             frame->document()->resumeScriptedAnimationControllerCallbacks();
1349     }
1350 }
1351
1352 enum class ThrottlingReasonOperation { Add, Remove };
1353 static void updateScriptedAnimationsThrottlingReason(Page& page, ThrottlingReasonOperation operation, ScriptedAnimationController::ThrottlingReason reason)
1354 {
1355     for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
1356         auto* document = frame->document();
1357         if (!document)
1358             continue;
1359         auto* scriptedAnimationController = document->scriptedAnimationController();
1360         if (!scriptedAnimationController)
1361             continue;
1362
1363         if (operation == ThrottlingReasonOperation::Add)
1364             scriptedAnimationController->addThrottlingReason(reason);
1365         else
1366             scriptedAnimationController->removeThrottlingReason(reason);
1367     }
1368 }
1369
1370 void Page::setIsVisuallyIdleInternal(bool isVisuallyIdle)
1371 {
1372     updateScriptedAnimationsThrottlingReason(*this, isVisuallyIdle ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::VisuallyIdle);
1373 }
1374
1375 void Page::handleLowModePowerChange(bool isLowPowerModeEnabled)
1376 {
1377     updateScriptedAnimationsThrottlingReason(*this, isLowPowerModeEnabled ? ThrottlingReasonOperation::Add : ThrottlingReasonOperation::Remove, ScriptedAnimationController::ThrottlingReason::LowPowerMode);
1378     if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1379         forEachDocument([&] (Document& document) {
1380             if (auto timeline = document.existingTimeline())
1381                 timeline->updateThrottlingState();
1382         });
1383     } else
1384         mainFrame().animation().updateThrottlingState();
1385     updateDOMTimerAlignmentInterval();
1386 }
1387
1388 void Page::userStyleSheetLocationChanged()
1389 {
1390     // FIXME: Eventually we will move to a model of just being handed the sheet
1391     // text instead of loading the URL ourselves.
1392     URL url = m_settings->userStyleSheetLocation();
1393     
1394     // Allow any local file URL scheme to be loaded.
1395     if (LegacySchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol().toStringWithoutCopying()))
1396         m_userStyleSheetPath = url.fileSystemPath();
1397     else
1398         m_userStyleSheetPath = String();
1399
1400     m_didLoadUserStyleSheet = false;
1401     m_userStyleSheet = String();
1402     m_userStyleSheetModificationTime = WTF::nullopt;
1403
1404     // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them
1405     // synchronously and avoid using a loader. 
1406     if (url.protocolIsData() && url.string().startsWith("data:text/css;charset=utf-8;base64,")) {
1407         m_didLoadUserStyleSheet = true;
1408
1409         Vector<char> styleSheetAsUTF8;
1410         if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, Base64IgnoreSpacesAndNewLines))
1411             m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size());
1412     }
1413
1414     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1415         if (frame->document())
1416             frame->document()->extensionStyleSheets().updatePageUserSheet();
1417     }
1418 }
1419
1420 const String& Page::userStyleSheet() const
1421 {
1422     if (m_userStyleSheetPath.isEmpty())
1423         return m_userStyleSheet;
1424
1425     auto modificationTime = FileSystem::getFileModificationTime(m_userStyleSheetPath);
1426     if (!modificationTime) {
1427         // The stylesheet either doesn't exist, was just deleted, or is
1428         // otherwise unreadable. If we've read the stylesheet before, we should
1429         // throw away that data now as it no longer represents what's on disk.
1430         m_userStyleSheet = String();
1431         return m_userStyleSheet;
1432     }
1433
1434     // If the stylesheet hasn't changed since the last time we read it, we can
1435     // just return the old data.
1436     if (m_didLoadUserStyleSheet && (m_userStyleSheetModificationTime && modificationTime.value() <= m_userStyleSheetModificationTime.value()))
1437         return m_userStyleSheet;
1438
1439     m_didLoadUserStyleSheet = true;
1440     m_userStyleSheet = String();
1441     m_userStyleSheetModificationTime = modificationTime;
1442
1443     // FIXME: It would be better to load this asynchronously to avoid blocking
1444     // the process, but we will first need to create an asynchronous loading
1445     // mechanism that is not tied to a particular Frame. We will also have to
1446     // determine what our behavior should be before the stylesheet is loaded
1447     // and what should happen when it finishes loading, especially with respect
1448     // to when the load event fires, when Document::close is called, and when
1449     // layout/paint are allowed to happen.
1450     auto data = SharedBuffer::createWithContentsOfFile(m_userStyleSheetPath);
1451     if (!data)
1452         return m_userStyleSheet;
1453
1454     m_userStyleSheet = TextResourceDecoder::create("text/css")->decodeAndFlush(data->data(), data->size());
1455
1456     return m_userStyleSheet;
1457 }
1458
1459 void Page::userAgentChanged()
1460 {
1461     for (auto* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1462         auto* window = frame->window();
1463         if (!window)
1464             continue;
1465         if (auto* navigator = window->optionalNavigator())
1466             navigator->userAgentChanged();
1467     }
1468 }
1469
1470 void Page::invalidateStylesForAllLinks()
1471 {
1472     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1473         if (!frame->document())
1474             continue;
1475         frame->document()->visitedLinkState().invalidateStyleForAllLinks();
1476     }
1477 }
1478
1479 void Page::invalidateStylesForLink(SharedStringHash linkHash)
1480 {
1481     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1482         if (!frame->document())
1483             continue;
1484         frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
1485     }
1486 }
1487
1488 void Page::invalidateInjectedStyleSheetCacheInAllFrames()
1489 {
1490     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext()) {
1491         Document* document = frame->document();
1492         if (!document)
1493             continue;
1494         document->extensionStyleSheets().invalidateInjectedStyleSheetCache();
1495     }
1496 }
1497
1498 void Page::setDebugger(JSC::Debugger* debugger)
1499 {
1500     if (m_debugger == debugger)
1501         return;
1502
1503     m_debugger = debugger;
1504
1505     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
1506         frame->windowProxy().attachDebugger(m_debugger);
1507 }
1508
1509 StorageNamespace* Page::sessionStorage(bool optionalCreate)
1510 {
1511     if (!m_sessionStorage && optionalCreate)
1512         m_sessionStorage = m_storageNamespaceProvider->createSessionStorageNamespace(*this, m_settings->sessionStorageQuota());
1513
1514     return m_sessionStorage.get();
1515 }
1516
1517 void Page::setSessionStorage(RefPtr<StorageNamespace>&& newStorage)
1518 {
1519     m_sessionStorage = WTFMove(newStorage);
1520 }
1521
1522 bool Page::hasCustomHTMLTokenizerTimeDelay() const
1523 {
1524     return m_settings->maxParseDuration() != -1;
1525 }
1526
1527 double Page::customHTMLTokenizerTimeDelay() const
1528 {
1529     ASSERT(m_settings->maxParseDuration() != -1);
1530     return m_settings->maxParseDuration();
1531 }
1532
1533 void Page::setMemoryCacheClientCallsEnabled(bool enabled)
1534 {
1535     if (m_areMemoryCacheClientCallsEnabled == enabled)
1536         return;
1537
1538     m_areMemoryCacheClientCallsEnabled = enabled;
1539     if (!enabled)
1540         return;
1541
1542     for (RefPtr<Frame> frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
1543         frame->loader().tellClientAboutPastMemoryCacheLoads();
1544 }
1545
1546 void Page::hiddenPageDOMTimerThrottlingStateChanged()
1547 {
1548     // Disable & reengage to ensure state is updated.
1549     setTimerThrottlingState(TimerThrottlingState::Disabled);
1550     updateTimerThrottlingState();
1551 }
1552
1553 void Page::updateTimerThrottlingState()
1554 {
1555     // Timer throttling disabled if page is visually active, or disabled by setting.
1556     if (!m_settings->hiddenPageDOMTimerThrottlingEnabled() || !(m_activityState & ActivityState::IsVisuallyIdle)) {
1557         setTimerThrottlingState(TimerThrottlingState::Disabled);
1558         return;
1559     }
1560
1561     // If the page is visible (but idle), there is any activity (loading, media playing, etc), or per setting,
1562     // we allow timer throttling, but not increasing timer throttling.
1563     if (!m_settings->hiddenPageDOMTimerThrottlingAutoIncreases()
1564         || m_activityState.containsAny({ActivityState::IsVisible, ActivityState::IsAudible, ActivityState::IsLoading, ActivityState::IsCapturingMedia })) {
1565         setTimerThrottlingState(TimerThrottlingState::Enabled);
1566         return;
1567     }
1568
1569     // If we get here increasing timer throttling is enabled.
1570     setTimerThrottlingState(TimerThrottlingState::EnabledIncreasing);
1571 }
1572
1573 void Page::setTimerThrottlingState(TimerThrottlingState state)
1574 {
1575     if (state == m_timerThrottlingState)
1576         return;
1577
1578     m_timerThrottlingState = state;
1579     m_timerThrottlingStateLastChangedTime = MonotonicTime::now();
1580
1581     updateDOMTimerAlignmentInterval();
1582
1583     // When throttling is disabled, release all throttled timers.
1584     if (state == TimerThrottlingState::Disabled) {
1585         for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1586             if (auto* document = frame->document())
1587                 document->didChangeTimerAlignmentInterval();
1588         }
1589     }
1590 }
1591
1592 void Page::setDOMTimerAlignmentIntervalIncreaseLimit(Seconds limit)
1593 {
1594     m_domTimerAlignmentIntervalIncreaseLimit = limit;
1595
1596     // If (m_domTimerAlignmentIntervalIncreaseLimit < m_domTimerAlignmentInterval) then we need
1597     // to update m_domTimerAlignmentInterval, if greater then need to restart the increase timer.
1598     if (m_timerThrottlingState == TimerThrottlingState::EnabledIncreasing)
1599         updateDOMTimerAlignmentInterval();
1600 }
1601
1602 void Page::updateDOMTimerAlignmentInterval()
1603 {
1604     bool needsIncreaseTimer = false;
1605
1606     switch (m_timerThrottlingState) {
1607     case TimerThrottlingState::Disabled:
1608         m_domTimerAlignmentInterval = isLowPowerModeEnabled() ? DOMTimer::defaultAlignmentIntervalInLowPowerMode() : DOMTimer::defaultAlignmentInterval();
1609         break;
1610
1611     case TimerThrottlingState::Enabled:
1612         m_domTimerAlignmentInterval = DOMTimer::hiddenPageAlignmentInterval();
1613         break;
1614
1615     case TimerThrottlingState::EnabledIncreasing:
1616         // For pages in prerender state maximum throttling kicks in immediately.
1617         if (m_isPrerender)
1618             m_domTimerAlignmentInterval = m_domTimerAlignmentIntervalIncreaseLimit;
1619         else {
1620             ASSERT(!!m_timerThrottlingStateLastChangedTime);
1621             m_domTimerAlignmentInterval = MonotonicTime::now() - m_timerThrottlingStateLastChangedTime;
1622             // If we're below the limit, set the timer. If above, clamp to limit.
1623             if (m_domTimerAlignmentInterval < m_domTimerAlignmentIntervalIncreaseLimit)
1624                 needsIncreaseTimer = true;
1625             else
1626                 m_domTimerAlignmentInterval = m_domTimerAlignmentIntervalIncreaseLimit;
1627         }
1628         // Alignment interval should not be less than DOMTimer::hiddenPageAlignmentInterval().
1629         m_domTimerAlignmentInterval = std::max(m_domTimerAlignmentInterval, DOMTimer::hiddenPageAlignmentInterval());
1630     }
1631
1632     // If throttling is enabled, auto-increasing of throttling is enabled, and the auto-increase
1633     // limit has not yet been reached, and then arm the timer to consider an increase. Time to wait
1634     // between increases is equal to the current throttle time. Since alinment interval increases
1635     // exponentially, time between steps is exponential too.
1636     if (!needsIncreaseTimer)
1637         m_domTimerAlignmentIntervalIncreaseTimer.stop();
1638     else if (!m_domTimerAlignmentIntervalIncreaseTimer.isActive())
1639         m_domTimerAlignmentIntervalIncreaseTimer.startOneShot(m_domTimerAlignmentInterval);
1640 }
1641
1642 void Page::domTimerAlignmentIntervalIncreaseTimerFired()
1643 {
1644     ASSERT(m_settings->hiddenPageDOMTimerThrottlingAutoIncreases());
1645     ASSERT(m_timerThrottlingState == TimerThrottlingState::EnabledIncreasing);
1646     ASSERT(m_domTimerAlignmentInterval < m_domTimerAlignmentIntervalIncreaseLimit);
1647     
1648     // Alignment interval is increased to equal the time the page has been throttled, to a limit.
1649     updateDOMTimerAlignmentInterval();
1650 }
1651
1652 void Page::dnsPrefetchingStateChanged()
1653 {
1654     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1655         if (!frame->document())
1656             continue;
1657         frame->document()->initDNSPrefetch();
1658     }
1659 }
1660
1661 Vector<Ref<PluginViewBase>> Page::pluginViews()
1662 {
1663     Vector<Ref<PluginViewBase>> views;
1664     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1665         auto* view = frame->view();
1666         if (!view)
1667             break;
1668         for (auto& widget : view->children()) {
1669             if (is<PluginViewBase>(widget))
1670                 views.append(downcast<PluginViewBase>(widget.get()));
1671         }
1672     }
1673     return views;
1674 }
1675
1676 void Page::storageBlockingStateChanged()
1677 {
1678     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1679         if (!frame->document())
1680             continue;
1681         frame->document()->storageBlockingStateDidChange();
1682     }
1683
1684     // Collect the PluginViews in to a vector to ensure that action the plug-in takes
1685     // from below storageBlockingStateChanged does not affect their lifetime.
1686     for (auto& view : pluginViews())
1687         view->storageBlockingStateChanged();
1688 }
1689
1690 void Page::updateIsPlayingMedia(uint64_t sourceElementID)
1691 {
1692     MediaProducer::MediaStateFlags state = MediaProducer::IsNotPlaying;
1693     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1694         if (Document* document = frame->document())
1695             state |= document->mediaState();
1696     }
1697
1698     if (state == m_mediaState)
1699         return;
1700
1701     m_mediaState = state;
1702
1703     chrome().client().isPlayingMediaDidChange(state, sourceElementID);
1704 }
1705
1706 void Page::schedulePlaybackControlsManagerUpdate()
1707 {
1708 #if ENABLE(VIDEO)
1709     if (!m_playbackControlsManagerUpdateTimer.isActive())
1710         m_playbackControlsManagerUpdateTimer.startOneShot(0_s);
1711 #endif
1712 }
1713
1714 #if ENABLE(VIDEO)
1715 void Page::playbackControlsManagerUpdateTimerFired()
1716 {
1717     if (auto bestMediaElement = HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose::ControlsManager))
1718         chrome().client().setUpPlaybackControlsManager(*bestMediaElement);
1719     else
1720         chrome().client().clearPlaybackControlsManager();
1721 }
1722 #endif
1723
1724 void Page::setMuted(MediaProducer::MutedStateFlags muted)
1725 {
1726     if (m_mutedState == muted)
1727         return;
1728
1729     m_mutedState = muted;
1730
1731     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1732         if (!frame->document())
1733             continue;
1734         frame->document()->pageMutedStateDidChange();
1735     }
1736 }
1737
1738 void Page::stopMediaCapture()
1739 {
1740 #if ENABLE(MEDIA_STREAM)
1741     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1742         if (!frame->document())
1743             continue;
1744
1745         frame->document()->stopMediaCapture();
1746     }
1747 #endif
1748 }
1749
1750 void Page::stopAllMediaPlayback()
1751 {
1752 #if ENABLE(VIDEO)
1753     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1754         if (auto* document = frame->document())
1755             document->stopAllMediaPlayback();
1756     }
1757 #endif
1758 }
1759
1760 void Page::suspendAllMediaPlayback()
1761 {
1762 #if ENABLE(VIDEO)
1763     ASSERT(!m_mediaPlaybackIsSuspended);
1764     if (m_mediaPlaybackIsSuspended)
1765         return;
1766
1767     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1768         if (auto* document = frame->document())
1769             document->suspendAllMediaPlayback();
1770     }
1771
1772     m_mediaPlaybackIsSuspended = true;
1773 #endif
1774 }
1775
1776 void Page::resumeAllMediaPlayback()
1777 {
1778 #if ENABLE(VIDEO)
1779     ASSERT(m_mediaPlaybackIsSuspended);
1780     if (!m_mediaPlaybackIsSuspended)
1781         return;
1782     m_mediaPlaybackIsSuspended = false;
1783
1784     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1785         if (auto* document = frame->document())
1786             document->resumeAllMediaPlayback();
1787     }
1788 #endif
1789 }
1790
1791 void Page::suspendAllMediaBuffering()
1792 {
1793 #if ENABLE(VIDEO)
1794     ASSERT(!m_mediaBufferingIsSuspended);
1795     if (m_mediaBufferingIsSuspended)
1796         return;
1797     m_mediaBufferingIsSuspended = true;
1798
1799     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1800         if (auto* document = frame->document())
1801             document->suspendAllMediaBuffering();
1802     }
1803 #endif
1804 }
1805
1806 void Page::resumeAllMediaBuffering()
1807 {
1808 #if ENABLE(VIDEO)
1809     if (!m_mediaBufferingIsSuspended)
1810         return;
1811     m_mediaBufferingIsSuspended = false;
1812
1813     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
1814         if (auto* document = frame->document())
1815             document->resumeAllMediaBuffering();
1816     }
1817 #endif
1818 }
1819
1820 #if ENABLE(MEDIA_SESSION)
1821 void Page::handleMediaEvent(MediaEventType eventType)
1822 {
1823     switch (eventType) {
1824     case MediaEventType::PlayPause:
1825         MediaSessionManager::singleton().togglePlayback();
1826         break;
1827     case MediaEventType::TrackNext:
1828         MediaSessionManager::singleton().skipToNextTrack();
1829         break;
1830     case MediaEventType::TrackPrevious:
1831         MediaSessionManager::singleton().skipToPreviousTrack();
1832         break;
1833     }
1834 }
1835
1836 void Page::setVolumeOfMediaElement(double volume, uint64_t elementID)
1837 {
1838     if (HTMLMediaElement* element = HTMLMediaElement::elementWithID(elementID))
1839         element->setVolume(volume, ASSERT_NO_EXCEPTION);
1840 }
1841 #endif
1842
1843 #if !ASSERT_DISABLED
1844 void Page::checkSubframeCountConsistency() const
1845 {
1846     ASSERT(m_subframeCount >= 0);
1847
1848     int subframeCount = 0;
1849     for (const Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
1850         ++subframeCount;
1851
1852     ASSERT(m_subframeCount + 1 == subframeCount);
1853 }
1854 #endif
1855
1856 void Page::resumeAnimatingImages()
1857 {
1858     // Drawing models which cache painted content while out-of-window (WebKit2's composited drawing areas, etc.)
1859     // require that we repaint animated images to kickstart the animation loop.
1860     if (FrameView* view = mainFrame().view())
1861         view->resumeVisibleImageAnimationsIncludingSubframes();
1862 }
1863
1864 void Page::setActivityState(OptionSet<ActivityState::Flag> activityState)
1865 {
1866     auto changed = m_activityState ^ activityState;
1867     if (!changed)
1868         return;
1869
1870     auto oldActivityState = m_activityState;
1871
1872     bool wasVisibleAndActive = isVisibleAndActive();
1873     m_activityState = activityState;
1874
1875     m_focusController->setActivityState(activityState);
1876
1877     if (changed & ActivityState::IsVisible)
1878         setIsVisibleInternal(activityState.contains(ActivityState::IsVisible));
1879     if (changed & ActivityState::IsInWindow)
1880         setIsInWindowInternal(activityState.contains(ActivityState::IsInWindow));
1881     if (changed & ActivityState::IsVisuallyIdle)
1882         setIsVisuallyIdleInternal(activityState.contains(ActivityState::IsVisuallyIdle));
1883     if (changed & ActivityState::WindowIsActive) {
1884         if (auto* view = m_mainFrame->view())
1885             view->updateTiledBackingAdaptiveSizing();
1886     }
1887
1888     if (changed.containsAny({ActivityState::IsVisible, ActivityState::IsVisuallyIdle, ActivityState::IsAudible, ActivityState::IsLoading, ActivityState::IsCapturingMedia }))
1889         updateTimerThrottlingState();
1890
1891     for (auto* observer : m_activityStateChangeObservers)
1892         observer->activityStateDidChange(oldActivityState, m_activityState);
1893
1894     if (wasVisibleAndActive != isVisibleAndActive())
1895         PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary();
1896
1897     if (m_performanceMonitor)
1898         m_performanceMonitor->activityStateChanged(oldActivityState, activityState);
1899 }
1900
1901 bool Page::isVisibleAndActive() const
1902 {
1903     return m_activityState.contains(ActivityState::IsVisible) && m_activityState.contains(ActivityState::WindowIsActive);
1904 }
1905
1906 bool Page::isWindowActive() const
1907 {
1908     return m_activityState.contains(ActivityState::WindowIsActive);
1909 }
1910
1911 void Page::setIsVisible(bool isVisible)
1912 {
1913     auto state = m_activityState;
1914
1915     if (isVisible) {
1916         state.remove(ActivityState::IsVisuallyIdle);
1917         state.add({ ActivityState::IsVisible, ActivityState::IsVisibleOrOccluded });
1918     } else {
1919         state.add(ActivityState::IsVisuallyIdle);
1920         state.remove({ ActivityState::IsVisible, ActivityState::IsVisibleOrOccluded });
1921     }
1922     setActivityState(state);
1923 }
1924
1925 enum class SVGAnimationsState { Paused, Resumed };
1926 static inline void setSVGAnimationsState(Page& page, SVGAnimationsState state)
1927 {
1928     for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
1929         auto* document = frame->document();
1930         if (!document)
1931             continue;
1932
1933         if (!document->svgExtensions())
1934             continue;
1935
1936         if (state == SVGAnimationsState::Paused)
1937             document->accessSVGExtensions().pauseAnimations();
1938         else
1939             document->accessSVGExtensions().unpauseAnimations();
1940     }
1941 }
1942
1943 void Page::setIsVisibleInternal(bool isVisible)
1944 {
1945     // FIXME: The visibility state should be stored on the top-level document.
1946     // https://bugs.webkit.org/show_bug.cgi?id=116769
1947
1948     if (isVisible) {
1949         m_isPrerender = false;
1950
1951         resumeScriptedAnimations();
1952 #if PLATFORM(IOS_FAMILY)
1953         resumeDeviceMotionAndOrientationUpdates();
1954 #endif
1955
1956         if (FrameView* view = mainFrame().view())
1957             view->show();
1958
1959         if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) {
1960             if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1961                 forEachDocument([&] (Document& document) {
1962                     if (auto* timeline = document.existingTimeline())
1963                         timeline->resumeAnimations();
1964                 });
1965             } else
1966                 mainFrame().animation().resumeAnimations();
1967         }
1968
1969         setSVGAnimationsState(*this, SVGAnimationsState::Resumed);
1970
1971         resumeAnimatingImages();
1972
1973         if (m_navigationToLogWhenVisible) {
1974             logNavigation(m_navigationToLogWhenVisible.value());
1975             m_navigationToLogWhenVisible = WTF::nullopt;
1976         }
1977     }
1978
1979     if (!isVisible) {
1980         if (m_settings->hiddenPageCSSAnimationSuspensionEnabled()) {
1981             if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
1982                 forEachDocument([&] (Document& document) {
1983                     if (auto* timeline = document.existingTimeline())
1984                         timeline->suspendAnimations();
1985                 });
1986             } else
1987                 mainFrame().animation().suspendAnimations();
1988         }
1989
1990         setSVGAnimationsState(*this, SVGAnimationsState::Paused);
1991
1992 #if PLATFORM(IOS_FAMILY)
1993         suspendDeviceMotionAndOrientationUpdates();
1994 #endif
1995
1996         suspendScriptedAnimations();
1997
1998         if (FrameView* view = mainFrame().view())
1999             view->hide();
2000     }
2001
2002     Vector<Ref<Document>> documents;
2003     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
2004         documents.append(*frame->document());
2005
2006     for (auto& document : documents)
2007         document->visibilityStateChanged();
2008 }
2009
2010 void Page::setIsPrerender()
2011 {
2012     m_isPrerender = true;
2013     updateDOMTimerAlignmentInterval();
2014 }
2015
2016 VisibilityState Page::visibilityState() const
2017 {
2018     if (isVisible())
2019         return VisibilityState::Visible;
2020     if (m_isPrerender)
2021         return VisibilityState::Prerender;
2022     return VisibilityState::Hidden;
2023 }
2024
2025 void Page::setHeaderHeight(int headerHeight)
2026 {
2027     if (headerHeight == m_headerHeight)
2028         return;
2029
2030     m_headerHeight = headerHeight;
2031
2032     FrameView* frameView = mainFrame().view();
2033     if (!frameView)
2034         return;
2035
2036     RenderView* renderView = frameView->renderView();
2037     if (!renderView)
2038         return;
2039
2040     frameView->setNeedsLayoutAfterViewConfigurationChange();
2041     frameView->setNeedsCompositingGeometryUpdate();
2042 }
2043
2044 void Page::setFooterHeight(int footerHeight)
2045 {
2046     if (footerHeight == m_footerHeight)
2047         return;
2048
2049     m_footerHeight = footerHeight;
2050
2051     FrameView* frameView = mainFrame().view();
2052     if (!frameView)
2053         return;
2054
2055     RenderView* renderView = frameView->renderView();
2056     if (!renderView)
2057         return;
2058
2059     frameView->setNeedsLayoutAfterViewConfigurationChange();
2060     frameView->setNeedsCompositingGeometryUpdate();
2061 }
2062
2063 void Page::incrementNestedRunLoopCount()
2064 {
2065     m_nestedRunLoopCount++;
2066 }
2067
2068 void Page::decrementNestedRunLoopCount()
2069 {
2070     ASSERT(m_nestedRunLoopCount);
2071     if (m_nestedRunLoopCount <= 0)
2072         return;
2073
2074     m_nestedRunLoopCount--;
2075
2076     if (!m_nestedRunLoopCount && m_unnestCallback) {
2077         callOnMainThread([this] {
2078             if (insideNestedRunLoop())
2079                 return;
2080
2081             // This callback may destruct the Page.
2082             if (m_unnestCallback) {
2083                 auto callback = WTFMove(m_unnestCallback);
2084                 callback();
2085             }
2086         });
2087     }
2088 }
2089
2090 void Page::whenUnnested(WTF::Function<void()>&& callback)
2091 {
2092     ASSERT(!m_unnestCallback);
2093
2094     m_unnestCallback = WTFMove(callback);
2095 }
2096
2097 #if ENABLE(REMOTE_INSPECTOR)
2098 bool Page::remoteInspectionAllowed() const
2099 {
2100     return m_inspectorDebuggable->remoteDebuggingAllowed();
2101 }
2102
2103 void Page::setRemoteInspectionAllowed(bool allowed)
2104 {
2105     m_inspectorDebuggable->setRemoteDebuggingAllowed(allowed);
2106 }
2107
2108 String Page::remoteInspectionNameOverride() const
2109 {
2110     return m_inspectorDebuggable->nameOverride();
2111 }
2112
2113 void Page::setRemoteInspectionNameOverride(const String& name)
2114 {
2115     m_inspectorDebuggable->setNameOverride(name);
2116 }
2117
2118 void Page::remoteInspectorInformationDidChange() const
2119 {
2120     m_inspectorDebuggable->update();
2121 }
2122 #endif
2123
2124 void Page::addLayoutMilestones(OptionSet<LayoutMilestone> milestones)
2125 {
2126     // In the future, we may want a function that replaces m_layoutMilestones instead of just adding to it.
2127     m_requestedLayoutMilestones.add(milestones);
2128 }
2129
2130 void Page::removeLayoutMilestones(OptionSet<LayoutMilestone> milestones)
2131 {
2132     m_requestedLayoutMilestones.remove(milestones);
2133 }
2134
2135 Color Page::pageExtendedBackgroundColor() const
2136 {
2137     FrameView* frameView = mainFrame().view();
2138     if (!frameView)
2139         return Color();
2140
2141     RenderView* renderView = frameView->renderView();
2142     if (!renderView)
2143         return Color();
2144
2145     return renderView->compositor().rootExtendedBackgroundColor();
2146 }
2147
2148 // These are magical constants that might be tweaked over time.
2149 static const double gMinimumPaintedAreaRatio = 0.1;
2150 static const double gMaximumUnpaintedAreaRatio = 0.04;
2151
2152 bool Page::isCountingRelevantRepaintedObjects() const
2153 {
2154     return m_isCountingRelevantRepaintedObjects && m_requestedLayoutMilestones.contains(DidHitRelevantRepaintedObjectsAreaThreshold);
2155 }
2156
2157 void Page::startCountingRelevantRepaintedObjects()
2158 {
2159     // Reset everything in case we didn't hit the threshold last time.
2160     resetRelevantPaintedObjectCounter();
2161
2162     m_isCountingRelevantRepaintedObjects = true;
2163 }
2164
2165 void Page::resetRelevantPaintedObjectCounter()
2166 {
2167     m_isCountingRelevantRepaintedObjects = false;
2168     m_relevantUnpaintedRenderObjects.clear();
2169     m_topRelevantPaintedRegion = Region();
2170     m_bottomRelevantPaintedRegion = Region();
2171     m_relevantUnpaintedRegion = Region();
2172 }
2173
2174 static LayoutRect relevantViewRect(RenderView* view)
2175 {
2176     LayoutRect viewRect = view->viewRect();
2177
2178     float relevantViewRectWidth = 980;
2179 #if PLATFORM(WATCHOS)
2180     // FIXME(186051): Consider limiting the relevant rect width to the view width everywhere.
2181     relevantViewRectWidth = std::min<float>(viewRect.width().toFloat(), relevantViewRectWidth);
2182 #endif
2183
2184     // DidHitRelevantRepaintedObjectsAreaThreshold is a LayoutMilestone intended to indicate that
2185     // a certain relevant amount of content has been drawn to the screen. This is the rect that
2186     // has been determined to be relevant in the context of this goal. We may choose to tweak
2187     // the rect over time, much like we may choose to tweak gMinimumPaintedAreaRatio and
2188     // gMaximumUnpaintedAreaRatio. But this seems to work well right now.
2189     LayoutRect relevantViewRect { 0, 0, LayoutUnit(relevantViewRectWidth), 1300 };
2190     // If the viewRect is wider than the relevantViewRect, center the relevantViewRect.
2191     if (viewRect.width() > relevantViewRect.width())
2192         relevantViewRect.setX((viewRect.width() - relevantViewRect.width()) / 2);
2193
2194     return relevantViewRect;
2195 }
2196
2197 void Page::addRelevantRepaintedObject(RenderObject* object, const LayoutRect& objectPaintRect)
2198 {
2199     if (!isCountingRelevantRepaintedObjects())
2200         return;
2201
2202     // Objects inside sub-frames are not considered to be relevant.
2203     if (&object->frame() != &mainFrame())
2204         return;
2205
2206     LayoutRect relevantRect = relevantViewRect(&object->view());
2207
2208     // The objects are only relevant if they are being painted within the viewRect().
2209     if (!objectPaintRect.intersects(snappedIntRect(relevantRect)))
2210         return;
2211
2212     IntRect snappedPaintRect = snappedIntRect(objectPaintRect);
2213
2214     // If this object was previously counted as an unpainted object, remove it from that HashSet
2215     // and corresponding Region. FIXME: This doesn't do the right thing if the objects overlap.
2216     if (m_relevantUnpaintedRenderObjects.remove(object))
2217         m_relevantUnpaintedRegion.subtract(snappedPaintRect);
2218
2219     // Split the relevantRect into a top half and a bottom half. Making sure we have coverage in
2220     // both halves helps to prevent cases where we have a fully loaded menu bar or masthead with
2221     // no content beneath that.
2222     LayoutRect topRelevantRect = relevantRect;
2223     topRelevantRect.contract(LayoutSize(0_lu, relevantRect.height() / 2));
2224     LayoutRect bottomRelevantRect = topRelevantRect;
2225     bottomRelevantRect.setY(relevantRect.height() / 2);
2226
2227     // If the rect straddles both Regions, split it appropriately.
2228     if (topRelevantRect.intersects(snappedPaintRect) && bottomRelevantRect.intersects(snappedPaintRect)) {
2229         IntRect topIntersection = snappedPaintRect;
2230         topIntersection.intersect(snappedIntRect(topRelevantRect));
2231         m_topRelevantPaintedRegion.unite(topIntersection);
2232
2233         IntRect bottomIntersection = snappedPaintRect;
2234         bottomIntersection.intersect(snappedIntRect(bottomRelevantRect));
2235         m_bottomRelevantPaintedRegion.unite(bottomIntersection);
2236     } else if (topRelevantRect.intersects(snappedPaintRect))
2237         m_topRelevantPaintedRegion.unite(snappedPaintRect);
2238     else
2239         m_bottomRelevantPaintedRegion.unite(snappedPaintRect);
2240
2241     float topPaintedArea = m_topRelevantPaintedRegion.totalArea();
2242     float bottomPaintedArea = m_bottomRelevantPaintedRegion.totalArea();
2243     float viewArea = relevantRect.width() * relevantRect.height();
2244
2245     float ratioThatIsPaintedOnTop = topPaintedArea / viewArea;
2246     float ratioThatIsPaintedOnBottom = bottomPaintedArea / viewArea;
2247     float ratioOfViewThatIsUnpainted = m_relevantUnpaintedRegion.totalArea() / viewArea;
2248
2249     if (ratioThatIsPaintedOnTop > (gMinimumPaintedAreaRatio / 2) && ratioThatIsPaintedOnBottom > (gMinimumPaintedAreaRatio / 2)
2250         && ratioOfViewThatIsUnpainted < gMaximumUnpaintedAreaRatio) {
2251         m_isCountingRelevantRepaintedObjects = false;
2252         resetRelevantPaintedObjectCounter();
2253         if (Frame* frame = &mainFrame())
2254             frame->loader().didReachLayoutMilestone(DidHitRelevantRepaintedObjectsAreaThreshold);
2255     }
2256 }
2257
2258 void Page::addRelevantUnpaintedObject(RenderObject* object, const LayoutRect& objectPaintRect)
2259 {
2260     if (!isCountingRelevantRepaintedObjects())
2261         return;
2262
2263     // The objects are only relevant if they are being painted within the relevantViewRect().
2264     if (!objectPaintRect.intersects(snappedIntRect(relevantViewRect(&object->view()))))
2265         return;
2266
2267     m_relevantUnpaintedRenderObjects.add(object);
2268     m_relevantUnpaintedRegion.unite(snappedIntRect(objectPaintRect));
2269 }
2270
2271 void Page::suspendDeviceMotionAndOrientationUpdates()
2272 {
2273     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2274         if (Document* document = frame->document())
2275             document->suspendDeviceMotionAndOrientationUpdates();
2276     }
2277 }
2278
2279 void Page::resumeDeviceMotionAndOrientationUpdates()
2280 {
2281     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2282         if (Document* document = frame->document())
2283             document->resumeDeviceMotionAndOrientationUpdates();
2284     }
2285 }
2286
2287 void Page::suspendActiveDOMObjectsAndAnimations()
2288 {
2289     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
2290         frame->suspendActiveDOMObjectsAndAnimations();
2291 }
2292
2293 void Page::resumeActiveDOMObjectsAndAnimations()
2294 {
2295     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
2296         frame->resumeActiveDOMObjectsAndAnimations();
2297
2298     resumeAnimatingImages();
2299 }
2300
2301 bool Page::hasSeenAnyPlugin() const
2302 {
2303     return !m_seenPlugins.isEmpty();
2304 }
2305
2306 bool Page::hasSeenPlugin(const String& serviceType) const
2307 {
2308     return m_seenPlugins.contains(serviceType);
2309 }
2310
2311 void Page::sawPlugin(const String& serviceType)
2312 {
2313     m_seenPlugins.add(serviceType);
2314 }
2315
2316 void Page::resetSeenPlugins()
2317 {
2318     m_seenPlugins.clear();
2319 }
2320
2321 bool Page::hasSeenAnyMediaEngine() const
2322 {
2323     return !m_seenMediaEngines.isEmpty();
2324 }
2325
2326 bool Page::hasSeenMediaEngine(const String& engineDescription) const
2327 {
2328     return m_seenMediaEngines.contains(engineDescription);
2329 }
2330
2331 void Page::sawMediaEngine(const String& engineDescription)
2332 {
2333     m_seenMediaEngines.add(engineDescription);
2334 }
2335
2336 void Page::resetSeenMediaEngines()
2337 {
2338     m_seenMediaEngines.clear();
2339 }
2340
2341 void Page::hiddenPageCSSAnimationSuspensionStateChanged()
2342 {
2343     if (!isVisible()) {
2344         if (RuntimeEnabledFeatures::sharedFeatures().webAnimationsCSSIntegrationEnabled()) {
2345             forEachDocument([&] (Document& document) {
2346                 if (auto* timeline = document.existingTimeline()) {
2347                     if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
2348                         timeline->suspendAnimations();
2349                     else
2350                         timeline->resumeAnimations();
2351                 }
2352             });
2353         } else {
2354             if (m_settings->hiddenPageCSSAnimationSuspensionEnabled())
2355                 mainFrame().animation().suspendAnimations();
2356             else
2357                 mainFrame().animation().resumeAnimations();
2358         }
2359     }
2360 }
2361
2362 #if ENABLE(VIDEO_TRACK)
2363 void Page::captionPreferencesChanged()
2364 {
2365     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2366         if (!frame->document())
2367             continue;
2368         frame->document()->captionPreferencesChanged();
2369     }
2370 }
2371 #endif
2372
2373 void Page::forbidPrompts()
2374 {
2375     ++m_forbidPromptsDepth;
2376 }
2377
2378 void Page::allowPrompts()
2379 {
2380     ASSERT(m_forbidPromptsDepth);
2381     --m_forbidPromptsDepth;
2382 }
2383
2384 bool Page::arePromptsAllowed()
2385 {
2386     return !m_forbidPromptsDepth;
2387 }
2388
2389 void Page::logNavigation(const Navigation& navigation)
2390 {
2391     String navigationDescription;
2392     switch (navigation.type) {
2393     case FrameLoadType::Standard:
2394         navigationDescription = "standard"_s;
2395         break;
2396     case FrameLoadType::Back:
2397         navigationDescription = "back"_s;
2398         break;
2399     case FrameLoadType::Forward:
2400         navigationDescription = "forward"_s;
2401         break;
2402     case FrameLoadType::IndexedBackForward:
2403         navigationDescription = "indexedBackForward"_s;
2404         break;
2405     case FrameLoadType::Reload:
2406         navigationDescription = "reload"_s;
2407         break;
2408     case FrameLoadType::Same:
2409         navigationDescription = "same"_s;
2410         break;
2411     case FrameLoadType::ReloadFromOrigin:
2412         navigationDescription = "reloadFromOrigin"_s;
2413         break;
2414     case FrameLoadType::ReloadExpiredOnly:
2415         navigationDescription = "reloadRevalidatingExpired"_s;
2416         break;
2417     case FrameLoadType::Replace:
2418     case FrameLoadType::RedirectWithLockedBackForwardList:
2419         // Not logging those for now.
2420         return;
2421     }
2422     diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::navigationKey(), navigationDescription, ShouldSample::No);
2423
2424     if (!navigation.domain.isEmpty())
2425         diagnosticLoggingClient().logDiagnosticMessageWithEnhancedPrivacy(DiagnosticLoggingKeys::domainVisitedKey(), navigation.domain.string(), ShouldSample::Yes);
2426 }
2427
2428 void Page::mainFrameLoadStarted(const URL& destinationURL, FrameLoadType type)
2429 {
2430     Navigation navigation = { RegistrableDomain { destinationURL }, type };
2431
2432     // To avoid being too verbose, we only log navigations if the page is or becomes visible. This avoids logging non-user observable loads.
2433     if (!isVisible()) {
2434         m_navigationToLogWhenVisible = navigation;
2435         return;
2436     }
2437
2438     m_navigationToLogWhenVisible = WTF::nullopt;
2439     logNavigation(navigation);
2440 }
2441
2442 PluginInfoProvider& Page::pluginInfoProvider()
2443 {
2444     return m_pluginInfoProvider;
2445 }
2446
2447 UserContentProvider& Page::userContentProvider()
2448 {
2449     return m_userContentProvider;
2450 }
2451
2452 void Page::setUserContentProvider(Ref<UserContentProvider>&& userContentProvider)
2453 {
2454     m_userContentProvider->removePage(*this);
2455     m_userContentProvider = WTFMove(userContentProvider);
2456     m_userContentProvider->addPage(*this);
2457
2458     invalidateInjectedStyleSheetCacheInAllFrames();
2459 }
2460
2461 VisitedLinkStore& Page::visitedLinkStore()
2462 {
2463     return m_visitedLinkStore;
2464 }
2465
2466 void Page::setVisitedLinkStore(Ref<VisitedLinkStore>&& visitedLinkStore)
2467 {
2468     m_visitedLinkStore->removePage(*this);
2469     m_visitedLinkStore = WTFMove(visitedLinkStore);
2470     m_visitedLinkStore->addPage(*this);
2471
2472     invalidateStylesForAllLinks();
2473 }
2474
2475 PAL::SessionID Page::sessionID() const
2476 {
2477     return m_sessionID;
2478 }
2479
2480 // This is only called by WebKitLegacy.
2481 void Page::setSessionID(PAL::SessionID sessionID)
2482 {
2483     ASSERT(sessionID.isValid());
2484     ASSERT(m_sessionID == PAL::SessionID::legacyPrivateSessionID() || m_sessionID == PAL::SessionID::defaultSessionID());
2485     ASSERT(sessionID == PAL::SessionID::legacyPrivateSessionID() || sessionID == PAL::SessionID::defaultSessionID());
2486
2487 #if ENABLE(INDEXED_DATABASE)
2488     if (sessionID != m_sessionID)
2489         m_idbConnectionToServer = nullptr;
2490 #endif
2491
2492     if (sessionID != m_sessionID && m_sessionStorage)
2493         m_sessionStorage->setSessionIDForTesting(sessionID);
2494
2495     bool privateBrowsingStateChanged = (sessionID.isEphemeral() != m_sessionID.isEphemeral());
2496
2497     m_sessionID = sessionID;
2498
2499     if (!privateBrowsingStateChanged)
2500         return;
2501
2502     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2503         if (!frame->document())
2504             continue;
2505         frame->document()->privateBrowsingStateDidChange(m_sessionID);
2506     }
2507
2508     // Collect the PluginViews in to a vector to ensure that action the plug-in takes
2509     // from below privateBrowsingStateChanged does not affect their lifetime.
2510
2511     for (auto& view : pluginViews())
2512         view->privateBrowsingStateChanged(sessionID.isEphemeral());
2513 }
2514
2515 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
2516 void Page::addPlaybackTargetPickerClient(uint64_t contextId)
2517 {
2518     chrome().client().addPlaybackTargetPickerClient(contextId);
2519 }
2520
2521 void Page::removePlaybackTargetPickerClient(uint64_t contextId)
2522 {
2523     chrome().client().removePlaybackTargetPickerClient(contextId);
2524 }
2525
2526 void Page::showPlaybackTargetPicker(uint64_t contextId, const WebCore::IntPoint& location, bool isVideo, RouteSharingPolicy routeSharingPolicy, const String& routingContextUID)
2527 {
2528 #if PLATFORM(IOS_FAMILY)
2529     // FIXME: refactor iOS implementation.
2530     UNUSED_PARAM(contextId);
2531     UNUSED_PARAM(location);
2532     chrome().client().showPlaybackTargetPicker(isVideo, routeSharingPolicy, routingContextUID);
2533 #else
2534     UNUSED_PARAM(routeSharingPolicy);
2535     UNUSED_PARAM(routingContextUID);
2536     chrome().client().showPlaybackTargetPicker(contextId, location, isVideo);
2537 #endif
2538 }
2539
2540 void Page::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state)
2541 {
2542     chrome().client().playbackTargetPickerClientStateDidChange(contextId, state);
2543 }
2544
2545 void Page::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
2546 {
2547     chrome().client().setMockMediaPlaybackTargetPickerEnabled(enabled);
2548 }
2549
2550 void Page::setMockMediaPlaybackTargetPickerState(const String& name, MediaPlaybackTargetContext::State state)
2551 {
2552     chrome().client().setMockMediaPlaybackTargetPickerState(name, state);
2553 }
2554
2555 void Page::setPlaybackTarget(uint64_t contextId, Ref<MediaPlaybackTarget>&& target)
2556 {
2557     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2558         if (!frame->document())
2559             continue;
2560         frame->document()->setPlaybackTarget(contextId, target.copyRef());
2561     }
2562 }
2563
2564 void Page::playbackTargetAvailabilityDidChange(uint64_t contextId, bool available)
2565 {
2566     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2567         if (!frame->document())
2568             continue;
2569         frame->document()->playbackTargetAvailabilityDidChange(contextId, available);
2570     }
2571 }
2572
2573 void Page::setShouldPlayToPlaybackTarget(uint64_t clientId, bool shouldPlay)
2574 {
2575     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2576         if (!frame->document())
2577             continue;
2578         frame->document()->setShouldPlayToPlaybackTarget(clientId, shouldPlay);
2579     }
2580 }
2581 #endif
2582
2583 WheelEventTestMonitor& Page::ensureWheelEventTestMonitor()
2584 {
2585     if (!m_wheelEventTestMonitor) {
2586         m_wheelEventTestMonitor = adoptRef(new WheelEventTestMonitor());
2587         // We need to update the scrolling coordinator so that the mainframe scrolling node can expect wheel event test triggers.
2588         if (auto* frameView = mainFrame().view()) {
2589             if (m_scrollingCoordinator)
2590                 m_scrollingCoordinator->updateIsMonitoringWheelEventsForFrameView(*frameView);
2591         }
2592     }
2593
2594     return *m_wheelEventTestMonitor;
2595 }
2596
2597 #if ENABLE(VIDEO)
2598 void Page::setAllowsMediaDocumentInlinePlayback(bool flag)
2599 {
2600     if (m_allowsMediaDocumentInlinePlayback == flag)
2601         return;
2602     m_allowsMediaDocumentInlinePlayback = flag;
2603
2604     Vector<Ref<Document>> documents;
2605     for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
2606         documents.append(*frame->document());
2607
2608     for (auto& document : documents)
2609         document->allowsMediaDocumentInlinePlaybackChanged();
2610 }
2611 #endif
2612
2613 #if ENABLE(INDEXED_DATABASE)
2614 IDBClient::IDBConnectionToServer& Page::idbConnection()
2615 {
2616     if (!m_idbConnectionToServer)
2617         m_idbConnectionToServer = &databaseProvider().idbConnectionToServerForSession(m_sessionID);
2618     
2619     return *m_idbConnectionToServer;
2620 }
2621
2622 IDBClient::IDBConnectionToServer* Page::optionalIDBConnection()
2623 {
2624     return m_idbConnectionToServer.get();
2625 }
2626
2627 void Page::clearIDBConnection()
2628 {
2629     m_idbConnectionToServer = nullptr;
2630 }
2631 #endif
2632
2633 #if ENABLE(RESOURCE_USAGE)
2634 void Page::setResourceUsageOverlayVisible(bool visible)
2635 {
2636     if (!visible) {
2637         m_resourceUsageOverlay = nullptr;
2638         return;
2639     }
2640
2641     if (!m_resourceUsageOverlay && m_settings->acceleratedCompositingEnabled())
2642         m_resourceUsageOverlay = makeUnique<ResourceUsageOverlay>(*this);
2643 }
2644 #endif
2645
2646 bool Page::isAlwaysOnLoggingAllowed() const
2647 {
2648     return m_sessionID.isAlwaysOnLoggingAllowed();
2649 }
2650
2651 String Page::captionUserPreferencesStyleSheet()
2652 {
2653     return m_captionUserPreferencesStyleSheet;
2654 }
2655
2656 void Page::setCaptionUserPreferencesStyleSheet(const String& styleSheet)
2657 {
2658     if (m_captionUserPreferencesStyleSheet == styleSheet)
2659         return;
2660
2661     m_captionUserPreferencesStyleSheet = styleSheet;
2662 }
2663
2664 void Page::accessibilitySettingsDidChange()
2665 {
2666     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2667         if (auto* document = frame->document()) {
2668             document->styleScope().evaluateMediaQueriesForAccessibilitySettingsChange();
2669             document->evaluateMediaQueryList();
2670         }
2671     }
2672 }
2673
2674 void Page::appearanceDidChange()
2675 {
2676     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2677         auto* document = frame->document();
2678         if (!document)
2679             continue;
2680
2681         document->styleScope().didChangeStyleSheetEnvironment();
2682         document->styleScope().evaluateMediaQueriesForAppearanceChange();
2683         document->evaluateMediaQueryList();
2684     }
2685 }
2686
2687 void Page::setUnobscuredSafeAreaInsets(const FloatBoxExtent& insets)
2688 {
2689     if (m_unobscuredSafeAreaInsets == insets)
2690         return;
2691
2692     m_unobscuredSafeAreaInsets = insets;
2693
2694     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2695         if (!frame->document())
2696             continue;
2697         frame->document()->constantProperties().didChangeSafeAreaInsets();
2698     }
2699 }
2700
2701 void Page::setUseSystemAppearance(bool value)
2702 {
2703     if (m_useSystemAppearance == value)
2704         return;
2705
2706     m_useSystemAppearance = value;
2707
2708     appearanceDidChange();
2709
2710     for (auto* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2711         auto* document = frame->document();
2712         if (!document)
2713             continue;
2714
2715         // System apperance change may affect stylesheet parsing. We need to reparse.
2716         document->extensionStyleSheets().clearPageUserSheet();
2717         document->extensionStyleSheets().invalidateInjectedStyleSheetCache();
2718     }
2719 }
2720
2721 void Page::effectiveAppearanceDidChange(bool useDarkAppearance, bool useElevatedUserInterfaceLevel)
2722 {
2723 #if HAVE(OS_DARK_MODE_SUPPORT)
2724     if (m_useDarkAppearance == useDarkAppearance && m_useElevatedUserInterfaceLevel == useElevatedUserInterfaceLevel)
2725         return;
2726
2727     m_useDarkAppearance = useDarkAppearance;
2728     m_useElevatedUserInterfaceLevel = useElevatedUserInterfaceLevel;
2729
2730     InspectorInstrumentation::defaultAppearanceDidChange(*this, useDarkAppearance);
2731
2732     appearanceDidChange();
2733 #else
2734     UNUSED_PARAM(useDarkAppearance);
2735
2736     if (m_useElevatedUserInterfaceLevel == useElevatedUserInterfaceLevel)
2737         return;
2738
2739     m_useElevatedUserInterfaceLevel = useElevatedUserInterfaceLevel;
2740
2741     appearanceDidChange();
2742 #endif
2743 }
2744
2745 bool Page::useDarkAppearance() const
2746 {
2747 #if HAVE(OS_DARK_MODE_SUPPORT)
2748     FrameView* view = mainFrame().view();
2749     if (!view || !equalLettersIgnoringASCIICase(view->mediaType(), "screen"))
2750         return false;
2751     if (m_useDarkAppearanceOverride)
2752         return m_useDarkAppearanceOverride.value();
2753     return m_useDarkAppearance;
2754 #else
2755     return false;
2756 #endif
2757 }
2758
2759 void Page::setUseDarkAppearanceOverride(Optional<bool> valueOverride)
2760 {
2761 #if HAVE(OS_DARK_MODE_SUPPORT)
2762     if (valueOverride == m_useDarkAppearanceOverride)
2763         return;
2764
2765     m_useDarkAppearanceOverride = valueOverride;
2766
2767     appearanceDidChange();
2768 #else
2769     UNUSED_PARAM(valueOverride);
2770 #endif
2771 }
2772
2773 void Page::setFullscreenInsets(const FloatBoxExtent& insets)
2774 {
2775     if (insets == m_fullscreenInsets)
2776         return;
2777     m_fullscreenInsets = insets;
2778
2779     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2780         if (!frame->document())
2781             continue;
2782         frame->document()->constantProperties().didChangeFullscreenInsets();
2783     }
2784 }
2785
2786 void Page::setFullscreenAutoHideDuration(Seconds duration)
2787 {
2788     if (duration == m_fullscreenAutoHideDuration)
2789         return;
2790     m_fullscreenAutoHideDuration = duration;
2791     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2792         if (!frame->document())
2793             continue;
2794         frame->document()->constantProperties().setFullscreenAutoHideDuration(duration);
2795     }
2796 }
2797
2798 void Page::setFullscreenControlsHidden(bool hidden)
2799 {
2800 #if ENABLE(FULLSCREEN_API)
2801     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2802         if (!frame->document())
2803             continue;
2804         frame->document()->fullscreenManager().setFullscreenControlsHidden(hidden);
2805     }
2806 #else
2807     UNUSED_PARAM(hidden);
2808 #endif
2809 }
2810
2811 #if ENABLE(DATA_INTERACTION)
2812
2813 bool Page::hasSelectionAtPosition(const FloatPoint& position) const
2814 {
2815     auto currentSelection = m_mainFrame->selection().selection();
2816     if (!currentSelection.isRange())
2817         return false;
2818
2819     if (auto selectedRange = currentSelection.toNormalizedRange()) {
2820         Vector<SelectionRect> selectionRects;
2821         selectedRange->collectSelectionRects(selectionRects);
2822         for (auto selectionRect : selectionRects) {
2823             if (FloatRect(selectionRect.rect()).contains(position))
2824                 return true;
2825         }
2826     }
2827
2828     return false;
2829 }
2830
2831 #endif
2832
2833 void Page::disableICECandidateFiltering()
2834 {
2835     m_shouldEnableICECandidateFilteringByDefault = false;
2836 #if ENABLE(WEB_RTC)
2837     m_rtcController.disableICECandidateFilteringForAllOrigins();
2838 #endif
2839 }
2840
2841 void Page::enableICECandidateFiltering()
2842 {
2843     m_shouldEnableICECandidateFilteringByDefault = true;
2844 #if ENABLE(WEB_RTC)
2845     m_rtcController.enableICECandidateFiltering();
2846 #endif
2847 }
2848
2849 void Page::didChangeMainDocument()
2850 {
2851 #if ENABLE(WEB_RTC)
2852     m_rtcController.reset(m_shouldEnableICECandidateFilteringByDefault);
2853 #endif
2854 #if ENABLE(POINTER_EVENTS)
2855     m_pointerCaptureController->reset();
2856 #endif
2857 }
2858
2859 RenderingUpdateScheduler& Page::renderingUpdateScheduler()
2860 {
2861     if (!m_renderingUpdateScheduler)
2862         m_renderingUpdateScheduler = RenderingUpdateScheduler::create(*this);
2863     return *m_renderingUpdateScheduler;
2864 }
2865
2866 void Page::forEachDocument(const Function<void(Document&)>& functor)
2867 {
2868     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
2869         if (!frame->document())
2870             continue;
2871
2872         functor(*frame->document());
2873     }
2874 }
2875
2876 void Page::applicationWillResignActive()
2877 {
2878     forEachDocument([&] (Document& document) {
2879         document.forEachApplicationStateChangeListener([&] (ApplicationStateChangeListener& listener) {
2880             listener.applicationWillResignActive();
2881         });
2882     });
2883 }
2884
2885 void Page::applicationDidEnterBackground()
2886 {
2887     m_libWebRTCProvider->setActive(false);
2888 }
2889
2890 void Page::applicationWillEnterForeground()
2891 {
2892     m_libWebRTCProvider->setActive(true);
2893 }
2894
2895 void Page::applicationDidBecomeActive()
2896 {
2897     forEachDocument([&] (Document& document) {
2898         document.forEachApplicationStateChangeListener([&] (ApplicationStateChangeListener& listener) {
2899             listener.applicationDidBecomeActive();
2900         });
2901     });
2902 }
2903
2904 #if PLATFORM(MAC)
2905 ScrollLatchingState* Page::latchingState()
2906 {
2907     if (m_latchingState.isEmpty())
2908         return nullptr;
2909
2910     return &m_latchingState.last();
2911 }
2912
2913 void Page::pushNewLatchingState()
2914 {
2915     m_latchingState.append(ScrollLatchingState());
2916 }
2917
2918 void Page::resetLatchingState()
2919 {
2920     m_latchingState.clear();
2921 }
2922
2923 void Page::popLatchingState()
2924 {
2925     m_latchingState.removeLast();
2926 }
2927
2928 void Page::removeLatchingStateForTarget(Element& targetNode)
2929 {
2930     if (m_latchingState.isEmpty())
2931         return;
2932
2933     m_latchingState.removeAllMatching([&targetNode] (ScrollLatchingState& state) {
2934         auto* wheelElement = state.wheelEventElement();
2935         if (!wheelElement)
2936             return false;
2937
2938         return targetNode.isEqualNode(wheelElement);
2939     });
2940 }
2941 #endif // PLATFORM(MAC)
2942
2943 static void dispatchPrintEvent(Frame& mainFrame, const AtomString& eventType)
2944 {
2945     Vector<Ref<Frame>> frames;
2946     for (auto* frame = &mainFrame; frame; frame = frame->tree().traverseNext())
2947         frames.append(*frame);
2948
2949     for (auto& frame : frames) {
2950         if (auto* window = frame->window())
2951             window->dispatchEvent(Event::create(eventType, Event::CanBubble::No, Event::IsCancelable::No), window->document());
2952     }
2953 }
2954
2955 void Page::dispatchBeforePrintEvent()
2956 {
2957     dispatchPrintEvent(m_mainFrame, eventNames().beforeprintEvent);
2958 }
2959
2960 void Page::dispatchAfterPrintEvent()
2961 {
2962     dispatchPrintEvent(m_mainFrame, eventNames().afterprintEvent);
2963 }
2964
2965 #if ENABLE(APPLE_PAY)
2966 void Page::setPaymentCoordinator(std::unique_ptr<PaymentCoordinator>&& paymentCoordinator)
2967 {
2968     m_paymentCoordinator = WTFMove(paymentCoordinator);
2969 }
2970 #endif
2971
2972 void Page::configureLoggingChannel(const String& channelName, WTFLogChannelState state, WTFLogLevel level)
2973 {
2974 #if !RELEASE_LOG_DISABLED
2975     if (auto* channel = getLogChannel(channelName)) {
2976         channel->state = state;
2977         channel->level = level;
2978
2979 #if USE(LIBWEBRTC)
2980         if (channel == &LogWebRTC && m_mainFrame->document())
2981             libWebRTCProvider().setEnableLogging(!sessionID().isEphemeral());
2982 #endif
2983     }
2984
2985     chrome().client().configureLoggingChannel(channelName, state, level);
2986 #else
2987     UNUSED_PARAM(channelName);
2988     UNUSED_PARAM(state);
2989     UNUSED_PARAM(level);
2990 #endif
2991 }
2992
2993 void Page::didFinishLoadingImageForElement(HTMLImageElement& element)
2994 {
2995     auto protectedElement = makeRef(element);
2996     if (auto frame = makeRefPtr(element.document().frame()))
2997         frame->editor().revealSelectionIfNeededAfterLoadingImageForElement(element);
2998     chrome().client().didFinishLoadingImageForElement(element);
2999 }
3000
3001 #if ENABLE(TEXT_AUTOSIZING)
3002 void Page::recomputeTextAutoSizingInAllFrames()
3003 {
3004     ASSERT(settings().textAutosizingEnabled() && settings().textAutosizingUsesIdempotentMode());
3005     for (auto* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
3006         if (!frame->document())
3007             continue;
3008         auto& document = *frame->document();
3009         if (!document.renderView() || !document.styleScope().resolverIfExists())
3010             continue;
3011
3012         auto& styleResolver = document.styleScope().resolver();
3013         for (auto& renderer : descendantsOfType<RenderElement>(*document.renderView())) {
3014             if (auto* element = renderer.element()) {
3015                 auto needsLayout = styleResolver.adjustRenderStyleForTextAutosizing(renderer.mutableStyle(), *element);
3016                 if (needsLayout)
3017                     renderer.setNeedsLayout();
3018             }
3019         }
3020     }
3021 }
3022 #endif
3023
3024 } // namespace WebCore