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