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