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