fb9b96c21f1b6771aba62e8d79a28d8d4d79dc25
[WebKit-https.git] / Source / WebKit / qt / WebCoreSupport / ChromeClientQt.cpp
1 /*
2  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
4  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "ChromeClientQt.h"
32
33 #include "ApplicationCacheStorage.h"
34 #include "DatabaseTracker.h"
35 #include "FileChooser.h"
36 #include "Frame.h"
37 #include "FrameLoadRequest.h"
38 #include "FrameLoader.h"
39 #include "FrameLoaderClientQt.h"
40 #include "FrameView.h"
41 #include "Geolocation.h"
42 #if USE(ACCELERATED_COMPOSITING)
43 #include "GraphicsLayer.h"
44 #endif
45 #include "HitTestResult.h"
46 #include "Icon.h"
47 #include "NavigationAction.h"
48 #include "NetworkingContext.h"
49 #include "NotImplemented.h"
50 #include "NotificationPresenterClientQt.h"
51 #include "PageClientQt.h"
52 #include "PopupMenuQt.h"
53 #if defined(Q_WS_MAEMO_5)
54 #include "QtMaemoWebPopup.h"
55 #else
56 #include "QtFallbackWebPopup.h"
57 #endif
58 #include "QWebPageClient.h"
59 #include "ScrollbarTheme.h"
60 #include "SearchPopupMenuQt.h"
61 #include "SecurityOrigin.h"
62 #include "ViewportArguments.h"
63 #include "WindowFeatures.h"
64
65 #include "qgraphicswebview.h"
66 #include "qwebframe_p.h"
67 #include "qwebpage.h"
68 #include "qwebpage_p.h"
69 #include "qwebsecurityorigin.h"
70 #include "qwebsecurityorigin_p.h"
71 #include "qwebview.h"
72 #include <qdebug.h>
73 #include <qeventloop.h>
74 #include <qtextdocument.h>
75 #include <qtooltip.h>
76 #include <wtf/OwnPtr.h>
77
78 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
79 #include "FullScreenVideoQt.h"
80 #include "HTMLMediaElement.h"
81 #include "HTMLNames.h"
82 #include "HTMLVideoElement.h"
83 #include "MediaPlayerPrivateQt.h"
84 #endif
85
86 namespace WebCore {
87
88 bool ChromeClientQt::dumpVisitedLinksCallbacks = false;
89
90 ChromeClientQt::ChromeClientQt(QWebPage* webPage)
91     : m_webPage(webPage)
92     , m_eventLoop(0)
93 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
94     , m_fullScreenVideo(0)
95 #endif
96 {
97     toolBarsVisible = statusBarVisible = menuBarVisible = true;
98 }
99
100 ChromeClientQt::~ChromeClientQt()
101 {
102     if (m_eventLoop)
103         m_eventLoop->exit();
104
105 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
106     delete m_fullScreenVideo;
107 #endif
108 }
109
110 void ChromeClientQt::setWindowRect(const FloatRect& rect)
111 {
112     if (!m_webPage)
113         return;
114     emit m_webPage->geometryChangeRequested(QRect(qRound(rect.x()), qRound(rect.y()),
115                             qRound(rect.width()), qRound(rect.height())));
116 }
117
118 /*!
119     windowRect represents the rect of the Window, including all interface elements
120     like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
121     by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
122 */
123 FloatRect ChromeClientQt::windowRect()
124 {
125     if (!platformPageClient())
126         return FloatRect();
127     return platformPageClient()->windowRect();
128 }
129
130 FloatRect ChromeClientQt::pageRect()
131 {
132     if (!m_webPage)
133         return FloatRect();
134     return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize()));
135 }
136
137 float ChromeClientQt::scaleFactor()
138 {
139     if (!m_webPage)
140         return 1;
141     return m_webPage->d->pixelRatio;
142 }
143
144 void ChromeClientQt::focus()
145 {
146     if (!m_webPage)
147         return;
148     QWidget* view = m_webPage->view();
149     if (!view)
150         return;
151
152     view->setFocus();
153 }
154
155
156 void ChromeClientQt::unfocus()
157 {
158     if (!m_webPage)
159         return;
160     QWidget* view = m_webPage->view();
161     if (!view)
162         return;
163     view->clearFocus();
164 }
165
166 bool ChromeClientQt::canTakeFocus(FocusDirection)
167 {
168     // This is called when cycling through links/focusable objects and we
169     // reach the last focusable object. Then we want to claim that we can
170     // take the focus to avoid wrapping.
171     return true;
172 }
173
174 void ChromeClientQt::takeFocus(FocusDirection)
175 {
176     // don't do anything. This is only called when cycling to links/focusable objects,
177     // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
178     // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
179     // here.
180 }
181
182
183 void ChromeClientQt::focusedNodeChanged(Node*)
184 {
185 }
186
187 void ChromeClientQt::focusedFrameChanged(Frame*)
188 {
189 }
190
191 Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
192 {
193     QWebPage* newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
194     if (!newPage)
195         return 0;
196
197     // A call to QWebPage::mainFrame() implicitly creates the main frame.
198     // Make sure it exists, as WebCore expects it when returning from this call.
199     newPage->mainFrame();
200     return newPage->d->page;
201 }
202
203 void ChromeClientQt::show()
204 {
205     if (!m_webPage)
206         return;
207     QWidget* view = m_webPage->view();
208     if (!view)
209         return;
210     view->window()->show();
211 }
212
213
214 bool ChromeClientQt::canRunModal()
215 {
216     return true;
217 }
218
219
220 void ChromeClientQt::runModal()
221 {
222     m_eventLoop = new QEventLoop();
223     QEventLoop* eventLoop = m_eventLoop;
224     m_eventLoop->exec();
225     delete eventLoop;
226 }
227
228
229 void ChromeClientQt::setToolbarsVisible(bool visible)
230 {
231     toolBarsVisible = visible;
232     emit m_webPage->toolBarVisibilityChangeRequested(visible);
233 }
234
235
236 bool ChromeClientQt::toolbarsVisible()
237 {
238     return toolBarsVisible;
239 }
240
241
242 void ChromeClientQt::setStatusbarVisible(bool visible)
243 {
244     emit m_webPage->statusBarVisibilityChangeRequested(visible);
245     statusBarVisible = visible;
246 }
247
248
249 bool ChromeClientQt::statusbarVisible()
250 {
251     return statusBarVisible;
252 }
253
254
255 void ChromeClientQt::setScrollbarsVisible(bool)
256 {
257     notImplemented();
258 }
259
260
261 bool ChromeClientQt::scrollbarsVisible()
262 {
263     notImplemented();
264     return true;
265 }
266
267
268 void ChromeClientQt::setMenubarVisible(bool visible)
269 {
270     menuBarVisible = visible;
271     emit m_webPage->menuBarVisibilityChangeRequested(visible);
272 }
273
274 bool ChromeClientQt::menubarVisible()
275 {
276     return menuBarVisible;
277 }
278
279 void ChromeClientQt::setResizable(bool)
280 {
281     notImplemented();
282 }
283
284 void ChromeClientQt::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
285                                          unsigned int lineNumber, const String& sourceID)
286 {
287     QString x = message;
288     QString y = sourceID;
289     m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
290 }
291
292 void ChromeClientQt::chromeDestroyed()
293 {
294     delete this;
295 }
296
297 bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
298 {
299     return true;
300 }
301
302 bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
303 {
304     return runJavaScriptConfirm(frame, message);
305 }
306
307 void ChromeClientQt::closeWindowSoon()
308 {
309     m_webPage->d->page->setGroupName(String());
310     m_webPage->mainFrame()->d->frame->loader()->stopAllLoaders();
311     emit m_webPage->windowCloseRequested();
312 }
313
314 void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg)
315 {
316     QString x = msg;
317     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
318     m_webPage->javaScriptAlert(webFrame, x);
319 }
320
321 bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg)
322 {
323     QString x = msg;
324     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
325     return m_webPage->javaScriptConfirm(webFrame, x);
326 }
327
328 bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result)
329 {
330     QString x = result;
331     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
332     bool rc = m_webPage->javaScriptPrompt(webFrame, (QString)message, (QString)defaultValue, &x);
333
334     // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty
335     // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914.
336     if (rc && x.isNull())
337         result = String("");
338     else
339         result = x;
340
341     return rc;
342 }
343
344 void ChromeClientQt::setStatusbarText(const String& msg)
345 {
346     QString x = msg;
347     emit m_webPage->statusBarMessage(x);
348 }
349
350 bool ChromeClientQt::shouldInterruptJavaScript()
351 {
352     bool shouldInterrupt = false;
353     QMetaObject::invokeMethod(m_webPage, "shouldInterruptJavaScript", Qt::DirectConnection, Q_RETURN_ARG(bool, shouldInterrupt));
354     return shouldInterrupt;
355 }
356
357 bool ChromeClientQt::tabsToLinks() const
358 {
359     return m_webPage->settings()->testAttribute(QWebSettings::LinksIncludedInFocusChain);
360 }
361
362 IntRect ChromeClientQt::windowResizerRect() const
363 {
364 #if defined(Q_WS_MAC)
365     if (!m_webPage)
366         return IntRect();
367
368     QWebPageClient* pageClient = platformPageClient();
369     if (!pageClient)
370         return IntRect();
371
372     QWidget* ownerWidget = pageClient->ownerWidget();
373     if (!ownerWidget)
374         return IntRect();
375
376     QWidget* topLevelWidget = ownerWidget->window();
377     QRect topLevelGeometry(topLevelWidget->geometry());
378
379     // There's no API in Qt to query for the size of the resizer, so we assume
380     // it has the same width and height as the scrollbar thickness.
381     int scollbarThickness = ScrollbarTheme::nativeTheme()->scrollbarThickness();
382
383     // There's no API in Qt to query for the position of the resizer. Sometimes
384     // it's drawn by the system, and sometimes it's a QSizeGrip. For RTL locales
385     // it might even be on the lower left side of the window, but in WebKit we
386     // always draw scrollbars on the right hand side, so we assume this to be the
387     // location when computing the resize rect to reserve for WebKit.
388     QPoint resizeCornerTopLeft = ownerWidget->mapFrom(topLevelWidget,
389             QPoint(topLevelGeometry.width(), topLevelGeometry.height())
390             - QPoint(scollbarThickness, scollbarThickness));
391
392     QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness));
393     return resizeCornerRect.intersected(pageClient->geometryRelativeToOwnerWidget());
394 #else
395     return IntRect();
396 #endif
397 }
398
399 void ChromeClientQt::invalidateWindow(const IntRect&, bool)
400 {
401     notImplemented();
402 }
403
404 void ChromeClientQt::invalidateContentsAndWindow(const IntRect& windowRect, bool immediate)
405 {
406     // No double buffer, so only update the QWidget if content changed.
407     if (platformPageClient()) {
408         QRect rect(windowRect);
409         rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize()));
410         if (!rect.isEmpty())
411             platformPageClient()->update(rect);
412     }
413     emit m_webPage->repaintRequested(windowRect);
414
415     // FIXME: There is no "immediate" support for window painting.  This should be done always whenever the flag
416     // is set.
417 }
418
419 void ChromeClientQt::invalidateContentsForSlowScroll(const IntRect& windowRect, bool immediate)
420 {
421     invalidateContentsAndWindow(windowRect, immediate);
422 }
423
424 void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&)
425 {
426     if (platformPageClient())
427         platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect);
428     emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect);
429 }
430
431 #if ENABLE(TILED_BACKING_STORE)
432 void ChromeClientQt::delegatedScrollRequested(const IntSize& delta)
433 {
434     emit m_webPage->scrollRequested(delta.width(), delta.height(), QRect(QPoint(0, 0), m_webPage->viewportSize()));
435 }
436 #endif
437
438 IntRect ChromeClientQt::windowToScreen(const IntRect& rect) const
439 {
440     QWebPageClient* pageClient = platformPageClient();
441     if (!pageClient)
442         return rect;
443
444     QWidget* ownerWidget = pageClient->ownerWidget();
445     if (!ownerWidget)
446        return rect;
447
448     QRect screenRect(rect);
449     screenRect.translate(ownerWidget->mapToGlobal(QPoint(0, 0)));
450
451     return screenRect;
452 }
453
454 IntPoint ChromeClientQt::screenToWindow(const IntPoint& point) const
455 {
456     QWebPageClient* pageClient = platformPageClient();
457     if (!pageClient)
458         return point;
459
460     QWidget* ownerWidget = pageClient->ownerWidget();
461     if (!ownerWidget)
462         return point;
463
464     return ownerWidget->mapFromGlobal(point);
465 }
466
467 PlatformPageClient ChromeClientQt::platformPageClient() const
468 {
469     return m_webPage->d->client.get();
470 }
471
472 void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const
473 {
474     if (frame->loader()->networkingContext())
475         QWebFramePrivate::kit(frame)->contentsSizeChanged(size);
476 }
477
478 void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
479 {
480     TextDirection dir;
481     if (result.absoluteLinkURL() != lastHoverURL
482         || result.title(dir) != lastHoverTitle
483         || result.textContent() != lastHoverContent) {
484         lastHoverURL = result.absoluteLinkURL();
485         lastHoverTitle = result.title(dir);
486         lastHoverContent = result.textContent();
487         emit m_webPage->linkHovered(lastHoverURL.prettyURL(),
488                 lastHoverTitle, lastHoverContent);
489     }
490 }
491
492 void ChromeClientQt::setToolTip(const String &tip, TextDirection)
493 {
494 #ifndef QT_NO_TOOLTIP
495     QWidget* view = m_webPage->view();
496     if (!view)
497         return;
498
499     if (tip.isEmpty()) {
500         view->setToolTip(QString());
501         QToolTip::hideText();
502     } else {
503         QString dtip = QLatin1String("<p>") + Qt::escape(tip) + QLatin1String("</p>");
504         view->setToolTip(dtip);
505     }
506 #else
507     Q_UNUSED(tip);
508 #endif
509 }
510
511 void ChromeClientQt::print(Frame* frame)
512 {
513     emit m_webPage->printRequested(QWebFramePrivate::kit(frame));
514 }
515
516 #if ENABLE(DATABASE)
517 void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseName)
518 {
519     quint64 quota = QWebSettings::offlineStorageDefaultQuota();
520
521     if (!DatabaseTracker::tracker().hasEntryForOrigin(frame->document()->securityOrigin()))
522         DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), quota);
523
524     emit m_webPage->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
525 }
526 #endif
527
528 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
529 void ChromeClientQt::reachedMaxAppCacheSize(int64_t)
530 {
531     // FIXME: Free some space.
532     notImplemented();
533 }
534
535 void ChromeClientQt::reachedApplicationCacheOriginQuota(SecurityOrigin* origin)
536 {
537     int64_t quota;
538     quint64 defaultOriginQuota = WebCore::cacheStorage().defaultOriginQuota();
539
540     QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(origin);
541     QWebSecurityOrigin* securityOrigin = new QWebSecurityOrigin(priv);
542
543     if (!WebCore::cacheStorage().quotaForOrigin(origin, quota))
544        WebCore::cacheStorage().storeUpdatedQuotaForOrigin(origin, defaultOriginQuota);
545
546     emit m_webPage->applicationCacheQuotaExceeded(securityOrigin, defaultOriginQuota);
547 }
548 #endif
549
550 #if ENABLE(NOTIFICATIONS)
551 NotificationPresenter* ChromeClientQt::notificationPresenter() const
552 {
553     return NotificationPresenterClientQt::notificationPresenter();
554 }
555 #endif
556
557 void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
558 {
559     RefPtr<FileChooser> fileChooser = prpFileChooser;
560     bool supportMulti = m_webPage->supportsExtension(QWebPage::ChooseMultipleFilesExtension);
561
562     if (fileChooser->allowsMultipleFiles() && supportMulti) {
563         QWebPage::ChooseMultipleFilesExtensionOption option;
564         option.parentFrame = QWebFramePrivate::kit(frame);
565
566         if (!fileChooser->filenames().isEmpty())
567             for (unsigned i = 0; i < fileChooser->filenames().size(); ++i)
568                 option.suggestedFileNames += fileChooser->filenames()[i];
569
570         QWebPage::ChooseMultipleFilesExtensionReturn output;
571         m_webPage->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);
572
573         if (!output.fileNames.isEmpty()) {
574             Vector<String> names;
575             for (int i = 0; i < output.fileNames.count(); ++i)
576                 names.append(output.fileNames.at(i));
577             fileChooser->chooseFiles(names);
578         }
579     } else {
580         QString suggestedFile;
581         if (!fileChooser->filenames().isEmpty())
582             suggestedFile = fileChooser->filenames()[0];
583         QString file = m_webPage->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
584         if (!file.isEmpty())
585             fileChooser->chooseFile(file);
586     }
587 }
588
589 void ChromeClientQt::chooseIconForFiles(const Vector<String>& filenames, FileChooser* chooser)
590 {
591     chooser->iconLoaded(Icon::createIconForFiles(filenames));
592 }
593
594 void ChromeClientQt::setCursor(const Cursor& cursor)
595 {
596 #ifndef QT_NO_CURSOR
597     QWebPageClient* pageClient = platformPageClient();
598     if (!pageClient)
599         return;
600     pageClient->setCursor(*cursor.platformCursor());
601 #else
602     UNUSED_PARAM(cursor);
603 #endif
604 }
605
606
607 #if USE(ACCELERATED_COMPOSITING)
608 void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
609 {
610     if (platformPageClient())
611         platformPageClient()->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0);
612 }
613
614 void ChromeClientQt::setNeedsOneShotDrawingSynchronization()
615 {
616     // we want the layers to synchronize next time we update the screen anyway
617     if (platformPageClient())
618         platformPageClient()->markForSync(false);
619 }
620
621 void ChromeClientQt::scheduleCompositingLayerSync()
622 {
623     // we want the layers to synchronize ASAP
624     if (platformPageClient())
625         platformPageClient()->markForSync(true);
626 }
627
628 ChromeClient::CompositingTriggerFlags ChromeClientQt::allowedCompositingTriggers() const
629 {
630     if (platformPageClient() && platformPageClient()->allowsAcceleratedCompositing())
631         return AllTriggers;
632
633     return 0;
634 }
635
636 #endif
637
638 #if ENABLE(TILED_BACKING_STORE)
639 IntRect ChromeClientQt::visibleRectForTiledBackingStore() const
640 {
641     if (!platformPageClient() || !m_webPage)
642         return IntRect();
643
644     if (!platformPageClient()->viewResizesToContentsEnabled())
645         return QRect(m_webPage->mainFrame()->scrollPosition(), m_webPage->mainFrame()->geometry().size());
646
647     return enclosingIntRect(FloatRect(platformPageClient()->graphicsItemVisibleRect()));
648 }
649 #endif
650
651 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
652 FullScreenVideoQt* ChromeClientQt::fullScreenVideo()
653 {
654     if (!m_fullScreenVideo)
655         m_fullScreenVideo = new FullScreenVideoQt(this);
656     return m_fullScreenVideo;
657 }
658
659 bool ChromeClientQt::supportsFullscreenForNode(const Node* node)
660 {
661     ASSERT(node);
662     return node->hasTagName(HTMLNames::videoTag) && fullScreenVideo()->isValid();
663 }
664
665 bool ChromeClientQt::requiresFullscreenForVideoPlayback()
666 {
667     return fullScreenVideo()->requiresFullScreenForVideoPlayback();
668 }
669
670 void ChromeClientQt::enterFullscreenForNode(Node* node)
671 {
672     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
673
674     HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(node);
675     PlatformMedia platformMedia = videoElement->platformMedia();
676
677     ASSERT(platformMedia.type == PlatformMedia::QtMediaPlayerType);
678     if (platformMedia.type != PlatformMedia::QtMediaPlayerType)
679         return;
680
681     fullScreenVideo()->enterFullScreenForNode(node);
682 }
683
684 void ChromeClientQt::exitFullscreenForNode(Node* node)
685 {
686     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
687
688     HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(node);
689     PlatformMedia platformMedia = videoElement->platformMedia();
690
691     ASSERT(platformMedia.type == PlatformMedia::QtMediaPlayerType);
692     if (platformMedia.type != PlatformMedia::QtMediaPlayerType)
693         return;
694
695     fullScreenVideo()->exitFullScreenForNode(node);
696
697 #endif
698
699 QWebSelectMethod* ChromeClientQt::createSelectPopup() const
700 {
701     QWebSelectMethod* result = m_platformPlugin.createSelectInputMethod();
702     if (result)
703         return result;
704
705 #if defined(Q_WS_MAEMO_5)
706     return new QtMaemoWebPopup;
707 #elif !defined(QT_NO_COMBOBOX)
708     return new QtFallbackWebPopup(this);
709 #else
710     return 0;
711 #endif
712 }
713
714 void ChromeClientQt::dispatchViewportDataDidChange(const ViewportArguments&) const
715 {
716     emit m_webPage->viewportChangeRequested();
717 }
718
719 bool ChromeClientQt::selectItemWritingDirectionIsNatural()
720 {
721     return false;
722 }
723
724 bool ChromeClientQt::selectItemAlignmentFollowsMenuWritingDirection()
725 {
726     return false;
727 }
728
729 PassRefPtr<PopupMenu> ChromeClientQt::createPopupMenu(PopupMenuClient* client) const
730 {
731     return adoptRef(new PopupMenuQt(client, this));
732 }
733
734 PassRefPtr<SearchPopupMenu> ChromeClientQt::createSearchPopupMenu(PopupMenuClient* client) const
735 {
736     return adoptRef(new SearchPopupMenuQt(createPopupMenu(client)));
737 }
738
739 void ChromeClientQt::populateVisitedLinks()
740 {
741     // We don't need to do anything here because history is tied to QWebPage rather than stored
742     // in a separate database
743     if (dumpVisitedLinksCallbacks) {
744         printf("Asked to populate visited links for WebView \"%s\"\n",
745                 qPrintable(m_webPage->mainFrame()->url().toString()));
746     }
747 }
748
749 } // namespace WebCore