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