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