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