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