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