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