1/* 2 * Copyright (C) 2006 Zack Rusin <zack@kde.org> 3 * Copyright (C) 2006, 2011 Apple Inc. All rights reserved. 4 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) 5 * Copyright (C) 2008 Collabora Ltd. All rights reserved. 6 * Coypright (C) 2008 Holger Hans Peter Freyther 7 * Coypright (C) 2009, 2010 Girish Ramakrishnan <girish@forwardbias.in> 8 * 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 28 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include "config.h" 34#include "FrameLoaderClientQt.h" 35 36#include "CSSComputedStyleDeclaration.h" 37#include "CSSPropertyNames.h" 38#include "DocumentLoader.h" 39#include "FormState.h" 40#include "FrameNetworkingContextQt.h" 41#include "FrameTree.h" 42#include "FrameView.h" 43#include "HTMLAppletElement.h" 44#include "HTMLFormElement.h" 45#include "HTMLPlugInElement.h" 46#include "HTTPParsers.h" 47#include "HistoryItem.h" 48#include "HitTestResult.h" 49#if ENABLE(ICONDATABASE) 50#include "IconDatabaseClientQt.h" 51#endif 52#if USE(JSC) 53#include "JSDOMWindowBase.h" 54#endif 55#include "MIMETypeRegistry.h" 56#include "MouseEvent.h" 57#include "NotImplemented.h" 58#include "Page.h" 59#include "PluginData.h" 60#include "PluginDatabase.h" 61#include "ProgressTracker.h" 62#include "QNetworkReplyHandler.h" 63#include "QWebPageClient.h" 64#include "RenderPart.h" 65#include "ResourceHandle.h" 66#include "ResourceHandleInternal.h" 67#include "ResourceRequest.h" 68#include "ResourceResponse.h" 69#include "ScriptController.h" 70#include "Settings.h" 71#if USE(V8) 72#include "V8DOMWindow.h" 73#endif 74#include "ViewportArguments.h" 75 76#include "qwebframe.h" 77#include "qwebframe_p.h" 78#include "qwebhistory_p.h" 79#include "qwebhistoryinterface.h" 80#include "qwebpage.h" 81#include "qwebpage_p.h" 82#include "qwebpluginfactory.h" 83 84#include <QCoreApplication> 85#include <QDebug> 86#include <QFileInfo> 87#include <QGraphicsScene> 88#include <QGraphicsWidget> 89#include <QNetworkReply> 90#include <QNetworkRequest> 91#include <QStringList> 92#include <wtf/OwnPtr.h> 93 94static QMap<unsigned long, QString> dumpAssignedUrls; 95 96// Compare with the file "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm". 97static QString drtDescriptionSuitableForTestResult(WebCore::Frame* webCoreFrame) 98{ 99 QWebFrame* frame = QWebFramePrivate::kit(webCoreFrame); 100 QString name = frame->frameName(); 101 102 bool isMainFrame = frame == frame->page()->mainFrame(); 103 if (isMainFrame) { 104 if (!name.isEmpty()) 105 return QString::fromLatin1("main frame \"%1\"").arg(name); 106 return QLatin1String("main frame"); 107 } 108 if (!name.isEmpty()) 109 return QString::fromLatin1("frame \"%1\"").arg(name); 110 return QLatin1String("frame (anonymous)"); 111} 112 113static QString drtPrintFrameUserGestureStatus(WebCore::Frame* frame) 114{ 115 if (frame->loader()->isProcessingUserGesture()) 116 return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("true")); 117 return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("false")); 118} 119 120static QString drtDescriptionSuitableForTestResult(const WebCore::KURL& kurl) 121{ 122 if (kurl.isEmpty() || !kurl.isLocalFile()) 123 return kurl.string(); 124 // Remove the leading path from file urls. 125 return QString(kurl.string()).remove(WebCore::FrameLoaderClientQt::dumpResourceLoadCallbacksPath).mid(1); 126} 127 128static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceError& error) 129{ 130 QString failingURL = error.failingURL(); 131 return QString::fromLatin1("<NSError domain NSURLErrorDomain, code %1, failing URL \"%2\">").arg(error.errorCode()).arg(failingURL); 132} 133 134static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceRequest& request) 135{ 136 QString url = drtDescriptionSuitableForTestResult(request.url()); 137 QString httpMethod = request.httpMethod(); 138 QString mainDocumentUrl = drtDescriptionSuitableForTestResult(request.firstPartyForCookies()); 139 return QString::fromLatin1("<NSURLRequest URL %1, main document URL %2, http method %3>").arg(url).arg(mainDocumentUrl).arg(httpMethod); 140} 141 142static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceResponse& response) 143{ 144 QString url = drtDescriptionSuitableForTestResult(response.url()); 145 int httpStatusCode = response.httpStatusCode(); 146 return QString::fromLatin1("<NSURLResponse %1, http status code %2>").arg(url).arg(httpStatusCode); 147} 148 149static QString drtDescriptionSuitableForTestResult(const RefPtr<WebCore::Node> node, int exception) 150{ 151 QString result; 152 if (exception) { 153 result.append(QLatin1String("ERROR")); 154 return result; 155 } 156 if (!node) { 157 result.append(QLatin1String("NULL")); 158 return result; 159 } 160 result.append(node->nodeName()); 161 RefPtr<WebCore::Node> parent = node->parentNode(); 162 if (parent) { 163 result.append(QLatin1String(" > ")); 164 result.append(drtDescriptionSuitableForTestResult(parent, 0)); 165 } 166 return result; 167} 168 169namespace WebCore { 170 171bool FrameLoaderClientQt::dumpFrameLoaderCallbacks = false; 172bool FrameLoaderClientQt::dumpUserGestureInFrameLoaderCallbacks = false; 173bool FrameLoaderClientQt::dumpResourceLoadCallbacks = false; 174bool FrameLoaderClientQt::sendRequestReturnsNullOnRedirect = false; 175bool FrameLoaderClientQt::sendRequestReturnsNull = false; 176bool FrameLoaderClientQt::dumpResourceResponseMIMETypes = false; 177bool FrameLoaderClientQt::deferMainResourceDataLoad = true; 178bool FrameLoaderClientQt::dumpHistoryCallbacks = false; 179 180QStringList FrameLoaderClientQt::sendRequestClearHeaders; 181QString FrameLoaderClientQt::dumpResourceLoadCallbacksPath; 182bool FrameLoaderClientQt::policyDelegateEnabled = false; 183bool FrameLoaderClientQt::policyDelegatePermissive = false; 184QMap<QString, QString> FrameLoaderClientQt::URLsToRedirect = QMap<QString, QString>(); 185 186// Taken from the file "WebKit/Tools/DumpRenderTree/chromium/WebViewHost.cpp". 187static const char* navigationTypeToString(NavigationType type) 188{ 189 switch (type) { 190 case NavigationTypeLinkClicked: 191 return "link clicked"; 192 case NavigationTypeFormSubmitted: 193 return "form submitted"; 194 case NavigationTypeBackForward: 195 return "back/forward"; 196 case NavigationTypeReload: 197 return "reload"; 198 case NavigationTypeFormResubmitted: 199 return "form resubmitted"; 200 case NavigationTypeOther: 201 return "other"; 202 } 203 return "illegal value"; 204} 205 206FrameLoaderClientQt::FrameLoaderClientQt() 207 : m_frame(0) 208 , m_webFrame(0) 209 , m_pluginView(0) 210 , m_hasSentResponseToPlugin(false) 211 , m_hasRepresentation(false) 212 , m_loadError(ResourceError()) 213{ 214} 215 216 217FrameLoaderClientQt::~FrameLoaderClientQt() 218{ 219} 220 221void FrameLoaderClientQt::setFrame(QWebFrame* webFrame, Frame* frame) 222{ 223 m_webFrame = webFrame; 224 m_frame = frame; 225 226 if (!m_webFrame || !m_webFrame->page()) { 227 qWarning("FrameLoaderClientQt::setFrame frame without Page!"); 228 return; 229 } 230 231 connect(this, SIGNAL(loadStarted()), 232 m_webFrame->page(), SIGNAL(loadStarted())); 233 connect(this, SIGNAL(loadStarted()), 234 m_webFrame, SIGNAL(loadStarted())); 235 connect(this, SIGNAL(loadProgress(int)), 236 m_webFrame->page(), SIGNAL(loadProgress(int))); 237 connect(this, SIGNAL(loadFinished(bool)), 238 m_webFrame->page(), SIGNAL(loadFinished(bool))); 239 connect(this, SIGNAL(loadFinished(bool)), 240 m_webFrame, SIGNAL(loadFinished(bool))); 241 connect(this, SIGNAL(titleChanged(QString)), 242 m_webFrame, SIGNAL(titleChanged(QString))); 243} 244 245void FrameLoaderClientQt::callPolicyFunction(FramePolicyFunction function, PolicyAction action) 246{ 247 (m_frame->loader()->policyChecker()->*function)(action); 248} 249 250bool FrameLoaderClientQt::hasWebView() const 251{ 252 // notImplemented(); 253 return true; 254} 255 256void FrameLoaderClientQt::savePlatformDataToCachedFrame(CachedFrame*) 257{ 258 notImplemented(); 259} 260 261void FrameLoaderClientQt::transitionToCommittedFromCachedFrame(CachedFrame*) 262{ 263} 264 265void FrameLoaderClientQt::transitionToCommittedForNewPage() 266{ 267 ASSERT(m_frame); 268 ASSERT(m_webFrame); 269 270 QBrush brush = m_webFrame->page()->palette().brush(QPalette::Base); 271 QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor(); 272 273 QWebPage* page = m_webFrame->page(); 274 const QSize preferredLayoutSize = page->preferredContentsSize(); 275 276 ScrollbarMode hScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Horizontal); 277 ScrollbarMode vScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Vertical); 278 bool hLock = hScrollbar != ScrollbarAuto; 279 bool vLock = vScrollbar != ScrollbarAuto; 280 281 IntSize currentVisibleContentSize = m_frame->view() ? m_frame->view()->actualVisibleContentRect().size() : IntSize(); 282 283 m_frame->createView(m_webFrame->page()->viewportSize(), 284 backgroundColor, !backgroundColor.alpha(), 285 preferredLayoutSize.isValid() ? IntSize(preferredLayoutSize) : IntSize(), 286 preferredLayoutSize.isValid(), 287 hScrollbar, hLock, 288 vScrollbar, vLock); 289 290 bool isMainFrame = m_frame == m_frame->page()->mainFrame(); 291 if (isMainFrame && page->d->client) { 292 m_frame->view()->setPaintsEntireContents(page->d->client->viewResizesToContentsEnabled()); 293 m_frame->view()->setDelegatesScrolling(page->d->client->viewResizesToContentsEnabled()); 294 } 295 296 // The HistoryController will update the scroll position later if needed. 297 m_frame->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize)); 298} 299 300void FrameLoaderClientQt::didSaveToPageCache() 301{ 302} 303 304void FrameLoaderClientQt::didRestoreFromPageCache() 305{ 306} 307 308void FrameLoaderClientQt::dispatchDidBecomeFrameset(bool) 309{ 310} 311 312void FrameLoaderClientQt::makeRepresentation(DocumentLoader*) 313{ 314 m_hasRepresentation = true; 315} 316 317 318void FrameLoaderClientQt::forceLayout() 319{ 320 FrameView* view = m_frame->view(); 321 if (view) 322 view->layout(true); 323} 324 325 326void FrameLoaderClientQt::forceLayoutForNonHTML() 327{ 328} 329 330 331void FrameLoaderClientQt::setCopiesOnScroll() 332{ 333 // Apparently this is mac specific. 334} 335 336 337void FrameLoaderClientQt::detachedFromParent2() 338{ 339} 340 341 342void FrameLoaderClientQt::detachedFromParent3() 343{ 344} 345 346void FrameLoaderClientQt::dispatchDidHandleOnloadEvents() 347{ 348 // Don't need this one. 349 if (dumpFrameLoaderCallbacks) 350 printf("%s - didHandleOnloadEventsForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 351} 352 353 354void FrameLoaderClientQt::dispatchDidReceiveServerRedirectForProvisionalLoad() 355{ 356 if (dumpFrameLoaderCallbacks) 357 printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 358 359 notImplemented(); 360} 361 362 363void FrameLoaderClientQt::dispatchDidCancelClientRedirect() 364{ 365 if (dumpFrameLoaderCallbacks) 366 printf("%s - didCancelClientRedirectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 367 368 notImplemented(); 369} 370 371 372void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url, double, double) 373{ 374 if (dumpFrameLoaderCallbacks) 375 printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url))); 376 377 notImplemented(); 378} 379 380 381void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage() 382{ 383 if (dumpFrameLoaderCallbacks) 384 printf("%s - didChangeLocationWithinPageForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 385 386 if (!m_webFrame) 387 return; 388 389 m_webFrame->d->emitUrlChanged(); 390 m_webFrame->page()->d->updateNavigationActions(); 391} 392 393#if USE(V8) 394void FrameLoaderClientQt::didCreateScriptContextForFrame() 395{ 396} 397void FrameLoaderClientQt::didDestroyScriptContextForFrame() 398{ 399} 400void FrameLoaderClientQt::didCreateIsolatedScriptContext() 401{ 402} 403#endif 404 405void FrameLoaderClientQt::dispatchDidPushStateWithinPage() 406{ 407 if (dumpFrameLoaderCallbacks) 408 printf("%s - dispatchDidPushStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 409 410 notImplemented(); 411} 412 413void FrameLoaderClientQt::dispatchDidReplaceStateWithinPage() 414{ 415 if (dumpFrameLoaderCallbacks) 416 printf("%s - dispatchDidReplaceStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 417 418 notImplemented(); 419} 420 421void FrameLoaderClientQt::dispatchDidPopStateWithinPage() 422{ 423 if (dumpFrameLoaderCallbacks) 424 printf("%s - dispatchDidPopStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 425 426 notImplemented(); 427} 428 429void FrameLoaderClientQt::dispatchWillClose() 430{ 431} 432 433 434void FrameLoaderClientQt::dispatchDidStartProvisionalLoad() 435{ 436 if (dumpFrameLoaderCallbacks) 437 printf("%s - didStartProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 438 439 if (dumpUserGestureInFrameLoaderCallbacks) 440 printf("%s - in didStartProvisionalLoadForFrame\n", qPrintable(drtPrintFrameUserGestureStatus(m_frame))); 441 442 m_lastRequestedUrl = m_frame->loader()->activeDocumentLoader()->requestURL(); 443 444 if (m_webFrame) 445 emit m_webFrame->provisionalLoad(); 446} 447 448 449void FrameLoaderClientQt::dispatchDidReceiveTitle(const StringWithDirection& title) 450{ 451 // FIXME: Use direction of title. 452 if (dumpFrameLoaderCallbacks) 453 printf("%s - didReceiveTitle: %s\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(QString(title.string()))); 454 455 if (!m_webFrame) 456 return; 457 458 emit titleChanged(title.string()); 459} 460 461 462void FrameLoaderClientQt::dispatchDidChangeIcons() 463{ 464 if (dumpFrameLoaderCallbacks) 465 printf("%s - didChangeIcons\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 466 467 if (!m_webFrame) 468 return; 469 470 // FIXME: In order to get notified of icon URLS' changes, add a notification. 471 // emit iconsChanged(); 472} 473 474 475void FrameLoaderClientQt::dispatchDidCommitLoad() 476{ 477 if (dumpFrameLoaderCallbacks) 478 printf("%s - didCommitLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 479 480 if (m_frame->tree()->parent() || !m_webFrame) 481 return; 482 483 m_webFrame->d->emitUrlChanged(); 484 m_webFrame->page()->d->updateNavigationActions(); 485 486 // We should assume first the frame has no title. If it has, then the above dispatchDidReceiveTitle() 487 // will be called very soon with the correct title. 488 // This properly resets the title when we navigate to a URI without a title. 489 emit titleChanged(QString()); 490 491 bool isMainFrame = (m_frame == m_frame->page()->mainFrame()); 492 if (!isMainFrame) 493 return; 494 495 emit m_webFrame->page()->viewportChangeRequested(); 496} 497 498 499void FrameLoaderClientQt::dispatchDidFinishDocumentLoad() 500{ 501 if (dumpFrameLoaderCallbacks) 502 printf("%s - didFinishDocumentLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 503 504 if (QWebPagePrivate::drtRun) { 505 int unloadEventCount = m_frame->domWindow()->pendingUnloadEventListeners(); 506 if (unloadEventCount) 507 printf("%s - has %u onunload handler(s)\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), unloadEventCount); 508 } 509 510 if (m_frame->tree()->parent() || !m_webFrame) 511 return; 512 513 m_webFrame->page()->d->updateNavigationActions(); 514} 515 516 517void FrameLoaderClientQt::dispatchDidFinishLoad() 518{ 519 if (dumpFrameLoaderCallbacks) 520 printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 521 522 // Clears the previous error. 523 m_loadError = ResourceError(); 524 525 if (!m_webFrame) 526 return; 527 m_webFrame->page()->d->updateNavigationActions(); 528} 529 530 531void FrameLoaderClientQt::dispatchDidFirstLayout() 532{ 533} 534 535void FrameLoaderClientQt::dispatchDidFirstVisuallyNonEmptyLayout() 536{ 537 if (m_webFrame) 538 emit m_webFrame->initialLayoutCompleted(); 539} 540 541void FrameLoaderClientQt::dispatchShow() 542{ 543 notImplemented(); 544} 545 546 547void FrameLoaderClientQt::cancelPolicyCheck() 548{ 549 // qDebug() << "FrameLoaderClientQt::cancelPolicyCheck"; 550} 551 552 553void FrameLoaderClientQt::dispatchWillSubmitForm(FramePolicyFunction function, 554 PassRefPtr<FormState>) 555{ 556 notImplemented(); 557 // FIXME: This is surely too simple. 558 callPolicyFunction(function, PolicyUse); 559} 560 561 562void FrameLoaderClientQt::dispatchDidLoadMainResource(DocumentLoader*) 563{ 564} 565 566 567void FrameLoaderClientQt::revertToProvisionalState(DocumentLoader*) 568{ 569 m_hasRepresentation = true; 570} 571 572 573void FrameLoaderClientQt::postProgressStartedNotification() 574{ 575 if (m_webFrame && m_frame->page()) { 576 // As a new load have started, clear the previous error. 577 m_loadError = ResourceError(); 578 emit loadStarted(); 579 postProgressEstimateChangedNotification(); 580 } 581 if (m_frame->tree()->parent() || !m_webFrame) 582 return; 583 m_webFrame->page()->d->updateNavigationActions(); 584} 585 586void FrameLoaderClientQt::postProgressEstimateChangedNotification() 587{ 588 if (m_webFrame && m_frame->page()) 589 emit loadProgress(qRound(m_frame->page()->progress()->estimatedProgress() * 100)); 590} 591 592void FrameLoaderClientQt::postProgressFinishedNotification() 593{ 594 // Send a mousemove event to: 595 // (1) update the cursor to change according to whatever is underneath the mouse cursor right now; 596 // (2) display the tool tip if the mouse hovers a node which has a tool tip. 597 if (m_frame && m_frame->eventHandler() && m_webFrame->page()) { 598 QWidget* view = m_webFrame->page()->view(); 599 if (view && view->hasFocus()) { 600 QPoint localPos = view->mapFromGlobal(QCursor::pos()); 601 if (view->rect().contains(localPos)) { 602 QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier); 603 m_frame->eventHandler()->mouseMoved(PlatformMouseEvent(&event, 0)); 604 } 605 } 606 } 607 608 if (m_webFrame && m_frame->page()) 609 emit loadFinished(m_loadError.isNull()); 610} 611 612void FrameLoaderClientQt::setMainFrameDocumentReady(bool) 613{ 614 // This is only interesting once we provide an external API for the DOM. 615} 616 617 618void FrameLoaderClientQt::willChangeTitle(DocumentLoader*) 619{ 620 // No need for, dispatchDidReceiveTitle is the right callback. 621} 622 623 624void FrameLoaderClientQt::didChangeTitle(DocumentLoader*) 625{ 626 // No need for, dispatchDidReceiveTitle is the right callback. 627} 628 629 630void FrameLoaderClientQt::finishedLoading(DocumentLoader* loader) 631{ 632 if (!m_pluginView) { 633 // This is necessary to create an empty document. See bug 634004. 634 // However, we only want to do this if makeRepresentation has been called, 635 // to match the behavior on the Mac. 636 if (m_hasRepresentation) 637 loader->writer()->setEncoding("", false); 638 return; 639 } 640 if (m_pluginView->isPluginView()) 641 m_pluginView->didFinishLoading(); 642 m_pluginView = 0; 643 m_hasSentResponseToPlugin = false; 644} 645 646bool FrameLoaderClientQt::canShowMIMETypeAsHTML(const String& MIMEType) const 647{ 648 notImplemented(); 649 return false; 650} 651 652bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const 653{ 654 String type = MIMEType; 655 type.makeLower(); 656 if (MIMETypeRegistry::isSupportedImageMIMEType(type)) 657 return true; 658 659 if (MIMETypeRegistry::isSupportedNonImageMIMEType(type)) 660 return true; 661 662 if (m_frame && m_frame->settings() && m_frame->settings()->arePluginsEnabled() 663 && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type)) 664 return true; 665 666 return false; 667} 668 669bool FrameLoaderClientQt::representationExistsForURLScheme(const String&) const 670{ 671 return false; 672} 673 674 675String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String&) const 676{ 677 notImplemented(); 678 return String(); 679} 680 681 682void FrameLoaderClientQt::frameLoadCompleted() 683{ 684 // Note that this can be called multiple times. 685} 686 687 688void FrameLoaderClientQt::restoreViewState() 689{ 690 if (!m_webFrame) 691 return; 692 emit m_webFrame->page()->restoreFrameStateRequested(m_webFrame); 693} 694 695 696void FrameLoaderClientQt::provisionalLoadStarted() 697{ 698 // Don't need to do anything here. 699} 700 701 702void FrameLoaderClientQt::didFinishLoad() 703{ 704 // notImplemented(); 705} 706 707 708void FrameLoaderClientQt::prepareForDataSourceReplacement() 709{ 710} 711 712void FrameLoaderClientQt::setTitle(const StringWithDirection& title, const KURL& url) 713{ 714 // Used by Apple WebKit to update the title of an existing history item. 715 // QtWebKit doesn't accomodate this on history items. If it ever does, 716 // it should be privateBrowsing-aware. For now, we are just passing 717 // globalhistory layout tests. 718 // FIXME: Use direction of title. 719 if (dumpHistoryCallbacks) { 720 printf("WebView updated the title for history URL \"%s\" to \"%s\".\n", 721 qPrintable(drtDescriptionSuitableForTestResult(url)), 722 qPrintable(QString(title.string()))); 723 } 724} 725 726 727String FrameLoaderClientQt::userAgent(const KURL& url) 728{ 729 if (m_webFrame) { 730 return m_webFrame->page()->userAgentForUrl(url); 731 } 732 return String(); 733} 734 735void FrameLoaderClientQt::dispatchDidReceiveIcon() 736{ 737 if (m_webFrame) 738 emit m_webFrame->iconChanged(); 739} 740 741void FrameLoaderClientQt::frameLoaderDestroyed() 742{ 743 delete m_webFrame; 744 m_frame = 0; 745 m_webFrame = 0; 746 747 delete this; 748} 749 750bool FrameLoaderClientQt::canHandleRequest(const WebCore::ResourceRequest&) const 751{ 752 return true; 753} 754 755void FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) 756{ 757 if (world != mainThreadNormalWorld()) 758 return; 759 760 if (m_webFrame) 761 emit m_webFrame->javaScriptWindowObjectCleared(); 762} 763 764void FrameLoaderClientQt::documentElementAvailable() 765{ 766 return; 767} 768 769void FrameLoaderClientQt::didPerformFirstNavigation() const 770{ 771 if (m_frame->tree()->parent() || !m_webFrame) 772 return; 773 m_webFrame->page()->d->updateNavigationActions(); 774} 775 776void FrameLoaderClientQt::registerForIconNotification(bool shouldRegister) 777{ 778#if ENABLE(ICONDATABASE) 779 if (shouldRegister) 780 connect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString)), Qt::UniqueConnection); 781 else 782 disconnect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString))); 783#endif 784} 785 786void FrameLoaderClientQt::onIconLoadedForPageURL(const QString& url) 787{ 788#if ENABLE(ICONDATABASE) 789 if (m_webFrame && m_webFrame->url() == url) 790 emit m_webFrame->iconChanged(); 791#endif 792} 793 794 795void FrameLoaderClientQt::updateGlobalHistory() 796{ 797 QWebHistoryInterface* history = QWebHistoryInterface::defaultInterface(); 798 WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader(); 799 if (history) 800 history->addHistoryEntry(loader->urlForHistory().string()); 801 802 if (dumpHistoryCallbacks) { 803 printf("WebView navigated to url \"%s\" with title \"%s\" with HTTP equivalent method \"%s\". The navigation was %s and was %s%s.\n", 804 qPrintable(drtDescriptionSuitableForTestResult(loader->urlForHistory())), 805 qPrintable(QString(loader->title().string())), 806 qPrintable(QString(loader->request().httpMethod())), 807 ((loader->substituteData().isValid() || (loader->response().httpStatusCode() >= 400)) ? "a failure" : "successful"), 808 ((!loader->clientRedirectSourceForHistory().isEmpty()) ? "a client redirect from " : "not a client redirect"), 809 (!loader->clientRedirectSourceForHistory().isEmpty()) ? qPrintable(drtDescriptionSuitableForTestResult(loader->clientRedirectSourceForHistory())) : ""); 810 } 811} 812 813void FrameLoaderClientQt::updateGlobalHistoryRedirectLinks() 814{ 815 // Apple WebKit is the only port that makes use of this callback. It calls 816 // WebCore::HistoryItem::addRedirectURL() with the contents of 817 // loader->[server|client]RedirectDestinationForHistory(). 818 // WebCore can associate a bunch of redirect URLs with a particular 819 // item in the history, presumably this allows Safari to skip the redirections 820 // when navigating to that history item. That might be a feature Qt wants to 821 // offer through QWebHistoryInterface in the future. For now, we're just 822 // passing tests in LayoutTests/http/tests/globalhistory. 823 WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader(); 824 825 if (!loader->clientRedirectSourceForHistory().isNull()) { 826 if (dumpHistoryCallbacks) { 827 printf("WebView performed a client redirect from \"%s\" to \"%s\".\n", 828 qPrintable(QString(loader->clientRedirectSourceForHistory())), 829 qPrintable(QString(loader->clientRedirectDestinationForHistory()))); 830 } 831 } 832 833 if (!loader->serverRedirectSourceForHistory().isNull()) { 834 if (dumpHistoryCallbacks) { 835 printf("WebView performed a server redirect from \"%s\" to \"%s\".\n", 836 qPrintable(QString(loader->serverRedirectSourceForHistory())), 837 qPrintable(QString(loader->serverRedirectDestinationForHistory()))); 838 } 839 } 840} 841 842bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem*) const 843{ 844 return true; 845} 846 847bool FrameLoaderClientQt::shouldStopLoadingForHistoryItem(WebCore::HistoryItem*) const 848{ 849 return true; 850} 851 852void FrameLoaderClientQt::dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const 853{ 854} 855 856void FrameLoaderClientQt::dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const 857{ 858} 859 860void FrameLoaderClientQt::dispatchDidChangeBackForwardIndex() const 861{ 862} 863 864void FrameLoaderClientQt::didDisplayInsecureContent() 865{ 866 if (dumpFrameLoaderCallbacks) 867 printf("didDisplayInsecureContent\n"); 868 869 notImplemented(); 870} 871 872void FrameLoaderClientQt::didRunInsecureContent(WebCore::SecurityOrigin*, const KURL&) 873{ 874 if (dumpFrameLoaderCallbacks) 875 printf("didRunInsecureContent\n"); 876 877 notImplemented(); 878} 879 880void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem* item) 881{ 882 QWebHistoryItem historyItem(new QWebHistoryItemPrivate(item)); 883 emit m_webFrame->page()->saveFrameStateRequested(m_webFrame, &historyItem); 884} 885 886bool FrameLoaderClientQt::canCachePage() const 887{ 888 return true; 889} 890 891void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader, const WebCore::ResourceError& error) 892{ 893 if (!m_pluginView) 894 return; 895 if (m_pluginView->isPluginView()) 896 m_pluginView->didFail(error); 897 m_pluginView = 0; 898 m_hasSentResponseToPlugin = false; 899} 900 901// FIXME: This function should be moved into WebCore. 902void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length) 903{ 904 if (!m_pluginView) 905 loader->commitData(data, length); 906 907 // We re-check here as the plugin can have been created. 908 if (m_pluginView && m_pluginView->isPluginView()) { 909 if (!m_hasSentResponseToPlugin) { 910 m_pluginView->didReceiveResponse(loader->response()); 911 // The function didReceiveResponse sets up a new stream to the plug-in. 912 // On a full-page plug-in, a failure in setting up this stream can cause the 913 // main document load to be cancelled, setting m_pluginView to null. 914 if (!m_pluginView) 915 return; 916 m_hasSentResponseToPlugin = true; 917 } 918 m_pluginView->didReceiveData(data, length); 919 } 920} 921 922WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request) 923{ 924 ResourceError error = ResourceError("QtNetwork", QNetworkReply::OperationCanceledError, request.url().string(), 925 QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8)); 926 error.setIsCancellation(true); 927 return error; 928} 929 930// This was copied from file "WebKit/Source/WebKit/mac/Misc/WebKitErrors.h". 931enum { 932 WebKitErrorCannotShowMIMEType = 100, 933 WebKitErrorCannotShowURL = 101, 934 WebKitErrorFrameLoadInterruptedByPolicyChange = 102, 935 WebKitErrorCannotUseRestrictedPort = 103, 936 WebKitErrorCannotFindPlugIn = 200, 937 WebKitErrorCannotLoadPlugIn = 201, 938 WebKitErrorJavaUnavailable = 202, 939 WebKitErrorPluginWillHandleLoad = 203 940}; 941 942WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request) 943{ 944 return ResourceError("WebKitErrorDomain", WebKitErrorCannotUseRestrictedPort, request.url().string(), 945 QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8)); 946} 947 948 949WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request) 950{ 951 return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowURL, request.url().string(), 952 QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8)); 953} 954 955WebCore::ResourceError FrameLoaderClientQt::interruptForPolicyChangeError(const WebCore::ResourceRequest& request) 956{ 957 return ResourceError("WebKitErrorDomain", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(), 958 QCoreApplication::translate("QWebFrame", "Frame load interrupted by policy change", 0, QCoreApplication::UnicodeUTF8)); 959} 960 961WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response) 962{ 963 return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowMIMEType, response.url().string(), 964 QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8)); 965} 966 967WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response) 968{ 969 return ResourceError("QtNetwork", QNetworkReply::ContentNotFoundError, response.url().string(), 970 QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8)); 971} 972 973WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response) 974{ 975 return ResourceError("WebKit", WebKitErrorPluginWillHandleLoad, response.url().string(), 976 QCoreApplication::translate("QWebFrame", "Loading is handled by the media engine", 0, QCoreApplication::UnicodeUTF8)); 977} 978 979bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError&) 980{ 981 notImplemented(); 982 return false; 983} 984 985WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData) 986{ 987 RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData); 988 if (!deferMainResourceDataLoad || substituteData.isValid()) { 989 loader->setDeferMainResourceDataLoad(false); 990 // Use the default timeout interval for JS as the HTML tokenizer delay. This ensures 991 // that long-running JavaScript will still allow setHtml() to be synchronous, while 992 // still giving a reasonable timeout to prevent deadlock. 993#if USE(JSC) 994 double delay = JSDOMWindowBase::commonJSGlobalData()->timeoutChecker.timeoutInterval() / 1000.0f; 995#elif USE(V8) 996 // FIXME: Hard coded for now. 997 double delay = 10000 / 1000.0f; 998#endif 999 m_frame->page()->setCustomHTMLTokenizerTimeDelay(delay); 1000 } else 1001 m_frame->page()->setCustomHTMLTokenizerTimeDelay(-1); 1002 return loader.release(); 1003} 1004 1005void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&) 1006{ 1007 if (!m_webFrame) 1008 return; 1009 1010 QNetworkReplyHandler* handler = handle->getInternal()->m_job; 1011 QNetworkReply* reply = handler->release(); 1012 if (reply) { 1013 QWebPage* page = m_webFrame->page(); 1014 if (page->forwardUnsupportedContent()) 1015 emit page->unsupportedContent(reply); 1016 else 1017 reply->abort(); 1018 } 1019} 1020 1021void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest& request) 1022{ 1023 if (dumpResourceLoadCallbacks) 1024 dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url()); 1025} 1026 1027void FrameLoaderClientQt::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse) 1028{ 1029 QUrl url = newRequest.url(); 1030 1031 if (dumpResourceLoadCallbacks) 1032 printf("%s - willSendRequest %s redirectResponse %s\n", 1033 qPrintable(dumpAssignedUrls[identifier]), 1034 qPrintable(drtDescriptionSuitableForTestResult(newRequest)), 1035 (redirectResponse.isNull()) ? "(null)" : qPrintable(drtDescriptionSuitableForTestResult(redirectResponse))); 1036 1037 if (sendRequestReturnsNull) { 1038 newRequest.setURL(QUrl()); 1039 return; 1040 } 1041 1042 if (sendRequestReturnsNullOnRedirect && !redirectResponse.isNull()) { 1043 printf("Returning null for this redirect\n"); 1044 newRequest.setURL(QUrl()); 1045 return; 1046 } 1047 1048 if (QWebPagePrivate::drtRun 1049 && url.isValid() 1050 && (url.scheme().toLower() == QLatin1String("http") || url.scheme().toLower() == QLatin1String("https")) 1051 && url.host() != QLatin1String("127.0.0.1") 1052 && url.host() != QLatin1String("255.255.255.255") 1053 && url.host().toLower() != QLatin1String("localhost")) { 1054 1055 printf("Blocked access to external URL %s\n", qPrintable(drtDescriptionSuitableForTestResult(newRequest.url()))); 1056 newRequest.setURL(QUrl()); 1057 return; 1058 } 1059 1060 for (int i = 0; i < sendRequestClearHeaders.size(); ++i) 1061 newRequest.setHTTPHeaderField(sendRequestClearHeaders.at(i).toLocal8Bit().constData(), QString()); 1062 1063 if (QWebPagePrivate::drtRun) { 1064 QMap<QString, QString>::const_iterator it = URLsToRedirect.constFind(url.toString()); 1065 if (it != URLsToRedirect.constEnd()) 1066 newRequest.setURL(QUrl(it.value())); 1067 } 1068 // Seems like the Mac code doesn't do anything here by default neither. 1069 // qDebug() << "FrameLoaderClientQt::dispatchWillSendRequest" << request.isNull() << url; 1070} 1071 1072bool FrameLoaderClientQt::shouldUseCredentialStorage(DocumentLoader*, unsigned long) 1073{ 1074 notImplemented(); 1075 return false; 1076} 1077 1078void FrameLoaderClientQt::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&) 1079{ 1080 notImplemented(); 1081} 1082 1083void FrameLoaderClientQt::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&) 1084{ 1085 notImplemented(); 1086} 1087 1088void FrameLoaderClientQt::dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse& response) 1089{ 1090 1091 m_response = response; 1092 if (dumpResourceLoadCallbacks) 1093 printf("%s - didReceiveResponse %s\n", 1094 qPrintable(dumpAssignedUrls[identifier]), 1095 qPrintable(drtDescriptionSuitableForTestResult(response))); 1096 1097 if (dumpResourceResponseMIMETypes) { 1098 printf("%s has MIME type %s\n", 1099 qPrintable(QString(response.url().lastPathComponent())), 1100 qPrintable(QString(response.mimeType()))); 1101 } 1102} 1103 1104void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int) 1105{ 1106} 1107 1108void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier) 1109{ 1110 if (dumpResourceLoadCallbacks) 1111 printf("%s - didFinishLoading\n", 1112 (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>")); 1113} 1114 1115void FrameLoaderClientQt::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error) 1116{ 1117 if (dumpResourceLoadCallbacks) 1118 printf("%s - didFailLoadingWithError: %s\n", 1119 (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>"), 1120 qPrintable(drtDescriptionSuitableForTestResult(error))); 1121} 1122 1123bool FrameLoaderClientQt::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int) 1124{ 1125 notImplemented(); 1126 return false; 1127} 1128 1129void FrameLoaderClientQt::callErrorPageExtension(const WebCore::ResourceError& error) 1130{ 1131 QWebPage* page = m_webFrame->page(); 1132 if (page->supportsExtension(QWebPage::ErrorPageExtension)) { 1133 QWebPage::ErrorPageExtensionOption option; 1134 1135 if (error.domain() == "QtNetwork") 1136 option.domain = QWebPage::QtNetwork; 1137 else if (error.domain() == "HTTP") 1138 option.domain = QWebPage::Http; 1139 else if (error.domain() == "WebKit") 1140 option.domain = QWebPage::WebKit; 1141 else 1142 return; 1143 1144 option.url = QUrl(error.failingURL()); 1145 option.frame = m_webFrame; 1146 option.error = error.errorCode(); 1147 option.errorString = error.localizedDescription(); 1148 1149 QWebPage::ErrorPageExtensionReturn output; 1150 if (!page->extension(QWebPage::ErrorPageExtension, &option, &output)) 1151 return; 1152 1153 KURL baseUrl(output.baseUrl); 1154 KURL failingUrl(option.url); 1155 1156 WebCore::ResourceRequest request(baseUrl); 1157 WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(output.content.constData(), output.content.length()); 1158 WebCore::SubstituteData substituteData(buffer, output.contentType, output.encoding, failingUrl); 1159 m_frame->loader()->load(request, substituteData, false); 1160 } 1161} 1162 1163void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError& error) 1164{ 1165 if (dumpFrameLoaderCallbacks) 1166 printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 1167 1168 m_loadError = error; 1169 if (!error.isNull() && !error.isCancellation()) 1170 callErrorPageExtension(error); 1171} 1172 1173void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError& error) 1174{ 1175 if (dumpFrameLoaderCallbacks) 1176 printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame))); 1177 1178 m_loadError = error; 1179 if (!error.isNull() && !error.isCancellation()) 1180 callErrorPageExtension(error); 1181} 1182 1183WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage(const WebCore::NavigationAction&) 1184{ 1185 if (!m_webFrame) 1186 return 0; 1187 QWebPage *newPage = m_webFrame->page()->createWindow(QWebPage::WebBrowserWindow); 1188 if (!newPage) 1189 return 0; 1190 return newPage->mainFrame()->d->frame; 1191} 1192 1193void FrameLoaderClientQt::dispatchDecidePolicyForResponse(FramePolicyFunction function, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest&) 1194{ 1195 // We need to call directly here. 1196 if (WebCore::contentDispositionType(response.httpHeaderField("Content-Disposition")) == WebCore::ContentDispositionAttachment) 1197 callPolicyFunction(function, PolicyDownload); 1198 else if (canShowMIMEType(response.mimeType())) 1199 callPolicyFunction(function, PolicyUse); 1200 else 1201 callPolicyFunction(function, PolicyDownload); 1202} 1203 1204void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WTF::String&) 1205{ 1206 Q_ASSERT(m_webFrame); 1207 QNetworkRequest r(request.toNetworkRequest(m_webFrame)); 1208 QWebPage* page = m_webFrame->page(); 1209 1210 if (!page->d->acceptNavigationRequest(0, r, QWebPage::NavigationType(action.type()))) { 1211 if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted) 1212 m_frame->loader()->resetMultipleFormSubmissionProtection(); 1213 1214 if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) { 1215 ResourceRequest emptyRequest; 1216 m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest); 1217 } 1218 1219 callPolicyFunction(function, PolicyIgnore); 1220 return; 1221 } 1222 callPolicyFunction(function, PolicyUse); 1223} 1224 1225void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>) 1226{ 1227 Q_ASSERT(m_webFrame); 1228 QNetworkRequest r(request.toNetworkRequest(m_webFrame)); 1229 QWebPage*page = m_webFrame->page(); 1230 PolicyAction result; 1231 1232 // Currently, this is only enabled by DRT. 1233 if (policyDelegateEnabled) { 1234 RefPtr<Node> node; 1235 for (const Event* event = action.event(); event; event = event->underlyingEvent()) { 1236 if (event->isMouseEvent()) { 1237 const MouseEvent* mouseEvent = static_cast<const MouseEvent*>(event); 1238 node = QWebFramePrivate::core(m_webFrame)->eventHandler()->hitTestResultAtPoint( 1239 mouseEvent->absoluteLocation(), false).innerNonSharedNode(); 1240 break; 1241 } 1242 } 1243 1244 printf("Policy delegate: attempt to load %s with navigation type '%s'%s\n", 1245 qPrintable(drtDescriptionSuitableForTestResult(request.url())), navigationTypeToString(action.type()), 1246 (node) ? qPrintable(QString::fromLatin1(" originating from ") + drtDescriptionSuitableForTestResult(node, 0)) : ""); 1247 1248 if (policyDelegatePermissive) 1249 result = PolicyUse; 1250 else 1251 result = PolicyIgnore; 1252 1253 callPolicyFunction(function, result); 1254 return; 1255 } 1256 1257 if (!page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()))) { 1258 if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted) 1259 m_frame->loader()->resetMultipleFormSubmissionProtection(); 1260 1261 if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) { 1262 ResourceRequest emptyRequest; 1263 m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest); 1264 } 1265 1266 callPolicyFunction(function, PolicyIgnore); 1267 return; 1268 } 1269 callPolicyFunction(function, PolicyUse); 1270} 1271 1272void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::ResourceError&) 1273{ 1274 notImplemented(); 1275} 1276 1277void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request) 1278{ 1279 if (!m_webFrame) 1280 return; 1281 1282 emit m_webFrame->page()->downloadRequested(request.toNetworkRequest(m_webFrame)); 1283} 1284 1285PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, 1286 const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) 1287{ 1288 if (!m_webFrame) 1289 return 0; 1290 1291 QWebFrameData frameData(m_frame->page(), m_frame, ownerElement, name); 1292 1293 if (url.isEmpty()) 1294 frameData.url = blankURL(); 1295 else 1296 frameData.url = url; 1297 1298 frameData.referrer = referrer; 1299 frameData.allowsScrolling = allowsScrolling; 1300 frameData.marginWidth = marginWidth; 1301 frameData.marginHeight = marginHeight; 1302 1303 QPointer<QWebFrame> webFrame = new QWebFrame(m_webFrame, &frameData); 1304 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. 1305 if (!webFrame->d->frame->page()) { 1306 frameData.frame.release(); 1307 ASSERT(webFrame.isNull()); 1308 return 0; 1309 } 1310 1311 emit m_webFrame->page()->frameCreated(webFrame); 1312 1313 // FIXME: Set override encoding if we have one. 1314 1315 m_frame->loader()->loadURLIntoChildFrame(frameData.url, frameData.referrer, frameData.frame.get()); 1316 1317 // The frame's onload handler may have removed it from the document. 1318 if (!frameData.frame->tree()->parent()) 1319 return 0; 1320 1321 return frameData.frame.release(); 1322} 1323 1324void FrameLoaderClientQt::didTransferChildFrameToNewDocument(Page*) 1325{ 1326 ASSERT(m_frame->ownerElement()); 1327 1328 if (!m_webFrame) 1329 return; 1330 1331 Frame* parentFrame = m_webFrame->d->frame->tree()->parent(); 1332 ASSERT(parentFrame); 1333 1334 if (QWebFrame* parent = QWebFramePrivate::kit(parentFrame)) { 1335 m_webFrame->d->setPage(parent->page()); 1336 1337 if (m_webFrame->parent() != qobject_cast<QObject*>(parent)) 1338 m_webFrame->setParent(parent); 1339 } 1340} 1341 1342void FrameLoaderClientQt::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) 1343{ 1344} 1345 1346ObjectContentType FrameLoaderClientQt::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages) 1347{ 1348 // qDebug()<<" ++++++++++++++++ url is "<<url.string()<<", mime = "<<mimeTypeIn; 1349 QFileInfo fi(url.path()); 1350 String extension = fi.suffix(); 1351 if (mimeTypeIn == "application/x-qt-plugin" || mimeTypeIn == "application/x-qt-styled-widget") 1352 return ObjectContentOtherPlugin; 1353 1354 if (url.isEmpty() && !mimeTypeIn.length()) 1355 return ObjectContentNone; 1356 1357 String mimeType = mimeTypeIn; 1358 if (!mimeType.length()) 1359 mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension); 1360 1361 if (!mimeType.length()) 1362 mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(extension); 1363 1364 if (!mimeType.length()) 1365 return ObjectContentFrame; 1366 1367 ObjectContentType plugInType = ObjectContentNone; 1368 if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType)) 1369 plugInType = ObjectContentNetscapePlugin; 1370 else if (m_frame->page() && m_frame->page()->pluginData() && m_frame->page()->pluginData()->supportsMimeType(mimeType)) 1371 plugInType = ObjectContentOtherPlugin; 1372 1373 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) 1374 return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage; 1375 1376 if (plugInType != ObjectContentNone) 1377 return plugInType; 1378 1379 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) 1380 return ObjectContentFrame; 1381 1382 if (url.protocol() == "about") 1383 return ObjectContentFrame; 1384 1385 return ObjectContentNone; 1386} 1387 1388static const CSSPropertyID qstyleSheetProperties[] = { 1389 CSSPropertyColor, 1390 CSSPropertyFontFamily, 1391 CSSPropertyFontSize, 1392 CSSPropertyFontStyle, 1393 CSSPropertyFontWeight 1394}; 1395 1396const unsigned numqStyleSheetProperties = sizeof(qstyleSheetProperties) / sizeof(qstyleSheetProperties[0]); 1397 1398class QtPluginWidget: public Widget 1399{ 1400public: 1401 QtPluginWidget(QWidget* w = 0): Widget(w) {} 1402 ~QtPluginWidget() 1403 { 1404 if (platformWidget()) 1405 platformWidget()->deleteLater(); 1406 } 1407 virtual void invalidateRect(const IntRect& r) 1408 { 1409 if (platformWidget()) 1410 platformWidget()->update(r); 1411 } 1412 virtual void frameRectsChanged() 1413 { 1414 if (!platformWidget()) 1415 return; 1416 1417 IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height())); 1418 platformWidget()->setGeometry(windowRect); 1419 1420 ScrollView* parentScrollView = parent(); 1421 if (!parentScrollView) 1422 return; 1423 1424 ASSERT(parentScrollView->isFrameView()); 1425 IntRect clipRect(static_cast<FrameView*>(parentScrollView)->windowClipRect()); 1426 clipRect.move(-windowRect.x(), -windowRect.y()); 1427 clipRect.intersect(platformWidget()->rect()); 1428 1429 QRegion clipRegion = QRegion(clipRect); 1430 platformWidget()->setMask(clipRegion); 1431 1432 handleVisibility(); 1433 1434 platformWidget()->update(); 1435 } 1436 1437 virtual void show() 1438 { 1439 Widget::show(); 1440 handleVisibility(); 1441 } 1442 1443private: 1444 void handleVisibility() 1445 { 1446 if (!isVisible()) 1447 return; 1448 1449 // If setMask is set with an empty QRegion, no clipping will 1450 // be performed, so in that case we hide the platformWidget. 1451 QRegion mask = platformWidget()->mask(); 1452 platformWidget()->setVisible(!mask.isEmpty()); 1453 } 1454}; 1455 1456#if !defined(QT_NO_GRAPHICSVIEW) 1457class QtPluginGraphicsWidget: public Widget 1458{ 1459public: 1460 static RefPtr<QtPluginGraphicsWidget> create(QGraphicsWidget* w = 0) 1461 { 1462 return adoptRef(new QtPluginGraphicsWidget(w)); 1463 } 1464 1465 ~QtPluginGraphicsWidget() 1466 { 1467 if (graphicsWidget) 1468 graphicsWidget->deleteLater(); 1469 } 1470 virtual void invalidateRect(const IntRect& r) 1471 { 1472 QGraphicsScene* scene = graphicsWidget ? graphicsWidget->scene() : 0; 1473 if (scene) 1474 scene->update(QRect(r)); 1475 } 1476 virtual void frameRectsChanged() 1477 { 1478 if (!graphicsWidget) 1479 return; 1480 1481 IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height())); 1482 graphicsWidget->setGeometry(QRect(windowRect)); 1483 1484 // FIXME: Make the code handle clipping of graphics widgets. 1485 } 1486 virtual void show() 1487 { 1488 if (graphicsWidget) 1489 graphicsWidget->show(); 1490 } 1491 virtual void hide() 1492 { 1493 if (graphicsWidget) 1494 graphicsWidget->hide(); 1495 } 1496private: 1497 QtPluginGraphicsWidget(QGraphicsWidget* w = 0) 1498 : Widget(0) 1499 , graphicsWidget(w) 1500 { 1501 setBindingObject(graphicsWidget); 1502 } 1503 1504 QGraphicsWidget* graphicsWidget; 1505}; 1506#endif // QT_NO_GRAPHICSVIEW 1507 1508PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, 1509 const Vector<String>& paramValues, const String& mimeType, bool loadManually) 1510{ 1511 // qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.string() << mimeType; 1512 // qDebug()<<"------\t url = "<<url.string(); 1513 1514 if (!m_webFrame) 1515 return 0; 1516 1517 QStringList params; 1518 QStringList values; 1519 QString classid(element->getAttribute("classid")); 1520 1521 for (unsigned i = 0; i < paramNames.size(); ++i) { 1522 params.append(paramNames[i]); 1523 if (paramNames[i] == "classid") 1524 classid = paramValues[i]; 1525 } 1526 for (unsigned i = 0; i < paramValues.size(); ++i) 1527 values.append(paramValues[i]); 1528 1529 QString urlStr(url.string()); 1530 QUrl qurl = urlStr; 1531 1532 QObject* object = 0; 1533 1534 if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") { 1535 object = m_webFrame->page()->createPlugin(classid, qurl, params, values); 1536#ifndef QT_NO_STYLE_STYLESHEET 1537 QWidget* widget = qobject_cast<QWidget*>(object); 1538 if (widget && mimeType == "application/x-qt-styled-widget") { 1539 1540 QString styleSheet = element->getAttribute("style"); 1541 if (!styleSheet.isEmpty()) 1542 styleSheet += QLatin1Char(';'); 1543 1544 for (unsigned i = 0; i < numqStyleSheetProperties; ++i) { 1545 CSSPropertyID property = qstyleSheetProperties[i]; 1546 1547 styleSheet += QString::fromLatin1(getPropertyName(property)); 1548 styleSheet += QLatin1Char(':'); 1549 styleSheet += computedStyle(element)->getPropertyValue(property); 1550 styleSheet += QLatin1Char(';'); 1551 } 1552 1553 widget->setStyleSheet(styleSheet); 1554 } 1555#endif // QT_NO_STYLE_STYLESHEET 1556 } 1557 1558 if (!object) { 1559 QWebPluginFactory* factory = m_webFrame->page()->pluginFactory(); 1560 if (factory) 1561 object = factory->create(mimeType, qurl, params, values); 1562 } 1563 1564 if (object) { 1565 QWidget* widget = qobject_cast<QWidget*>(object); 1566 if (widget) { 1567 QWidget* parentWidget = 0; 1568 if (m_webFrame->page()->d->client) 1569 parentWidget = qobject_cast<QWidget*>(m_webFrame->page()->d->client->pluginParent()); 1570 if (parentWidget) // Don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose. 1571 widget->setParent(parentWidget); 1572 widget->hide(); 1573 RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget()); 1574 w->setPlatformWidget(widget); 1575 // Make sure it's invisible until properly placed into the layout. 1576 w->setFrameRect(IntRect(0, 0, 0, 0)); 1577 return w; 1578 } 1579 1580#if !defined(QT_NO_GRAPHICSVIEW) 1581 QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object); 1582 if (graphicsWidget) { 1583 QGraphicsObject* parentWidget = 0; 1584 if (m_webFrame->page()->d->client) 1585 parentWidget = qobject_cast<QGraphicsObject*>(m_webFrame->page()->d->client->pluginParent()); 1586 graphicsWidget->hide(); 1587 if (parentWidget) // Don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose. 1588 graphicsWidget->setParentItem(parentWidget); 1589 RefPtr<QtPluginGraphicsWidget> w = QtPluginGraphicsWidget::create(graphicsWidget); 1590 // Make sure it's invisible until properly placed into the layout. 1591 w->setFrameRect(IntRect(0, 0, 0, 0)); 1592 return w; 1593 } 1594#endif // QT_NO_GRAPHICSVIEW 1595 1596 // FIXME: Make things work for widgetless plugins as well. 1597 delete object; 1598 } 1599#if ENABLE(NETSCAPE_PLUGIN_API) 1600 else { // NPAPI Plugins 1601 Vector<String> params = paramNames; 1602 Vector<String> values = paramValues; 1603 if (mimeType == "application/x-shockwave-flash") { 1604 QWebPageClient* client = m_webFrame->page()->d->client.get(); 1605 const bool isQWebView = client && qobject_cast<QWidget*>(client->pluginParent()); 1606#if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO >= 5) 1607 size_t wmodeIndex = params.find("wmode"); 1608 if (wmodeIndex == -1) { 1609 // Disable XEmbed mode and force it to opaque mode. 1610 params.append("wmode"); 1611 values.append("opaque"); 1612 } else if (!isQWebView) { 1613 // Disable transparency if client is not a QWebView. 1614 values[wmodeIndex] = "opaque"; 1615 } 1616#else 1617 if (!isQWebView) { 1618 // Inject wmode=opaque when there is no client or the client is not a QWebView. 1619 size_t wmodeIndex = params.find("wmode"); 1620 if (wmodeIndex == -1) { 1621 params.append("wmode"); 1622 values.append("opaque"); 1623 } else if (equalIgnoringCase(values[wmodeIndex], "window")) 1624 values[wmodeIndex] = "opaque"; 1625 } 1626#endif 1627 } 1628 1629 RefPtr<PluginView> pluginView = PluginView::create(m_frame, pluginSize, element, url, 1630 params, values, mimeType, loadManually); 1631 return pluginView; 1632 } 1633#endif // ENABLE(NETSCAPE_PLUGIN_API) 1634 1635 return 0; 1636} 1637 1638void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget) 1639{ 1640 ASSERT(!m_pluginView); 1641 m_pluginView = static_cast<PluginView*>(pluginWidget); 1642 m_hasSentResponseToPlugin = false; 1643} 1644 1645PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& url, 1646 const Vector<String>& paramNames, const Vector<String>& paramValues) 1647{ 1648 return createPlugin(pluginSize, element, url, paramNames, paramValues, "application/x-java-applet", true); 1649} 1650 1651String FrameLoaderClientQt::overrideMediaType() const 1652{ 1653 return String(); 1654} 1655 1656QString FrameLoaderClientQt::chooseFile(const QString& oldFile) 1657{ 1658 return m_webFrame->page()->chooseFile(m_webFrame, oldFile); 1659} 1660 1661PassRefPtr<FrameNetworkingContext> FrameLoaderClientQt::createNetworkingContext() 1662{ 1663 QVariant value = m_webFrame->page()->property("_q_MIMESniffingDisabled"); 1664 bool MIMESniffingDisabled = value.isValid() && value.toBool(); 1665 1666 return FrameNetworkingContextQt::create(m_frame, m_webFrame, !MIMESniffingDisabled, m_webFrame->page()->networkAccessManager()); 1667} 1668 1669} 1670 1671#include "moc_FrameLoaderClientQt.cpp" 1672