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