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