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