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