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