FrameLoaderClientQt.cpp 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611
  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. #include "config.h"
  33. #include "FrameLoaderClientQt.h"
  34. #include "CSSComputedStyleDeclaration.h"
  35. #include "CSSPropertyNames.h"
  36. #include "DocumentLoader.h"
  37. #include "EventHandler.h"
  38. #include "FormState.h"
  39. #include "FrameLoadRequest.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 "HTTPStatusCodes.h"
  48. #include "HistoryItem.h"
  49. #include "HitTestResult.h"
  50. #if ENABLE(ICONDATABASE)
  51. #include "IconDatabaseClientQt.h"
  52. #endif
  53. #include "JSDOMWindowBase.h"
  54. #include "MIMETypeRegistry.h"
  55. #include "MouseEvent.h"
  56. #include "NotImplemented.h"
  57. #include "Page.h"
  58. #include "PlatformMouseEvent.h"
  59. #include "PluginData.h"
  60. #include "PluginDatabase.h"
  61. #include "PolicyChecker.h"
  62. #include "ProgressTracker.h"
  63. #include "QNetworkReplyHandler.h"
  64. #include "QWebFrameAdapter.h"
  65. #include "QWebPageAdapter.h"
  66. #include "QWebPageClient.h"
  67. #include "QtPluginWidgetAdapter.h"
  68. #include "RenderPart.h"
  69. #include "ResourceHandle.h"
  70. #include "ResourceHandleInternal.h"
  71. #include "ResourceLoader.h"
  72. #include "ResourceRequest.h"
  73. #include "ResourceResponse.h"
  74. #include "ScriptController.h"
  75. #include "Settings.h"
  76. #include "ViewportArguments.h"
  77. #include "WebEventConversion.h"
  78. #include "qwebhistory.h"
  79. #include "qwebhistory_p.h"
  80. #include "qwebhistoryinterface.h"
  81. #include "qwebpluginfactory.h"
  82. #include "qwebsettings.h"
  83. #include <QCoreApplication>
  84. #include <QDebug>
  85. #include <QFileInfo>
  86. #include <QMouseEvent>
  87. #include <QNetworkReply>
  88. #include <QNetworkRequest>
  89. #include <QStringList>
  90. #include <wtf/OwnPtr.h>
  91. #include <wtf/text/StringBuilder.h>
  92. static QMap<unsigned long, QString> dumpAssignedUrls;
  93. // Compare with the file "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm".
  94. static QString drtDescriptionSuitableForTestResult(WebCore::Frame* webCoreFrame)
  95. {
  96. QWebFrameAdapter* frame = QWebFrameAdapter::kit(webCoreFrame);
  97. QString name = webCoreFrame->tree()->uniqueName();
  98. bool isMainFrame = frame == frame->pageAdapter->mainFrameAdapter();
  99. if (isMainFrame) {
  100. if (!name.isEmpty())
  101. return QString::fromLatin1("main frame \"%1\"").arg(name);
  102. return QLatin1String("main frame");
  103. }
  104. if (!name.isEmpty())
  105. return QString::fromLatin1("frame \"%1\"").arg(name);
  106. return QLatin1String("frame (anonymous)");
  107. }
  108. static QString drtPrintFrameUserGestureStatus(WebCore::Frame* frame)
  109. {
  110. if (WebCore::ScriptController::processingUserGesture())
  111. return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("true"));
  112. return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("false"));
  113. }
  114. static QString drtDescriptionSuitableForTestResult(const WebCore::KURL& kurl)
  115. {
  116. if (kurl.isEmpty() || !kurl.isLocalFile())
  117. return kurl.string();
  118. // Remove the leading path from file urls.
  119. return QString(kurl.string()).remove(WebCore::FrameLoaderClientQt::dumpResourceLoadCallbacksPath).mid(1);
  120. }
  121. static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceError& error)
  122. {
  123. QString failingURL = error.failingURL();
  124. return QString::fromLatin1("<NSError domain NSURLErrorDomain, code %1, failing URL \"%2\">").arg(error.errorCode()).arg(failingURL);
  125. }
  126. static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceRequest& request)
  127. {
  128. QString url = drtDescriptionSuitableForTestResult(request.url());
  129. QString httpMethod = request.httpMethod();
  130. QString mainDocumentUrl = drtDescriptionSuitableForTestResult(request.firstPartyForCookies());
  131. return QString::fromLatin1("<NSURLRequest URL %1, main document URL %2, http method %3>").arg(url).arg(mainDocumentUrl).arg(httpMethod);
  132. }
  133. static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceResponse& response)
  134. {
  135. QString url = drtDescriptionSuitableForTestResult(response.url());
  136. int httpStatusCode = response.httpStatusCode();
  137. return QString::fromLatin1("<NSURLResponse %1, http status code %2>").arg(url).arg(httpStatusCode);
  138. }
  139. static QString drtDescriptionSuitableForTestResult(const RefPtr<WebCore::Node> node, int exception)
  140. {
  141. QString result;
  142. if (exception) {
  143. result.append(QLatin1String("ERROR"));
  144. return result;
  145. }
  146. if (!node) {
  147. result.append(QLatin1String("NULL"));
  148. return result;
  149. }
  150. result.append(node->nodeName());
  151. RefPtr<WebCore::Node> parent = node->parentNode();
  152. if (parent) {
  153. result.append(QLatin1String(" > "));
  154. result.append(drtDescriptionSuitableForTestResult(parent, 0));
  155. }
  156. return result;
  157. }
  158. namespace WebCore {
  159. bool FrameLoaderClientQt::dumpFrameLoaderCallbacks = false;
  160. bool FrameLoaderClientQt::dumpProgressFinishedCallback = false;
  161. bool FrameLoaderClientQt::dumpUserGestureInFrameLoaderCallbacks = false;
  162. bool FrameLoaderClientQt::dumpWillCacheResponseCallbacks = false;
  163. bool FrameLoaderClientQt::dumpResourceLoadCallbacks = false;
  164. bool FrameLoaderClientQt::sendRequestReturnsNullOnRedirect = false;
  165. bool FrameLoaderClientQt::sendRequestReturnsNull = false;
  166. bool FrameLoaderClientQt::dumpResourceResponseMIMETypes = false;
  167. bool FrameLoaderClientQt::deferMainResourceDataLoad = true;
  168. bool FrameLoaderClientQt::dumpHistoryCallbacks = false;
  169. QStringList FrameLoaderClientQt::sendRequestClearHeaders;
  170. QString FrameLoaderClientQt::dumpResourceLoadCallbacksPath;
  171. bool FrameLoaderClientQt::policyDelegateEnabled = false;
  172. bool FrameLoaderClientQt::policyDelegatePermissive = false;
  173. QMap<QString, QString> FrameLoaderClientQt::URLsToRedirect = QMap<QString, QString>();
  174. // Taken from the file "WebKit/Tools/DumpRenderTree/chromium/WebViewHost.cpp".
  175. static const char* navigationTypeToString(NavigationType type)
  176. {
  177. switch (type) {
  178. case NavigationTypeLinkClicked:
  179. return "link clicked";
  180. case NavigationTypeFormSubmitted:
  181. return "form submitted";
  182. case NavigationTypeBackForward:
  183. return "back/forward";
  184. case NavigationTypeReload:
  185. return "reload";
  186. case NavigationTypeFormResubmitted:
  187. return "form resubmitted";
  188. case NavigationTypeOther:
  189. return "other";
  190. }
  191. return "illegal value";
  192. }
  193. FrameLoaderClientQt::FrameLoaderClientQt()
  194. : m_frame(0)
  195. , m_webFrame(0)
  196. , m_pluginView(0)
  197. , m_hasSentResponseToPlugin(false)
  198. , m_isOriginatingLoad(false)
  199. {
  200. }
  201. FrameLoaderClientQt::~FrameLoaderClientQt()
  202. {
  203. }
  204. void FrameLoaderClientQt::setFrame(QWebFrameAdapter* webFrame, Frame* frame)
  205. {
  206. m_webFrame = webFrame;
  207. m_frame = frame;
  208. if (!m_webFrame || !m_webFrame->pageAdapter) {
  209. qWarning("FrameLoaderClientQt::setFrame frame without Page!");
  210. return;
  211. }
  212. connect(this, SIGNAL(loadProgress(int)),
  213. m_webFrame->pageAdapter->handle(), SIGNAL(loadProgress(int)));
  214. connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
  215. m_webFrame->pageAdapter->handle(), SIGNAL(unsupportedContent(QNetworkReply*)));
  216. connect(this, SIGNAL(titleChanged(QString)),
  217. m_webFrame->handle(), SIGNAL(titleChanged(QString)));
  218. }
  219. void FrameLoaderClientQt::callPolicyFunction(FramePolicyFunction function, PolicyAction action)
  220. {
  221. (m_frame->loader()->policyChecker()->*function)(action);
  222. }
  223. bool FrameLoaderClientQt::hasWebView() const
  224. {
  225. // notImplemented();
  226. return true;
  227. }
  228. void FrameLoaderClientQt::savePlatformDataToCachedFrame(CachedFrame*)
  229. {
  230. notImplemented();
  231. }
  232. void FrameLoaderClientQt::transitionToCommittedFromCachedFrame(CachedFrame*)
  233. {
  234. }
  235. void FrameLoaderClientQt::transitionToCommittedForNewPage()
  236. {
  237. ASSERT(m_frame);
  238. ASSERT(m_webFrame);
  239. QObject* qWebPage = m_webFrame->pageAdapter->handle();
  240. QBrush brush = qWebPage->property("palette").value<QPalette>().brush(QPalette::Base);
  241. QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
  242. const QSize preferredLayoutSize = qWebPage->property("preferredContentsSize").toSize();
  243. ScrollbarMode hScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Horizontal);
  244. ScrollbarMode vScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Vertical);
  245. bool hLock = hScrollbar != ScrollbarAuto;
  246. bool vLock = vScrollbar != ScrollbarAuto;
  247. // The HistoryController will update the scroll position later if needed.
  248. IntRect currentVisibleContentRect = m_frame->view() ? IntRect(IntPoint::zero(), m_frame->view()->fixedVisibleContentRect().size()) : IntRect();
  249. m_frame->createView(qWebPage->property("viewportSize").toSize(),
  250. backgroundColor, !backgroundColor.alpha(),
  251. preferredLayoutSize.isValid() ? IntSize(preferredLayoutSize) : IntSize(),
  252. currentVisibleContentRect,
  253. preferredLayoutSize.isValid(),
  254. hScrollbar, hLock,
  255. vScrollbar, vLock);
  256. bool isMainFrame = m_frame == m_frame->page()->mainFrame();
  257. if (isMainFrame &&m_webFrame->pageAdapter->client) {
  258. bool resizesToContents = m_webFrame->pageAdapter->client->viewResizesToContentsEnabled();
  259. m_frame->view()->setPaintsEntireContents(resizesToContents);
  260. m_frame->view()->setDelegatesScrolling(resizesToContents);
  261. }
  262. }
  263. void FrameLoaderClientQt::didSaveToPageCache()
  264. {
  265. }
  266. void FrameLoaderClientQt::didRestoreFromPageCache()
  267. {
  268. }
  269. void FrameLoaderClientQt::dispatchDidBecomeFrameset(bool)
  270. {
  271. }
  272. void FrameLoaderClientQt::forceLayout()
  273. {
  274. FrameView* view = m_frame->view();
  275. if (view)
  276. view->layout(true);
  277. }
  278. void FrameLoaderClientQt::forceLayoutForNonHTML()
  279. {
  280. }
  281. void FrameLoaderClientQt::setCopiesOnScroll()
  282. {
  283. // Apparently this is mac specific.
  284. }
  285. void FrameLoaderClientQt::detachedFromParent2()
  286. {
  287. }
  288. void FrameLoaderClientQt::detachedFromParent3()
  289. {
  290. }
  291. void FrameLoaderClientQt::dispatchDidHandleOnloadEvents()
  292. {
  293. // Don't need this one.
  294. if (dumpFrameLoaderCallbacks)
  295. printf("%s - didHandleOnloadEventsForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  296. }
  297. void FrameLoaderClientQt::dispatchDidReceiveServerRedirectForProvisionalLoad()
  298. {
  299. if (dumpFrameLoaderCallbacks)
  300. printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  301. notImplemented();
  302. }
  303. void FrameLoaderClientQt::dispatchDidCancelClientRedirect()
  304. {
  305. if (dumpFrameLoaderCallbacks)
  306. printf("%s - didCancelClientRedirectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  307. notImplemented();
  308. }
  309. void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url, double, double)
  310. {
  311. if (dumpFrameLoaderCallbacks)
  312. printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url)));
  313. if (dumpUserGestureInFrameLoaderCallbacks)
  314. printf("%s - in willPerformClientRedirect\n", qPrintable(drtPrintFrameUserGestureStatus(m_frame)));
  315. notImplemented();
  316. }
  317. void FrameLoaderClientQt::dispatchDidNavigateWithinPage()
  318. {
  319. if (!m_webFrame)
  320. return;
  321. FrameLoader* loader = m_frame->loader();
  322. bool loaderCompleted = !(loader->activeDocumentLoader() && loader->activeDocumentLoader()->isLoadingInAPISense());
  323. if (!loaderCompleted)
  324. return;
  325. dispatchDidCommitLoad();
  326. dispatchDidFinishLoad();
  327. }
  328. void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage()
  329. {
  330. if (dumpFrameLoaderCallbacks)
  331. printf("%s - didChangeLocationWithinPageForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  332. if (!m_webFrame)
  333. return;
  334. m_webFrame->emitUrlChanged();
  335. m_webFrame->pageAdapter->updateNavigationActions();
  336. }
  337. void FrameLoaderClientQt::dispatchDidPushStateWithinPage()
  338. {
  339. if (dumpFrameLoaderCallbacks)
  340. printf("%s - dispatchDidPushStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  341. dispatchDidNavigateWithinPage();
  342. }
  343. void FrameLoaderClientQt::dispatchDidReplaceStateWithinPage()
  344. {
  345. if (dumpFrameLoaderCallbacks)
  346. printf("%s - dispatchDidReplaceStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  347. dispatchDidNavigateWithinPage();
  348. }
  349. void FrameLoaderClientQt::dispatchDidPopStateWithinPage()
  350. {
  351. if (dumpFrameLoaderCallbacks)
  352. printf("%s - dispatchDidPopStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  353. // No need to call dispatchDidNavigateWithinPage here, it's already been done in loadInSameDocument().
  354. }
  355. void FrameLoaderClientQt::dispatchWillClose()
  356. {
  357. }
  358. void FrameLoaderClientQt::dispatchDidStartProvisionalLoad()
  359. {
  360. if (dumpFrameLoaderCallbacks)
  361. printf("%s - didStartProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  362. if (dumpUserGestureInFrameLoaderCallbacks)
  363. printf("%s - in didStartProvisionalLoadForFrame\n", qPrintable(drtPrintFrameUserGestureStatus(m_frame)));
  364. m_lastRequestedUrl = m_frame->loader()->activeDocumentLoader()->requestURL();
  365. if (!m_webFrame)
  366. return;
  367. emitLoadStarted();
  368. postProgressEstimateChangedNotification();
  369. m_webFrame->didStartProvisionalLoad();
  370. }
  371. void FrameLoaderClientQt::dispatchDidReceiveTitle(const StringWithDirection& title)
  372. {
  373. // FIXME: Use direction of title.
  374. if (dumpFrameLoaderCallbacks)
  375. printf("%s - didReceiveTitle: %s\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(QString(title.string())));
  376. if (!m_webFrame)
  377. return;
  378. emit titleChanged(title.string());
  379. }
  380. void FrameLoaderClientQt::dispatchDidChangeIcons(WebCore::IconType)
  381. {
  382. if (dumpFrameLoaderCallbacks)
  383. printf("%s - didChangeIcons\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  384. if (!m_webFrame)
  385. return;
  386. // FIXME: In order to get notified of icon URLS' changes, add a notification.
  387. // emit iconsChanged();
  388. }
  389. void FrameLoaderClientQt::dispatchDidCommitLoad()
  390. {
  391. if (dumpFrameLoaderCallbacks)
  392. printf("%s - didCommitLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  393. if (m_frame->tree()->parent() || !m_webFrame)
  394. return;
  395. m_webFrame->emitUrlChanged();
  396. m_webFrame->pageAdapter->updateNavigationActions();
  397. // We should assume first the frame has no title. If it has, then the above dispatchDidReceiveTitle()
  398. // will be called very soon with the correct title.
  399. // This properly resets the title when we navigate to a URI without a title.
  400. emit titleChanged(QString());
  401. bool isMainFrame = (m_frame == m_frame->page()->mainFrame());
  402. if (!isMainFrame)
  403. return;
  404. emit m_webFrame->pageAdapter->emitViewportChangeRequested();
  405. }
  406. void FrameLoaderClientQt::dispatchDidFinishDocumentLoad()
  407. {
  408. if (dumpFrameLoaderCallbacks)
  409. printf("%s - didFinishDocumentLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  410. if (QWebPageAdapter::drtRun) {
  411. int unloadEventCount = m_frame->document()->domWindow()->pendingUnloadEventListeners();
  412. if (unloadEventCount)
  413. printf("%s - has %u onunload handler(s)\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), unloadEventCount);
  414. }
  415. if (m_frame->tree()->parent() || !m_webFrame)
  416. return;
  417. m_webFrame->pageAdapter->updateNavigationActions();
  418. }
  419. void FrameLoaderClientQt::dispatchDidFinishLoad()
  420. {
  421. if (dumpFrameLoaderCallbacks)
  422. printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  423. if (!m_webFrame)
  424. return;
  425. m_webFrame->pageAdapter->updateNavigationActions();
  426. emitLoadFinished(true);
  427. }
  428. void FrameLoaderClientQt::dispatchDidLayout(LayoutMilestones milestones)
  429. {
  430. if (!m_webFrame)
  431. return;
  432. if (milestones & DidFirstVisuallyNonEmptyLayout)
  433. m_webFrame->emitInitialLayoutCompleted();
  434. }
  435. void FrameLoaderClientQt::dispatchShow()
  436. {
  437. notImplemented();
  438. }
  439. void FrameLoaderClientQt::cancelPolicyCheck()
  440. {
  441. // qDebug() << "FrameLoaderClientQt::cancelPolicyCheck";
  442. }
  443. void FrameLoaderClientQt::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState>)
  444. {
  445. notImplemented();
  446. // FIXME: This is surely too simple.
  447. callPolicyFunction(function, PolicyUse);
  448. }
  449. void FrameLoaderClientQt::postProgressStartedNotification()
  450. {
  451. if (m_webFrame && m_frame->page())
  452. m_isOriginatingLoad = true;
  453. if (m_frame->tree()->parent() || !m_webFrame)
  454. return;
  455. m_webFrame->pageAdapter->updateNavigationActions();
  456. }
  457. void FrameLoaderClientQt::postProgressEstimateChangedNotification()
  458. {
  459. if (m_webFrame && m_frame->page())
  460. emit loadProgress(qRound(m_frame->page()->progress()->estimatedProgress() * 100));
  461. }
  462. void FrameLoaderClientQt::postProgressFinishedNotification()
  463. {
  464. if (dumpProgressFinishedCallback)
  465. printf("postProgressFinishedNotification\n");
  466. // Send a mousemove event to:
  467. // (1) update the cursor to change according to whatever is underneath the mouse cursor right now;
  468. // (2) display the tool tip if the mouse hovers a node which has a tool tip.
  469. if (m_frame && m_frame->eventHandler() && m_webFrame) {
  470. QPoint localPos;
  471. if (m_webFrame->handleProgressFinished(&localPos)) {
  472. QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
  473. m_frame->eventHandler()->mouseMoved(convertMouseEvent(&event, 0));
  474. }
  475. }
  476. }
  477. void FrameLoaderClientQt::setMainFrameDocumentReady(bool)
  478. {
  479. // This is only interesting once we provide an external API for the DOM.
  480. }
  481. void FrameLoaderClientQt::willChangeTitle(DocumentLoader*)
  482. {
  483. // No need for, dispatchDidReceiveTitle is the right callback.
  484. }
  485. void FrameLoaderClientQt::didChangeTitle(DocumentLoader*)
  486. {
  487. // No need for, dispatchDidReceiveTitle is the right callback.
  488. }
  489. void FrameLoaderClientQt::finishedLoading(DocumentLoader*)
  490. {
  491. if (!m_pluginView)
  492. return;
  493. if (m_pluginView->isPluginView())
  494. m_pluginView->didFinishLoading();
  495. m_pluginView = 0;
  496. m_hasSentResponseToPlugin = false;
  497. }
  498. bool FrameLoaderClientQt::canShowMIMETypeAsHTML(const String& MIMEType) const
  499. {
  500. notImplemented();
  501. return false;
  502. }
  503. bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const
  504. {
  505. String type = MIMEType;
  506. type.makeLower();
  507. if (MIMETypeRegistry::canShowMIMEType(type))
  508. return true;
  509. if (m_frame && m_frame->settings() && m_frame->settings()->arePluginsEnabled()
  510. && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type))
  511. return true;
  512. return false;
  513. }
  514. bool FrameLoaderClientQt::representationExistsForURLScheme(const String&) const
  515. {
  516. return false;
  517. }
  518. String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String&) const
  519. {
  520. notImplemented();
  521. return String();
  522. }
  523. void FrameLoaderClientQt::frameLoadCompleted()
  524. {
  525. // Note that this can be called multiple times.
  526. if (!m_webFrame)
  527. return;
  528. m_webFrame->pageAdapter->updateNavigationActions();
  529. }
  530. void FrameLoaderClientQt::restoreViewState()
  531. {
  532. if (!m_webFrame)
  533. return;
  534. m_webFrame->pageAdapter->emitRestoreFrameStateRequested(m_webFrame);
  535. }
  536. void FrameLoaderClientQt::provisionalLoadStarted()
  537. {
  538. // Don't need to do anything here.
  539. }
  540. void FrameLoaderClientQt::didFinishLoad()
  541. {
  542. // notImplemented();
  543. }
  544. void FrameLoaderClientQt::prepareForDataSourceReplacement()
  545. {
  546. }
  547. void FrameLoaderClientQt::setTitle(const StringWithDirection& title, const KURL& url)
  548. {
  549. // Used by Apple WebKit to update the title of an existing history item.
  550. // QtWebKit doesn't accomodate this on history items. If it ever does,
  551. // it should be privateBrowsing-aware. For now, we are just passing
  552. // globalhistory layout tests.
  553. // FIXME: Use direction of title.
  554. if (dumpHistoryCallbacks) {
  555. printf("WebView updated the title for history URL \"%s\" to \"%s\".\n",
  556. qPrintable(drtDescriptionSuitableForTestResult(url)),
  557. qPrintable(QString(title.string())));
  558. }
  559. }
  560. String FrameLoaderClientQt::userAgent(const KURL& url)
  561. {
  562. if (m_webFrame)
  563. return m_webFrame->pageAdapter->userAgentForUrl(url).remove(QLatin1Char('\n')).remove(QLatin1Char('\r'));
  564. return String();
  565. }
  566. void FrameLoaderClientQt::dispatchDidReceiveIcon()
  567. {
  568. if (m_webFrame)
  569. m_webFrame->emitIconChanged();
  570. }
  571. void FrameLoaderClientQt::frameLoaderDestroyed()
  572. {
  573. // Delete QWebFrame (handle()), which owns QWebFramePrivate, which
  574. // _is_ a QWebFrameAdapter.
  575. if (m_webFrame)
  576. delete m_webFrame->handle();
  577. m_frame = 0;
  578. m_webFrame = 0;
  579. delete this;
  580. }
  581. bool FrameLoaderClientQt::canHandleRequest(const WebCore::ResourceRequest&) const
  582. {
  583. return true;
  584. }
  585. void FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
  586. {
  587. if (world != mainThreadNormalWorld())
  588. return;
  589. if (m_webFrame)
  590. m_webFrame->didClearWindowObject();
  591. }
  592. void FrameLoaderClientQt::documentElementAvailable()
  593. {
  594. return;
  595. }
  596. void FrameLoaderClientQt::didPerformFirstNavigation() const
  597. {
  598. if (m_frame->tree()->parent() || !m_webFrame)
  599. return;
  600. m_webFrame->pageAdapter->updateNavigationActions();
  601. }
  602. void FrameLoaderClientQt::registerForIconNotification(bool shouldRegister)
  603. {
  604. #if ENABLE(ICONDATABASE)
  605. if (shouldRegister)
  606. connect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString)), Qt::UniqueConnection);
  607. else
  608. disconnect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString)));
  609. #endif
  610. }
  611. void FrameLoaderClientQt::onIconLoadedForPageURL(const QString& url)
  612. {
  613. #if ENABLE(ICONDATABASE)
  614. if (m_webFrame && m_webFrame->url == url)
  615. m_webFrame->emitIconChanged();
  616. #endif
  617. }
  618. void FrameLoaderClientQt::updateGlobalHistory()
  619. {
  620. QWebHistoryInterface* history = QWebHistoryInterface::defaultInterface();
  621. WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader();
  622. if (history)
  623. history->addHistoryEntry(loader->urlForHistory().string());
  624. if (dumpHistoryCallbacks) {
  625. printf("WebView navigated to url \"%s\" with title \"%s\" with HTTP equivalent method \"%s\". The navigation was %s and was %s%s.\n",
  626. qPrintable(drtDescriptionSuitableForTestResult(loader->urlForHistory())),
  627. qPrintable(QString(loader->title().string())),
  628. qPrintable(QString(loader->request().httpMethod())),
  629. ((loader->substituteData().isValid() || (loader->response().httpStatusCode() >= 400)) ? "a failure" : "successful"),
  630. ((!loader->clientRedirectSourceForHistory().isEmpty()) ? "a client redirect from " : "not a client redirect"),
  631. (!loader->clientRedirectSourceForHistory().isEmpty()) ? qPrintable(drtDescriptionSuitableForTestResult(loader->clientRedirectSourceForHistory())) : "");
  632. }
  633. }
  634. void FrameLoaderClientQt::updateGlobalHistoryRedirectLinks()
  635. {
  636. // Apple WebKit is the only port that makes use of this callback. It calls
  637. // WebCore::HistoryItem::addRedirectURL() with the contents of
  638. // loader->[server|client]RedirectDestinationForHistory().
  639. // WebCore can associate a bunch of redirect URLs with a particular
  640. // item in the history, presumably this allows Safari to skip the redirections
  641. // when navigating to that history item. That might be a feature Qt wants to
  642. // offer through QWebHistoryInterface in the future. For now, we're just
  643. // passing tests in LayoutTests/http/tests/globalhistory.
  644. WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader();
  645. if (!loader->clientRedirectSourceForHistory().isNull()) {
  646. if (dumpHistoryCallbacks) {
  647. printf("WebView performed a client redirect from \"%s\" to \"%s\".\n",
  648. qPrintable(QString(loader->clientRedirectSourceForHistory())),
  649. qPrintable(QString(loader->clientRedirectDestinationForHistory())));
  650. }
  651. }
  652. if (!loader->serverRedirectSourceForHistory().isNull()) {
  653. if (dumpHistoryCallbacks) {
  654. printf("WebView performed a server redirect from \"%s\" to \"%s\".\n",
  655. qPrintable(QString(loader->serverRedirectSourceForHistory())),
  656. qPrintable(QString(loader->serverRedirectDestinationForHistory())));
  657. }
  658. }
  659. }
  660. bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem*) const
  661. {
  662. return true;
  663. }
  664. bool FrameLoaderClientQt::shouldStopLoadingForHistoryItem(WebCore::HistoryItem*) const
  665. {
  666. return true;
  667. }
  668. void FrameLoaderClientQt::didDisplayInsecureContent()
  669. {
  670. if (dumpFrameLoaderCallbacks)
  671. printf("didDisplayInsecureContent\n");
  672. notImplemented();
  673. }
  674. void FrameLoaderClientQt::didRunInsecureContent(WebCore::SecurityOrigin*, const KURL&)
  675. {
  676. if (dumpFrameLoaderCallbacks)
  677. printf("didRunInsecureContent\n");
  678. notImplemented();
  679. }
  680. void FrameLoaderClientQt::didDetectXSS(const KURL&, bool)
  681. {
  682. if (dumpFrameLoaderCallbacks)
  683. printf("didDetectXSS\n");
  684. notImplemented();
  685. }
  686. void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem* item)
  687. {
  688. QWebHistoryItem historyItem(new QWebHistoryItemPrivate(item));
  689. m_webFrame->pageAdapter->emitSaveFrameStateRequested(m_webFrame, &historyItem);
  690. }
  691. bool FrameLoaderClientQt::canCachePage() const
  692. {
  693. return true;
  694. }
  695. void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader, const WebCore::ResourceError& error)
  696. {
  697. if (!m_pluginView)
  698. return;
  699. if (m_pluginView->isPluginView())
  700. m_pluginView->didFail(error);
  701. m_pluginView = 0;
  702. m_hasSentResponseToPlugin = false;
  703. }
  704. // FIXME: This function should be moved into WebCore.
  705. void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
  706. {
  707. if (!m_pluginView)
  708. loader->commitData(data, length);
  709. // If we are sending data to MediaDocument, we should stop here and cancel the request.
  710. if (m_frame->document()->isMediaDocument())
  711. loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
  712. // We re-check here as the plugin can have been created.
  713. if (m_pluginView && m_pluginView->isPluginView()) {
  714. if (!m_hasSentResponseToPlugin) {
  715. m_pluginView->didReceiveResponse(loader->response());
  716. // The function didReceiveResponse sets up a new stream to the plug-in.
  717. // On a full-page plug-in, a failure in setting up this stream can cause the
  718. // main document load to be cancelled, setting m_pluginView to null.
  719. if (!m_pluginView)
  720. return;
  721. m_hasSentResponseToPlugin = true;
  722. }
  723. m_pluginView->didReceiveData(data, length);
  724. }
  725. }
  726. WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request)
  727. {
  728. ResourceError error = ResourceError("QtNetwork", QNetworkReply::OperationCanceledError, request.url().string(),
  729. QCoreApplication::translate("QWebFrame", "Request cancelled", 0));
  730. error.setIsCancellation(true);
  731. return error;
  732. }
  733. // This was copied from file "WebKit/Source/WebKit/mac/Misc/WebKitErrors.h".
  734. enum {
  735. WebKitErrorCannotShowMIMEType = 100,
  736. WebKitErrorCannotShowURL = 101,
  737. WebKitErrorFrameLoadInterruptedByPolicyChange = 102,
  738. WebKitErrorCannotUseRestrictedPort = 103,
  739. WebKitErrorCannotFindPlugIn = 200,
  740. WebKitErrorCannotLoadPlugIn = 201,
  741. WebKitErrorJavaUnavailable = 202,
  742. WebKitErrorPluginWillHandleLoad = 203
  743. };
  744. WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request)
  745. {
  746. return ResourceError("WebKitErrorDomain", WebKitErrorCannotUseRestrictedPort, request.url().string(),
  747. QCoreApplication::translate("QWebFrame", "Request blocked", 0));
  748. }
  749. WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request)
  750. {
  751. return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowURL, request.url().string(),
  752. QCoreApplication::translate("QWebFrame", "Cannot show URL", 0));
  753. }
  754. WebCore::ResourceError FrameLoaderClientQt::interruptedForPolicyChangeError(const WebCore::ResourceRequest& request)
  755. {
  756. return ResourceError("WebKitErrorDomain", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(),
  757. QCoreApplication::translate("QWebFrame", "Frame load interrupted by policy change", 0));
  758. }
  759. WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response)
  760. {
  761. return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowMIMEType, response.url().string(),
  762. QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0));
  763. }
  764. WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response)
  765. {
  766. return ResourceError("QtNetwork", QNetworkReply::ContentNotFoundError, response.url().string(),
  767. QCoreApplication::translate("QWebFrame", "File does not exist", 0));
  768. }
  769. WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response)
  770. {
  771. return ResourceError("WebKit", WebKitErrorPluginWillHandleLoad, response.url().string(),
  772. QCoreApplication::translate("QWebFrame", "Loading is handled by the media engine", 0));
  773. }
  774. bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError& error)
  775. {
  776. DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest())));
  777. DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse())));
  778. DEFINE_STATIC_LOCAL(const ResourceError, errorInterruptedForPolicyChange, (this->interruptedForPolicyChangeError(ResourceRequest())));
  779. if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain())
  780. return false;
  781. if (error.errorCode() == errorInterruptedForPolicyChange.errorCode() && error.domain() == errorInterruptedForPolicyChange.domain())
  782. return false;
  783. if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain())
  784. return false;
  785. return true;
  786. }
  787. WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
  788. {
  789. RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
  790. if (!deferMainResourceDataLoad || substituteData.isValid())
  791. loader->setDeferMainResourceDataLoad(false);
  792. else
  793. m_frame->page()->setCustomHTMLTokenizerTimeDelay(-1);
  794. return loader.release();
  795. }
  796. void FrameLoaderClientQt::convertMainResourceLoadToDownload(WebCore::DocumentLoader* documentLoader, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&)
  797. {
  798. if (!m_webFrame)
  799. return;
  800. QNetworkReplyHandler* handler = documentLoader->mainResourceLoader()->handle()->getInternal()->m_job;
  801. QNetworkReply* reply = handler->release();
  802. if (reply) {
  803. if (m_webFrame->pageAdapter->forwardUnsupportedContent)
  804. emit unsupportedContent(reply);
  805. else
  806. reply->abort();
  807. }
  808. }
  809. void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest& request)
  810. {
  811. if (dumpResourceLoadCallbacks)
  812. dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url());
  813. }
  814. static void blockRequest(WebCore::ResourceRequest& request)
  815. {
  816. request.setURL(QUrl());
  817. }
  818. static bool isLocalhost(const QString& host)
  819. {
  820. return host == QLatin1String("127.0.0.1") || host == QLatin1String("localhost");
  821. }
  822. static bool hostIsUsedBySomeTestsToGenerateError(const QString& host)
  823. {
  824. return host == QLatin1String("255.255.255.255");
  825. }
  826. void FrameLoaderClientQt::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse)
  827. {
  828. if (dumpResourceLoadCallbacks)
  829. printf("%s - willSendRequest %s redirectResponse %s\n",
  830. qPrintable(dumpAssignedUrls[identifier]),
  831. qPrintable(drtDescriptionSuitableForTestResult(newRequest)),
  832. (redirectResponse.isNull()) ? "(null)" : qPrintable(drtDescriptionSuitableForTestResult(redirectResponse)));
  833. if (sendRequestReturnsNull) {
  834. blockRequest(newRequest);
  835. return;
  836. }
  837. if (sendRequestReturnsNullOnRedirect && !redirectResponse.isNull()) {
  838. printf("Returning null for this redirect\n");
  839. blockRequest(newRequest);
  840. return;
  841. }
  842. QUrl url = newRequest.url();
  843. QString host = url.host();
  844. QString urlScheme = url.scheme().toLower();
  845. if (QWebPageAdapter::drtRun
  846. && !host.isEmpty()
  847. && (urlScheme == QLatin1String("http") || urlScheme == QLatin1String("https"))) {
  848. QUrl testURL = m_webFrame->pageAdapter->mainFrameAdapter()->frameLoaderClient->lastRequestedUrl();
  849. QString testHost = testURL.host();
  850. QString testURLScheme = testURL.scheme().toLower();
  851. if (!isLocalhost(host)
  852. && !hostIsUsedBySomeTestsToGenerateError(host)
  853. && ((testURLScheme != QLatin1String("http") && testURLScheme != QLatin1String("https")) || isLocalhost(testHost))) {
  854. printf("Blocked access to external URL %s\n", qPrintable(drtDescriptionSuitableForTestResult(newRequest.url())));
  855. blockRequest(newRequest);
  856. return;
  857. }
  858. }
  859. for (int i = 0; i < sendRequestClearHeaders.size(); ++i)
  860. newRequest.setHTTPHeaderField(sendRequestClearHeaders.at(i).toLocal8Bit().constData(), QString());
  861. if (QWebPageAdapter::drtRun) {
  862. QMap<QString, QString>::const_iterator it = URLsToRedirect.constFind(url.toString());
  863. if (it != URLsToRedirect.constEnd())
  864. newRequest.setURL(QUrl(it.value()));
  865. }
  866. // Seems like the Mac code doesn't do anything here by default neither.
  867. // qDebug() << "FrameLoaderClientQt::dispatchWillSendRequest" << request.isNull() << url;
  868. }
  869. bool FrameLoaderClientQt::shouldUseCredentialStorage(DocumentLoader*, unsigned long)
  870. {
  871. notImplemented();
  872. return false;
  873. }
  874. void FrameLoaderClientQt::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
  875. {
  876. notImplemented();
  877. }
  878. void FrameLoaderClientQt::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
  879. {
  880. notImplemented();
  881. }
  882. void FrameLoaderClientQt::dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse& response)
  883. {
  884. m_response = response;
  885. if (dumpWillCacheResponseCallbacks)
  886. printf("%s - willCacheResponse: called\n",
  887. qPrintable(dumpAssignedUrls[identifier]));
  888. if (dumpResourceLoadCallbacks)
  889. printf("%s - didReceiveResponse %s\n",
  890. qPrintable(dumpAssignedUrls[identifier]),
  891. qPrintable(drtDescriptionSuitableForTestResult(response)));
  892. if (dumpResourceResponseMIMETypes) {
  893. printf("%s has MIME type %s\n",
  894. qPrintable(QString(response.url().lastPathComponent())),
  895. qPrintable(QString(response.mimeType())));
  896. }
  897. }
  898. void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int)
  899. {
  900. }
  901. void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier)
  902. {
  903. if (dumpResourceLoadCallbacks)
  904. printf("%s - didFinishLoading\n",
  905. (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>"));
  906. }
  907. void FrameLoaderClientQt::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
  908. {
  909. if (dumpResourceLoadCallbacks)
  910. printf("%s - didFailLoadingWithError: %s\n",
  911. (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>"),
  912. qPrintable(drtDescriptionSuitableForTestResult(error)));
  913. }
  914. bool FrameLoaderClientQt::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int)
  915. {
  916. notImplemented();
  917. return false;
  918. }
  919. bool FrameLoaderClientQt::callErrorPageExtension(const WebCore::ResourceError& error)
  920. {
  921. QWebPageAdapter* page = m_webFrame->pageAdapter;
  922. if (!page->supportsErrorPageExtension())
  923. return false;
  924. QWebPageAdapter::ErrorPageOption option;
  925. option.url = QUrl(error.failingURL());
  926. option.frame = m_webFrame;
  927. option.domain = error.domain();
  928. option.error = error.errorCode();
  929. option.errorString = error.localizedDescription();
  930. QWebPageAdapter::ErrorPageReturn output;
  931. if (!page->errorPageExtension(&option, &output))
  932. return false;
  933. KURL baseUrl(output.baseUrl);
  934. KURL failingUrl(option.url);
  935. WebCore::ResourceRequest request(baseUrl);
  936. WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(output.content.constData(), output.content.length());
  937. WebCore::SubstituteData substituteData(buffer, output.contentType, output.encoding, failingUrl);
  938. m_frame->loader()->load(WebCore::FrameLoadRequest(m_frame, request, substituteData));
  939. return true;
  940. }
  941. void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError& error)
  942. {
  943. if (dumpFrameLoaderCallbacks)
  944. printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  945. if (!error.isNull() && !error.isCancellation()) {
  946. if (callErrorPageExtension(error))
  947. return;
  948. }
  949. if (m_webFrame)
  950. emitLoadFinished(false);
  951. }
  952. void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError& error)
  953. {
  954. if (dumpFrameLoaderCallbacks)
  955. printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
  956. if (!error.isNull() && !error.isCancellation()) {
  957. if (callErrorPageExtension(error))
  958. return;
  959. }
  960. if (m_webFrame)
  961. emitLoadFinished(false);
  962. }
  963. WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage(const WebCore::NavigationAction&)
  964. {
  965. if (!m_webFrame)
  966. return 0;
  967. QWebPageAdapter* newPage = m_webFrame->pageAdapter->createWindow(/* modalDialog = */ false);
  968. if (!newPage)
  969. return 0;
  970. return newPage->mainFrameAdapter()->frame;
  971. }
  972. void FrameLoaderClientQt::dispatchDecidePolicyForResponse(FramePolicyFunction function, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest&)
  973. {
  974. // We need to call directly here.
  975. switch (response.httpStatusCode()) {
  976. case HTTPResetContent:
  977. // FIXME: a 205 response requires that the requester reset the document view.
  978. // Fallthrough
  979. case HTTPNoContent:
  980. callPolicyFunction(function, PolicyIgnore);
  981. return;
  982. }
  983. if (WebCore::contentDispositionType(response.httpHeaderField("Content-Disposition")) == WebCore::ContentDispositionAttachment)
  984. callPolicyFunction(function, PolicyDownload);
  985. else if (canShowMIMEType(response.mimeType()))
  986. callPolicyFunction(function, PolicyUse);
  987. else
  988. callPolicyFunction(function, PolicyDownload);
  989. }
  990. void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WTF::String&)
  991. {
  992. Q_ASSERT(m_webFrame);
  993. QNetworkRequest r(request.toNetworkRequest(m_frame->loader()->networkingContext()));
  994. if (!m_webFrame->pageAdapter->acceptNavigationRequest(0, r, (int)action.type())) {
  995. if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
  996. m_frame->loader()->resetMultipleFormSubmissionProtection();
  997. if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
  998. ResourceRequest emptyRequest;
  999. m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
  1000. }
  1001. callPolicyFunction(function, PolicyIgnore);
  1002. return;
  1003. }
  1004. callPolicyFunction(function, PolicyUse);
  1005. }
  1006. void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>)
  1007. {
  1008. Q_ASSERT(m_webFrame);
  1009. QNetworkRequest r(request.toNetworkRequest(m_frame->loader()->networkingContext()));
  1010. PolicyAction result;
  1011. // Currently, this is only enabled by DRT.
  1012. if (policyDelegateEnabled) {
  1013. RefPtr<Node> node;
  1014. for (const Event* event = action.event(); event; event = event->underlyingEvent()) {
  1015. if (event->isMouseEvent()) {
  1016. const MouseEvent* mouseEvent = static_cast<const MouseEvent*>(event);
  1017. node = m_webFrame->frame->eventHandler()->hitTestResultAtPoint(
  1018. mouseEvent->absoluteLocation()).innerNonSharedNode();
  1019. break;
  1020. }
  1021. }
  1022. printf("Policy delegate: attempt to load %s with navigation type '%s'%s\n",
  1023. qPrintable(drtDescriptionSuitableForTestResult(request.url())), navigationTypeToString(action.type()),
  1024. (node) ? qPrintable(QString::fromLatin1(" originating from ") + drtDescriptionSuitableForTestResult(node, 0)) : "");
  1025. if (policyDelegatePermissive)
  1026. result = PolicyUse;
  1027. else
  1028. result = PolicyIgnore;
  1029. m_webFrame->pageAdapter->acceptNavigationRequest(m_webFrame, r, (int)action.type());
  1030. callPolicyFunction(function, result);
  1031. return;
  1032. }
  1033. if (!m_webFrame->pageAdapter->acceptNavigationRequest(m_webFrame, r, (int)action.type())) {
  1034. if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
  1035. m_frame->loader()->resetMultipleFormSubmissionProtection();
  1036. if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
  1037. ResourceRequest emptyRequest;
  1038. m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
  1039. }
  1040. callPolicyFunction(function, PolicyIgnore);
  1041. return;
  1042. }
  1043. callPolicyFunction(function, PolicyUse);
  1044. }
  1045. void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::ResourceError&)
  1046. {
  1047. notImplemented();
  1048. }
  1049. void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request, const String& /* suggestedName */)
  1050. {
  1051. if (!m_webFrame)
  1052. return;
  1053. m_webFrame->pageAdapter->emitDownloadRequested(request.toNetworkRequest(m_frame->loader()->networkingContext()));
  1054. }
  1055. PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
  1056. {
  1057. if (!m_webFrame)
  1058. return 0;
  1059. QWebFrameData frameData(m_frame->page(), m_frame, ownerElement, name);
  1060. frameData.referrer = referrer;
  1061. frameData.allowsScrolling = allowsScrolling;
  1062. frameData.marginWidth = marginWidth;
  1063. frameData.marginHeight = marginHeight;
  1064. QWebFrameAdapter* childWebFrame = m_webFrame->createChildFrame(&frameData);
  1065. // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
  1066. if (!childWebFrame->frame->page()) {
  1067. QPointer<QObject> qWebFrame = childWebFrame->handle();
  1068. frameData.frame.release();
  1069. ASSERT_UNUSED(qWebFrame, !qWebFrame);
  1070. return 0;
  1071. }
  1072. m_webFrame->pageAdapter->emitFrameCreated(childWebFrame);
  1073. // FIXME: Set override encoding if we have one.
  1074. KURL urlToLoad = url;
  1075. if (urlToLoad.isEmpty())
  1076. urlToLoad = blankURL();
  1077. m_frame->loader()->loadURLIntoChildFrame(urlToLoad, frameData.referrer, frameData.frame.get());
  1078. // The frame's onload handler may have removed it from the document.
  1079. if (!frameData.frame->tree()->parent())
  1080. return 0;
  1081. return frameData.frame.release();
  1082. }
  1083. ObjectContentType FrameLoaderClientQt::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
  1084. {
  1085. // qDebug()<<" ++++++++++++++++ url is "<<url.string()<<", mime = "<<mimeTypeIn;
  1086. QFileInfo fi(url.path());
  1087. String extension = fi.suffix();
  1088. if (mimeTypeIn == "application/x-qt-plugin" || mimeTypeIn == "application/x-qt-styled-widget")
  1089. return ObjectContentOtherPlugin;
  1090. if (url.isEmpty() && !mimeTypeIn.length())
  1091. return ObjectContentNone;
  1092. String mimeType = mimeTypeIn;
  1093. if (!mimeType.length())
  1094. mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
  1095. bool arePluginsEnabled = (m_frame && m_frame->settings() && m_frame->settings()->arePluginsEnabled());
  1096. if (arePluginsEnabled && !mimeType.length())
  1097. mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(extension);
  1098. if (!mimeType.length())
  1099. return ObjectContentFrame;
  1100. ObjectContentType plugInType = ObjectContentNone;
  1101. if (arePluginsEnabled && PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
  1102. plugInType = ObjectContentNetscapePlugin;
  1103. else if (m_frame->page() && m_frame->page()->pluginData()) {
  1104. bool allowPlugins = m_frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin);
  1105. if ((m_frame->page()->pluginData()->supportsMimeType(mimeType, PluginData::AllPlugins) && allowPlugins)
  1106. || m_frame->page()->pluginData()->supportsMimeType(mimeType, PluginData::OnlyApplicationPlugins))
  1107. plugInType = ObjectContentOtherPlugin;
  1108. }
  1109. if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
  1110. return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
  1111. if (plugInType != ObjectContentNone)
  1112. return plugInType;
  1113. if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
  1114. return ObjectContentFrame;
  1115. if (url.protocol() == "about")
  1116. return ObjectContentFrame;
  1117. return ObjectContentNone;
  1118. }
  1119. static const CSSPropertyID qstyleSheetProperties[] = {
  1120. CSSPropertyColor,
  1121. CSSPropertyFontFamily,
  1122. CSSPropertyFontSize,
  1123. CSSPropertyFontStyle,
  1124. CSSPropertyFontWeight
  1125. };
  1126. const unsigned numqStyleSheetProperties = sizeof(qstyleSheetProperties) / sizeof(qstyleSheetProperties[0]);
  1127. class QtPluginWidget: public Widget {
  1128. public:
  1129. QtPluginWidget(QtPluginWidgetAdapter* w)
  1130. : Widget(w->handle())
  1131. , m_adapter(w)
  1132. {
  1133. setBindingObject(w->handle());
  1134. }
  1135. ~QtPluginWidget()
  1136. {
  1137. delete m_adapter;
  1138. }
  1139. inline QtPluginWidgetAdapter* widgetAdapter() const
  1140. {
  1141. return m_adapter;
  1142. }
  1143. virtual void invalidateRect(const IntRect& r)
  1144. {
  1145. if (platformWidget())
  1146. widgetAdapter()->update(r);
  1147. }
  1148. virtual void frameRectsChanged()
  1149. {
  1150. QtPluginWidgetAdapter* widget = widgetAdapter();
  1151. if (!widget)
  1152. return;
  1153. QRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height()));
  1154. ScrollView* parentScrollView = parent();
  1155. QRect clipRect;
  1156. if (parentScrollView) {
  1157. ASSERT_WITH_SECURITY_IMPLICATION(parentScrollView->isFrameView());
  1158. clipRect = toFrameView(parentScrollView)->windowClipRect();
  1159. clipRect.translate(-windowRect.x(), -windowRect.y());
  1160. }
  1161. widget->setGeometryAndClip(windowRect, clipRect, isVisible());
  1162. }
  1163. virtual void show()
  1164. {
  1165. Widget::show();
  1166. handleVisibility();
  1167. }
  1168. virtual void hide()
  1169. {
  1170. Widget::hide();
  1171. if (platformWidget())
  1172. widgetAdapter()->setVisible(false);
  1173. }
  1174. private:
  1175. QtPluginWidgetAdapter* m_adapter;
  1176. void handleVisibility()
  1177. {
  1178. if (!isVisible())
  1179. return;
  1180. widgetAdapter()->setVisible(true);
  1181. }
  1182. };
  1183. PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
  1184. {
  1185. // qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.string() << mimeType;
  1186. // qDebug()<<"------\t url = "<<url.string();
  1187. if (!m_webFrame)
  1188. return 0;
  1189. QStringList params;
  1190. QStringList values;
  1191. QString classid(element->getAttribute("classid"));
  1192. for (unsigned i = 0; i < paramNames.size(); ++i) {
  1193. params.append(paramNames[i]);
  1194. if (paramNames[i] == "classid")
  1195. classid = paramValues[i];
  1196. }
  1197. for (unsigned i = 0; i < paramValues.size(); ++i)
  1198. values.append(paramValues[i]);
  1199. QString urlStr(url.string());
  1200. QUrl qurl = urlStr;
  1201. QObject* pluginAdapter = 0;
  1202. if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") {
  1203. pluginAdapter = m_webFrame->pageAdapter->createPlugin(classid, qurl, params, values);
  1204. #ifndef QT_NO_STYLE_STYLESHEET
  1205. QtPluginWidgetAdapter* widget = qobject_cast<QtPluginWidgetAdapter*>(pluginAdapter);
  1206. if (widget && mimeType == "application/x-qt-styled-widget") {
  1207. StringBuilder styleSheet;
  1208. styleSheet.append(element->getAttribute("style"));
  1209. if (!styleSheet.isEmpty())
  1210. styleSheet.append(';');
  1211. for (unsigned i = 0; i < numqStyleSheetProperties; ++i) {
  1212. CSSPropertyID property = qstyleSheetProperties[i];
  1213. styleSheet.append(getPropertyName(property));
  1214. styleSheet.append(':');
  1215. styleSheet.append(CSSComputedStyleDeclaration::create(element)->getPropertyValue(property));
  1216. styleSheet.append(';');
  1217. }
  1218. widget->setStyleSheet(styleSheet.toString());
  1219. }
  1220. #endif // QT_NO_STYLE_STYLESHEET
  1221. }
  1222. if (!pluginAdapter) {
  1223. QWebPluginFactory* factory = m_webFrame->pageAdapter->pluginFactory;
  1224. if (factory)
  1225. pluginAdapter = m_webFrame->pageAdapter->adapterForWidget(factory->create(mimeType, qurl, params, values));
  1226. }
  1227. if (pluginAdapter) {
  1228. QtPluginWidgetAdapter* widget = qobject_cast<QtPluginWidgetAdapter*>(pluginAdapter);
  1229. if (widget) {
  1230. QObject* parentWidget = 0;
  1231. if (m_webFrame->pageAdapter->client)
  1232. parentWidget = m_webFrame->pageAdapter->client->pluginParent();
  1233. if (parentWidget) // Don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose.
  1234. widget->setWidgetParent(parentWidget);
  1235. widget->setVisible(false);
  1236. RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget(widget));
  1237. // Make sure it's invisible until properly placed into the layout.
  1238. w->setFrameRect(IntRect(0, 0, 0, 0));
  1239. return w;
  1240. }
  1241. // FIXME: Make things work for widgetless plugins as well.
  1242. delete pluginAdapter;
  1243. }
  1244. #if ENABLE(NETSCAPE_PLUGIN_API)
  1245. else { // NPAPI Plugins
  1246. Vector<String> params = paramNames;
  1247. Vector<String> values = paramValues;
  1248. if (mimeType == "application/x-shockwave-flash") {
  1249. // Inject wmode=opaque when there is no client or the client is not a QWebView.
  1250. size_t wmodeIndex = params.find("wmode");
  1251. if (wmodeIndex == WTF::notFound) {
  1252. params.append("wmode");
  1253. values.append("opaque");
  1254. } else if (equalIgnoringCase(values[wmodeIndex], "window"))
  1255. values[wmodeIndex] = "opaque";
  1256. }
  1257. RefPtr<PluginView> pluginView = PluginView::create(m_frame, pluginSize, element, url,
  1258. params, values, mimeType, loadManually);
  1259. return pluginView;
  1260. }
  1261. #endif // ENABLE(NETSCAPE_PLUGIN_API)
  1262. return 0;
  1263. }
  1264. void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget)
  1265. {
  1266. m_pluginView = toPluginView(pluginWidget);
  1267. if (pluginWidget)
  1268. m_hasSentResponseToPlugin = false;
  1269. }
  1270. PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues)
  1271. {
  1272. return createPlugin(pluginSize, element, url, paramNames, paramValues, "application/x-java-applet", true);
  1273. }
  1274. String FrameLoaderClientQt::overrideMediaType() const
  1275. {
  1276. if (m_webFrame && m_webFrame->pageAdapter && m_webFrame->pageAdapter->settings)
  1277. return m_webFrame->pageAdapter->settings->cssMediaType();
  1278. return String();
  1279. }
  1280. QString FrameLoaderClientQt::chooseFile(const QString& oldFile)
  1281. {
  1282. QStringList result = m_webFrame->pageAdapter->chooseFiles(m_webFrame, /*allowMulti*/ false, (QStringList() << oldFile));
  1283. return result.isEmpty() ? QString() : result.first();
  1284. }
  1285. PassRefPtr<FrameNetworkingContext> FrameLoaderClientQt::createNetworkingContext()
  1286. {
  1287. QVariant value = m_webFrame->pageAdapter->handle()->property("_q_MIMESniffingDisabled");
  1288. bool MIMESniffingDisabled = value.isValid() && value.toBool();
  1289. return FrameNetworkingContextQt::create(m_frame, m_webFrame->handle(), !MIMESniffingDisabled);
  1290. }
  1291. QWebFrameAdapter* FrameLoaderClientQt::webFrame() const
  1292. {
  1293. return m_webFrame;
  1294. }
  1295. void FrameLoaderClientQt::emitLoadStarted()
  1296. {
  1297. m_webFrame->emitLoadStarted(m_isOriginatingLoad);
  1298. }
  1299. void FrameLoaderClientQt::emitLoadFinished(bool ok)
  1300. {
  1301. // Signal handlers can lead to a new load, that will use the member again.
  1302. const bool wasOriginatingLoad = m_isOriginatingLoad;
  1303. m_isOriginatingLoad = false;
  1304. m_webFrame->emitLoadFinished(wasOriginatingLoad, ok);
  1305. }
  1306. }
  1307. #include "moc_FrameLoaderClientQt.cpp"