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