acb136a38ae181cfcc96c061eb4c24216f39b963
[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 "GeolocationPermissionClientQt.h"
46 #include "HitTestResult.h"
47 #include "Icon.h"
48 #include "NavigationAction.h"
49 #include "NetworkingContext.h"
50 #include "NotImplemented.h"
51 #include "NotificationPresenterClientQt.h"
52 #include "PageClientQt.h"
53 #include "PopupMenuQt.h"
54 #if defined(Q_WS_MAEMO_5)
55 #include "QtMaemoWebPopup.h"
56 #else
57 #include "QtFallbackWebPopup.h"
58 #endif
59 #include "QWebPageClient.h"
60 #include "ScrollbarTheme.h"
61 #include "SearchPopupMenuQt.h"
62 #include "SecurityOrigin.h"
63 #include "ViewportArguments.h"
64 #include "WindowFeatures.h"
65
66 #include "qgraphicswebview.h"
67 #include "qwebframe_p.h"
68 #include "qwebpage.h"
69 #include "qwebpage_p.h"
70 #include "qwebsecurityorigin.h"
71 #include "qwebsecurityorigin_p.h"
72 #include "qwebview.h"
73 #include <qdebug.h>
74 #include <qeventloop.h>
75 #include <qtextdocument.h>
76 #include <qtooltip.h>
77 #include <wtf/OwnPtr.h>
78
79 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
80 #include "FullScreenVideoQt.h"
81 #include "HTMLMediaElement.h"
82 #include "HTMLNames.h"
83 #include "HTMLVideoElement.h"
84 #include "MediaPlayerPrivateQt.h"
85 #endif
86
87 namespace WebCore {
88
89 bool ChromeClientQt::dumpVisitedLinksCallbacks = false;
90
91 ChromeClientQt::ChromeClientQt(QWebPage* webPage)
92     : m_webPage(webPage)
93     , m_eventLoop(0)
94 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
95     , m_fullScreenVideo(0)
96 #endif
97 {
98     toolBarsVisible = statusBarVisible = menuBarVisible = true;
99 }
100
101 ChromeClientQt::~ChromeClientQt()
102 {
103     if (m_eventLoop)
104         m_eventLoop->exit();
105
106 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
107     delete m_fullScreenVideo;
108 #endif
109 }
110
111 void ChromeClientQt::setWindowRect(const FloatRect& rect)
112 {
113     if (!m_webPage)
114         return;
115     emit m_webPage->geometryChangeRequested(QRect(qRound(rect.x()), qRound(rect.y()),
116                             qRound(rect.width()), qRound(rect.height())));
117 }
118
119 /*!
120     windowRect represents the rect of the Window, including all interface elements
121     like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
122     by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
123 */
124 FloatRect ChromeClientQt::windowRect()
125 {
126     if (!platformPageClient())
127         return FloatRect();
128     return platformPageClient()->windowRect();
129 }
130
131 FloatRect ChromeClientQt::pageRect()
132 {
133     if (!m_webPage)
134         return FloatRect();
135     return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize()));
136 }
137
138 float ChromeClientQt::scaleFactor()
139 {
140     if (!m_webPage)
141         return 1;
142     return m_webPage->d->pixelRatio;
143 }
144
145 void ChromeClientQt::focus()
146 {
147     if (!m_webPage)
148         return;
149     QWidget* view = m_webPage->view();
150     if (!view)
151         return;
152
153     view->setFocus();
154 }
155
156
157 void ChromeClientQt::unfocus()
158 {
159     if (!m_webPage)
160         return;
161     QWidget* view = m_webPage->view();
162     if (!view)
163         return;
164     view->clearFocus();
165 }
166
167 bool ChromeClientQt::canTakeFocus(FocusDirection)
168 {
169     // This is called when cycling through links/focusable objects and we
170     // reach the last focusable object. Then we want to claim that we can
171     // take the focus to avoid wrapping.
172     return true;
173 }
174
175 void ChromeClientQt::takeFocus(FocusDirection)
176 {
177     // don't do anything. This is only called when cycling to links/focusable objects,
178     // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
179     // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
180     // here.
181 }
182
183
184 void ChromeClientQt::focusedNodeChanged(Node*)
185 {
186 }
187
188 void ChromeClientQt::focusedFrameChanged(Frame*)
189 {
190 }
191
192 Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
193 {
194     QWebPage* newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
195     if (!newPage)
196         return 0;
197
198     // A call to QWebPage::mainFrame() implicitly creates the main frame.
199     // Make sure it exists, as WebCore expects it when returning from this call.
200     newPage->mainFrame();
201     return newPage->d->page;
202 }
203
204 void ChromeClientQt::show()
205 {
206     if (!m_webPage)
207         return;
208     QWidget* view = m_webPage->view();
209     if (!view)
210         return;
211     view->window()->show();
212 }
213
214
215 bool ChromeClientQt::canRunModal()
216 {
217     return true;
218 }
219
220
221 void ChromeClientQt::runModal()
222 {
223     m_eventLoop = new QEventLoop();
224     QEventLoop* eventLoop = m_eventLoop;
225     m_eventLoop->exec();
226     delete eventLoop;
227 }
228
229
230 void ChromeClientQt::setToolbarsVisible(bool visible)
231 {
232     toolBarsVisible = visible;
233     emit m_webPage->toolBarVisibilityChangeRequested(visible);
234 }
235
236
237 bool ChromeClientQt::toolbarsVisible()
238 {
239     return toolBarsVisible;
240 }
241
242
243 void ChromeClientQt::setStatusbarVisible(bool visible)
244 {
245     emit m_webPage->statusBarVisibilityChangeRequested(visible);
246     statusBarVisible = visible;
247 }
248
249
250 bool ChromeClientQt::statusbarVisible()
251 {
252     return statusBarVisible;
253 }
254
255
256 void ChromeClientQt::setScrollbarsVisible(bool)
257 {
258     notImplemented();
259 }
260
261
262 bool ChromeClientQt::scrollbarsVisible()
263 {
264     notImplemented();
265     return true;
266 }
267
268
269 void ChromeClientQt::setMenubarVisible(bool visible)
270 {
271     menuBarVisible = visible;
272     emit m_webPage->menuBarVisibilityChangeRequested(visible);
273 }
274
275 bool ChromeClientQt::menubarVisible()
276 {
277     return menuBarVisible;
278 }
279
280 void ChromeClientQt::setResizable(bool)
281 {
282     notImplemented();
283 }
284
285 void ChromeClientQt::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
286                                          unsigned int lineNumber, const String& sourceID)
287 {
288     QString x = message;
289     QString y = sourceID;
290     m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
291 }
292
293 void ChromeClientQt::chromeDestroyed()
294 {
295     delete this;
296 }
297
298 bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
299 {
300     return true;
301 }
302
303 bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
304 {
305     return runJavaScriptConfirm(frame, message);
306 }
307
308 void ChromeClientQt::closeWindowSoon()
309 {
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 void ChromeClientQt::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
607 {
608 #if ENABLE(GEOLOCATION)
609     QWebFrame* webFrame = QWebFramePrivate::kit(frame);
610     GeolocationPermissionClientQt::geolocationPermissionClient()->requestGeolocationPermissionForFrame(webFrame, geolocation);
611 #endif
612 }
613
614 void ChromeClientQt::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation)
615 {
616 #if ENABLE(GEOLOCATION)
617     QWebFrame* webFrame = QWebFramePrivate::kit(frame);
618     GeolocationPermissionClientQt::geolocationPermissionClient()->cancelGeolocationPermissionRequestForFrame(webFrame, geolocation);
619 #endif
620 }
621
622 #if USE(ACCELERATED_COMPOSITING)
623 void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
624 {
625     if (platformPageClient())
626         platformPageClient()->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0);
627 }
628
629 void ChromeClientQt::setNeedsOneShotDrawingSynchronization()
630 {
631     // we want the layers to synchronize next time we update the screen anyway
632     if (platformPageClient())
633         platformPageClient()->markForSync(false);
634 }
635
636 void ChromeClientQt::scheduleCompositingLayerSync()
637 {
638     // we want the layers to synchronize ASAP
639     if (platformPageClient())
640         platformPageClient()->markForSync(true);
641 }
642
643 ChromeClient::CompositingTriggerFlags ChromeClientQt::allowedCompositingTriggers() const
644 {
645     if (platformPageClient() && platformPageClient()->allowsAcceleratedCompositing())
646         return AllTriggers;
647
648     return 0;
649 }
650
651 #endif
652
653 #if ENABLE(TILED_BACKING_STORE)
654 IntRect ChromeClientQt::visibleRectForTiledBackingStore() const
655 {
656     if (!platformPageClient() || !m_webPage)
657         return IntRect();
658
659     if (!platformPageClient()->viewResizesToContentsEnabled())
660         return QRect(m_webPage->mainFrame()->scrollPosition(), m_webPage->mainFrame()->geometry().size());
661
662     return enclosingIntRect(FloatRect(platformPageClient()->graphicsItemVisibleRect()));
663 }
664 #endif
665
666 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
667 FullScreenVideoQt* ChromeClientQt::fullScreenVideo()
668 {
669     if (!m_fullScreenVideo)
670         m_fullScreenVideo = new FullScreenVideoQt(this);
671     return m_fullScreenVideo;
672 }
673
674 bool ChromeClientQt::supportsFullscreenForNode(const Node* node)
675 {
676     ASSERT(node);
677     return node->hasTagName(HTMLNames::videoTag) && fullScreenVideo()->isValid();
678 }
679
680 bool ChromeClientQt::requiresFullscreenForVideoPlayback()
681 {
682     return fullScreenVideo()->requiresFullScreenForVideoPlayback();
683 }
684
685 void ChromeClientQt::enterFullscreenForNode(Node* node)
686 {
687     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
688
689     HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(node);
690     PlatformMedia platformMedia = videoElement->platformMedia();
691
692     ASSERT(platformMedia.type == PlatformMedia::QtMediaPlayerType);
693     if (platformMedia.type != PlatformMedia::QtMediaPlayerType)
694         return;
695
696     fullScreenVideo()->enterFullScreenForNode(node);
697 }
698
699 void ChromeClientQt::exitFullscreenForNode(Node* node)
700 {
701     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
702
703     HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(node);
704     PlatformMedia platformMedia = videoElement->platformMedia();
705
706     ASSERT(platformMedia.type == PlatformMedia::QtMediaPlayerType);
707     if (platformMedia.type != PlatformMedia::QtMediaPlayerType)
708         return;
709
710     fullScreenVideo()->exitFullScreenForNode(node);
711
712 #endif
713
714 QWebSelectMethod* ChromeClientQt::createSelectPopup() const
715 {
716     QWebSelectMethod* result = m_platformPlugin.createSelectInputMethod();
717     if (result)
718         return result;
719
720 #if defined(Q_WS_MAEMO_5)
721     return new QtMaemoWebPopup;
722 #elif !defined(QT_NO_COMBOBOX)
723     return new QtFallbackWebPopup(this);
724 #else
725     return 0;
726 #endif
727 }
728
729 void ChromeClientQt::dispatchViewportDataDidChange(const ViewportArguments&) const
730 {
731     emit m_webPage->viewportChangeRequested();
732 }
733
734 bool ChromeClientQt::selectItemWritingDirectionIsNatural()
735 {
736     return false;
737 }
738
739 PassRefPtr<PopupMenu> ChromeClientQt::createPopupMenu(PopupMenuClient* client) const
740 {
741     return adoptRef(new PopupMenuQt(client, this));
742 }
743
744 PassRefPtr<SearchPopupMenu> ChromeClientQt::createSearchPopupMenu(PopupMenuClient* client) const
745 {
746     return adoptRef(new SearchPopupMenuQt(createPopupMenu(client)));
747 }
748
749 void ChromeClientQt::populateVisitedLinks()
750 {
751     // We don't need to do anything here because history is tied to QWebPage rather than stored
752     // in a separate database
753     if (dumpVisitedLinksCallbacks) {
754         printf("Asked to populate visited links for WebView \"%s\"\n",
755                 qPrintable(m_webPage->mainFrame()->url().toString()));
756     }
757 }
758
759 } // namespace WebCore