eaaeb012f86d0a53110b579773f6d5b8c05d9342
[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 "ColorChooser.h"
35 #include "ColorChooserClient.h"
36 #include "DatabaseTracker.h"
37 #include "Document.h"
38 #include "FileChooser.h"
39 #include "FileIconLoader.h"
40 #include "Frame.h"
41 #include "FrameLoadRequest.h"
42 #include "FrameLoader.h"
43 #include "FrameLoaderClientQt.h"
44 #include "FrameView.h"
45 #include "Geolocation.h"
46 #if USE(ACCELERATED_COMPOSITING)
47 #include "GraphicsLayer.h"
48 #endif
49 #include "HTMLFormElement.h"
50 #include "HitTestResult.h"
51 #include "Icon.h"
52 #include "NavigationAction.h"
53 #include "NetworkingContext.h"
54 #include "NotImplemented.h"
55 #include "Page.h"
56 #include "PageClientQt.h"
57 #include "PopupMenuQt.h"
58 #include "QtFallbackWebPopup.h"
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 <qabstractanimation.h>
74 #include <qdebug.h>
75 #include <qeventloop.h>
76 #include <qtooltip.h>
77 #include <wtf/OwnPtr.h>
78
79 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
80 #include "FullScreenVideoQt.h"
81 #include "HTMLMediaElement.h"
82 #include "HTMLNames.h"
83 #include "HTMLVideoElement.h"
84 #if USE(QT_MULTIMEDIA)
85 #include "MediaPlayerPrivateQt.h"
86 #endif
87 #endif
88
89 namespace WebCore {
90
91 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
92 class RefreshAnimation : public QAbstractAnimation {
93 public:
94     RefreshAnimation(ChromeClientQt* chromeClient)
95         : QAbstractAnimation()
96         , m_chromeClient(chromeClient)
97         , m_animationScheduled(false)
98     { }
99
100     virtual int duration() const { return -1; }
101
102     void scheduleAnimation()
103     {
104         m_animationScheduled = true;
105         if (state() != QAbstractAnimation::Running)
106             QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
107     }
108
109 protected:
110     virtual void updateCurrentTime(int currentTime)
111     {
112         UNUSED_PARAM(currentTime);
113         if (m_animationScheduled) {
114             m_animationScheduled = false;
115             m_chromeClient->serviceScriptedAnimations();
116         } else
117             stop();
118     }
119 private:
120     ChromeClientQt* m_chromeClient;
121     bool m_animationScheduled;
122 };
123 #endif
124
125 bool ChromeClientQt::dumpVisitedLinksCallbacks = false;
126
127 ChromeClientQt::ChromeClientQt(QWebPage* webPage)
128     : m_webPage(webPage)
129     , m_eventLoop(0)
130 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
131     , m_fullScreenVideo(0)
132 #endif
133 {
134     toolBarsVisible = statusBarVisible = menuBarVisible = true;
135 }
136
137 ChromeClientQt::~ChromeClientQt()
138 {
139     if (m_eventLoop)
140         m_eventLoop->exit();
141
142 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
143     delete m_fullScreenVideo;
144 #endif
145 }
146
147 void ChromeClientQt::setWindowRect(const FloatRect& rect)
148 {
149     if (!m_webPage)
150         return;
151     emit m_webPage->geometryChangeRequested(QRect(qRound(rect.x()), qRound(rect.y()),
152                             qRound(rect.width()), qRound(rect.height())));
153 }
154
155 /*!
156     windowRect represents the rect of the Window, including all interface elements
157     like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
158     by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
159 */
160 FloatRect ChromeClientQt::windowRect()
161 {
162     if (!platformPageClient())
163         return FloatRect();
164     return platformPageClient()->windowRect();
165 }
166
167 bool ChromeClientQt::allowsAcceleratedCompositing() const
168 {
169     if (!platformPageClient())
170         return false;
171     return platformPageClient()->allowsAcceleratedCompositing();
172 }
173
174 FloatRect ChromeClientQt::pageRect()
175 {
176     if (!m_webPage)
177         return FloatRect();
178     return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize()));
179 }
180
181 void ChromeClientQt::focus()
182 {
183     if (!m_webPage)
184         return;
185     QWidget* view = m_webPage->view();
186     if (!view)
187         return;
188
189     view->setFocus();
190 }
191
192
193 void ChromeClientQt::unfocus()
194 {
195     if (!m_webPage)
196         return;
197     QWidget* view = m_webPage->view();
198     if (!view)
199         return;
200     view->clearFocus();
201 }
202
203 bool ChromeClientQt::canTakeFocus(FocusDirection)
204 {
205     // This is called when cycling through links/focusable objects and we
206     // reach the last focusable object. Then we want to claim that we can
207     // take the focus to avoid wrapping.
208     return true;
209 }
210
211 void ChromeClientQt::takeFocus(FocusDirection)
212 {
213     // don't do anything. This is only called when cycling to links/focusable objects,
214     // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
215     // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
216     // here.
217 }
218
219
220 void ChromeClientQt::focusedNodeChanged(Node*)
221 {
222 }
223
224 void ChromeClientQt::focusedFrameChanged(Frame*)
225 {
226 }
227
228 Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
229 {
230     QWebPage* newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
231     if (!newPage)
232         return 0;
233
234     // A call to QWebPage::mainFrame() implicitly creates the main frame.
235     // Make sure it exists, as WebCore expects it when returning from this call.
236     newPage->mainFrame();
237     return newPage->d->page;
238 }
239
240 void ChromeClientQt::show()
241 {
242     if (!m_webPage)
243         return;
244     QWidget* view = m_webPage->view();
245     if (!view)
246         return;
247     view->window()->show();
248 }
249
250
251 bool ChromeClientQt::canRunModal()
252 {
253     return true;
254 }
255
256
257 void ChromeClientQt::runModal()
258 {
259     m_eventLoop = new QEventLoop();
260     QEventLoop* eventLoop = m_eventLoop;
261     m_eventLoop->exec();
262     delete eventLoop;
263 }
264
265
266 void ChromeClientQt::setToolbarsVisible(bool visible)
267 {
268     toolBarsVisible = visible;
269     emit m_webPage->toolBarVisibilityChangeRequested(visible);
270 }
271
272
273 bool ChromeClientQt::toolbarsVisible()
274 {
275     return toolBarsVisible;
276 }
277
278
279 void ChromeClientQt::setStatusbarVisible(bool visible)
280 {
281     emit m_webPage->statusBarVisibilityChangeRequested(visible);
282     statusBarVisible = visible;
283 }
284
285
286 bool ChromeClientQt::statusbarVisible()
287 {
288     return statusBarVisible;
289 }
290
291
292 void ChromeClientQt::setScrollbarsVisible(bool)
293 {
294     notImplemented();
295 }
296
297
298 bool ChromeClientQt::scrollbarsVisible()
299 {
300     notImplemented();
301     return true;
302 }
303
304
305 void ChromeClientQt::setMenubarVisible(bool visible)
306 {
307     menuBarVisible = visible;
308     emit m_webPage->menuBarVisibilityChangeRequested(visible);
309 }
310
311 bool ChromeClientQt::menubarVisible()
312 {
313     return menuBarVisible;
314 }
315
316 void ChromeClientQt::setResizable(bool)
317 {
318     notImplemented();
319 }
320
321 void ChromeClientQt::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
322                                          unsigned int lineNumber, const String& sourceID)
323 {
324     QString x = message;
325     QString y = sourceID;
326     m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
327 }
328
329 void ChromeClientQt::chromeDestroyed()
330 {
331     delete this;
332 }
333
334 bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
335 {
336     return true;
337 }
338
339 bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
340 {
341     return runJavaScriptConfirm(frame, message);
342 }
343
344 void ChromeClientQt::closeWindowSoon()
345 {
346     m_webPage->d->page->setGroupName(String());
347     m_webPage->mainFrame()->d->frame->loader()->stopAllLoaders();
348     emit m_webPage->windowCloseRequested();
349 }
350
351 void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg)
352 {
353     QString x = msg;
354     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
355     m_webPage->javaScriptAlert(webFrame, x);
356 }
357
358 bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg)
359 {
360     QString x = msg;
361     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
362     return m_webPage->javaScriptConfirm(webFrame, x);
363 }
364
365 bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result)
366 {
367     QString x = result;
368     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
369     bool rc = m_webPage->javaScriptPrompt(webFrame, (QString)message, (QString)defaultValue, &x);
370
371     // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty
372     // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914.
373     if (rc && x.isNull())
374         result = String("");
375     else
376         result = x;
377
378     return rc;
379 }
380
381 void ChromeClientQt::setStatusbarText(const String& msg)
382 {
383     QString x = msg;
384     emit m_webPage->statusBarMessage(x);
385 }
386
387 bool ChromeClientQt::shouldInterruptJavaScript()
388 {
389     bool shouldInterrupt = false;
390     QMetaObject::invokeMethod(m_webPage, "shouldInterruptJavaScript", Qt::DirectConnection, Q_RETURN_ARG(bool, shouldInterrupt));
391     return shouldInterrupt;
392 }
393
394 KeyboardUIMode ChromeClientQt::keyboardUIMode()
395 {
396     return m_webPage->settings()->testAttribute(QWebSettings::LinksIncludedInFocusChain)
397         ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
398 }
399
400 IntRect ChromeClientQt::windowResizerRect() const
401 {
402 #if defined(Q_WS_MAC)
403     if (!m_webPage)
404         return IntRect();
405
406     QWebPageClient* pageClient = platformPageClient();
407     if (!pageClient)
408         return IntRect();
409
410     QWidget* ownerWidget = pageClient->ownerWidget();
411     if (!ownerWidget)
412         return IntRect();
413
414     QWidget* topLevelWidget = ownerWidget->window();
415     QRect topLevelGeometry(topLevelWidget->geometry());
416
417     // There's no API in Qt to query for the size of the resizer, so we assume
418     // it has the same width and height as the scrollbar thickness.
419     int scollbarThickness = ScrollbarTheme::theme()->scrollbarThickness();
420
421     // There's no API in Qt to query for the position of the resizer. Sometimes
422     // it's drawn by the system, and sometimes it's a QSizeGrip. For RTL locales
423     // it might even be on the lower left side of the window, but in WebKit we
424     // always draw scrollbars on the right hand side, so we assume this to be the
425     // location when computing the resize rect to reserve for WebKit.
426     QPoint resizeCornerTopLeft = ownerWidget->mapFrom(topLevelWidget,
427             QPoint(topLevelGeometry.width(), topLevelGeometry.height())
428             - QPoint(scollbarThickness, scollbarThickness));
429
430     QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness));
431     return resizeCornerRect.intersected(pageClient->geometryRelativeToOwnerWidget());
432 #else
433     return IntRect();
434 #endif
435 }
436
437 void ChromeClientQt::invalidateRootView(const IntRect& windowRect, bool)
438 {
439 #if USE(TILED_BACKING_STORE)
440     if (platformPageClient()) {
441         WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(m_webPage->mainFrame())->tiledBackingStore();
442         if (!backingStore)
443             return;
444         backingStore->invalidate(windowRect);
445     }
446 #else
447     Q_UNUSED(windowRect);
448 #endif
449 }
450
451 void ChromeClientQt::invalidateContentsAndRootView(const IntRect& windowRect, bool immediate)
452 {
453     // No double buffer, so only update the QWidget if content changed.
454     if (platformPageClient()) {
455         QRect rect(windowRect);
456         rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize()));
457         if (!rect.isEmpty())
458             platformPageClient()->update(rect);
459     }
460     QMetaObject::invokeMethod(m_webPage, "repaintRequested", Qt::QueuedConnection, Q_ARG(QRect, windowRect));
461
462     // FIXME: There is no "immediate" support for window painting.  This should be done always whenever the flag
463     // is set.
464 }
465
466 void ChromeClientQt::invalidateContentsForSlowScroll(const IntRect& windowRect, bool immediate)
467 {
468     invalidateContentsAndRootView(windowRect, immediate);
469 }
470
471 void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&)
472 {
473     if (platformPageClient())
474         platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect);
475     emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect);
476 }
477
478 #if USE(TILED_BACKING_STORE)
479 void ChromeClientQt::delegatedScrollRequested(const IntPoint& point)
480 {
481     QPoint currentPosition(m_webPage->mainFrame()->scrollPosition());
482     emit m_webPage->scrollRequested(point.x() - currentPosition.x(), point.y() - currentPosition.y(), QRect(QPoint(0, 0), m_webPage->viewportSize()));
483 }
484 #endif
485
486 IntRect ChromeClientQt::rootViewToScreen(const IntRect& rect) const
487 {
488     QWebPageClient* pageClient = platformPageClient();
489     if (!pageClient)
490         return rect;
491
492     QWidget* ownerWidget = pageClient->ownerWidget();
493     if (!ownerWidget)
494        return rect;
495
496     QRect screenRect(rect);
497     screenRect.translate(ownerWidget->mapToGlobal(QPoint(0, 0)));
498
499     return screenRect;
500 }
501
502 IntPoint ChromeClientQt::screenToRootView(const IntPoint& point) const
503 {
504     QWebPageClient* pageClient = platformPageClient();
505     if (!pageClient)
506         return point;
507
508     QWidget* ownerWidget = pageClient->ownerWidget();
509     if (!ownerWidget)
510         return point;
511
512     return ownerWidget->mapFromGlobal(point);
513 }
514
515 PlatformPageClient ChromeClientQt::platformPageClient() const
516 {
517     return m_webPage->d->client.get();
518 }
519
520 void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const
521 {
522     if (frame->loader()->networkingContext())
523         QWebFramePrivate::kit(frame)->contentsSizeChanged(size);
524 }
525
526 void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
527 {
528     TextDirection dir;
529     if (result.absoluteLinkURL() != lastHoverURL
530         || result.title(dir) != lastHoverTitle
531         || result.textContent() != lastHoverContent) {
532         lastHoverURL = result.absoluteLinkURL();
533         lastHoverTitle = result.title(dir);
534         lastHoverContent = result.textContent();
535         emit m_webPage->linkHovered(lastHoverURL.string(),
536                 lastHoverTitle, lastHoverContent);
537     }
538 }
539
540 void ChromeClientQt::setToolTip(const String &tip, TextDirection)
541 {
542 #ifndef QT_NO_TOOLTIP
543     QWidget* view = m_webPage->view();
544     if (!view)
545         return;
546
547     if (tip.isEmpty()) {
548         view->setToolTip(QString());
549         QToolTip::hideText();
550     } else {
551         QString dtip = QLatin1String("<p>") + QString(tip).toHtmlEscaped() + QLatin1String("</p>");
552         view->setToolTip(dtip);
553     }
554 #else
555     Q_UNUSED(tip);
556 #endif
557 }
558
559 void ChromeClientQt::print(Frame* frame)
560 {
561     emit m_webPage->printRequested(QWebFramePrivate::kit(frame));
562 }
563
564 #if ENABLE(SQL_DATABASE)
565 void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseName)
566 {
567     quint64 quota = QWebSettings::offlineStorageDefaultQuota();
568
569     if (!DatabaseTracker::tracker().hasEntryForOrigin(frame->document()->securityOrigin()))
570         DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), quota);
571
572     emit m_webPage->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
573 }
574 #endif
575
576 void ChromeClientQt::reachedMaxAppCacheSize(int64_t)
577 {
578     // FIXME: Free some space.
579     notImplemented();
580 }
581
582 void ChromeClientQt::reachedApplicationCacheOriginQuota(SecurityOrigin* origin, int64_t totalSpaceNeeded)
583 {
584     int64_t quota;
585     quint64 defaultOriginQuota = WebCore::cacheStorage().defaultOriginQuota();
586
587     QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(origin);
588     QWebSecurityOrigin* securityOrigin = new QWebSecurityOrigin(priv);
589
590     if (!WebCore::cacheStorage().calculateQuotaForOrigin(origin, quota))
591        WebCore::cacheStorage().storeUpdatedQuotaForOrigin(origin, defaultOriginQuota);
592
593     emit m_webPage->applicationCacheQuotaExceeded(securityOrigin, defaultOriginQuota, static_cast<quint64>(totalSpaceNeeded));
594 }
595
596 #if ENABLE(INPUT_TYPE_COLOR)
597 PassOwnPtr<ColorChooser> ChromeClientQt::createColorChooser(ColorChooserClient* client, const Color& color)
598 {
599     const QColor selectedColor = m_webPage->d->colorSelectionRequested(QColor(color));
600     client->didChooseColor(selectedColor);
601     client->didEndChooser();
602     return nullptr;
603 }
604 #endif
605
606 void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
607 {
608     RefPtr<FileChooser> fileChooser = prpFileChooser;
609     bool supportMulti = m_webPage->supportsExtension(QWebPage::ChooseMultipleFilesExtension);
610
611     if (fileChooser->settings().allowsMultipleFiles && supportMulti) {
612         QWebPage::ChooseMultipleFilesExtensionOption option;
613         option.parentFrame = QWebFramePrivate::kit(frame);
614
615         if (!fileChooser->settings().selectedFiles.isEmpty())
616             for (unsigned i = 0; i < fileChooser->settings().selectedFiles.size(); ++i)
617                 option.suggestedFileNames += fileChooser->settings().selectedFiles[i];
618
619         QWebPage::ChooseMultipleFilesExtensionReturn output;
620         m_webPage->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);
621
622         if (!output.fileNames.isEmpty()) {
623             Vector<String> names;
624             for (int i = 0; i < output.fileNames.count(); ++i)
625                 names.append(output.fileNames.at(i));
626             fileChooser->chooseFiles(names);
627         }
628     } else {
629         QString suggestedFile;
630         if (!fileChooser->settings().selectedFiles.isEmpty())
631             suggestedFile = fileChooser->settings().selectedFiles[0];
632         QString file = m_webPage->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
633         if (!file.isEmpty())
634             fileChooser->chooseFile(file);
635     }
636 }
637
638 void ChromeClientQt::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader)
639 {
640     loader->notifyFinished(Icon::createIconForFiles(filenames));
641 }
642
643 void ChromeClientQt::setCursor(const Cursor& cursor)
644 {
645 #ifndef QT_NO_CURSOR
646     QWebPageClient* pageClient = platformPageClient();
647     if (!pageClient)
648         return;
649     pageClient->setCursor(*cursor.platformCursor());
650 #else
651     UNUSED_PARAM(cursor);
652 #endif
653 }
654
655 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
656 void ChromeClientQt::scheduleAnimation()
657 {
658     if (!m_refreshAnimation)
659         m_refreshAnimation = adoptPtr(new RefreshAnimation(this));
660     m_refreshAnimation->scheduleAnimation();
661 }
662
663 void ChromeClientQt::serviceScriptedAnimations()
664 {
665     m_webPage->mainFrame()->d->frame->view()->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime()));
666 }
667 #endif
668
669 #if USE(ACCELERATED_COMPOSITING)
670 void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
671 {
672     if (platformPageClient())
673         platformPageClient()->setRootGraphicsLayer(graphicsLayer);
674 }
675
676 void ChromeClientQt::setNeedsOneShotDrawingSynchronization()
677 {
678     // we want the layers to synchronize next time we update the screen anyway
679     if (platformPageClient())
680         platformPageClient()->markForSync(false);
681 }
682
683 void ChromeClientQt::scheduleCompositingLayerFlush()
684 {
685     // we want the layers to synchronize ASAP
686     if (platformPageClient())
687         platformPageClient()->markForSync(true);
688 }
689
690 ChromeClient::CompositingTriggerFlags ChromeClientQt::allowedCompositingTriggers() const
691 {
692     if (platformPageClient() && platformPageClient()->allowsAcceleratedCompositing())
693         return ThreeDTransformTrigger | VideoTrigger | CanvasTrigger | AnimationTrigger;
694
695     return 0;
696 }
697
698 #endif
699
700 #if USE(TILED_BACKING_STORE)
701 IntRect ChromeClientQt::visibleRectForTiledBackingStore() const
702 {
703     if (!platformPageClient() || !m_webPage)
704         return IntRect();
705
706     if (!platformPageClient()->viewResizesToContentsEnabled())
707         return QRect(m_webPage->mainFrame()->scrollPosition(), m_webPage->mainFrame()->geometry().size());
708
709     return enclosingIntRect(FloatRect(platformPageClient()->graphicsItemVisibleRect()));
710 }
711 #endif
712
713 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
714 FullScreenVideoQt* ChromeClientQt::fullScreenVideo()
715 {
716     if (!m_fullScreenVideo)
717         m_fullScreenVideo = new FullScreenVideoQt(this);
718     return m_fullScreenVideo;
719 }
720
721 bool ChromeClientQt::supportsFullscreenForNode(const Node* node)
722 {
723     ASSERT(node);
724     return node->hasTagName(HTMLNames::videoTag) && fullScreenVideo()->isValid();
725 }
726
727 bool ChromeClientQt::requiresFullscreenForVideoPlayback()
728 {
729     return fullScreenVideo()->requiresFullScreenForVideoPlayback();
730 }
731
732 void ChromeClientQt::enterFullscreenForNode(Node* node)
733 {
734     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
735
736     fullScreenVideo()->enterFullScreenForNode(node);
737 }
738
739 void ChromeClientQt::exitFullscreenForNode(Node* node)
740 {
741     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
742
743     fullScreenVideo()->exitFullScreenForNode(node);
744
745 #endif
746
747 PassOwnPtr<QWebSelectMethod> ChromeClientQt::createSelectPopup() const
748 {
749     OwnPtr<QWebSelectMethod> result = m_platformPlugin.createSelectInputMethod();
750     if (result)
751         return result.release();
752
753 #if !defined(QT_NO_COMBOBOX)
754     return adoptPtr(new QtFallbackWebPopup(this));
755 #else
756     return nullptr;
757 #endif
758 }
759
760 void ChromeClientQt::dispatchViewportPropertiesDidChange(const ViewportArguments&) const
761 {
762     emit m_webPage->viewportChangeRequested();
763 }
764
765 bool ChromeClientQt::selectItemWritingDirectionIsNatural()
766 {
767     return false;
768 }
769
770 bool ChromeClientQt::selectItemAlignmentFollowsMenuWritingDirection()
771 {
772     return false;
773 }
774
775 bool ChromeClientQt::hasOpenedPopup() const
776 {
777     notImplemented();
778     return false;
779 }
780
781 PassRefPtr<PopupMenu> ChromeClientQt::createPopupMenu(PopupMenuClient* client) const
782 {
783     return adoptRef(new PopupMenuQt(client, this));
784 }
785
786 PassRefPtr<SearchPopupMenu> ChromeClientQt::createSearchPopupMenu(PopupMenuClient* client) const
787 {
788     return adoptRef(new SearchPopupMenuQt(createPopupMenu(client)));
789 }
790
791 void ChromeClientQt::populateVisitedLinks()
792 {
793     // We don't need to do anything here because history is tied to QWebPage rather than stored
794     // in a separate database
795     if (dumpVisitedLinksCallbacks) {
796         printf("Asked to populate visited links for WebView \"%s\"\n",
797                 qPrintable(m_webPage->mainFrame()->url().toString()));
798     }
799 }
800
801 } // namespace WebCore