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