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