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