Remove unused ChromeClient::formStateDidChange().
[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 "DrawingArea.h"
31 #include "InjectedBundleNavigationAction.h"
32 #include "InjectedBundleUserMessageCoders.h"
33 #include "LayerTreeHost.h"
34 #include "PageBanner.h"
35 #include "WebColorChooser.h"
36 #include "WebCoreArgumentCoders.h"
37 #include "WebFrame.h"
38 #include "WebFrameLoaderClient.h"
39 #include "WebFullScreenManager.h"
40 #include "WebImage.h"
41 #include "WebOpenPanelParameters.h"
42 #include "WebOpenPanelResultListener.h"
43 #include "WebPage.h"
44 #include "WebPageCreationParameters.h"
45 #include "WebPageProxyMessages.h"
46 #include "WebPopupMenu.h"
47 #include "WebPreferencesStore.h"
48 #include "WebProcess.h"
49 #include "WebProcessProxyMessages.h"
50 #include "WebSearchPopupMenu.h"
51 #include "WebSecurityOrigin.h"
52 #include <WebCore/AXObjectCache.h>
53 #include <WebCore/ColorChooser.h>
54 #include <WebCore/DatabaseManager.h>
55 #include <WebCore/DocumentLoader.h>
56 #include <WebCore/FileChooser.h>
57 #include <WebCore/FileIconLoader.h>
58 #include <WebCore/FrameLoadRequest.h>
59 #include <WebCore/FrameLoader.h>
60 #include <WebCore/FrameView.h>
61 #include <WebCore/HTMLInputElement.h>
62 #include <WebCore/HTMLNames.h>
63 #include <WebCore/HTMLParserIdioms.h>
64 #include <WebCore/HTMLPlugInImageElement.h>
65 #include <WebCore/Icon.h>
66 #include <WebCore/MainFrame.h>
67 #include <WebCore/NotImplemented.h>
68 #include <WebCore/Page.h>
69 #include <WebCore/SecurityOrigin.h>
70 #include <WebCore/Settings.h>
71
72 #if PLATFORM(IOS)
73 #include "WebVideoFullscreenManager.h"
74 #endif
75
76 #if ENABLE(ASYNC_SCROLLING)
77 #include "RemoteScrollingCoordinator.h"
78 #endif
79
80 #if PLATFORM(GTK)
81 #include "PrinterListGtk.h"
82 #endif
83
84 using namespace WebCore;
85 using namespace HTMLNames;
86
87 namespace WebKit {
88
89 static double area(WebFrame* frame)
90 {
91     IntSize size = frame->visibleContentBoundsExcludingScrollbars().size();
92     return static_cast<double>(size.height()) * size.width();
93 }
94
95
96 static WebFrame* findLargestFrameInFrameSet(WebPage* page)
97 {
98     // Approximate what a user could consider a default target frame for application menu operations.
99
100     WebFrame* mainFrame = page->mainWebFrame();
101     if (!mainFrame || !mainFrame->isFrameSet())
102         return 0;
103
104     WebFrame* largestSoFar = 0;
105
106     RefPtr<API::Array> frameChildren = mainFrame->childFrames();
107     size_t count = frameChildren->size();
108     for (size_t i = 0; i < count; ++i) {
109         WebFrame* childFrame = frameChildren->at<WebFrame>(i);
110         if (!largestSoFar || area(childFrame) > area(largestSoFar))
111             largestSoFar = childFrame;
112     }
113
114     return largestSoFar;
115 }
116
117 void WebChromeClient::chromeDestroyed()
118 {
119     delete this;
120 }
121
122 void WebChromeClient::setWindowRect(const FloatRect& windowFrame)
123 {
124     m_page->sendSetWindowFrame(windowFrame);
125 }
126
127 FloatRect WebChromeClient::windowRect()
128 {
129 #if PLATFORM(MAC)
130     if (m_page->hasCachedWindowFrame())
131         return m_page->windowFrameInUnflippedScreenCoordinates();
132 #endif
133
134     FloatRect newWindowFrame;
135
136     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetWindowFrame(), Messages::WebPageProxy::GetWindowFrame::Reply(newWindowFrame), m_page->pageID()))
137         return FloatRect();
138
139     return newWindowFrame;
140 }
141
142 FloatRect WebChromeClient::pageRect()
143 {
144     return FloatRect(FloatPoint(), m_page->size());
145 }
146
147 void WebChromeClient::focus()
148 {
149     m_page->send(Messages::WebPageProxy::SetFocus(true));
150 }
151
152 void WebChromeClient::unfocus()
153 {
154     m_page->send(Messages::WebPageProxy::SetFocus(false));
155 }
156
157 #if PLATFORM(MAC)
158 void WebChromeClient::makeFirstResponder()
159 {
160     m_page->send(Messages::WebPageProxy::MakeFirstResponder());
161 }    
162 #endif    
163
164 bool WebChromeClient::canTakeFocus(FocusDirection)
165 {
166     notImplemented();
167     return true;
168 }
169
170 void WebChromeClient::takeFocus(FocusDirection direction)
171 {
172     m_page->send(Messages::WebPageProxy::TakeFocus(direction));
173 }
174
175 void WebChromeClient::focusedElementChanged(Element* element)
176 {
177     if (!element)
178         return;
179     if (!isHTMLInputElement(element))
180         return;
181
182     HTMLInputElement* inputElement = toHTMLInputElement(element);
183     if (!inputElement->isText())
184         return;
185
186     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(element->document().frame()->loader().client());
187     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
188     ASSERT(webFrame);
189     m_page->injectedBundleFormClient().didFocusTextField(m_page, inputElement, webFrame);
190 }
191
192 void WebChromeClient::focusedFrameChanged(Frame* frame)
193 {
194     WebFrameLoaderClient* webFrameLoaderClient = frame ? toWebFrameLoaderClient(frame->loader().client()) : 0;
195     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
196
197     WebProcess::shared().parentProcessConnection()->send(Messages::WebPageProxy::FocusedFrameChanged(webFrame ? webFrame->frameID() : 0), m_page->pageID());
198 }
199
200 Page* WebChromeClient::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& windowFeatures, const NavigationAction& navigationAction)
201 {
202     uint32_t modifiers = static_cast<uint32_t>(InjectedBundleNavigationAction::modifiersForNavigationAction(navigationAction));
203     int32_t mouseButton = static_cast<int32_t>(InjectedBundleNavigationAction::mouseButtonForNavigationAction(navigationAction));
204
205 #if ENABLE(FULLSCREEN_API)
206     if (frame->document() && frame->document()->webkitCurrentFullScreenElement())
207         frame->document()->webkitCancelFullScreen();
208 #else
209     UNUSED_PARAM(frame);
210 #endif
211
212     uint64_t newPageID = 0;
213     WebPageCreationParameters parameters;
214     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::CreateNewPage(request.resourceRequest(), windowFeatures, modifiers, mouseButton), Messages::WebPageProxy::CreateNewPage::Reply(newPageID, parameters), m_page->pageID()))
215         return 0;
216
217     if (!newPageID)
218         return 0;
219
220     WebProcess::shared().createWebPage(newPageID, parameters);
221     return WebProcess::shared().webPage(newPageID)->corePage();
222 }
223
224 void WebChromeClient::show()
225 {
226     m_page->show();
227 }
228
229 bool WebChromeClient::canRunModal()
230 {
231     return m_page->canRunModal();
232 }
233
234 void WebChromeClient::runModal()
235 {
236     m_page->runModal();
237 }
238
239 void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible)
240 {
241     m_page->send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible));
242 }
243
244 bool WebChromeClient::toolbarsVisible()
245 {
246     WKBundlePageUIElementVisibility toolbarsVisibility = m_page->injectedBundleUIClient().toolbarsAreVisible(m_page);
247     if (toolbarsVisibility != WKBundlePageUIElementVisibilityUnknown)
248         return toolbarsVisibility == WKBundlePageUIElementVisible;
249     
250     bool toolbarsAreVisible = true;
251     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetToolbarsAreVisible(), Messages::WebPageProxy::GetToolbarsAreVisible::Reply(toolbarsAreVisible), m_page->pageID()))
252         return true;
253
254     return toolbarsAreVisible;
255 }
256
257 void WebChromeClient::setStatusbarVisible(bool statusBarIsVisible)
258 {
259     m_page->send(Messages::WebPageProxy::SetStatusBarIsVisible(statusBarIsVisible));
260 }
261
262 bool WebChromeClient::statusbarVisible()
263 {
264     WKBundlePageUIElementVisibility statusbarVisibility = m_page->injectedBundleUIClient().statusBarIsVisible(m_page);
265     if (statusbarVisibility != WKBundlePageUIElementVisibilityUnknown)
266         return statusbarVisibility == WKBundlePageUIElementVisible;
267
268     bool statusBarIsVisible = true;
269     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetStatusBarIsVisible(), Messages::WebPageProxy::GetStatusBarIsVisible::Reply(statusBarIsVisible), m_page->pageID()))
270         return true;
271
272     return statusBarIsVisible;
273 }
274
275 void WebChromeClient::setScrollbarsVisible(bool)
276 {
277     notImplemented();
278 }
279
280 bool WebChromeClient::scrollbarsVisible()
281 {
282     notImplemented();
283     return true;
284 }
285
286 void WebChromeClient::setMenubarVisible(bool menuBarVisible)
287 {
288     m_page->send(Messages::WebPageProxy::SetMenuBarIsVisible(menuBarVisible));
289 }
290
291 bool WebChromeClient::menubarVisible()
292 {
293     WKBundlePageUIElementVisibility menubarVisibility = m_page->injectedBundleUIClient().menuBarIsVisible(m_page);
294     if (menubarVisibility != WKBundlePageUIElementVisibilityUnknown)
295         return menubarVisibility == WKBundlePageUIElementVisible;
296     
297     bool menuBarIsVisible = true;
298     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::GetMenuBarIsVisible(), Messages::WebPageProxy::GetMenuBarIsVisible::Reply(menuBarIsVisible), m_page->pageID()))
299         return true;
300
301     return menuBarIsVisible;
302 }
303
304 void WebChromeClient::setResizable(bool resizable)
305 {
306     m_page->send(Messages::WebPageProxy::SetIsResizable(resizable));
307 }
308
309 void WebChromeClient::addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, unsigned /*columnNumber*/, const String& /*sourceID*/)
310 {
311     // Notify the bundle client.
312     m_page->injectedBundleUIClient().willAddMessageToConsole(m_page, message, lineNumber);
313
314     notImplemented();
315 }
316
317 bool WebChromeClient::canRunBeforeUnloadConfirmPanel()
318 {
319     return m_page->canRunBeforeUnloadConfirmPanel();
320 }
321
322 bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
323 {
324     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
325     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
326     ASSERT(webFrame);
327
328     bool shouldClose = false;
329     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunBeforeUnloadConfirmPanel(message, webFrame->frameID()), Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::Reply(shouldClose), m_page->pageID()))
330         return false;
331
332     return shouldClose;
333 }
334
335 void WebChromeClient::closeWindowSoon()
336 {
337     // FIXME: This code assumes that the client will respond to a close page
338     // message by actually closing the page. Safari does this, but there is
339     // no guarantee that other applications will, which will leave this page
340     // half detached. This approach is an inherent limitation making parts of
341     // a close execute synchronously as part of window.close, but other parts
342     // later on.
343
344     m_page->corePage()->setGroupName(String());
345
346     if (WebFrame* frame = m_page->mainWebFrame()) {
347         if (Frame* coreFrame = frame->coreFrame())
348             coreFrame->loader().stopForUserCancel();
349     }
350
351     m_page->sendClose();
352 }
353
354 void WebChromeClient::runJavaScriptAlert(Frame* frame, const String& alertText)
355 {
356     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
357     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
358     ASSERT(webFrame);
359
360     // Notify the bundle client.
361     m_page->injectedBundleUIClient().willRunJavaScriptAlert(m_page, alertText, webFrame);
362
363     // FIXME (126021): It is not good to change IPC behavior conditionally, and SpinRunLoopWhileWaitingForReply was known to cause trouble in other similar cases.
364     unsigned syncSendFlags = (WebCore::AXObjectCache::accessibilityEnabled()) ? IPC::SpinRunLoopWhileWaitingForReply : 0;
365     WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply(), m_page->pageID(), std::chrono::milliseconds::max(), syncSendFlags);
366 }
367
368 bool WebChromeClient::runJavaScriptConfirm(Frame* frame, const String& message)
369 {
370     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
371     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
372     ASSERT(webFrame);
373
374     // Notify the bundle client.
375     m_page->injectedBundleUIClient().willRunJavaScriptConfirm(m_page, message, webFrame);
376
377     // FIXME (126021): It is not good to change IPC behavior conditionally, and SpinRunLoopWhileWaitingForReply was known to cause trouble in other similar cases.
378     unsigned syncSendFlags = (WebCore::AXObjectCache::accessibilityEnabled()) ? IPC::SpinRunLoopWhileWaitingForReply : 0;
379     bool result = false;
380     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result), m_page->pageID(), std::chrono::milliseconds::max(), syncSendFlags))
381         return false;
382
383     return result;
384 }
385
386 bool WebChromeClient::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
387 {
388     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
389     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
390     ASSERT(webFrame);
391
392     // Notify the bundle client.
393     m_page->injectedBundleUIClient().willRunJavaScriptPrompt(m_page, message, defaultValue, webFrame);
394
395     // FIXME (126021): It is not good to change IPC behavior conditionally, and SpinRunLoopWhileWaitingForReply was known to cause trouble in other similar cases.
396     unsigned syncSendFlags = (WebCore::AXObjectCache::accessibilityEnabled()) ? IPC::SpinRunLoopWhileWaitingForReply : 0;
397     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result), m_page->pageID(), std::chrono::milliseconds::max(), syncSendFlags))
398         return false;
399
400     return !result.isNull();
401 }
402
403 void WebChromeClient::setStatusbarText(const String& statusbarText)
404 {
405     // Notify the bundle client.
406     m_page->injectedBundleUIClient().willSetStatusbarText(m_page, statusbarText);
407
408     m_page->send(Messages::WebPageProxy::SetStatusText(statusbarText));
409 }
410
411 bool WebChromeClient::shouldInterruptJavaScript()
412 {
413     bool shouldInterrupt = false;
414     if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::ShouldInterruptJavaScript(), Messages::WebPageProxy::ShouldInterruptJavaScript::Reply(shouldInterrupt), m_page->pageID()))
415         return false;
416
417     return shouldInterrupt;
418 }
419
420 KeyboardUIMode WebChromeClient::keyboardUIMode()
421 {
422     return m_page->keyboardUIMode();
423 }
424
425 IntRect WebChromeClient::windowResizerRect() const
426 {
427     return m_page->windowResizerRect();
428 }
429
430 void WebChromeClient::invalidateRootView(const IntRect&, bool)
431 {
432     // Do nothing here, there's no concept of invalidating the window in the web process.
433 }
434
435 void WebChromeClient::invalidateContentsAndRootView(const IntRect& rect, bool)
436 {
437     if (Document* document = m_page->corePage()->mainFrame().document()) {
438         if (document->printing())
439             return;
440     }
441
442     m_page->drawingArea()->setNeedsDisplayInRect(rect);
443 }
444
445 void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& rect, bool)
446 {
447     if (Document* document = m_page->corePage()->mainFrame().document()) {
448         if (document->printing())
449             return;
450     }
451
452     m_page->pageDidScroll();
453 #if USE(COORDINATED_GRAPHICS)
454     m_page->drawingArea()->scroll(rect, IntSize());
455 #else
456     m_page->drawingArea()->setNeedsDisplayInRect(rect);
457 #endif
458 }
459
460 void WebChromeClient::scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect)
461 {
462     m_page->pageDidScroll();
463     m_page->drawingArea()->scroll(intersection(scrollRect, clipRect), scrollDelta);
464 }
465
466 #if USE(TILED_BACKING_STORE)
467 void WebChromeClient::delegatedScrollRequested(const IntPoint& scrollOffset)
468 {
469     m_page->pageDidRequestScroll(scrollOffset);
470 }
471 #endif
472
473 IntPoint WebChromeClient::screenToRootView(const IntPoint& point) const
474 {
475     return m_page->screenToWindow(point);
476 }
477
478 IntRect WebChromeClient::rootViewToScreen(const IntRect& rect) const
479 {
480     return m_page->windowToScreen(rect);
481 }
482
483 PlatformPageClient WebChromeClient::platformPageClient() const
484 {
485     notImplemented();
486     return 0;
487 }
488
489 void WebChromeClient::contentsSizeChanged(Frame* frame, const IntSize& size) const
490 {
491     if (!m_page->corePage()->settings().frameFlatteningEnabled()) {
492         WebFrame* largestFrame = findLargestFrameInFrameSet(m_page);
493         if (largestFrame != m_cachedFrameSetLargestFrame.get()) {
494             m_cachedFrameSetLargestFrame = largestFrame;
495             m_page->send(Messages::WebPageProxy::FrameSetLargestFrameChanged(largestFrame ? largestFrame->frameID() : 0));
496         }
497     }
498
499     if (&frame->page()->mainFrame() != frame)
500         return;
501
502 #if USE(COORDINATED_GRAPHICS)
503     if (m_page->useFixedLayout())
504         m_page->drawingArea()->layerTreeHost()->sizeDidChange(size);
505
506     m_page->send(Messages::WebPageProxy::DidChangeContentSize(size));
507 #endif
508
509     m_page->drawingArea()->mainFrameContentSizeChanged(size);
510
511     FrameView* frameView = frame->view();
512     if (frameView && !frameView->delegatesScrolling())  {
513         bool hasHorizontalScrollbar = frameView->horizontalScrollbar();
514         bool hasVerticalScrollbar = frameView->verticalScrollbar();
515
516         if (hasHorizontalScrollbar != m_cachedMainFrameHasHorizontalScrollbar || hasVerticalScrollbar != m_cachedMainFrameHasVerticalScrollbar) {
517             m_page->send(Messages::WebPageProxy::DidChangeScrollbarsForMainFrame(hasHorizontalScrollbar, hasVerticalScrollbar));
518
519             m_cachedMainFrameHasHorizontalScrollbar = hasHorizontalScrollbar;
520             m_cachedMainFrameHasVerticalScrollbar = hasVerticalScrollbar;
521         }
522     }
523 }
524
525 void WebChromeClient::scrollRectIntoView(const IntRect&) const
526 {
527     notImplemented();
528 }
529
530 bool WebChromeClient::shouldUnavailablePluginMessageBeButton(RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
531 {
532     switch (pluginUnavailabilityReason) {
533     case RenderEmbeddedObject::PluginMissing:
534         // FIXME: <rdar://problem/8794397> We should only return true when there is a
535         // missingPluginButtonClicked callback defined on the Page UI client.
536     case RenderEmbeddedObject::InsecurePluginVersion:
537         return true;
538
539
540     case RenderEmbeddedObject::PluginCrashed:
541     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
542         return false;
543     }
544
545     ASSERT_NOT_REACHED();
546     return false;
547 }
548     
549 void WebChromeClient::unavailablePluginButtonClicked(Element* element, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
550 {
551 #if ENABLE(NETSCAPE_PLUGIN_API)
552     ASSERT(element->hasTagName(objectTag) || element->hasTagName(embedTag) || element->hasTagName(appletTag));
553     ASSERT(pluginUnavailabilityReason == RenderEmbeddedObject::PluginMissing || pluginUnavailabilityReason == RenderEmbeddedObject::InsecurePluginVersion || pluginUnavailabilityReason);
554
555     HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(element);
556
557     String frameURLString = pluginElement->document().frame()->loader().documentLoader()->responseURL().string();
558     String pageURLString = m_page->mainFrame()->loader().documentLoader()->responseURL().string();
559     String pluginURLString = pluginElement->document().completeURL(pluginElement->url()).string();
560     URL pluginspageAttributeURL = element->document().completeURL(stripLeadingAndTrailingHTMLSpaces(pluginElement->getAttribute(pluginspageAttr)));
561     if (!pluginspageAttributeURL.protocolIsInHTTPFamily())
562         pluginspageAttributeURL = URL();
563     m_page->send(Messages::WebPageProxy::UnavailablePluginButtonClicked(pluginUnavailabilityReason, pluginElement->serviceType(), pluginURLString, pluginspageAttributeURL.string(), frameURLString, pageURLString));
564 #else
565     UNUSED_PARAM(element);
566     UNUSED_PARAM(pluginUnavailabilityReason);
567 #endif // ENABLE(NETSCAPE_PLUGIN_API)
568 }
569
570 void WebChromeClient::scrollbarsModeDidChange() const
571 {
572     notImplemented();
573 }
574
575 void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& hitTestResult, unsigned modifierFlags)
576 {
577     RefPtr<API::Object> userData;
578
579     // Notify the bundle client.
580     m_page->injectedBundleUIClient().mouseDidMoveOverElement(m_page, hitTestResult, static_cast<WebEvent::Modifiers>(modifierFlags), userData);
581
582     // Notify the UIProcess.
583     WebHitTestResult::Data webHitTestResultData(hitTestResult);
584     m_page->send(Messages::WebPageProxy::MouseDidMoveOverElement(webHitTestResultData, modifierFlags, InjectedBundleUserMessageEncoder(userData.get())));
585 }
586
587 void WebChromeClient::setToolTip(const String& toolTip, TextDirection)
588 {
589     // Only send a tool tip to the WebProcess if it has changed since the last time this function was called.
590
591     if (toolTip == m_cachedToolTip)
592         return;
593     m_cachedToolTip = toolTip;
594
595     m_page->send(Messages::WebPageProxy::SetToolTip(m_cachedToolTip));
596 }
597
598 void WebChromeClient::print(Frame* frame)
599 {
600     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
601     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
602     ASSERT(webFrame);
603
604 #if PLATFORM(GTK) && defined(HAVE_GTK_UNIX_PRINTING)
605     // When printing synchronously in GTK+ we need to make sure that we have a list of Printers before starting the print operation.
606     // Getting the list of printers is done synchronously by GTK+, but using a nested main loop that might process IPC messages
607     // comming from the UI process like EndPrinting. When the EndPriting message is received while the printer list is being populated,
608     // the print operation is finished unexpectely and the web process crashes, see https://bugs.webkit.org/show_bug.cgi?id=126979.
609     // The PrinterListGtk class gets the list of printers in the constructor so we just need to ensure there's an instance alive
610     // during the synchronous print operation.
611     RefPtr<PrinterListGtk> printerList = PrinterListGtk::shared();
612 #endif
613
614     m_page->sendSync(Messages::WebPageProxy::PrintFrame(webFrame->frameID()), Messages::WebPageProxy::PrintFrame::Reply());
615 }
616
617 #if ENABLE(SQL_DATABASE)
618 void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& databaseName, DatabaseDetails details)
619 {
620     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
621     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
622     ASSERT(webFrame);
623     
624     SecurityOrigin* origin = frame->document()->securityOrigin();
625
626     DatabaseManager& dbManager = DatabaseManager::manager();
627     uint64_t currentQuota = dbManager.quotaForOrigin(origin);
628     uint64_t currentOriginUsage = dbManager.usageForOrigin(origin);
629     uint64_t newQuota = 0;
630     RefPtr<WebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createFromDatabaseIdentifier(origin->databaseIdentifier());
631     newQuota = m_page->injectedBundleUIClient().didExceedDatabaseQuota(m_page, webSecurityOrigin.get(), databaseName, details.displayName(), currentQuota, currentOriginUsage, details.currentUsage(), details.expectedUsage());
632
633     if (!newQuota) {
634         WebProcess::shared().parentProcessConnection()->sendSync(
635             Messages::WebPageProxy::ExceededDatabaseQuota(webFrame->frameID(), origin->databaseIdentifier(), databaseName, details.displayName(), currentQuota, currentOriginUsage, details.currentUsage(), details.expectedUsage()),
636             Messages::WebPageProxy::ExceededDatabaseQuota::Reply(newQuota), m_page->pageID());
637     }
638
639     dbManager.setQuota(origin, newQuota);
640 }
641 #endif
642
643
644 void WebChromeClient::reachedMaxAppCacheSize(int64_t)
645 {
646     notImplemented();
647 }
648
649 void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin* origin, int64_t totalBytesNeeded)
650 {
651     RefPtr<WebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createFromString(origin->toString());
652     m_page->injectedBundleUIClient().didReachApplicationCacheOriginQuota(m_page, webSecurityOrigin.get(), totalBytesNeeded);
653 }
654
655 #if ENABLE(DASHBOARD_SUPPORT)
656 void WebChromeClient::annotatedRegionsChanged()
657 {
658     notImplemented();
659 }
660 #endif
661
662 void WebChromeClient::populateVisitedLinks()
663 {
664 }
665
666 bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename)
667 {
668     generatedFilename = m_page->injectedBundleUIClient().shouldGenerateFileForUpload(m_page, path);
669     return !generatedFilename.isNull();
670 }
671
672 String WebChromeClient::generateReplacementFile(const String& path)
673 {
674     return m_page->injectedBundleUIClient().generateFileForUpload(m_page, path);
675 }
676
677 #if ENABLE(INPUT_TYPE_COLOR)
678 PassOwnPtr<ColorChooser> WebChromeClient::createColorChooser(ColorChooserClient* client, const Color& initialColor)
679 {
680     return adoptPtr(new WebColorChooser(m_page, client, initialColor));
681 }
682 #endif
683
684 void WebChromeClient::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
685 {
686     if (m_page->activeOpenPanelResultListener())
687         return;
688
689     RefPtr<FileChooser> fileChooser = prpFileChooser;
690
691     m_page->setActiveOpenPanelResultListener(WebOpenPanelResultListener::create(m_page, fileChooser.get()));
692
693     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
694     WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
695     ASSERT(webFrame);
696
697     m_page->send(Messages::WebPageProxy::RunOpenPanel(webFrame->frameID(), fileChooser->settings()));
698 }
699
700 void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader)
701 {
702     loader->notifyFinished(Icon::createIconForFiles(filenames));
703 }
704
705 #if !PLATFORM(IOS)
706 void WebChromeClient::setCursor(const WebCore::Cursor& cursor)
707 {
708     m_page->send(Messages::WebPageProxy::SetCursor(cursor));
709 }
710
711 void WebChromeClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
712 {
713     m_page->send(Messages::WebPageProxy::SetCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves));
714 }
715 #endif
716
717 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
718 void WebChromeClient::scheduleAnimation()
719 {
720 #if USE(COORDINATED_GRAPHICS)
721     m_page->drawingArea()->layerTreeHost()->scheduleAnimation();
722 #endif
723 }
724 #endif
725
726 void WebChromeClient::didAssociateFormControls(const Vector<RefPtr<WebCore::Element>>& elements)
727 {
728     return m_page->injectedBundleFormClient().didAssociateFormControls(m_page, elements);
729 }
730
731 bool WebChromeClient::shouldNotifyOnFormChanges()
732 {
733     return m_page->injectedBundleFormClient().shouldNotifyOnFormChanges(m_page);
734 }
735
736 bool WebChromeClient::selectItemWritingDirectionIsNatural()
737 {
738 #if PLATFORM(EFL)
739     return true;
740 #else
741     return false;
742 #endif
743 }
744
745 bool WebChromeClient::selectItemAlignmentFollowsMenuWritingDirection()
746 {
747     return true;
748 }
749
750 bool WebChromeClient::hasOpenedPopup() const
751 {
752     notImplemented();
753     return false;
754 }
755
756 PassRefPtr<WebCore::PopupMenu> WebChromeClient::createPopupMenu(WebCore::PopupMenuClient* client) const
757 {
758     return WebPopupMenu::create(m_page, client);
759 }
760
761 PassRefPtr<WebCore::SearchPopupMenu> WebChromeClient::createSearchPopupMenu(WebCore::PopupMenuClient* client) const
762 {
763     return WebSearchPopupMenu::create(m_page, client);
764 }
765
766 GraphicsLayerFactory* WebChromeClient::graphicsLayerFactory() const
767 {
768     return m_page->drawingArea()->graphicsLayerFactory();
769 }
770
771 void WebChromeClient::attachRootGraphicsLayer(Frame*, GraphicsLayer* layer)
772 {
773     if (layer)
774         m_page->enterAcceleratedCompositingMode(layer);
775     else
776         m_page->exitAcceleratedCompositingMode();
777 }
778
779 void WebChromeClient::setNeedsOneShotDrawingSynchronization()
780 {
781     notImplemented();
782 }
783
784 void WebChromeClient::scheduleCompositingLayerFlush()
785 {
786     if (m_page->drawingArea())
787         m_page->drawingArea()->scheduleCompositingLayerFlush();
788 }
789
790
791 bool WebChromeClient::layerTreeStateIsFrozen() const
792 {
793     if (m_page->drawingArea())
794         return m_page->drawingArea()->layerTreeStateIsFrozen();
795
796     return false;
797 }
798
799 #if ENABLE(ASYNC_SCROLLING)
800 PassRefPtr<ScrollingCoordinator> WebChromeClient::createScrollingCoordinator(Page* page) const
801 {
802     ASSERT(m_page->corePage() == page);
803     if (m_page->drawingArea()->type() == DrawingAreaTypeRemoteLayerTree)
804         return RemoteScrollingCoordinator::create(m_page);
805
806     return 0;
807 }
808 #endif
809
810 #if PLATFORM(IOS)
811 bool WebChromeClient::supportsFullscreenForNode(const WebCore::Node* node)
812 {
813     return m_page->videoFullscreenManager()->supportsFullscreen(node);
814 }
815
816 void WebChromeClient::enterFullscreenForNode(WebCore::Node* node)
817 {
818     m_page->videoFullscreenManager()->enterFullscreenForNode(node);
819 }
820
821 void WebChromeClient::exitFullscreenForNode(WebCore::Node* node)
822 {
823     m_page->videoFullscreenManager()->exitFullscreenForNode(node);
824 }
825 #endif
826     
827 #if ENABLE(FULLSCREEN_API)
828 bool WebChromeClient::supportsFullScreenForElement(const WebCore::Element*, bool withKeyboard)
829 {
830     return m_page->fullScreenManager()->supportsFullScreen(withKeyboard);
831 }
832
833 void WebChromeClient::enterFullScreenForElement(WebCore::Element* element)
834 {
835     m_page->fullScreenManager()->enterFullScreenForElement(element);
836 }
837
838 void WebChromeClient::exitFullScreenForElement(WebCore::Element* element)
839 {
840     m_page->fullScreenManager()->exitFullScreenForElement(element);
841 }
842 #endif
843
844 void WebChromeClient::dispatchViewportPropertiesDidChange(const ViewportArguments& viewportArguments) const
845 {
846     UNUSED_PARAM(viewportArguments);
847 #if PLATFORM(IOS)
848     m_page->viewportPropertiesDidChange(viewportArguments);
849 #endif
850 #if USE(TILED_BACKING_STORE)
851     if (!m_page->useFixedLayout())
852         return;
853
854     m_page->sendViewportAttributesChanged();
855 #endif
856 }
857
858 void WebChromeClient::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb)
859 {
860     m_page->send(Messages::WebPageProxy::NotifyScrollerThumbIsVisibleInRect(scrollerThumb));
861 }
862
863 void WebChromeClient::recommendedScrollbarStyleDidChange(int32_t newStyle)
864 {
865     m_page->send(Messages::WebPageProxy::RecommendedScrollbarStyleDidChange(newStyle));
866 }
867
868 Color WebChromeClient::underlayColor() const
869 {
870     return m_page->underlayColor();
871 }
872
873 void WebChromeClient::numWheelEventHandlersChanged(unsigned count)
874 {
875     m_page->numWheelEventHandlersChanged(count);
876 }
877
878 void WebChromeClient::logDiagnosticMessage(const String& message, const String& description, const String& success)
879 {
880     if (!m_page->corePage()->settings().diagnosticLoggingEnabled())
881         return;
882
883     m_page->injectedBundleDiagnosticLoggingClient().logDiagnosticMessage(m_page, message, description, success);
884 }
885
886 String WebChromeClient::plugInStartLabelTitle(const String& mimeType) const
887 {
888     return m_page->injectedBundleUIClient().plugInStartLabelTitle(mimeType);
889 }
890
891 String WebChromeClient::plugInStartLabelSubtitle(const String& mimeType) const
892 {
893     return m_page->injectedBundleUIClient().plugInStartLabelSubtitle(mimeType);
894 }
895
896 String WebChromeClient::plugInExtraStyleSheet() const
897 {
898     return m_page->injectedBundleUIClient().plugInExtraStyleSheet();
899 }
900
901 String WebChromeClient::plugInExtraScript() const
902 {
903     return m_page->injectedBundleUIClient().plugInExtraScript();
904 }
905
906 void WebChromeClient::enableSuddenTermination()
907 {
908     m_page->send(Messages::WebProcessProxy::EnableSuddenTermination());
909 }
910
911 void WebChromeClient::disableSuddenTermination()
912 {
913     m_page->send(Messages::WebProcessProxy::DisableSuddenTermination());
914 }
915
916 void WebChromeClient::didAddHeaderLayer(GraphicsLayer* headerParent)
917 {
918 #if ENABLE(RUBBER_BANDING)
919     if (PageBanner* banner = m_page->headerPageBanner())
920         banner->didAddParentLayer(headerParent);
921 #else
922     UNUSED_PARAM(headerParent);
923 #endif
924 }
925
926 void WebChromeClient::didAddFooterLayer(GraphicsLayer* footerParent)
927 {
928 #if ENABLE(RUBBER_BANDING)
929     if (PageBanner* banner = m_page->footerPageBanner())
930         banner->didAddParentLayer(footerParent);
931 #else
932     UNUSED_PARAM(footerParent);
933 #endif
934 }
935
936 bool WebChromeClient::shouldUseTiledBackingForFrameView(const FrameView* frameView) const
937 {
938     return m_page->drawingArea()->shouldUseTiledBackingForFrameView(frameView);
939 }
940
941 } // namespace WebKit