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