Fullscreen requires active document.
[WebKit-https.git] / Source / WebKit / WebProcess / WebCoreSupport / WebChromeClient.cpp
1 /*
2  * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "WebChromeClient.h"
29
30 #include "APIArray.h"
31 #include "APISecurityOrigin.h"
32 #include "DrawingArea.h"
33 #include "FindController.h"
34 #include "FrameInfoData.h"
35 #include "HangDetectionDisabler.h"
36 #include "InjectedBundleNavigationAction.h"
37 #include "InjectedBundleNodeHandle.h"
38 #include "NavigationActionData.h"
39 #include "PageBanner.h"
40 #include "UserData.h"
41 #include "WebColorChooser.h"
42 #include "WebCoreArgumentCoders.h"
43 #include "WebDataListSuggestionPicker.h"
44 #include "WebFrame.h"
45 #include "WebFrameLoaderClient.h"
46 #include "WebFullScreenManager.h"
47 #include "WebHitTestResultData.h"
48 #include "WebImage.h"
49 #include "WebOpenPanelResultListener.h"
50 #include "WebPage.h"
51 #include "WebPageCreationParameters.h"
52 #include "WebPageProxyMessages.h"
53 #include "WebPopupMenu.h"
54 #include "WebProcess.h"
55 #include "WebProcessPoolMessages.h"
56 #include "WebProcessProxyMessages.h"
57 #include "WebSearchPopupMenu.h"
58 #include <WebCore/ApplicationCacheStorage.h>
59 #include <WebCore/AXObjectCache.h>
60 #include <WebCore/ColorChooser.h>
61 #include <WebCore/DataListSuggestionPicker.h>
62 #include <WebCore/DatabaseTracker.h>
63 #include <WebCore/DocumentLoader.h>
64 #include <WebCore/FileChooser.h>
65 #include <WebCore/FileIconLoader.h>
66 #include <WebCore/Frame.h>
67 #include <WebCore/FrameLoadRequest.h>
68 #include <WebCore/FrameLoader.h>
69 #include <WebCore/FrameView.h>
70 #include <WebCore/HTMLInputElement.h>
71 #include <WebCore/HTMLNames.h>
72 #include <WebCore/HTMLParserIdioms.h>
73 #include <WebCore/HTMLPlugInImageElement.h>
74 #include <WebCore/Icon.h>
75 #include <WebCore/NotImplemented.h>
76 #include <WebCore/Page.h>
77 #include <WebCore/ScriptController.h>
78 #include <WebCore/SecurityOrigin.h>
79 #include <WebCore/SecurityOriginData.h>
80 #include <WebCore/Settings.h>
81
82 #if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
83 #include "PlaybackSessionManager.h"
84 #include "VideoFullscreenManager.h"
85 #endif
86
87 #if ENABLE(ASYNC_SCROLLING)
88 #include "RemoteScrollingCoordinator.h"
89 #endif
90
91 #if PLATFORM(GTK)
92 #include "PrinterListGtk.h"
93 #endif
94
95 using namespace WebCore;
96 using namespace HTMLNames;
97
98 namespace WebKit {
99
100 static double area(WebFrame* frame)
101 {
102     IntSize size = frame->visibleContentBoundsExcludingScrollbars().size();
103     return static_cast<double>(size.height()) * size.width();
104 }
105
106 static WebFrame* findLargestFrameInFrameSet(WebPage& page)
107 {
108     // Approximate what a user could consider a default target frame for application menu operations.
109
110     WebFrame* mainFrame = page.mainWebFrame();
111     if (!mainFrame || !mainFrame->isFrameSet())
112         return nullptr;
113
114     WebFrame* largestSoFar = nullptr;
115
116     Ref<API::Array> frameChildren = mainFrame->childFrames();
117     size_t count = frameChildren->size();
118     for (size_t i = 0; i < count; ++i) {
119         auto* childFrame = frameChildren->at<WebFrame>(i);
120         if (!largestSoFar || area(childFrame) > area(largestSoFar))
121             largestSoFar = childFrame;
122     }
123
124     return largestSoFar;
125 }
126
127 WebChromeClient::WebChromeClient(WebPage& page)
128     : m_page(page)
129 {
130 }
131
132 void WebChromeClient::didInsertMenuElement(HTMLMenuElement& element)
133 {
134     m_page.didInsertMenuElement(element);
135 }
136
137 void WebChromeClient::didRemoveMenuElement(HTMLMenuElement& element)
138 {
139     m_page.didRemoveMenuElement(element);
140 }
141
142 void WebChromeClient::didInsertMenuItemElement(HTMLMenuItemElement& element)
143 {
144     m_page.didInsertMenuItemElement(element);
145 }
146
147 void WebChromeClient::didRemoveMenuItemElement(HTMLMenuItemElement& element)
148 {
149     m_page.didRemoveMenuItemElement(element);
150 }
151
152 inline WebChromeClient::~WebChromeClient()
153 {
154 }
155
156 void WebChromeClient::chromeDestroyed()
157 {
158     delete this;
159 }
160
161 void WebChromeClient::setWindowRect(const FloatRect& windowFrame)
162 {
163     m_page.sendSetWindowFrame(windowFrame);
164 }
165
166 FloatRect WebChromeClient::windowRect()
167 {
168 #if PLATFORM(IOS)
169     return FloatRect();
170 #else
171 #if PLATFORM(MAC)
172     if (m_page.hasCachedWindowFrame())
173         return m_page.windowFrameInUnflippedScreenCoordinates();
174 #endif
175
176     FloatRect newWindowFrame;
177
178     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetWindowFrame(), Messages::WebPageProxy::GetWindowFrame::Reply(newWindowFrame), m_page.pageID()))
179         return FloatRect();
180
181     return newWindowFrame;
182 #endif
183 }
184
185 FloatRect WebChromeClient::pageRect()
186 {
187     return FloatRect(FloatPoint(), m_page.size());
188 }
189
190 void WebChromeClient::focus()
191 {
192     m_page.send(Messages::WebPageProxy::SetFocus(true));
193 }
194
195 void WebChromeClient::unfocus()
196 {
197     m_page.send(Messages::WebPageProxy::SetFocus(false));
198 }
199
200 #if PLATFORM(COCOA)
201
202 void WebChromeClient::elementDidFocus(Element& element)
203 {
204     m_page.elementDidFocus(&element);
205 }
206
207 void WebChromeClient::elementDidBlur(Element& element)
208 {
209     m_page.elementDidBlur(&element);
210 }
211
212 void WebChromeClient::makeFirstResponder()
213 {
214     m_page.send(Messages::WebPageProxy::MakeFirstResponder());
215 }
216
217 void WebChromeClient::assistiveTechnologyMakeFirstResponder()
218 {
219     m_page.send(Messages::WebPageProxy::AssistiveTechnologyMakeFirstResponder());
220 }
221
222 #endif    
223
224 bool WebChromeClient::canTakeFocus(FocusDirection)
225 {
226     notImplemented();
227     return true;
228 }
229
230 void WebChromeClient::takeFocus(FocusDirection direction)
231 {
232     m_page.send(Messages::WebPageProxy::TakeFocus(direction));
233 }
234
235 void WebChromeClient::focusedElementChanged(Element* element)
236 {
237     if (!is<HTMLInputElement>(element))
238         return;
239
240     HTMLInputElement& inputElement = downcast<HTMLInputElement>(*element);
241     if (!inputElement.isText())
242         return;
243
244     WebFrame* webFrame = WebFrame::fromCoreFrame(*element->document().frame());
245     ASSERT(webFrame);
246     m_page.injectedBundleFormClient().didFocusTextField(&m_page, &inputElement, webFrame);
247 }
248
249 void WebChromeClient::focusedFrameChanged(Frame* frame)
250 {
251     WebFrame* webFrame = frame ? WebFrame::fromCoreFrame(*frame) : nullptr;
252
253     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::FocusedFrameChanged(webFrame ? webFrame->frameID() : 0), m_page.pageID());
254 }
255
256 Page* WebChromeClient::createWindow(Frame& frame, const FrameLoadRequest& request, const WindowFeatures& windowFeatures, const NavigationAction& navigationAction)
257 {
258 #if ENABLE(FULLSCREEN_API)
259     if (frame.document() && frame.document()->webkitCurrentFullScreenElement())
260         frame.document()->webkitCancelFullScreen();
261 #endif
262
263     auto& webProcess = WebProcess::singleton();
264
265     NavigationActionData navigationActionData;
266     navigationActionData.navigationType = navigationAction.type();
267     navigationActionData.modifiers = InjectedBundleNavigationAction::modifiersForNavigationAction(navigationAction);
268     navigationActionData.mouseButton = InjectedBundleNavigationAction::mouseButtonForNavigationAction(navigationAction);
269     navigationActionData.syntheticClickType = InjectedBundleNavigationAction::syntheticClickTypeForNavigationAction(navigationAction);
270     navigationActionData.clickLocationInRootViewCoordinates = InjectedBundleNavigationAction::clickLocationInRootViewCoordinatesForNavigationAction(navigationAction);
271     navigationActionData.userGestureTokenIdentifier = webProcess.userGestureTokenIdentifier(navigationAction.userGestureToken());
272     navigationActionData.canHandleRequest = m_page.canHandleRequest(request.resourceRequest());
273     navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
274     navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
275
276     WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
277
278     uint64_t newPageID = 0;
279     WebPageCreationParameters parameters;
280     if (!webProcess.parentProcessConnection()->sendSync(Messages::WebPageProxy::CreateNewPage(webFrame->info(), webFrame->page()->pageID(), request.resourceRequest(), windowFeatures, navigationActionData), Messages::WebPageProxy::CreateNewPage::Reply(newPageID, parameters), m_page.pageID()))
281         return nullptr;
282
283     if (!newPageID)
284         return nullptr;
285
286     webProcess.createWebPage(newPageID, WTFMove(parameters));
287     return webProcess.webPage(newPageID)->corePage();
288 }
289
290 void WebChromeClient::show()
291 {
292     m_page.show();
293 }
294
295 bool WebChromeClient::canRunModal()
296 {
297     return m_page.canRunModal();
298 }
299
300 void WebChromeClient::runModal()
301 {
302     m_page.runModal();
303 }
304
305 void WebChromeClient::reportProcessCPUTime(Seconds cpuTime, ActivityStateForCPUSampling activityState)
306 {
307     WebProcess::singleton().send(Messages::WebProcessPool::ReportWebContentCPUTime(cpuTime, static_cast<uint64_t>(activityState)), 0);
308 }
309
310 void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible)
311 {
312     m_page.send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible));
313 }
314
315 bool WebChromeClient::toolbarsVisible()
316 {
317     API::InjectedBundle::PageUIClient::UIElementVisibility toolbarsVisibility = m_page.injectedBundleUIClient().toolbarsAreVisible(&m_page);
318     if (toolbarsVisibility != API::InjectedBundle::PageUIClient::UIElementVisibility::Unknown)
319         return toolbarsVisibility == API::InjectedBundle::PageUIClient::UIElementVisibility::Visible;
320     
321     bool toolbarsAreVisible = true;
322     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetToolbarsAreVisible(), Messages::WebPageProxy::GetToolbarsAreVisible::Reply(toolbarsAreVisible), m_page.pageID()))
323         return true;
324
325     return toolbarsAreVisible;
326 }
327
328 void WebChromeClient::setStatusbarVisible(bool statusBarIsVisible)
329 {
330     m_page.send(Messages::WebPageProxy::SetStatusBarIsVisible(statusBarIsVisible));
331 }
332
333 bool WebChromeClient::statusbarVisible()
334 {
335     API::InjectedBundle::PageUIClient::UIElementVisibility statusbarVisibility = m_page.injectedBundleUIClient().statusBarIsVisible(&m_page);
336     if (statusbarVisibility != API::InjectedBundle::PageUIClient::UIElementVisibility::Unknown)
337         return statusbarVisibility == API::InjectedBundle::PageUIClient::UIElementVisibility::Visible;
338
339     bool statusBarIsVisible = true;
340     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetStatusBarIsVisible(), Messages::WebPageProxy::GetStatusBarIsVisible::Reply(statusBarIsVisible), m_page.pageID()))
341         return true;
342
343     return statusBarIsVisible;
344 }
345
346 void WebChromeClient::setScrollbarsVisible(bool)
347 {
348     notImplemented();
349 }
350
351 bool WebChromeClient::scrollbarsVisible()
352 {
353     notImplemented();
354     return true;
355 }
356
357 void WebChromeClient::setMenubarVisible(bool menuBarVisible)
358 {
359     m_page.send(Messages::WebPageProxy::SetMenuBarIsVisible(menuBarVisible));
360 }
361
362 bool WebChromeClient::menubarVisible()
363 {
364     API::InjectedBundle::PageUIClient::UIElementVisibility menubarVisibility = m_page.injectedBundleUIClient().menuBarIsVisible(&m_page);
365     if (menubarVisibility != API::InjectedBundle::PageUIClient::UIElementVisibility::Unknown)
366         return menubarVisibility == API::InjectedBundle::PageUIClient::UIElementVisibility::Visible;
367     
368     bool menuBarIsVisible = true;
369     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetMenuBarIsVisible(), Messages::WebPageProxy::GetMenuBarIsVisible::Reply(menuBarIsVisible), m_page.pageID()))
370         return true;
371
372     return menuBarIsVisible;
373 }
374
375 void WebChromeClient::setResizable(bool resizable)
376 {
377     m_page.send(Messages::WebPageProxy::SetIsResizable(resizable));
378 }
379
380 void WebChromeClient::addMessageToConsole(MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, unsigned columnNumber, const String& sourceID)
381 {
382     // Notify the bundle client.
383     m_page.injectedBundleUIClient().willAddMessageToConsole(&m_page, source, level, message, lineNumber, columnNumber, sourceID);
384 }
385
386 bool WebChromeClient::canRunBeforeUnloadConfirmPanel()
387 {
388     return m_page.canRunBeforeUnloadConfirmPanel();
389 }
390
391 bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame& frame)
392 {
393     WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
394
395     bool shouldClose = false;
396
397     HangDetectionDisabler hangDetectionDisabler;
398
399     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunBeforeUnloadConfirmPanel(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::Reply(shouldClose), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend))
400         return false;
401
402     return shouldClose;
403 }
404
405 void WebChromeClient::closeWindowSoon()
406 {
407     // FIXME: This code assumes that the client will respond to a close page
408     // message by actually closing the page. Safari does this, but there is
409     // no guarantee that other applications will, which will leave this page
410     // half detached. This approach is an inherent limitation making parts of
411     // a close execute synchronously as part of window.close, but other parts
412     // later on.
413
414     m_page.corePage()->setGroupName(String());
415
416     if (WebFrame* frame = m_page.mainWebFrame()) {
417         if (Frame* coreFrame = frame->coreFrame())
418             coreFrame->loader().stopForUserCancel();
419     }
420
421     m_page.sendClose();
422 }
423
424 static bool shouldSuppressJavaScriptDialogs(Frame& frame)
425 {
426     if (frame.loader().opener() && frame.loader().stateMachine().isDisplayingInitialEmptyDocument() && frame.loader().provisionalDocumentLoader())
427         return true;
428
429     return false;
430 }
431
432 void WebChromeClient::runJavaScriptAlert(Frame& frame, const String& alertText)
433 {
434     if (shouldSuppressJavaScriptDialogs(frame))
435         return;
436
437     WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
438     ASSERT(webFrame);
439
440     // Notify the bundle client.
441     m_page.injectedBundleUIClient().willRunJavaScriptAlert(&m_page, alertText, webFrame);
442
443     HangDetectionDisabler hangDetectionDisabler;
444
445     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply(), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend);
446 }
447
448 bool WebChromeClient::runJavaScriptConfirm(Frame& frame, const String& message)
449 {
450     if (shouldSuppressJavaScriptDialogs(frame))
451         return false;
452
453     WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
454     ASSERT(webFrame);
455
456     // Notify the bundle client.
457     m_page.injectedBundleUIClient().willRunJavaScriptConfirm(&m_page, message, webFrame);
458
459     HangDetectionDisabler hangDetectionDisabler;
460
461     bool result = false;
462     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend))
463         return false;
464
465     return result;
466 }
467
468 bool WebChromeClient::runJavaScriptPrompt(Frame& frame, const String& message, const String& defaultValue, String& result)
469 {
470     if (shouldSuppressJavaScriptDialogs(frame))
471         return false;
472
473     WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
474     ASSERT(webFrame);
475
476     // Notify the bundle client.
477     m_page.injectedBundleUIClient().willRunJavaScriptPrompt(&m_page, message, defaultValue, webFrame);
478
479     HangDetectionDisabler hangDetectionDisabler;
480
481     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend))
482         return false;
483
484     return !result.isNull();
485 }
486
487 void WebChromeClient::setStatusbarText(const String& statusbarText)
488 {
489     // Notify the bundle client.
490     m_page.injectedBundleUIClient().willSetStatusbarText(&m_page, statusbarText);
491
492     m_page.send(Messages::WebPageProxy::SetStatusText(statusbarText));
493 }
494
495 KeyboardUIMode WebChromeClient::keyboardUIMode()
496 {
497     return m_page.keyboardUIMode();
498 }
499
500 #if ENABLE(POINTER_LOCK)
501
502 bool WebChromeClient::requestPointerLock()
503 {
504     m_page.send(Messages::WebPageProxy::RequestPointerLock());
505     return true;
506 }
507
508 void WebChromeClient::requestPointerUnlock()
509 {
510     m_page.send(Messages::WebPageProxy::RequestPointerUnlock());
511 }
512
513 #endif
514
515 void WebChromeClient::invalidateRootView(const IntRect&)
516 {
517     // Do nothing here, there's no concept of invalidating the window in the web process.
518 }
519
520 void WebChromeClient::invalidateContentsAndRootView(const IntRect& rect)
521 {
522     if (Document* document = m_page.corePage()->mainFrame().document()) {
523         if (document->printing())
524             return;
525     }
526
527     m_page.drawingArea()->setNeedsDisplayInRect(rect);
528 }
529
530 void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& rect)
531 {
532     if (Document* document = m_page.corePage()->mainFrame().document()) {
533         if (document->printing())
534             return;
535     }
536
537     m_page.pageDidScroll();
538 #if USE(COORDINATED_GRAPHICS)
539     FrameView* frameView = m_page.mainFrame()->view();
540     if (frameView && frameView->delegatesScrolling()) {
541         m_page.drawingArea()->scroll(rect, IntSize());
542         return;
543     }
544 #endif
545     m_page.drawingArea()->setNeedsDisplayInRect(rect);
546 }
547
548 void WebChromeClient::scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect)
549 {
550     m_page.pageDidScroll();
551     m_page.drawingArea()->scroll(intersection(scrollRect, clipRect), scrollDelta);
552 }
553
554 IntPoint WebChromeClient::screenToRootView(const IntPoint& point) const
555 {
556     return m_page.screenToRootView(point);
557 }
558
559 IntRect WebChromeClient::rootViewToScreen(const IntRect& rect) const
560 {
561     return m_page.rootViewToScreen(rect);
562 }
563     
564 #if PLATFORM(IOS)
565 IntPoint WebChromeClient::accessibilityScreenToRootView(const IntPoint& point) const
566 {
567     return m_page.accessibilityScreenToRootView(point);
568 }
569
570 IntRect WebChromeClient::rootViewToAccessibilityScreen(const IntRect& rect) const
571 {
572     return m_page.rootViewToAccessibilityScreen(rect);
573 }
574 #endif
575
576 PlatformPageClient WebChromeClient::platformPageClient() const
577 {
578     notImplemented();
579     return 0;
580 }
581
582 void WebChromeClient::contentsSizeChanged(Frame& frame, const IntSize& size) const
583 {
584     FrameView* frameView = frame.view();
585
586     if (frameView && frameView->effectiveFrameFlattening() == FrameFlattening::Disabled) {
587         WebFrame* largestFrame = findLargestFrameInFrameSet(m_page);
588         if (largestFrame != m_cachedFrameSetLargestFrame.get()) {
589             m_cachedFrameSetLargestFrame = largestFrame;
590             m_page.send(Messages::WebPageProxy::FrameSetLargestFrameChanged(largestFrame ? largestFrame->frameID() : 0));
591         }
592     }
593
594     if (&frame.page()->mainFrame() != &frame)
595         return;
596
597     m_page.send(Messages::WebPageProxy::DidChangeContentSize(size));
598
599     m_page.drawingArea()->mainFrameContentSizeChanged(size);
600
601     if (frameView && !frameView->delegatesScrolling())  {
602         bool hasHorizontalScrollbar = frameView->horizontalScrollbar();
603         bool hasVerticalScrollbar = frameView->verticalScrollbar();
604
605         if (hasHorizontalScrollbar != m_cachedMainFrameHasHorizontalScrollbar || hasVerticalScrollbar != m_cachedMainFrameHasVerticalScrollbar) {
606             m_page.send(Messages::WebPageProxy::DidChangeScrollbarsForMainFrame(hasHorizontalScrollbar, hasVerticalScrollbar));
607
608             m_cachedMainFrameHasHorizontalScrollbar = hasHorizontalScrollbar;
609             m_cachedMainFrameHasVerticalScrollbar = hasVerticalScrollbar;
610         }
611     }
612 }
613
614 void WebChromeClient::scrollRectIntoView(const IntRect&) const
615 {
616     notImplemented();
617 }
618
619 bool WebChromeClient::shouldUnavailablePluginMessageBeButton(RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
620 {
621     switch (pluginUnavailabilityReason) {
622     case RenderEmbeddedObject::PluginMissing:
623         // FIXME: <rdar://problem/8794397> We should only return true when there is a
624         // missingPluginButtonClicked callback defined on the Page UI client.
625     case RenderEmbeddedObject::InsecurePluginVersion:
626         return true;
627
628
629     case RenderEmbeddedObject::PluginCrashed:
630     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
631     case RenderEmbeddedObject::UnsupportedPlugin:
632         return false;
633     }
634
635     ASSERT_NOT_REACHED();
636     return false;
637 }
638     
639 void WebChromeClient::unavailablePluginButtonClicked(Element& element, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
640 {
641 #if ENABLE(NETSCAPE_PLUGIN_API)
642     ASSERT(element.hasTagName(objectTag) || element.hasTagName(embedTag) || element.hasTagName(appletTag));
643     ASSERT(pluginUnavailabilityReason == RenderEmbeddedObject::PluginMissing || pluginUnavailabilityReason == RenderEmbeddedObject::InsecurePluginVersion || pluginUnavailabilityReason);
644
645     auto& pluginElement = downcast<HTMLPlugInImageElement>(element);
646
647     String frameURLString = pluginElement.document().frame()->loader().documentLoader()->responseURL().string();
648     String pageURLString = m_page.mainFrame()->loader().documentLoader()->responseURL().string();
649     String pluginURLString = pluginElement.document().completeURL(pluginElement.url()).string();
650     URL pluginspageAttributeURL = pluginElement.document().completeURL(stripLeadingAndTrailingHTMLSpaces(pluginElement.attributeWithoutSynchronization(pluginspageAttr)));
651     if (!pluginspageAttributeURL.protocolIsInHTTPFamily())
652         pluginspageAttributeURL = URL();
653     m_page.send(Messages::WebPageProxy::UnavailablePluginButtonClicked(pluginUnavailabilityReason, pluginElement.serviceType(), pluginURLString, pluginspageAttributeURL.string(), frameURLString, pageURLString));
654 #else
655     UNUSED_PARAM(element);
656     UNUSED_PARAM(pluginUnavailabilityReason);
657 #endif // ENABLE(NETSCAPE_PLUGIN_API)
658 }
659
660 void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& hitTestResult, unsigned modifierFlags)
661 {
662     RefPtr<API::Object> userData;
663
664     // Notify the bundle client.
665     m_page.injectedBundleUIClient().mouseDidMoveOverElement(&m_page, hitTestResult, static_cast<WebEvent::Modifiers>(modifierFlags), userData);
666
667     // Notify the UIProcess.
668     WebHitTestResultData webHitTestResultData(hitTestResult);
669     m_page.send(Messages::WebPageProxy::MouseDidMoveOverElement(webHitTestResultData, modifierFlags, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
670 }
671
672 void WebChromeClient::setToolTip(const String& toolTip, TextDirection)
673 {
674     // Only send a tool tip to the WebProcess if it has changed since the last time this function was called.
675
676     if (toolTip == m_cachedToolTip)
677         return;
678     m_cachedToolTip = toolTip;
679
680     m_page.send(Messages::WebPageProxy::SetToolTip(m_cachedToolTip));
681 }
682
683 void WebChromeClient::print(Frame& frame)
684 {
685     WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
686     ASSERT(webFrame);
687
688 #if PLATFORM(GTK) && HAVE(GTK_UNIX_PRINTING)
689     // When printing synchronously in GTK+ we need to make sure that we have a list of Printers before starting the print operation.
690     // Getting the list of printers is done synchronously by GTK+, but using a nested main loop that might process IPC messages
691     // comming from the UI process like EndPrinting. When the EndPriting message is received while the printer list is being populated,
692     // the print operation is finished unexpectely and the web process crashes, see https://bugs.webkit.org/show_bug.cgi?id=126979.
693     // The PrinterListGtk class gets the list of printers in the constructor so we just need to ensure there's an instance alive
694     // during the synchronous print operation.
695     RefPtr<PrinterListGtk> printerList = PrinterListGtk::getOrCreate();
696     if (!printerList) {
697         // PrinterListGtk::getOrCreate() returns nullptr when called while a printers enumeration is ongoing.
698         // This can happen if a synchronous print is started by a JavaScript and another one is inmeditaley started
699         // from a JavaScript event listener. The second print operation is handled by the nested main loop used by GTK+
700         // to enumerate the printers, and we end up here trying to get a reference of an object that is being constructed.
701         // It's very unlikely that the user wants to print twice in a row, and other browsers don't do two print operations
702         // in this particular case either. So, the safest solution is to return early here and ignore the second print.
703         // See https://bugs.webkit.org/show_bug.cgi?id=141035
704         return;
705     }
706 #endif
707
708     m_page.sendSync(Messages::WebPageProxy::PrintFrame(webFrame->frameID()), Messages::WebPageProxy::PrintFrame::Reply(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend);
709 }
710
711 void WebChromeClient::testIncomingSyncIPCMessageWhileWaitingForSyncReply()
712 {
713     bool wasHandled = false;
714     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebProcessProxy::TestIncomingSyncIPCMessageWhileWaitingForSyncReply(), Messages::WebProcessProxy::TestIncomingSyncIPCMessageWhileWaitingForSyncReply::Reply(wasHandled), 0, Seconds::infinity(), IPC::SendSyncOption::DoNotProcessIncomingMessagesWhenWaitingForSyncReply);
715     RELEASE_ASSERT(wasHandled);
716 }
717
718 void WebChromeClient::exceededDatabaseQuota(Frame& frame, const String& databaseName, DatabaseDetails details)
719 {
720     WebFrame* webFrame = WebFrame::fromCoreFrame(frame);
721     ASSERT(webFrame);
722     
723     auto& origin = frame.document()->securityOrigin();
724     auto& originData = origin.data();
725     auto& tracker = DatabaseTracker::singleton();
726     auto currentQuota = tracker.quota(originData);
727     auto currentOriginUsage = tracker.usage(originData);
728     uint64_t newQuota = 0;
729     RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(originData.databaseIdentifier())->securityOrigin());
730     newQuota = m_page.injectedBundleUIClient().didExceedDatabaseQuota(&m_page, securityOrigin.get(), databaseName, details.displayName(), currentQuota, currentOriginUsage, details.currentUsage(), details.expectedUsage());
731
732     if (!newQuota) {
733         WebProcess::singleton().parentProcessConnection()->sendSync(
734             Messages::WebPageProxy::ExceededDatabaseQuota(webFrame->frameID(), originData.databaseIdentifier(), databaseName, details.displayName(), currentQuota, currentOriginUsage, details.currentUsage(), details.expectedUsage()),
735             Messages::WebPageProxy::ExceededDatabaseQuota::Reply(newQuota), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend);
736     }
737
738     tracker.setQuota(originData, newQuota);
739 }
740
741 void WebChromeClient::reachedMaxAppCacheSize(int64_t)
742 {
743     notImplemented();
744 }
745
746 void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin& origin, int64_t totalBytesNeeded)
747 {
748     RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::createFromString(origin.toString());
749     if (m_page.injectedBundleUIClient().didReachApplicationCacheOriginQuota(&m_page, securityOrigin.get(), totalBytesNeeded))
750         return;
751
752     auto& cacheStorage = m_page.corePage()->applicationCacheStorage();
753     int64_t currentQuota = 0;
754     if (!cacheStorage.calculateQuotaForOrigin(origin, currentQuota))
755         return;
756
757     uint64_t newQuota = 0;
758     WebProcess::singleton().parentProcessConnection()->sendSync(
759         Messages::WebPageProxy::ReachedApplicationCacheOriginQuota(origin.data().databaseIdentifier(), currentQuota, totalBytesNeeded),
760         Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::Reply(newQuota), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend);
761
762     cacheStorage.storeUpdatedQuotaForOrigin(&origin, newQuota);
763 }
764
765 #if ENABLE(DASHBOARD_SUPPORT)
766
767 void WebChromeClient::annotatedRegionsChanged()
768 {
769     notImplemented();
770 }
771
772 #endif
773
774 bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename)
775 {
776     generatedFilename = m_page.injectedBundleUIClient().shouldGenerateFileForUpload(&m_page, path);
777     return !generatedFilename.isNull();
778 }
779
780 String WebChromeClient::generateReplacementFile(const String& path)
781 {
782     return m_page.injectedBundleUIClient().generateFileForUpload(&m_page, path);
783 }
784
785 #if ENABLE(INPUT_TYPE_COLOR)
786
787 std::unique_ptr<ColorChooser> WebChromeClient::createColorChooser(ColorChooserClient& client, const Color& initialColor)
788 {
789     return std::make_unique<WebColorChooser>(&m_page, &client, initialColor);
790 }
791
792 #endif
793
794 #if ENABLE(DATALIST_ELEMENT)
795
796 std::unique_ptr<DataListSuggestionPicker> WebChromeClient::createDataListSuggestionPicker(DataListSuggestionsClient& client)
797 {
798     return std::make_unique<WebDataListSuggestionPicker>(&m_page, &client);
799 }
800
801 #endif
802
803 void WebChromeClient::runOpenPanel(Frame& frame, FileChooser& fileChooser)
804 {
805     if (m_page.activeOpenPanelResultListener())
806         return;
807
808     m_page.setActiveOpenPanelResultListener(WebOpenPanelResultListener::create(m_page, fileChooser));
809
810     auto* webFrame = WebFrame::fromCoreFrame(frame);
811     ASSERT(webFrame);
812     m_page.send(Messages::WebPageProxy::RunOpenPanel(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), fileChooser.settings()));
813 }
814
815 void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader& loader)
816 {
817     loader.iconLoaded(createIconForFiles(filenames));
818 }
819
820 #if !PLATFORM(IOS)
821
822 void WebChromeClient::setCursor(const Cursor& cursor)
823 {
824     m_page.send(Messages::WebPageProxy::SetCursor(cursor));
825 }
826
827 void WebChromeClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
828 {
829     m_page.send(Messages::WebPageProxy::SetCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves));
830 }
831
832 RefPtr<Icon> WebChromeClient::createIconForFiles(const Vector<String>& filenames)
833 {
834     return Icon::createIconForFiles(filenames);
835 }
836
837 #endif
838
839 void WebChromeClient::didAssociateFormControls(const Vector<RefPtr<Element>>& elements)
840 {
841     return m_page.injectedBundleFormClient().didAssociateFormControls(&m_page, elements);
842 }
843
844 bool WebChromeClient::shouldNotifyOnFormChanges()
845 {
846     return m_page.injectedBundleFormClient().shouldNotifyOnFormChanges(&m_page);
847 }
848
849 bool WebChromeClient::selectItemWritingDirectionIsNatural()
850 {
851     return false;
852 }
853
854 bool WebChromeClient::selectItemAlignmentFollowsMenuWritingDirection()
855 {
856     return true;
857 }
858
859 RefPtr<PopupMenu> WebChromeClient::createPopupMenu(PopupMenuClient& client) const
860 {
861     return WebPopupMenu::create(&m_page, &client);
862 }
863
864 RefPtr<SearchPopupMenu> WebChromeClient::createSearchPopupMenu(PopupMenuClient& client) const
865 {
866     return WebSearchPopupMenu::create(&m_page, &client);
867 }
868
869 GraphicsLayerFactory* WebChromeClient::graphicsLayerFactory() const
870 {
871     if (auto drawingArea = m_page.drawingArea())
872         return drawingArea->graphicsLayerFactory();
873     return nullptr;
874 }
875
876 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
877
878 RefPtr<DisplayRefreshMonitor> WebChromeClient::createDisplayRefreshMonitor(PlatformDisplayID displayID) const
879 {
880     return m_page.drawingArea()->createDisplayRefreshMonitor(displayID);
881 }
882
883 #endif
884
885 void WebChromeClient::attachRootGraphicsLayer(Frame&, GraphicsLayer* layer)
886 {
887     if (layer)
888         m_page.enterAcceleratedCompositingMode(layer);
889     else
890         m_page.exitAcceleratedCompositingMode();
891 }
892
893 void WebChromeClient::attachViewOverlayGraphicsLayer(Frame& frame, GraphicsLayer* graphicsLayer)
894 {
895     if (auto drawingArea = m_page.drawingArea())
896         drawingArea->attachViewOverlayGraphicsLayer(&frame, graphicsLayer);
897 }
898
899 void WebChromeClient::setNeedsOneShotDrawingSynchronization()
900 {
901     notImplemented();
902 }
903
904 void WebChromeClient::scheduleCompositingLayerFlush()
905 {
906     if (m_page.drawingArea())
907         m_page.drawingArea()->scheduleCompositingLayerFlush();
908 }
909
910 void WebChromeClient::contentRuleListNotification(const URL& url, const HashSet<std::pair<String, String>>& notificationPairs)
911 {
912     Vector<String> identifiers;
913     Vector<String> notifications;
914     identifiers.reserveInitialCapacity(notificationPairs.size());
915     notifications.reserveInitialCapacity(notificationPairs.size());
916     for (auto& notification : notificationPairs) {
917         identifiers.uncheckedAppend(notification.first);
918         notifications.uncheckedAppend(notification.second);
919     }
920
921     m_page.send(Messages::WebPageProxy::ContentRuleListNotification(url, identifiers, notifications));
922 }
923
924 bool WebChromeClient::adjustLayerFlushThrottling(LayerFlushThrottleState::Flags flags)
925 {
926     return m_page.drawingArea() && m_page.drawingArea()->adjustLayerFlushThrottling(flags);
927 }
928
929 bool WebChromeClient::layerTreeStateIsFrozen() const
930 {
931     if (m_page.drawingArea())
932         return m_page.drawingArea()->layerTreeStateIsFrozen();
933
934     return false;
935 }
936
937 #if ENABLE(ASYNC_SCROLLING)
938
939 RefPtr<ScrollingCoordinator> WebChromeClient::createScrollingCoordinator(Page& page) const
940 {
941     ASSERT_UNUSED(page, m_page.corePage() == &page);
942 #if PLATFORM(COCOA)
943     if (m_page.drawingArea()->type() != DrawingAreaTypeRemoteLayerTree)
944         return nullptr;
945     return RemoteScrollingCoordinator::create(&m_page);
946 #else
947     return nullptr;
948 #endif
949 }
950
951 #endif
952
953 #if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
954
955 bool WebChromeClient::supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode mode)
956 {
957     return m_page.videoFullscreenManager().supportsVideoFullscreen(mode);
958 }
959
960 bool WebChromeClient::supportsVideoFullscreenStandby()
961 {
962     return m_page.videoFullscreenManager().supportsVideoFullscreenStandby();
963 }
964
965 void WebChromeClient::setUpPlaybackControlsManager(HTMLMediaElement& mediaElement)
966 {
967     m_page.playbackSessionManager().setUpPlaybackControlsManager(mediaElement);
968 }
969
970 void WebChromeClient::clearPlaybackControlsManager()
971 {
972     m_page.playbackSessionManager().clearPlaybackControlsManager();
973 }
974
975 void WebChromeClient::enterVideoFullscreenForVideoElement(HTMLVideoElement& videoElement, HTMLMediaElementEnums::VideoFullscreenMode mode, bool standby)
976 {
977 #if ENABLE(FULLSCREEN_API) && PLATFORM(IOS)
978     ASSERT(standby || mode != HTMLMediaElementEnums::VideoFullscreenModeNone);
979 #else
980     ASSERT(mode != HTMLMediaElementEnums::VideoFullscreenModeNone);
981 #endif
982     m_page.videoFullscreenManager().enterVideoFullscreenForVideoElement(videoElement, mode, standby);
983 }
984
985 void WebChromeClient::exitVideoFullscreenForVideoElement(HTMLVideoElement& videoElement)
986 {
987     m_page.videoFullscreenManager().exitVideoFullscreenForVideoElement(videoElement);
988 }
989
990 #endif
991
992 #if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
993
994 void WebChromeClient::exitVideoFullscreenToModeWithoutAnimation(HTMLVideoElement& videoElement, HTMLMediaElementEnums::VideoFullscreenMode targetMode)
995 {
996     m_page.videoFullscreenManager().exitVideoFullscreenToModeWithoutAnimation(videoElement, targetMode);
997 }
998
999 #endif
1000
1001 #if ENABLE(FULLSCREEN_API)
1002
1003 bool WebChromeClient::supportsFullScreenForElement(const Element&, bool withKeyboard)
1004 {
1005     return m_page.fullScreenManager()->supportsFullScreen(withKeyboard);
1006 }
1007
1008 void WebChromeClient::enterFullScreenForElement(Element& element)
1009 {
1010     m_page.fullScreenManager()->enterFullScreenForElement(&element);
1011 }
1012
1013 void WebChromeClient::exitFullScreenForElement(Element* element)
1014 {
1015     m_page.fullScreenManager()->exitFullScreenForElement(element);
1016 }
1017
1018 #endif
1019
1020 #if PLATFORM(IOS)
1021
1022 FloatSize WebChromeClient::screenSize() const
1023 {
1024     return m_page.screenSize();
1025 }
1026
1027 FloatSize WebChromeClient::availableScreenSize() const
1028 {
1029     return m_page.availableScreenSize();
1030 }
1031
1032 FloatSize WebChromeClient::overrideScreenSize() const
1033 {
1034     return m_page.overrideScreenSize();
1035 }
1036
1037 #endif
1038
1039 void WebChromeClient::dispatchDisabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>& disabledAdaptations) const
1040 {
1041     m_page.disabledAdaptationsDidChange(disabledAdaptations);
1042 }
1043
1044 void WebChromeClient::dispatchViewportPropertiesDidChange(const ViewportArguments& viewportArguments) const
1045 {
1046     m_page.viewportPropertiesDidChange(viewportArguments);
1047 }
1048
1049 void WebChromeClient::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb)
1050 {
1051     m_page.send(Messages::WebPageProxy::NotifyScrollerThumbIsVisibleInRect(scrollerThumb));
1052 }
1053
1054 void WebChromeClient::recommendedScrollbarStyleDidChange(ScrollbarStyle newStyle)
1055 {
1056     m_page.send(Messages::WebPageProxy::RecommendedScrollbarStyleDidChange(static_cast<int32_t>(newStyle)));
1057 }
1058
1059 std::optional<ScrollbarOverlayStyle> WebChromeClient::preferredScrollbarOverlayStyle()
1060 {
1061     return m_page.scrollbarOverlayStyle();
1062 }
1063
1064 Color WebChromeClient::underlayColor() const
1065 {
1066     return m_page.underlayColor();
1067 }
1068
1069 void WebChromeClient::pageExtendedBackgroundColorDidChange(Color backgroundColor) const
1070 {
1071 #if PLATFORM(MAC)
1072     m_page.send(Messages::WebPageProxy::PageExtendedBackgroundColorDidChange(backgroundColor));
1073 #else
1074     UNUSED_PARAM(backgroundColor);
1075 #endif
1076 }
1077
1078 void WebChromeClient::wheelEventHandlersChanged(bool hasHandlers)
1079 {
1080     m_page.wheelEventHandlersChanged(hasHandlers);
1081 }
1082
1083 String WebChromeClient::plugInStartLabelTitle(const String& mimeType) const
1084 {
1085     return m_page.injectedBundleUIClient().plugInStartLabelTitle(mimeType);
1086 }
1087
1088 String WebChromeClient::plugInStartLabelSubtitle(const String& mimeType) const
1089 {
1090     return m_page.injectedBundleUIClient().plugInStartLabelSubtitle(mimeType);
1091 }
1092
1093 String WebChromeClient::plugInExtraStyleSheet() const
1094 {
1095     return m_page.injectedBundleUIClient().plugInExtraStyleSheet();
1096 }
1097
1098 String WebChromeClient::plugInExtraScript() const
1099 {
1100     return m_page.injectedBundleUIClient().plugInExtraScript();
1101 }
1102
1103 void WebChromeClient::enableSuddenTermination()
1104 {
1105     m_page.send(Messages::WebProcessProxy::EnableSuddenTermination());
1106 }
1107
1108 void WebChromeClient::disableSuddenTermination()
1109 {
1110     m_page.send(Messages::WebProcessProxy::DisableSuddenTermination());
1111 }
1112
1113 void WebChromeClient::didAddHeaderLayer(GraphicsLayer& headerParent)
1114 {
1115 #if ENABLE(RUBBER_BANDING)
1116     if (PageBanner* banner = m_page.headerPageBanner())
1117         banner->didAddParentLayer(&headerParent);
1118 #else
1119     UNUSED_PARAM(headerParent);
1120 #endif
1121 }
1122
1123 void WebChromeClient::didAddFooterLayer(GraphicsLayer& footerParent)
1124 {
1125 #if ENABLE(RUBBER_BANDING)
1126     if (PageBanner* banner = m_page.footerPageBanner())
1127         banner->didAddParentLayer(&footerParent);
1128 #else
1129     UNUSED_PARAM(footerParent);
1130 #endif
1131 }
1132
1133 bool WebChromeClient::shouldUseTiledBackingForFrameView(const FrameView& frameView) const
1134 {
1135     return m_page.drawingArea()->shouldUseTiledBackingForFrameView(frameView);
1136 }
1137
1138 void WebChromeClient::isPlayingMediaDidChange(MediaProducer::MediaStateFlags state, uint64_t sourceElementID)
1139 {
1140     m_page.send(Messages::WebPageProxy::IsPlayingMediaDidChange(state, sourceElementID));
1141 }
1142
1143 void WebChromeClient::handleAutoplayEvent(AutoplayEvent event, OptionSet<AutoplayEventFlags> flags)
1144 {
1145     m_page.send(Messages::WebPageProxy::HandleAutoplayEvent(event, flags));
1146 }
1147
1148 #if ENABLE(MEDIA_SESSION)
1149
1150 void WebChromeClient::hasMediaSessionWithActiveMediaElementsDidChange(bool state)
1151 {
1152     m_page.send(Messages::WebPageProxy::HasMediaSessionWithActiveMediaElementsDidChange(state));
1153 }
1154
1155 void WebChromeClient::mediaSessionMetadataDidChange(const MediaSessionMetadata& metadata)
1156 {
1157     m_page.send(Messages::WebPageProxy::MediaSessionMetadataDidChange(metadata));
1158 }
1159
1160 void WebChromeClient::focusedContentMediaElementDidChange(uint64_t elementID)
1161 {
1162     m_page.send(Messages::WebPageProxy::FocusedContentMediaElementDidChange(elementID));
1163 }
1164
1165 #endif
1166
1167 #if ENABLE(SUBTLE_CRYPTO)
1168
1169 bool WebChromeClient::wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) const
1170 {
1171     bool succeeded;
1172     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::WrapCryptoKey(key), Messages::WebPageProxy::WrapCryptoKey::Reply(succeeded, wrappedKey), m_page.pageID()))
1173         return false;
1174     return succeeded;
1175 }
1176
1177 bool WebChromeClient::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) const
1178 {
1179     bool succeeded;
1180     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::UnwrapCryptoKey(wrappedKey), Messages::WebPageProxy::UnwrapCryptoKey::Reply(succeeded, key), m_page.pageID()))
1181         return false;
1182     return succeeded;
1183 }
1184
1185 #endif
1186
1187 String WebChromeClient::signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const WebCore::URL& url) const
1188 {
1189     String result;
1190     if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::SignedPublicKeyAndChallengeString(keySizeIndex, challengeString, url), Messages::WebPageProxy::SignedPublicKeyAndChallengeString::Reply(result), m_page.pageID()))
1191         return emptyString();
1192     return result;
1193 }
1194
1195 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(MAC)
1196
1197 void WebChromeClient::handleTelephoneNumberClick(const String& number, const IntPoint& point)
1198 {
1199     m_page.handleTelephoneNumberClick(number, point);
1200 }
1201
1202 #endif
1203
1204 #if ENABLE(SERVICE_CONTROLS)
1205
1206 void WebChromeClient::handleSelectionServiceClick(FrameSelection& selection, const Vector<String>& telephoneNumbers, const IntPoint& point)
1207 {
1208     m_page.handleSelectionServiceClick(selection, telephoneNumbers, point);
1209 }
1210
1211 bool WebChromeClient::hasRelevantSelectionServices(bool isTextOnly) const
1212 {
1213     return (isTextOnly && WebProcess::singleton().hasSelectionServices()) || WebProcess::singleton().hasRichContentServices();
1214 }
1215
1216 #endif
1217
1218 bool WebChromeClient::shouldDispatchFakeMouseMoveEvents() const
1219 {
1220     return m_page.shouldDispatchFakeMouseMoveEvents();
1221 }
1222
1223 void WebChromeClient::handleAutoFillButtonClick(HTMLInputElement& inputElement)
1224 {
1225     RefPtr<API::Object> userData;
1226
1227     // Notify the bundle client.
1228     auto nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement);
1229     m_page.injectedBundleUIClient().didClickAutoFillButton(m_page, nodeHandle.get(), userData);
1230
1231     // Notify the UIProcess.
1232     m_page.send(Messages::WebPageProxy::HandleAutoFillButtonClick(UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1233 }
1234
1235 void WebChromeClient::inputElementDidResignStrongPasswordAppearance(HTMLInputElement& inputElement)
1236 {
1237     RefPtr<API::Object> userData;
1238
1239     // Notify the bundle client.
1240     auto nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement);
1241     m_page.injectedBundleUIClient().didResignInputElementStrongPasswordAppearance(m_page, nodeHandle.get(), userData);
1242
1243     // Notify the UIProcess.
1244     m_page.send(Messages::WebPageProxy::DidResignInputElementStrongPasswordAppearance { UserData { WebProcess::singleton().transformObjectsToHandles(userData.get()).get() } });
1245 }
1246
1247 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
1248
1249 void WebChromeClient::addPlaybackTargetPickerClient(uint64_t contextId)
1250 {
1251     m_page.send(Messages::WebPageProxy::AddPlaybackTargetPickerClient(contextId));
1252 }
1253
1254 void WebChromeClient::removePlaybackTargetPickerClient(uint64_t contextId)
1255 {
1256     m_page.send(Messages::WebPageProxy::RemovePlaybackTargetPickerClient(contextId));
1257 }
1258
1259 void WebChromeClient::showPlaybackTargetPicker(uint64_t contextId, const IntPoint& position, bool isVideo)
1260 {
1261     FrameView* frameView = m_page.mainFrame()->view();
1262     FloatRect rect(frameView->contentsToRootView(frameView->windowToContents(position)), FloatSize());
1263     m_page.send(Messages::WebPageProxy::ShowPlaybackTargetPicker(contextId, rect, isVideo));
1264 }
1265
1266 void WebChromeClient::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state)
1267 {
1268     m_page.send(Messages::WebPageProxy::PlaybackTargetPickerClientStateDidChange(contextId, state));
1269 }
1270
1271 void WebChromeClient::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
1272 {
1273     m_page.send(Messages::WebPageProxy::SetMockMediaPlaybackTargetPickerEnabled(enabled));
1274 }
1275
1276 void WebChromeClient::setMockMediaPlaybackTargetPickerState(const String& name, MediaPlaybackTargetContext::State state)
1277 {
1278     m_page.send(Messages::WebPageProxy::SetMockMediaPlaybackTargetPickerState(name, state));
1279 }
1280
1281 #endif
1282
1283 void WebChromeClient::imageOrMediaDocumentSizeChanged(const IntSize& newSize)
1284 {
1285     m_page.imageOrMediaDocumentSizeChanged(newSize);
1286 }
1287
1288 #if ENABLE(VIDEO) && USE(GSTREAMER)
1289
1290 void WebChromeClient::requestInstallMissingMediaPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback& callback)
1291 {
1292     m_page.requestInstallMissingMediaPlugins(details, description, callback);
1293 }
1294
1295 #endif
1296
1297 void WebChromeClient::didInvalidateDocumentMarkerRects()
1298 {
1299     m_page.findController().didInvalidateDocumentMarkerRects();
1300 }
1301
1302 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
1303 void WebChromeClient::hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t, CompletionHandler<void(bool)>&& callback)
1304 {
1305     m_page.hasStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, WTFMove(callback));
1306 }
1307
1308 void WebChromeClient::requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t, CompletionHandler<void(bool)>&& callback)
1309 {
1310     m_page.requestStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, WTFMove(callback));
1311 }
1312 #endif
1313
1314 bool WebChromeClient::isViewVisible()
1315 {
1316     bool isVisible = false;
1317     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetIsViewVisible(), Messages::WebPageProxy::GetIsViewVisible::Reply(isVisible), m_page.pageID());
1318     return isVisible;
1319 }
1320
1321 } // namespace WebKit