/src/3rdparty/webkit/Source/WebKit/qt/Api/qwebpage.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 4219 lines · 2641 code · 403 blank · 1175 comment · 401 complexity · a3c2af90db056dba79fb76b251779af7 MD5 · raw file

  1. /*
  2. Copyright (C) 2008, 2009 Nokia Corporation and/or its subsidiary(-ies)
  3. Copyright (C) 2007 Staikos Computing Services Inc.
  4. Copyright (C) 2007 Apple Inc.
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public License
  14. along with this library; see the file COPYING.LIB. If not, write to
  15. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. Boston, MA 02110-1301, USA.
  17. */
  18. #include "config.h"
  19. #include "qwebpage.h"
  20. #include "qwebview.h"
  21. #include "qwebframe.h"
  22. #include "qwebpage_p.h"
  23. #include "qwebframe_p.h"
  24. #include "qwebhistory.h"
  25. #include "qwebhistory_p.h"
  26. #include "qwebinspector.h"
  27. #include "qwebinspector_p.h"
  28. #include "qwebsettings.h"
  29. #include "qwebkitplatformplugin.h"
  30. #include "qwebkitversion.h"
  31. #include "CSSComputedStyleDeclaration.h"
  32. #include "CSSParser.h"
  33. #include "ApplicationCacheStorage.h"
  34. #include "BackForwardListImpl.h"
  35. #include "MemoryCache.h"
  36. #include "Chrome.h"
  37. #include "ChromeClientQt.h"
  38. #include "ClientRect.h"
  39. #include "ContextMenu.h"
  40. #include "ContextMenuClientQt.h"
  41. #include "ContextMenuController.h"
  42. #include "DeviceMotionClientQt.h"
  43. #include "DeviceOrientationClientQt.h"
  44. #include "DocumentLoader.h"
  45. #include "DragClientQt.h"
  46. #include "DragController.h"
  47. #include "DragData.h"
  48. #include "Editor.h"
  49. #include "EditorClientQt.h"
  50. #include "FocusController.h"
  51. #include "FormState.h"
  52. #include "Frame.h"
  53. #include "FrameLoadRequest.h"
  54. #include "FrameLoader.h"
  55. #include "FrameLoader.h"
  56. #include "FrameLoaderClientQt.h"
  57. #include "FrameTree.h"
  58. #include "FrameView.h"
  59. #if ENABLE(CLIENT_BASED_GEOLOCATION)
  60. #include "GeolocationClientMock.h"
  61. #include "GeolocationClientQt.h"
  62. #endif // CLIENT_BASED_GEOLOCATION
  63. #include "GeolocationPermissionClientQt.h"
  64. #include "HTMLFormElement.h"
  65. #include "HTMLFrameOwnerElement.h"
  66. #include "HTMLInputElement.h"
  67. #include "HTMLNames.h"
  68. #include "HashMap.h"
  69. #include "HitTestResult.h"
  70. #include "Image.h"
  71. #include "InspectorClientQt.h"
  72. #include "InspectorController.h"
  73. #include "InspectorServerQt.h"
  74. #include "KURL.h"
  75. #include "LocalizedStrings.h"
  76. #include "Logging.h"
  77. #include "MIMETypeRegistry.h"
  78. #include "NavigationAction.h"
  79. #include "NetworkingContext.h"
  80. #include "NodeList.h"
  81. #include "NotificationPresenterClientQt.h"
  82. #include "NotImplemented.h"
  83. #include "Page.h"
  84. #include "PageClientQt.h"
  85. #include "PageGroup.h"
  86. #include "Pasteboard.h"
  87. #include "PlatformKeyboardEvent.h"
  88. #include "PlatformTouchEvent.h"
  89. #include "PlatformWheelEvent.h"
  90. #include "PluginDatabase.h"
  91. #include "PluginDatabase.h"
  92. #include "PluginPackage.h"
  93. #include "ProgressTracker.h"
  94. #include "QtPlatformPlugin.h"
  95. #include "RefPtr.h"
  96. #include "RenderTextControl.h"
  97. #include "SchemeRegistry.h"
  98. #include "Scrollbar.h"
  99. #include "SecurityOrigin.h"
  100. #include "Settings.h"
  101. #if defined Q_OS_WIN32
  102. #include "SystemInfo.h"
  103. #endif // Q_OS_WIN32
  104. #include "TextIterator.h"
  105. #include "WebPlatformStrategies.h"
  106. #if USE(QTKIT)
  107. #include "WebSystemInterface.h"
  108. #endif
  109. #include "WindowFeatures.h"
  110. #include "WorkerThread.h"
  111. #include "runtime/InitializeThreading.h"
  112. #include "wtf/Threading.h"
  113. #include <QApplication>
  114. #include <QBasicTimer>
  115. #include <QBitArray>
  116. #include <QDebug>
  117. #include <QDesktopWidget>
  118. #include <QDragEnterEvent>
  119. #include <QDragLeaveEvent>
  120. #include <QDragMoveEvent>
  121. #include <QDropEvent>
  122. #include <QFileDialog>
  123. #include <QHttpRequestHeader>
  124. #include <QInputDialog>
  125. #include <QMessageBox>
  126. #include <QNetworkProxy>
  127. #include <QUndoStack>
  128. #include <QUrl>
  129. #include <QPainter>
  130. #include <QClipboard>
  131. #include <QSslSocket>
  132. #include <QStyle>
  133. #include <QSysInfo>
  134. #include <QTextCharFormat>
  135. #include <QTextDocument>
  136. #include <QTouchEvent>
  137. #include <QNetworkAccessManager>
  138. #include <QNetworkRequest>
  139. #if defined(Q_WS_X11)
  140. #include <QX11Info>
  141. #endif
  142. #if USE(QT_MOBILITY_SYSTEMINFO)
  143. #include <qsysteminfo.h>
  144. #endif
  145. using namespace WebCore;
  146. // from text/qfont.cpp
  147. QT_BEGIN_NAMESPACE
  148. extern Q_GUI_EXPORT int qt_defaultDpi();
  149. QT_END_NAMESPACE
  150. bool QWebPagePrivate::drtRun = false;
  151. // Lookup table mapping QWebPage::WebActions to the associated Editor commands
  152. static const char* editorCommandWebActions[] =
  153. {
  154. 0, // OpenLink,
  155. 0, // OpenLinkInNewWindow,
  156. 0, // OpenFrameInNewWindow,
  157. 0, // DownloadLinkToDisk,
  158. 0, // CopyLinkToClipboard,
  159. 0, // OpenImageInNewWindow,
  160. 0, // DownloadImageToDisk,
  161. 0, // CopyImageToClipboard,
  162. 0, // Back,
  163. 0, // Forward,
  164. 0, // Stop,
  165. 0, // Reload,
  166. "Cut", // Cut,
  167. "Copy", // Copy,
  168. "Paste", // Paste,
  169. "Undo", // Undo,
  170. "Redo", // Redo,
  171. "MoveForward", // MoveToNextChar,
  172. "MoveBackward", // MoveToPreviousChar,
  173. "MoveWordForward", // MoveToNextWord,
  174. "MoveWordBackward", // MoveToPreviousWord,
  175. "MoveDown", // MoveToNextLine,
  176. "MoveUp", // MoveToPreviousLine,
  177. "MoveToBeginningOfLine", // MoveToStartOfLine,
  178. "MoveToEndOfLine", // MoveToEndOfLine,
  179. "MoveToBeginningOfParagraph", // MoveToStartOfBlock,
  180. "MoveToEndOfParagraph", // MoveToEndOfBlock,
  181. "MoveToBeginningOfDocument", // MoveToStartOfDocument,
  182. "MoveToEndOfDocument", // MoveToEndOfDocument,
  183. "MoveForwardAndModifySelection", // SelectNextChar,
  184. "MoveBackwardAndModifySelection", // SelectPreviousChar,
  185. "MoveWordForwardAndModifySelection", // SelectNextWord,
  186. "MoveWordBackwardAndModifySelection", // SelectPreviousWord,
  187. "MoveDownAndModifySelection", // SelectNextLine,
  188. "MoveUpAndModifySelection", // SelectPreviousLine,
  189. "MoveToBeginningOfLineAndModifySelection", // SelectStartOfLine,
  190. "MoveToEndOfLineAndModifySelection", // SelectEndOfLine,
  191. "MoveToBeginningOfParagraphAndModifySelection", // SelectStartOfBlock,
  192. "MoveToEndOfParagraphAndModifySelection", // SelectEndOfBlock,
  193. "MoveToBeginningOfDocumentAndModifySelection", //SelectStartOfDocument,
  194. "MoveToEndOfDocumentAndModifySelection", // SelectEndOfDocument,
  195. "DeleteWordBackward", // DeleteStartOfWord,
  196. "DeleteWordForward", // DeleteEndOfWord,
  197. 0, // SetTextDirectionDefault,
  198. 0, // SetTextDirectionLeftToRight,
  199. 0, // SetTextDirectionRightToLeft,
  200. "ToggleBold", // ToggleBold,
  201. "ToggleItalic", // ToggleItalic,
  202. "ToggleUnderline", // ToggleUnderline,
  203. 0, // InspectElement,
  204. "InsertNewline", // InsertParagraphSeparator
  205. "InsertLineBreak", // InsertLineSeparator
  206. "SelectAll", // SelectAll
  207. 0, // ReloadAndBypassCache,
  208. "PasteAndMatchStyle", // PasteAndMatchStyle
  209. "RemoveFormat", // RemoveFormat
  210. "Strikethrough", // ToggleStrikethrough,
  211. "Subscript", // ToggleSubscript
  212. "Superscript", // ToggleSuperscript
  213. "InsertUnorderedList", // InsertUnorderedList
  214. "InsertOrderedList", // InsertOrderedList
  215. "Indent", // Indent
  216. "Outdent", // Outdent,
  217. "AlignCenter", // AlignCenter,
  218. "AlignJustified", // AlignJustified,
  219. "AlignLeft", // AlignLeft,
  220. "AlignRight", // AlignRight,
  221. 0, // StopScheduledPageRefresh,
  222. 0, // CopyImageUrlToClipboard,
  223. 0 // WebActionCount
  224. };
  225. // Lookup the appropriate editor command to use for WebAction \a action
  226. const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action)
  227. {
  228. if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*))))
  229. return editorCommandWebActions[action];
  230. return 0;
  231. }
  232. static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
  233. {
  234. unsigned result = 0;
  235. if (actions & Qt::CopyAction)
  236. result |= DragOperationCopy;
  237. // DragOperationgeneric represents InternetExplorer's equivalent of Move operation,
  238. // hence it should be considered as "move"
  239. if (actions & Qt::MoveAction)
  240. result |= (DragOperationMove | DragOperationGeneric);
  241. if (actions & Qt::LinkAction)
  242. result |= DragOperationLink;
  243. if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink))
  244. result = DragOperationEvery;
  245. return (DragOperation)result;
  246. }
  247. static inline Qt::DropAction dragOpToDropAction(unsigned actions)
  248. {
  249. Qt::DropAction result = Qt::IgnoreAction;
  250. if (actions & DragOperationCopy)
  251. result = Qt::CopyAction;
  252. else if (actions & DragOperationMove)
  253. result = Qt::MoveAction;
  254. // DragOperationgeneric represents InternetExplorer's equivalent of Move operation,
  255. // hence it should be considered as "move"
  256. else if (actions & DragOperationGeneric)
  257. result = Qt::MoveAction;
  258. else if (actions & DragOperationLink)
  259. result = Qt::LinkAction;
  260. return result;
  261. }
  262. QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
  263. : q(qq)
  264. , page(0)
  265. , mainFrame(0)
  266. #ifndef QT_NO_UNDOSTACK
  267. , undoStack(0)
  268. #endif
  269. , insideOpenCall(false)
  270. , m_totalBytes(0)
  271. , m_bytesReceived()
  272. , clickCausedFocus(false)
  273. , networkManager(0)
  274. , forwardUnsupportedContent(false)
  275. , smartInsertDeleteEnabled(true)
  276. , selectTrailingWhitespaceEnabled(false)
  277. , linkPolicy(QWebPage::DontDelegateLinks)
  278. , viewportSize(QSize(0, 0))
  279. , pixelRatio(1)
  280. #ifndef QT_NO_CONTEXTMENU
  281. , currentContextMenu(0)
  282. #endif
  283. , settings(0)
  284. , useFixedLayout(false)
  285. , pluginFactory(0)
  286. , inspectorFrontend(0)
  287. , inspector(0)
  288. , inspectorIsInternalOnly(false)
  289. , m_lastDropAction(Qt::IgnoreAction)
  290. {
  291. WebCore::InitializeLoggingChannelsIfNecessary();
  292. ScriptController::initializeThreading();
  293. WTF::initializeMainThread();
  294. WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);
  295. WebPlatformStrategies::initialize();
  296. #if USE(QTKIT)
  297. InitWebCoreSystemInterface();
  298. #endif
  299. Page::PageClients pageClients;
  300. pageClients.chromeClient = new ChromeClientQt(q);
  301. pageClients.contextMenuClient = new ContextMenuClientQt();
  302. pageClients.editorClient = new EditorClientQt(q);
  303. pageClients.dragClient = new DragClientQt(q);
  304. pageClients.inspectorClient = new InspectorClientQt(q);
  305. #if ENABLE(DEVICE_ORIENTATION)
  306. pageClients.deviceOrientationClient = new DeviceOrientationClientQt(q);
  307. pageClients.deviceMotionClient = new DeviceMotionClientQt(q);
  308. #endif
  309. #if ENABLE(CLIENT_BASED_GEOLOCATION)
  310. if (QWebPagePrivate::drtRun)
  311. pageClients.geolocationClient = new GeolocationClientMock();
  312. else
  313. pageClients.geolocationClient = new GeolocationClientQt(q);
  314. #endif
  315. page = new Page(pageClients);
  316. // By default each page is put into their own unique page group, which affects popup windows
  317. // and visited links. Page groups (per process only) is a feature making it possible to use
  318. // separate settings for each group, so that for instance an integrated browser/email reader
  319. // can use different settings for displaying HTML pages and HTML email. To make QtWebKit work
  320. // as expected out of the box, we use a default group similar to what other ports are doing.
  321. page->setGroupName("Default Group");
  322. #if ENABLE(CLIENT_BASED_GEOLOCATION)
  323. // In case running in DumpRenderTree mode set the controller to mock provider.
  324. if (QWebPagePrivate::drtRun)
  325. static_cast<GeolocationClientMock*>(pageClients.geolocationClient)->setController(page->geolocationController());
  326. #endif
  327. settings = new QWebSettings(page->settings());
  328. history.d = new QWebHistoryPrivate(static_cast<WebCore::BackForwardListImpl*>(page->backForwardList()));
  329. memset(actions, 0, sizeof(actions));
  330. PageGroup::setShouldTrackVisitedLinks(true);
  331. #if ENABLE(NOTIFICATIONS)
  332. NotificationPresenterClientQt::notificationPresenter()->addClient();
  333. #endif
  334. }
  335. QWebPagePrivate::~QWebPagePrivate()
  336. {
  337. if (inspector && inspectorIsInternalOnly) {
  338. // Since we have to delete an internal inspector,
  339. // call setInspector(0) directly to prevent potential crashes
  340. setInspector(0);
  341. }
  342. #ifndef QT_NO_CONTEXTMENU
  343. delete currentContextMenu;
  344. #endif
  345. #ifndef QT_NO_UNDOSTACK
  346. delete undoStack;
  347. #endif
  348. delete settings;
  349. delete page;
  350. if (inspector)
  351. inspector->setPage(0);
  352. #if ENABLE(NOTIFICATIONS)
  353. NotificationPresenterClientQt::notificationPresenter()->removeClient();
  354. #endif
  355. }
  356. WebCore::ViewportArguments QWebPagePrivate::viewportArguments()
  357. {
  358. return page ? page->viewportArguments() : WebCore::ViewportArguments();
  359. }
  360. WebCore::Page* QWebPagePrivate::core(const QWebPage* page)
  361. {
  362. return page->d->page;
  363. }
  364. QWebPagePrivate* QWebPagePrivate::priv(QWebPage* page)
  365. {
  366. return page->d;
  367. }
  368. bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
  369. {
  370. if (insideOpenCall
  371. && frame == mainFrame)
  372. return true;
  373. return q->acceptNavigationRequest(frame, request, type);
  374. }
  375. void QWebPagePrivate::createMainFrame()
  376. {
  377. if (!mainFrame) {
  378. QWebFrameData frameData(page);
  379. mainFrame = new QWebFrame(q, &frameData);
  380. emit q->frameCreated(mainFrame);
  381. }
  382. }
  383. static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
  384. {
  385. switch (action) {
  386. case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
  387. case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
  388. case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
  389. case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
  390. case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
  391. case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
  392. case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
  393. case WebCore::ContextMenuItemTagCopyImageUrlToClipboard: return QWebPage::CopyImageUrlToClipboard;
  394. case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
  395. case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
  396. case WebCore::ContextMenuItemTagGoBack: return QWebPage::Back;
  397. case WebCore::ContextMenuItemTagGoForward: return QWebPage::Forward;
  398. case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
  399. case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
  400. case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
  401. case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
  402. case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault;
  403. case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight;
  404. case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft;
  405. case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold;
  406. case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic;
  407. case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline;
  408. case WebCore::ContextMenuItemTagSelectAll: return QWebPage::SelectAll;
  409. #if ENABLE(INSPECTOR)
  410. case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement;
  411. #endif
  412. default: break;
  413. }
  414. return QWebPage::NoWebAction;
  415. }
  416. #ifndef QT_NO_CONTEXTMENU
  417. QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu,
  418. const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions)
  419. {
  420. if (!client || !webcoreMenu)
  421. return 0;
  422. QMenu* menu = new QMenu(client->ownerWidget());
  423. for (int i = 0; i < items->count(); ++i) {
  424. const ContextMenuItem &item = items->at(i);
  425. switch (item.type()) {
  426. case WebCore::CheckableActionType: /* fall through */
  427. case WebCore::ActionType: {
  428. QWebPage::WebAction action = webActionForContextMenuAction(item.action());
  429. QAction *a = q->action(action);
  430. if (a) {
  431. ContextMenuItem it(item);
  432. page->contextMenuController()->checkOrEnableIfNeeded(it);
  433. PlatformMenuItemDescription desc = it.releasePlatformDescription();
  434. a->setEnabled(desc.enabled);
  435. a->setChecked(desc.checked);
  436. a->setCheckable(item.type() == WebCore::CheckableActionType);
  437. menu->addAction(a);
  438. visitedWebActions->setBit(action);
  439. }
  440. break;
  441. }
  442. case WebCore::SeparatorType:
  443. menu->addSeparator();
  444. break;
  445. case WebCore::SubmenuType: {
  446. QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu(), visitedWebActions);
  447. bool anyEnabledAction = false;
  448. QList<QAction *> actions = subMenu->actions();
  449. for (int i = 0; i < actions.count(); ++i) {
  450. if (actions.at(i)->isVisible())
  451. anyEnabledAction |= actions.at(i)->isEnabled();
  452. }
  453. // don't show sub-menus with just disabled actions
  454. if (anyEnabledAction) {
  455. subMenu->setTitle(item.title());
  456. menu->addAction(subMenu->menuAction());
  457. } else
  458. delete subMenu;
  459. break;
  460. }
  461. }
  462. }
  463. return menu;
  464. }
  465. #endif // QT_NO_CONTEXTMENU
  466. #ifndef QT_NO_ACTION
  467. void QWebPagePrivate::_q_webActionTriggered(bool checked)
  468. {
  469. QAction *a = qobject_cast<QAction *>(q->sender());
  470. if (!a)
  471. return;
  472. QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
  473. q->triggerAction(action, checked);
  474. }
  475. #endif // QT_NO_ACTION
  476. void QWebPagePrivate::_q_cleanupLeakMessages()
  477. {
  478. #ifndef NDEBUG
  479. // Need this to make leak messages accurate.
  480. memoryCache()->setCapacities(0, 0, 0);
  481. #endif
  482. }
  483. void QWebPagePrivate::updateAction(QWebPage::WebAction action)
  484. {
  485. #ifdef QT_NO_ACTION
  486. Q_UNUSED(action)
  487. #else
  488. QAction *a = actions[action];
  489. if (!a || !mainFrame)
  490. return;
  491. WebCore::FrameLoader *loader = mainFrame->d->frame->loader();
  492. WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
  493. bool enabled = a->isEnabled();
  494. bool checked = a->isChecked();
  495. switch (action) {
  496. case QWebPage::Back:
  497. enabled = page->canGoBackOrForward(-1);
  498. break;
  499. case QWebPage::Forward:
  500. enabled = page->canGoBackOrForward(1);
  501. break;
  502. case QWebPage::Stop:
  503. enabled = loader->isLoading();
  504. break;
  505. case QWebPage::Reload:
  506. case QWebPage::ReloadAndBypassCache:
  507. enabled = !loader->isLoading();
  508. break;
  509. #ifndef QT_NO_UNDOSTACK
  510. case QWebPage::Undo:
  511. case QWebPage::Redo:
  512. // those two are handled by QUndoStack
  513. break;
  514. #endif // QT_NO_UNDOSTACK
  515. case QWebPage::SelectAll: // editor command is always enabled
  516. break;
  517. case QWebPage::SetTextDirectionDefault:
  518. case QWebPage::SetTextDirectionLeftToRight:
  519. case QWebPage::SetTextDirectionRightToLeft:
  520. enabled = editor->canEdit();
  521. checked = false;
  522. break;
  523. default: {
  524. // see if it's an editor command
  525. const char* commandName = editorCommandForWebActions(action);
  526. // if it's an editor command, let it's logic determine state
  527. if (commandName) {
  528. Editor::Command command = editor->command(commandName);
  529. enabled = command.isEnabled();
  530. if (enabled)
  531. checked = command.state() != FalseTriState;
  532. else
  533. checked = false;
  534. }
  535. break;
  536. }
  537. }
  538. a->setEnabled(enabled);
  539. if (a->isCheckable())
  540. a->setChecked(checked);
  541. #endif // QT_NO_ACTION
  542. }
  543. void QWebPagePrivate::updateNavigationActions()
  544. {
  545. updateAction(QWebPage::Back);
  546. updateAction(QWebPage::Forward);
  547. updateAction(QWebPage::Stop);
  548. updateAction(QWebPage::Reload);
  549. updateAction(QWebPage::ReloadAndBypassCache);
  550. }
  551. void QWebPagePrivate::updateEditorActions()
  552. {
  553. updateAction(QWebPage::Cut);
  554. updateAction(QWebPage::Copy);
  555. updateAction(QWebPage::Paste);
  556. updateAction(QWebPage::MoveToNextChar);
  557. updateAction(QWebPage::MoveToPreviousChar);
  558. updateAction(QWebPage::MoveToNextWord);
  559. updateAction(QWebPage::MoveToPreviousWord);
  560. updateAction(QWebPage::MoveToNextLine);
  561. updateAction(QWebPage::MoveToPreviousLine);
  562. updateAction(QWebPage::MoveToStartOfLine);
  563. updateAction(QWebPage::MoveToEndOfLine);
  564. updateAction(QWebPage::MoveToStartOfBlock);
  565. updateAction(QWebPage::MoveToEndOfBlock);
  566. updateAction(QWebPage::MoveToStartOfDocument);
  567. updateAction(QWebPage::MoveToEndOfDocument);
  568. updateAction(QWebPage::SelectNextChar);
  569. updateAction(QWebPage::SelectPreviousChar);
  570. updateAction(QWebPage::SelectNextWord);
  571. updateAction(QWebPage::SelectPreviousWord);
  572. updateAction(QWebPage::SelectNextLine);
  573. updateAction(QWebPage::SelectPreviousLine);
  574. updateAction(QWebPage::SelectStartOfLine);
  575. updateAction(QWebPage::SelectEndOfLine);
  576. updateAction(QWebPage::SelectStartOfBlock);
  577. updateAction(QWebPage::SelectEndOfBlock);
  578. updateAction(QWebPage::SelectStartOfDocument);
  579. updateAction(QWebPage::SelectEndOfDocument);
  580. updateAction(QWebPage::DeleteStartOfWord);
  581. updateAction(QWebPage::DeleteEndOfWord);
  582. updateAction(QWebPage::SetTextDirectionDefault);
  583. updateAction(QWebPage::SetTextDirectionLeftToRight);
  584. updateAction(QWebPage::SetTextDirectionRightToLeft);
  585. updateAction(QWebPage::ToggleBold);
  586. updateAction(QWebPage::ToggleItalic);
  587. updateAction(QWebPage::ToggleUnderline);
  588. updateAction(QWebPage::InsertParagraphSeparator);
  589. updateAction(QWebPage::InsertLineSeparator);
  590. updateAction(QWebPage::PasteAndMatchStyle);
  591. updateAction(QWebPage::RemoveFormat);
  592. updateAction(QWebPage::ToggleStrikethrough);
  593. updateAction(QWebPage::ToggleSubscript);
  594. updateAction(QWebPage::ToggleSuperscript);
  595. updateAction(QWebPage::InsertUnorderedList);
  596. updateAction(QWebPage::InsertOrderedList);
  597. updateAction(QWebPage::Indent);
  598. updateAction(QWebPage::Outdent);
  599. updateAction(QWebPage::AlignCenter);
  600. updateAction(QWebPage::AlignJustified);
  601. updateAction(QWebPage::AlignLeft);
  602. updateAction(QWebPage::AlignRight);
  603. }
  604. void QWebPagePrivate::timerEvent(QTimerEvent *ev)
  605. {
  606. int timerId = ev->timerId();
  607. if (timerId == tripleClickTimer.timerId())
  608. tripleClickTimer.stop();
  609. else
  610. q->timerEvent(ev);
  611. }
  612. template<class T>
  613. void QWebPagePrivate::mouseMoveEvent(T* ev)
  614. {
  615. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  616. if (!frame->view())
  617. return;
  618. bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0));
  619. ev->setAccepted(accepted);
  620. }
  621. template<class T>
  622. void QWebPagePrivate::mousePressEvent(T* ev)
  623. {
  624. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  625. if (!frame->view())
  626. return;
  627. RefPtr<WebCore::Node> oldNode;
  628. Frame* focusedFrame = page->focusController()->focusedFrame();
  629. if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
  630. oldNode = focusedDocument->focusedNode();
  631. if (tripleClickTimer.isActive()
  632. && (ev->pos() - tripleClick).manhattanLength()
  633. < QApplication::startDragDistance()) {
  634. mouseTripleClickEvent(ev);
  635. return;
  636. }
  637. bool accepted = false;
  638. adjustPointForClicking(ev);
  639. PlatformMouseEvent mev(ev, 1);
  640. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  641. if (mev.button() != NoButton)
  642. accepted = frame->eventHandler()->handleMousePressEvent(mev);
  643. ev->setAccepted(accepted);
  644. RefPtr<WebCore::Node> newNode;
  645. focusedFrame = page->focusController()->focusedFrame();
  646. if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
  647. newNode = focusedDocument->focusedNode();
  648. if (newNode && oldNode != newNode)
  649. clickCausedFocus = true;
  650. }
  651. template<class T>
  652. void QWebPagePrivate::mouseDoubleClickEvent(T *ev)
  653. {
  654. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  655. if (!frame->view())
  656. return;
  657. bool accepted = false;
  658. PlatformMouseEvent mev(ev, 2);
  659. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  660. if (mev.button() != NoButton)
  661. accepted = frame->eventHandler()->handleMousePressEvent(mev);
  662. ev->setAccepted(accepted);
  663. tripleClickTimer.start(QApplication::doubleClickInterval(), q);
  664. tripleClick = QPointF(ev->pos()).toPoint();
  665. }
  666. template<class T>
  667. void QWebPagePrivate::mouseTripleClickEvent(T *ev)
  668. {
  669. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  670. if (!frame->view())
  671. return;
  672. bool accepted = false;
  673. PlatformMouseEvent mev(ev, 3);
  674. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  675. if (mev.button() != NoButton)
  676. accepted = frame->eventHandler()->handleMousePressEvent(mev);
  677. ev->setAccepted(accepted);
  678. }
  679. void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button)
  680. {
  681. #ifndef QT_NO_CLIPBOARD
  682. if (QApplication::clipboard()->supportsSelection()) {
  683. bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
  684. Pasteboard::generalPasteboard()->setSelectionMode(true);
  685. WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame();
  686. if (button == Qt::LeftButton) {
  687. if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) {
  688. Pasteboard::generalPasteboard()->writeSelection(focusFrame->editor()->selectedRange().get(), focusFrame->editor()->canSmartCopyOrDelete(), focusFrame);
  689. ev->setAccepted(true);
  690. }
  691. } else if (button == Qt::MidButton) {
  692. if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) {
  693. focusFrame->editor()->paste();
  694. ev->setAccepted(true);
  695. }
  696. }
  697. Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
  698. }
  699. #endif
  700. }
  701. template<class T>
  702. void QWebPagePrivate::mouseReleaseEvent(T *ev)
  703. {
  704. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  705. if (!frame->view())
  706. return;
  707. bool accepted = false;
  708. adjustPointForClicking(ev);
  709. PlatformMouseEvent mev(ev, 0);
  710. // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
  711. if (mev.button() != NoButton)
  712. accepted = frame->eventHandler()->handleMouseReleaseEvent(mev);
  713. ev->setAccepted(accepted);
  714. handleClipboard(ev, ev->button());
  715. handleSoftwareInputPanel(ev->button(), QPointF(ev->pos()).toPoint());
  716. }
  717. void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button, const QPoint& pos)
  718. {
  719. Frame* frame = page->focusController()->focusedFrame();
  720. if (!frame)
  721. return;
  722. if (client && client->inputMethodEnabled()
  723. && frame->document()->focusedNode()
  724. && button == Qt::LeftButton && qApp->autoSipEnabled()) {
  725. QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
  726. client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
  727. if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
  728. HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(frame->view()->windowToContents(pos), false);
  729. if (result.isContentEditable()) {
  730. QEvent event(QEvent::RequestSoftwareInputPanel);
  731. QApplication::sendEvent(client->ownerWidget(), &event);
  732. }
  733. }
  734. }
  735. clickCausedFocus = false;
  736. }
  737. #ifndef QT_NO_CONTEXTMENU
  738. void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos)
  739. {
  740. QMenu *menu = q->createStandardContextMenu();
  741. if (menu) {
  742. menu->exec(globalPos);
  743. delete menu;
  744. }
  745. }
  746. #endif // QT_NO_CONTEXTMENU
  747. /*!
  748. \since 4.5
  749. This function creates the standard context menu which is shown when
  750. the user clicks on the web page with the right mouse button. It is
  751. called from the default contextMenuEvent() handler. The popup menu's
  752. ownership is transferred to the caller.
  753. */
  754. QMenu *QWebPage::createStandardContextMenu()
  755. {
  756. #ifndef QT_NO_CONTEXTMENU
  757. QMenu *menu = d->currentContextMenu;
  758. d->currentContextMenu = 0;
  759. return menu;
  760. #else
  761. return 0;
  762. #endif
  763. }
  764. #ifndef QT_NO_WHEELEVENT
  765. template<class T>
  766. void QWebPagePrivate::wheelEvent(T *ev)
  767. {
  768. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  769. if (!frame->view())
  770. return;
  771. WebCore::PlatformWheelEvent pev(ev);
  772. bool accepted = frame->eventHandler()->handleWheelEvent(pev);
  773. ev->setAccepted(accepted);
  774. }
  775. #endif // QT_NO_WHEELEVENT
  776. #ifndef QT_NO_SHORTCUT
  777. QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event)
  778. {
  779. static struct {
  780. QKeySequence::StandardKey standardKey;
  781. QWebPage::WebAction action;
  782. } editorActions[] = {
  783. { QKeySequence::Cut, QWebPage::Cut },
  784. { QKeySequence::Copy, QWebPage::Copy },
  785. { QKeySequence::Paste, QWebPage::Paste },
  786. { QKeySequence::Undo, QWebPage::Undo },
  787. { QKeySequence::Redo, QWebPage::Redo },
  788. { QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar },
  789. { QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar },
  790. { QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord },
  791. { QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord },
  792. { QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine },
  793. { QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine },
  794. { QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine },
  795. { QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine },
  796. { QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock },
  797. { QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock },
  798. { QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument },
  799. { QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument },
  800. { QKeySequence::SelectNextChar, QWebPage::SelectNextChar },
  801. { QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar },
  802. { QKeySequence::SelectNextWord, QWebPage::SelectNextWord },
  803. { QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord },
  804. { QKeySequence::SelectNextLine, QWebPage::SelectNextLine },
  805. { QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine },
  806. { QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine },
  807. { QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine },
  808. { QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock },
  809. { QKeySequence::SelectEndOfBlock, QWebPage::SelectEndOfBlock },
  810. { QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument },
  811. { QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument },
  812. { QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord },
  813. { QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord },
  814. { QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator },
  815. { QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator },
  816. { QKeySequence::SelectAll, QWebPage::SelectAll },
  817. { QKeySequence::UnknownKey, QWebPage::NoWebAction }
  818. };
  819. for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i)
  820. if (event == editorActions[i].standardKey)
  821. return editorActions[i].action;
  822. return QWebPage::NoWebAction;
  823. }
  824. #endif // QT_NO_SHORTCUT
  825. void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
  826. {
  827. bool handled = false;
  828. WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
  829. // we forward the key event to WebCore first to handle potential DOM
  830. // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent
  831. // to trigger editor commands via triggerAction().
  832. if (!handled)
  833. handled = frame->eventHandler()->keyEvent(ev);
  834. if (!handled) {
  835. handled = true;
  836. if (!handleScrolling(ev, frame)) {
  837. switch (ev->key()) {
  838. case Qt::Key_Back:
  839. q->triggerAction(QWebPage::Back);
  840. break;
  841. case Qt::Key_Forward:
  842. q->triggerAction(QWebPage::Forward);
  843. break;
  844. case Qt::Key_Stop:
  845. q->triggerAction(QWebPage::Stop);
  846. break;
  847. case Qt::Key_Refresh:
  848. q->triggerAction(QWebPage::Reload);
  849. break;
  850. case Qt::Key_Backspace:
  851. if (ev->modifiers() == Qt::ShiftModifier)
  852. q->triggerAction(QWebPage::Forward);
  853. else
  854. q->triggerAction(QWebPage::Back);
  855. break;
  856. default:
  857. handled = false;
  858. break;
  859. }
  860. }
  861. }
  862. ev->setAccepted(handled);
  863. }
  864. void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
  865. {
  866. if (ev->isAutoRepeat()) {
  867. ev->setAccepted(true);
  868. return;
  869. }
  870. WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
  871. bool handled = frame->eventHandler()->keyEvent(ev);
  872. ev->setAccepted(handled);
  873. }
  874. void QWebPagePrivate::focusInEvent(QFocusEvent*)
  875. {
  876. FocusController *focusController = page->focusController();
  877. focusController->setActive(true);
  878. focusController->setFocused(true);
  879. if (!focusController->focusedFrame())
  880. focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame));
  881. }
  882. void QWebPagePrivate::focusOutEvent(QFocusEvent*)
  883. {
  884. // only set the focused frame inactive so that we stop painting the caret
  885. // and the focus frame. But don't tell the focus controller so that upon
  886. // focusInEvent() we can re-activate the frame.
  887. FocusController *focusController = page->focusController();
  888. // Call setFocused first so that window.onblur doesn't get called twice
  889. focusController->setFocused(false);
  890. focusController->setActive(false);
  891. }
  892. template<class T>
  893. void QWebPagePrivate::dragEnterEvent(T* ev)
  894. {
  895. #ifndef QT_NO_DRAGANDDROP
  896. DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
  897. QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
  898. Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
  899. ev->setDropAction(action);
  900. ev->acceptProposedAction();
  901. #endif
  902. }
  903. template<class T>
  904. void QWebPagePrivate::dragLeaveEvent(T *ev)
  905. {
  906. #ifndef QT_NO_DRAGANDDROP
  907. DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
  908. page->dragController()->dragExited(&dragData);
  909. ev->accept();
  910. #endif
  911. }
  912. template<class T>
  913. void QWebPagePrivate::dragMoveEvent(T *ev)
  914. {
  915. #ifndef QT_NO_DRAGANDDROP
  916. DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
  917. QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
  918. m_lastDropAction = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
  919. ev->setDropAction(m_lastDropAction);
  920. if (m_lastDropAction != Qt::IgnoreAction)
  921. ev->accept();
  922. #endif
  923. }
  924. template<class T>
  925. void QWebPagePrivate::dropEvent(T *ev)
  926. {
  927. #ifndef QT_NO_DRAGANDDROP
  928. DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
  929. QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
  930. if (page->dragController()->performDrag(&dragData)) {
  931. ev->setDropAction(m_lastDropAction);
  932. ev->accept();
  933. }
  934. #endif
  935. }
  936. void QWebPagePrivate::leaveEvent(QEvent*)
  937. {
  938. // Fake a mouse move event just outside of the widget, since all
  939. // the interesting mouse-out behavior like invalidating scrollbars
  940. // is handled by the WebKit event handler's mouseMoved function.
  941. QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
  942. mouseMoveEvent(&fakeEvent);
  943. }
  944. /*!
  945. \property QWebPage::palette
  946. \brief the page's palette
  947. The base brush of the palette is used to draw the background of the main frame.
  948. By default, this property contains the application's default palette.
  949. */
  950. void QWebPage::setPalette(const QPalette &pal)
  951. {
  952. d->palette = pal;
  953. if (!d->mainFrame || !d->mainFrame->d->frame->view())
  954. return;
  955. QBrush brush = pal.brush(QPalette::Base);
  956. QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
  957. QWebFramePrivate::core(d->mainFrame)->view()->updateBackgroundRecursively(backgroundColor, !backgroundColor.alpha());
  958. }
  959. QPalette QWebPage::palette() const
  960. {
  961. return d->palette;
  962. }
  963. void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
  964. {
  965. WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
  966. WebCore::Editor *editor = frame->editor();
  967. if (!editor->canEdit()) {
  968. ev->ignore();
  969. return;
  970. }
  971. Node* node = 0;
  972. if (frame->selection()->rootEditableElement())
  973. node = frame->selection()->rootEditableElement()->shadowAncestorNode();
  974. Vector<CompositionUnderline> underlines;
  975. bool hasSelection = false;
  976. for (int i = 0; i < ev->attributes().size(); ++i) {
  977. const QInputMethodEvent::Attribute& a = ev->attributes().at(i);
  978. switch (a.type) {
  979. case QInputMethodEvent::TextFormat: {
  980. QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat();
  981. QColor qcolor = textCharFormat.underlineColor();
  982. underlines.append(CompositionUnderline(qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)), Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())), false));
  983. break;
  984. }
  985. case QInputMethodEvent::Cursor: {
  986. frame->selection()->setCaretVisible(a.length); //if length is 0 cursor is invisible
  987. if (a.length > 0) {
  988. RenderObject* caretRenderer = frame->selection()->caretRenderer();
  989. if (caretRenderer) {
  990. QColor qcolor = a.value.value<QColor>();
  991. caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())));
  992. }
  993. }
  994. break;
  995. }
  996. case QInputMethodEvent::Selection: {
  997. hasSelection = true;
  998. // A selection in the inputMethodEvent is always reflected in the visible text
  999. if (node)
  1000. setSelectionRange(node, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)));
  1001. if (!ev->preeditString().isEmpty())
  1002. editor->setComposition(ev->preeditString(), underlines, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)));
  1003. else {
  1004. // If we are in the middle of a composition, an empty pre-edit string and a selection of zero
  1005. // cancels the current composition
  1006. if (editor->hasComposition() && (a.start + a.length == 0))
  1007. editor->setComposition(QString(), underlines, 0, 0);
  1008. }
  1009. break;
  1010. }
  1011. default:
  1012. break;
  1013. }
  1014. }
  1015. if (node && ev->replacementLength() > 0) {
  1016. int cursorPos = frame->selection()->extent().offsetInContainerNode();
  1017. int start = cursorPos + ev->replacementStart();
  1018. setSelectionRange(node, start, start + ev->replacementLength());
  1019. // Commit regardless of whether commitString is empty, to get rid of selection.
  1020. editor->confirmComposition(ev->commitString());
  1021. } else if (!ev->commitString().isEmpty()) {
  1022. if (editor->hasComposition())
  1023. editor->confirmComposition(ev->commitString());
  1024. else
  1025. editor->insertText(ev->commitString(), 0);
  1026. } else if (!hasSelection && !ev->preeditString().isEmpty())
  1027. editor->setComposition(ev->preeditString(), underlines, 0, 0);
  1028. else if (ev->preeditString().isEmpty() && editor->hasComposition())
  1029. editor->confirmComposition(String());
  1030. ev->accept();
  1031. }
  1032. #ifndef QT_NO_PROPERTIES
  1033. typedef struct {
  1034. const char* name;
  1035. double deferredRepaintDelay;
  1036. double initialDeferredRepaintDelayDuringLoading;
  1037. double maxDeferredRepaintDelayDuringLoading;
  1038. double deferredRepaintDelayIncrementDuringLoading;
  1039. } QRepaintThrottlingPreset;
  1040. void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event)
  1041. {
  1042. if (event->propertyName() == "_q_viewMode") {
  1043. page->setViewMode(Page::stringToViewMode(q->property("_q_viewMode").toString()));
  1044. } else if (event->propertyName() == "_q_HTMLTokenizerChunkSize") {
  1045. int chunkSize = q->property("_q_HTMLTokenizerChunkSize").toInt();
  1046. q->handle()->page->setCustomHTMLTokenizerChunkSize(chunkSize);
  1047. } else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") {
  1048. double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble();
  1049. q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay);
  1050. } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") {
  1051. double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble();
  1052. FrameView::setRepaintThrottlingDeferredRepaintDelay(p);
  1053. } else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") {
  1054. double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble();
  1055. FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p);
  1056. } else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") {
  1057. double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble();
  1058. FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p);
  1059. } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") {
  1060. double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble();
  1061. FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p);
  1062. } else if (event->propertyName() == "_q_RepaintThrottlingPreset") {
  1063. static const QRepaintThrottlingPreset presets[] = {
  1064. { "NoThrottling", 0, 0, 0, 0 },
  1065. { "Legacy", 0.025, 0, 2.5, 0.5 },
  1066. { "Minimal", 0.01, 0, 1, 0.2 },
  1067. { "Medium", 0.025, 1, 5, 0.5 },
  1068. { "Heavy", 0.1, 2, 10, 1 }
  1069. };
  1070. QString p = q->property("_q_RepaintThrottlingPreset").toString();
  1071. for (size_t i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) {
  1072. if (p == QLatin1String(presets[i].name)) {
  1073. FrameView::setRepaintThrottlingDeferredRepaintDelay(
  1074. presets[i].deferredRepaintDelay);
  1075. FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(
  1076. presets[i].initialDeferredRepaintDelayDuringLoading);
  1077. FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(
  1078. presets[i].maxDeferredRepaintDelayDuringLoading);
  1079. FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(
  1080. presets[i].deferredRepaintDelayIncrementDuringLoading);
  1081. break;
  1082. }
  1083. }
  1084. }
  1085. #if ENABLE(TILED_BACKING_STORE)
  1086. else if (event->propertyName() == "_q_TiledBackingStoreTileSize") {
  1087. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1088. if (!frame->tiledBackingStore())
  1089. return;
  1090. QSize tileSize = q->property("_q_TiledBackingStoreTileSize").toSize();
  1091. frame->tiledBackingStore()->setTileSize(tileSize);
  1092. } else if (event->propertyName() == "_q_TiledBackingStoreTileCreationDelay") {
  1093. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1094. if (!frame->tiledBackingStore())
  1095. return;
  1096. int tileCreationDelay = q->property("_q_TiledBackingStoreTileCreationDelay").toInt();
  1097. frame->tiledBackingStore()->setTileCreationDelay(static_cast<double>(tileCreationDelay) / 1000.);
  1098. } else if (event->propertyName() == "_q_TiledBackingStoreKeepAreaMultiplier") {
  1099. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1100. if (!frame->tiledBackingStore())
  1101. return;
  1102. FloatSize keepMultiplier;
  1103. FloatSize coverMultiplier;
  1104. frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1105. QSizeF qSize = q->property("_q_TiledBackingStoreKeepAreaMultiplier").toSizeF();
  1106. keepMultiplier = FloatSize(qSize.width(), qSize.height());
  1107. frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1108. } else if (event->propertyName() == "_q_TiledBackingStoreCoverAreaMultiplier") {
  1109. WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
  1110. if (!frame->tiledBackingStore())
  1111. return;
  1112. FloatSize keepMultiplier;
  1113. FloatSize coverMultiplier;
  1114. frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1115. QSizeF qSize = q->property("_q_TiledBackingStoreCoverAreaMultiplier").toSizeF();
  1116. coverMultiplier = FloatSize(qSize.width(), qSize.height());
  1117. frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
  1118. }
  1119. #endif
  1120. else if (event->propertyName() == "_q_webInspectorServerPort") {
  1121. InspectorServerQt* inspectorServer = InspectorServerQt::server();
  1122. inspectorServer->listen(inspectorServerPort());
  1123. } else if (event->propertyName() == "_q_deadDecodedDataDeletionInterval") {
  1124. double interval = q->property("_q_deadDecodedDataDeletionInterval").toDouble();
  1125. memoryCache()->setDeadDecodedDataDeletionInterval(interval);
  1126. }
  1127. }
  1128. #endif
  1129. void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event)
  1130. {
  1131. WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
  1132. WebCore::Editor* editor = frame->editor();
  1133. if (editor->canEdit()) {
  1134. if (event->modifiers() == Qt::NoModifier
  1135. || event->modifiers() == Qt::ShiftModifier
  1136. || event->modifiers() == Qt::KeypadModifier) {
  1137. if (event->key() < Qt::Key_Escape) {
  1138. event->accept();
  1139. } else {
  1140. switch (event->key()) {
  1141. case Qt::Key_Return:
  1142. case Qt::Key_Enter:
  1143. case Qt::Key_Delete:
  1144. case Qt::Key_Home:
  1145. case Qt::Key_End:
  1146. case Qt::Key_Backspace:
  1147. case Qt::Key_Left:
  1148. case Qt::Key_Right:
  1149. case Qt::Key_Up:
  1150. case Qt::Key_Down:
  1151. case Qt::Key_Tab:
  1152. event->accept();
  1153. default:
  1154. break;
  1155. }
  1156. }
  1157. }
  1158. #ifndef QT_NO_SHORTCUT
  1159. else if (editorActionForKeyEvent(event) != QWebPage::NoWebAction)
  1160. event->accept();
  1161. #endif
  1162. }
  1163. }
  1164. bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame)
  1165. {
  1166. ScrollDirection direction;
  1167. ScrollGranularity granularity;
  1168. #ifndef QT_NO_SHORTCUT
  1169. if (ev == QKeySequence::MoveToNextPage
  1170. || (ev->key() == Qt::Key_Space && !(ev->modifiers() & Qt::ShiftModifier))) {
  1171. granularity = ScrollByPage;
  1172. direction = ScrollDown;
  1173. } else if (ev == QKeySequence::MoveToPreviousPage
  1174. || ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) {
  1175. granularity = ScrollByPage;
  1176. direction = ScrollUp;
  1177. } else
  1178. #endif // QT_NO_SHORTCUT
  1179. if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier)
  1180. || ev->key() == Qt::Key_Home) {
  1181. granularity = ScrollByDocument;
  1182. direction = ScrollUp;
  1183. } else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier)
  1184. || ev->key() == Qt::Key_End) {
  1185. granularity = ScrollByDocument;
  1186. direction = ScrollDown;
  1187. } else {
  1188. switch (ev->key()) {
  1189. case Qt::Key_Up:
  1190. granularity = ScrollByLine;
  1191. direction = ScrollUp;
  1192. break;
  1193. case Qt::Key_Down:
  1194. granularity = ScrollByLine;
  1195. direction = ScrollDown;
  1196. break;
  1197. case Qt::Key_Left:
  1198. granularity = ScrollByLine;
  1199. direction = ScrollLeft;
  1200. break;
  1201. case Qt::Key_Right:
  1202. granularity = ScrollByLine;
  1203. direction = ScrollRight;
  1204. break;
  1205. default:
  1206. return false;
  1207. }
  1208. }
  1209. return frame->eventHandler()->scrollRecursively(direction, granularity);
  1210. }
  1211. void QWebPagePrivate::adjustPointForClicking(QMouseEvent*)
  1212. {
  1213. notImplemented();
  1214. }
  1215. #if !defined(QT_NO_GRAPHICSVIEW)
  1216. void QWebPagePrivate::adjustPointForClicking(QGraphicsSceneMouseEvent* ev)
  1217. {
  1218. QtPlatformPlugin platformPlugin;
  1219. QWebTouchModifier* touchModifier = platformPlugin.createTouchModifier();
  1220. if (!touchModifier)
  1221. return;
  1222. unsigned topPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Up);
  1223. unsigned rightPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Right);
  1224. unsigned bottomPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Down);
  1225. unsigned leftPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Left);
  1226. delete touchModifier;
  1227. touchModifier = 0;
  1228. if (!topPadding && !rightPadding && !bottomPadding && !leftPadding)
  1229. return;
  1230. Document* startingDocument = page->mainFrame()->document();
  1231. if (!startingDocument)
  1232. return;
  1233. IntPoint originalPoint(QPointF(ev->pos()).toPoint());
  1234. TouchAdjuster touchAdjuster(topPadding, rightPadding, bottomPadding, leftPadding);
  1235. IntPoint adjustedPoint = touchAdjuster.findCandidatePointForTouch(originalPoint, startingDocument);
  1236. if (adjustedPoint == IntPoint::zero())
  1237. return;
  1238. ev->setPos(QPointF(adjustedPoint));
  1239. }
  1240. #endif
  1241. bool QWebPagePrivate::touchEvent(QTouchEvent* event)
  1242. {
  1243. #if ENABLE(TOUCH_EVENTS)
  1244. WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
  1245. if (!frame->view())
  1246. return false;
  1247. // Always accept the QTouchEvent so that we'll receive also TouchUpdate and TouchEnd events
  1248. event->setAccepted(true);
  1249. // Return whether the default action was cancelled in the JS event handler
  1250. return frame->eventHandler()->handleTouchEvent(PlatformTouchEvent(event));
  1251. #else
  1252. event->ignore();
  1253. return false;
  1254. #endif
  1255. }
  1256. /*!
  1257. This method is used by the input method to query a set of properties of the page
  1258. to be able to support complex input method operations as support for surrounding
  1259. text and reconversions.
  1260. \a property specifies which property is queried.
  1261. \sa QWidget::inputMethodEvent(), QInputMethodEvent, QInputContext
  1262. */
  1263. QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const
  1264. {
  1265. Frame* frame = d->page->focusController()->focusedFrame();
  1266. if (!frame)
  1267. return QVariant();
  1268. WebCore::Editor* editor = frame->editor();
  1269. RenderObject* renderer = 0;
  1270. RenderTextControl* renderTextControl = 0;
  1271. if (frame->selection()->rootEditableElement())
  1272. renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer();
  1273. if (renderer && renderer->isTextControl())
  1274. renderTextControl = toRenderTextControl(renderer);
  1275. switch (property) {
  1276. case Qt::ImMicroFocus: {
  1277. WebCore::FrameView* view = frame->view();
  1278. if (view && view->needsLayout()) {
  1279. // We can't access absoluteCaretBounds() while the view needs to layout.
  1280. return QVariant();
  1281. }
  1282. return QVariant(view->contentsToWindow(frame->selection()->absoluteCaretBounds()));
  1283. }
  1284. case Qt::ImFont: {
  1285. if (renderTextControl) {
  1286. RenderStyle* renderStyle = renderTextControl->style();
  1287. return QVariant(QFont(renderStyle->font().font()));
  1288. }
  1289. return QVariant(QFont());
  1290. }
  1291. case Qt::ImCursorPosition: {
  1292. if (editor->hasComposition())
  1293. return QVariant(frame->selection()->end().offsetInContainerNode());
  1294. return QVariant(frame->selection()->extent().offsetInContainerNode());
  1295. }
  1296. case Qt::ImSurroundingText: {
  1297. if (renderTextControl) {
  1298. QString text = renderTextControl->text();
  1299. RefPtr<Range> range = editor->compositionRange();
  1300. if (range)
  1301. text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get()));
  1302. return QVariant(text);
  1303. }
  1304. return QVariant();
  1305. }
  1306. case Qt::ImCurrentSelection: {
  1307. if (!editor->hasComposition() && renderTextControl) {
  1308. int start = frame->selection()->start().offsetInContainerNode();
  1309. int end = frame->selection()->end().offsetInContainerNode();
  1310. if (end > start)
  1311. return QVariant(QString(renderTextControl->text()).mid(start, end - start));
  1312. }
  1313. return QVariant();
  1314. }
  1315. case Qt::ImAnchorPosition: {
  1316. if (editor->hasComposition())
  1317. return QVariant(frame->selection()->start().offsetInContainerNode());
  1318. return QVariant(frame->selection()->base().offsetInContainerNode());
  1319. }
  1320. case Qt::ImMaximumTextLength: {
  1321. if (frame->selection()->isContentEditable()) {
  1322. if (frame->document() && frame->document()->focusedNode()) {
  1323. if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) {
  1324. HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode());
  1325. return QVariant(inputElement->maxLength());
  1326. }
  1327. }
  1328. return QVariant(InputElement::s_maximumLength);
  1329. }
  1330. return QVariant(0);
  1331. }
  1332. default:
  1333. return QVariant();
  1334. }
  1335. }
  1336. /*!
  1337. \internal
  1338. */
  1339. void QWebPagePrivate::setInspector(QWebInspector* insp)
  1340. {
  1341. if (inspector)
  1342. inspector->d->setFrontend(0);
  1343. if (inspectorIsInternalOnly) {
  1344. QWebInspector* inspToDelete = inspector;
  1345. inspector = 0;
  1346. inspectorIsInternalOnly = false;
  1347. delete inspToDelete; // Delete after to prevent infinite recursion
  1348. }
  1349. inspector = insp;
  1350. // Give inspector frontend web view if previously created
  1351. if (inspector && inspectorFrontend)
  1352. inspector->d->setFrontend(inspectorFrontend);
  1353. }
  1354. /*!
  1355. \internal
  1356. Returns the inspector and creates it if it wasn't created yet.
  1357. The instance created here will not be available through QWebPage's API.
  1358. */
  1359. QWebInspector* QWebPagePrivate::getOrCreateInspector()
  1360. {
  1361. #if ENABLE(INSPECTOR)
  1362. if (!inspector) {
  1363. QWebInspector* insp = new QWebInspector;
  1364. insp->setPage(q);
  1365. inspectorIsInternalOnly = true;
  1366. Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q)
  1367. }
  1368. #endif
  1369. return inspector;
  1370. }
  1371. /*! \internal */
  1372. InspectorController* QWebPagePrivate::inspectorController()
  1373. {
  1374. #if ENABLE(INSPECTOR)
  1375. return page->inspectorController();
  1376. #else
  1377. return 0;
  1378. #endif
  1379. }
  1380. quint16 QWebPagePrivate::inspectorServerPort()
  1381. {
  1382. #if ENABLE(INSPECTOR) && !defined(QT_NO_PROPERTIES)
  1383. if (q && q->property("_q_webInspectorServerPort").isValid())
  1384. return q->property("_q_webInspectorServerPort").toInt();
  1385. #endif
  1386. return 0;
  1387. }
  1388. static bool hasMouseListener(Element* element)
  1389. {
  1390. ASSERT(element);
  1391. return element->hasEventListeners(eventNames().clickEvent)
  1392. || element->hasEventListeners(eventNames().mousedownEvent)
  1393. || element->hasEventListeners(eventNames().mouseupEvent);
  1394. }
  1395. static bool isClickableElement(Element* element, RefPtr<NodeList> list)
  1396. {
  1397. ASSERT(element);
  1398. bool isClickable = hasMouseListener(element);
  1399. if (!isClickable && list) {
  1400. Element* parent = element->parentElement();
  1401. unsigned count = list->length();
  1402. for (unsigned i = 0; i < count && parent; i++) {
  1403. if (list->item(i) != parent)
  1404. continue;
  1405. isClickable = hasMouseListener(parent);
  1406. if (isClickable)
  1407. break;
  1408. parent = parent->parentElement();
  1409. }
  1410. }
  1411. ExceptionCode ec = 0;
  1412. return isClickable
  1413. || element->webkitMatchesSelector("a,*:link,*:visited,*[role=button],button,input,select,label", ec)
  1414. || computedStyle(element)->getPropertyValue(cssPropertyID("cursor")) == "pointer";
  1415. }
  1416. static bool isValidFrameOwner(Element* element)
  1417. {
  1418. ASSERT(element);
  1419. return element->isFrameOwnerElement() && static_cast<HTMLFrameOwnerElement*>(element)->contentFrame();
  1420. }
  1421. static Element* nodeToElement(Node* node)
  1422. {
  1423. if (node && node->isElementNode())
  1424. return static_cast<Element*>(node);
  1425. return 0;
  1426. }
  1427. QWebPagePrivate::TouchAdjuster::TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
  1428. : m_topPadding(topPadding)
  1429. , m_rightPadding(rightPadding)
  1430. , m_bottomPadding(bottomPadding)
  1431. , m_leftPadding(leftPadding)
  1432. {
  1433. }
  1434. IntPoint QWebPagePrivate::TouchAdjuster::findCandidatePointForTouch(const IntPoint& touchPoint, Document* document) const
  1435. {
  1436. if (!document)
  1437. return IntPoint();
  1438. int x = touchPoint.x();
  1439. int y = touchPoint.y();
  1440. RefPtr<NodeList> intersectedNodes = document->nodesFromRect(x, y, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding, false);
  1441. if (!intersectedNodes)
  1442. return IntPoint();
  1443. Element* closestClickableElement = 0;
  1444. IntRect largestIntersectionRect;
  1445. FrameView* view = document->frame()->view();
  1446. // Touch rect in contents coordinates.
  1447. IntRect touchRect(HitTestResult::rectForPoint(view->windowToContents(IntPoint(x, y)), m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding));
  1448. // Iterate over the list of nodes hit looking for the one whose bounding area
  1449. // has largest intersection with the touch area (point + padding).
  1450. for (unsigned i = 0; i < intersectedNodes->length(); i++) {
  1451. Node* currentNode = intersectedNodes->item(i);
  1452. Element* currentElement = nodeToElement(currentNode);
  1453. if (!currentElement || (!isClickableElement(currentElement, 0) && !isValidFrameOwner(currentElement)))
  1454. continue;
  1455. IntRect currentElementBoundingRect = currentElement->getRect();
  1456. currentElementBoundingRect.intersect(touchRect);
  1457. if (currentElementBoundingRect.isEmpty())
  1458. continue;
  1459. int currentIntersectionRectArea = currentElementBoundingRect.width() * currentElementBoundingRect.height();
  1460. int largestIntersectionRectArea = largestIntersectionRect.width() * largestIntersectionRect.height();
  1461. if (currentIntersectionRectArea > largestIntersectionRectArea) {
  1462. closestClickableElement = currentElement;
  1463. largestIntersectionRect = currentElementBoundingRect;
  1464. }
  1465. }
  1466. if (largestIntersectionRect.isEmpty())
  1467. return IntPoint();
  1468. // Handle the case when user taps a inner frame. It is done in three steps:
  1469. // 1) Transform the original touch point to the inner document coordinates;
  1470. // 1) Call nodesFromRect for the inner document in case;
  1471. // 3) Re-add the inner frame offset (location) before passing the new clicking
  1472. // position to WebCore.
  1473. if (closestClickableElement->isFrameOwnerElement()) {
  1474. // Adjust client coordinates' origin to be top left of inner frame viewport.
  1475. PassRefPtr<ClientRect> rect = closestClickableElement->getBoundingClientRect();
  1476. IntPoint newTouchPoint = touchPoint;
  1477. IntSize offset = IntSize(rect->left(), rect->top());
  1478. newTouchPoint -= offset;
  1479. HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(closestClickableElement);
  1480. Document* childDocument = owner->contentFrame()->document();
  1481. return findCandidatePointForTouch(newTouchPoint, childDocument);
  1482. }
  1483. return view->contentsToWindow(largestIntersectionRect).center();
  1484. }
  1485. /*!
  1486. \enum QWebPage::FindFlag
  1487. This enum describes the options available to the findText() function. The options
  1488. can be OR-ed together from the following list:
  1489. \value FindBackward Searches backwards instead of forwards.
  1490. \value FindCaseSensitively By default findText() works case insensitive. Specifying this option
  1491. changes the behaviour to a case sensitive find operation.
  1492. \value FindWrapsAroundDocument Makes findText() restart from the beginning of the document if the end
  1493. was reached and the text was not found.
  1494. \value HighlightAllOccurrences Highlights all existing occurrences of a specific string.
  1495. */
  1496. /*!
  1497. \enum QWebPage::LinkDelegationPolicy
  1498. This enum defines the delegation policies a webpage can have when activating links and emitting
  1499. the linkClicked() signal.
  1500. \value DontDelegateLinks No links are delegated. Instead, QWebPage tries to handle them all.
  1501. \value DelegateExternalLinks When activating links that point to documents not stored on the
  1502. local filesystem or an equivalent - such as the Qt resource system - then linkClicked() is emitted.
  1503. \value DelegateAllLinks Whenever a link is activated the linkClicked() signal is emitted.
  1504. \sa QWebPage::linkDelegationPolicy
  1505. */
  1506. /*!
  1507. \enum QWebPage::NavigationType
  1508. This enum describes the types of navigation available when browsing through hyperlinked
  1509. documents.
  1510. \value NavigationTypeLinkClicked The user clicked on a link or pressed return on a focused link.
  1511. \value NavigationTypeFormSubmitted The user activated a submit button for an HTML form.
  1512. \value NavigationTypeBackOrForward Navigation to a previously shown document in the back or forward history is requested.
  1513. \value NavigationTypeReload The user activated the reload action.
  1514. \value NavigationTypeFormResubmitted An HTML form was submitted a second time.
  1515. \value NavigationTypeOther A navigation to another document using a method not listed above.
  1516. \sa acceptNavigationRequest()
  1517. */
  1518. /*!
  1519. \enum QWebPage::WebAction
  1520. This enum describes the types of action which can be performed on the web page.
  1521. Actions only have an effect when they are applicable. The availability of
  1522. actions can be be determined by checking \l{QAction::}{isEnabled()} on the
  1523. action returned by action().
  1524. One method of enabling the text editing, cursor movement, and text selection actions
  1525. is by setting \l contentEditable to true.
  1526. \value NoWebAction No action is triggered.
  1527. \value OpenLink Open the current link.
  1528. \value OpenLinkInNewWindow Open the current link in a new window.
  1529. \value OpenFrameInNewWindow Replicate the current frame in a new window.
  1530. \value DownloadLinkToDisk Download the current link to the disk.
  1531. \value CopyLinkToClipboard Copy the current link to the clipboard.
  1532. \value OpenImageInNewWindow Open the highlighted image in a new window.
  1533. \value DownloadImageToDisk Download the highlighted image to the disk.
  1534. \value CopyImageToClipboard Copy the highlighted image to the clipboard.
  1535. \value CopyImageUrlToClipboard Copy the highlighted image's URL to the clipboard.
  1536. \value Back Navigate back in the history of navigated links.
  1537. \value Forward Navigate forward in the history of navigated links.
  1538. \value Stop Stop loading the current page.
  1539. \value StopScheduledPageRefresh Stop all pending page refresh/redirect requests.
  1540. \value Reload Reload the current page.
  1541. \value ReloadAndBypassCache Reload the current page, but do not use any local cache. (Added in Qt 4.6)
  1542. \value Cut Cut the content currently selected into the clipboard.
  1543. \value Copy Copy the content currently selected into the clipboard.
  1544. \value Paste Paste content from the clipboard.
  1545. \value Undo Undo the last editing action.
  1546. \value Redo Redo the last editing action.
  1547. \value MoveToNextChar Move the cursor to the next character.
  1548. \value MoveToPreviousChar Move the cursor to the previous character.
  1549. \value MoveToNextWord Move the cursor to the next word.
  1550. \value MoveToPreviousWord Move the cursor to the previous word.
  1551. \value MoveToNextLine Move the cursor to the next line.
  1552. \value MoveToPreviousLine Move the cursor to the previous line.
  1553. \value MoveToStartOfLine Move the cursor to the start of the line.
  1554. \value MoveToEndOfLine Move the cursor to the end of the line.
  1555. \value MoveToStartOfBlock Move the cursor to the start of the block.
  1556. \value MoveToEndOfBlock Move the cursor to the end of the block.
  1557. \value MoveToStartOfDocument Move the cursor to the start of the document.
  1558. \value MoveToEndOfDocument Move the cursor to the end of the document.
  1559. \value SelectNextChar Select to the next character.
  1560. \value SelectPreviousChar Select to the previous character.
  1561. \value SelectNextWord Select to the next word.
  1562. \value SelectPreviousWord Select to the previous word.
  1563. \value SelectNextLine Select to the next line.
  1564. \value SelectPreviousLine Select to the previous line.
  1565. \value SelectStartOfLine Select to the start of the line.
  1566. \value SelectEndOfLine Select to the end of the line.
  1567. \value SelectStartOfBlock Select to the start of the block.
  1568. \value SelectEndOfBlock Select to the end of the block.
  1569. \value SelectStartOfDocument Select to the start of the document.
  1570. \value SelectEndOfDocument Select to the end of the document.
  1571. \value DeleteStartOfWord Delete to the start of the word.
  1572. \value DeleteEndOfWord Delete to the end of the word.
  1573. \value SetTextDirectionDefault Set the text direction to the default direction.
  1574. \value SetTextDirectionLeftToRight Set the text direction to left-to-right.
  1575. \value SetTextDirectionRightToLeft Set the text direction to right-to-left.
  1576. \value ToggleBold Toggle the formatting between bold and normal weight.
  1577. \value ToggleItalic Toggle the formatting between italic and normal style.
  1578. \value ToggleUnderline Toggle underlining.
  1579. \value InspectElement Show the Web Inspector with the currently highlighted HTML element.
  1580. \value InsertParagraphSeparator Insert a new paragraph.
  1581. \value InsertLineSeparator Insert a new line.
  1582. \value SelectAll Selects all content.
  1583. \value PasteAndMatchStyle Paste content from the clipboard with current style.
  1584. \value RemoveFormat Removes formatting and style.
  1585. \value ToggleStrikethrough Toggle the formatting between strikethrough and normal style.
  1586. \value ToggleSubscript Toggle the formatting between subscript and baseline.
  1587. \value ToggleSuperscript Toggle the formatting between supercript and baseline.
  1588. \value InsertUnorderedList Toggles the selection between an ordered list and a normal block.
  1589. \value InsertOrderedList Toggles the selection between an ordered list and a normal block.
  1590. \value Indent Increases the indentation of the currently selected format block by one increment.
  1591. \value Outdent Decreases the indentation of the currently selected format block by one increment.
  1592. \value AlignCenter Applies center alignment to content.
  1593. \value AlignJustified Applies full justification to content.
  1594. \value AlignLeft Applies left justification to content.
  1595. \value AlignRight Applies right justification to content.
  1596. \omitvalue WebActionCount
  1597. */
  1598. /*!
  1599. \enum QWebPage::WebWindowType
  1600. This enum describes the types of window that can be created by the createWindow() function.
  1601. \value WebBrowserWindow The window is a regular web browser window.
  1602. \value WebModalDialog The window acts as modal dialog.
  1603. */
  1604. /*!
  1605. \class QWebPage::ViewportAttributes
  1606. \since 4.7
  1607. \brief The QWebPage::ViewportAttributes class describes hints that can be applied to a viewport.
  1608. QWebPage::ViewportAttributes provides a description of a viewport, such as viewport geometry,
  1609. initial scale factor with limits, plus information about whether a user should be able
  1610. to scale the contents in the viewport or not, ie. by zooming.
  1611. ViewportAttributes can be set by a web author using the viewport meta tag extension, documented
  1612. at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}.
  1613. All values might not be set, as such when dealing with the hints, the developer needs to
  1614. check whether the values are valid. Negative values denote an invalid qreal value.
  1615. \inmodule QtWebKit
  1616. */
  1617. /*!
  1618. Constructs an empty QWebPage::ViewportAttributes.
  1619. */
  1620. QWebPage::ViewportAttributes::ViewportAttributes()
  1621. : d(0)
  1622. , m_initialScaleFactor(-1.0)
  1623. , m_minimumScaleFactor(-1.0)
  1624. , m_maximumScaleFactor(-1.0)
  1625. , m_devicePixelRatio(-1.0)
  1626. , m_isUserScalable(true)
  1627. , m_isValid(false)
  1628. {
  1629. }
  1630. /*!
  1631. Constructs a QWebPage::ViewportAttributes which is a copy from \a other .
  1632. */
  1633. QWebPage::ViewportAttributes::ViewportAttributes(const QWebPage::ViewportAttributes& other)
  1634. : d(other.d)
  1635. , m_initialScaleFactor(other.m_initialScaleFactor)
  1636. , m_minimumScaleFactor(other.m_minimumScaleFactor)
  1637. , m_maximumScaleFactor(other.m_maximumScaleFactor)
  1638. , m_devicePixelRatio(other.m_devicePixelRatio)
  1639. , m_isUserScalable(other.m_isUserScalable)
  1640. , m_isValid(other.m_isValid)
  1641. , m_size(other.m_size)
  1642. {
  1643. }
  1644. /*!
  1645. Destroys the QWebPage::ViewportAttributes.
  1646. */
  1647. QWebPage::ViewportAttributes::~ViewportAttributes()
  1648. {
  1649. }
  1650. /*!
  1651. Assigns the given QWebPage::ViewportAttributes to this viewport hints and returns a
  1652. reference to this.
  1653. */
  1654. QWebPage::ViewportAttributes& QWebPage::ViewportAttributes::operator=(const QWebPage::ViewportAttributes& other)
  1655. {
  1656. if (this != &other) {
  1657. d = other.d;
  1658. m_initialScaleFactor = other.m_initialScaleFactor;
  1659. m_minimumScaleFactor = other.m_minimumScaleFactor;
  1660. m_maximumScaleFactor = other.m_maximumScaleFactor;
  1661. m_isUserScalable = other.m_isUserScalable;
  1662. m_isValid = other.m_isValid;
  1663. m_size = other.m_size;
  1664. }
  1665. return *this;
  1666. }
  1667. /*! \fn inline bool QWebPage::ViewportAttributes::isValid() const
  1668. Returns whether this is a valid ViewportAttributes or not.
  1669. An invalid ViewportAttributes will have an empty QSize, negative values for scale factors and
  1670. true for the boolean isUserScalable.
  1671. */
  1672. /*! \fn inline QSize QWebPage::ViewportAttributes::size() const
  1673. Returns the size of the viewport.
  1674. */
  1675. /*! \fn inline qreal QWebPage::ViewportAttributes::initialScaleFactor() const
  1676. Returns the initial scale of the viewport as a multiplier.
  1677. */
  1678. /*! \fn inline qreal QWebPage::ViewportAttributes::minimumScaleFactor() const
  1679. Returns the minimum scale value of the viewport as a multiplier.
  1680. */
  1681. /*! \fn inline qreal QWebPage::ViewportAttributes::maximumScaleFactor() const
  1682. Returns the maximum scale value of the viewport as a multiplier.
  1683. */
  1684. /*! \fn inline bool QWebPage::ViewportAttributes::isUserScalable() const
  1685. Determines whether or not the scale can be modified by the user.
  1686. */
  1687. /*!
  1688. \class QWebPage
  1689. \since 4.4
  1690. \brief The QWebPage class provides an object to view and edit web documents.
  1691. \inmodule QtWebKit
  1692. QWebPage holds a main frame responsible for web content, settings, the history
  1693. of navigated links and actions. This class can be used, together with QWebFrame,
  1694. to provide functionality like QWebView in a widget-less environment.
  1695. QWebPage's API is very similar to QWebView, as you are still provided with
  1696. common functions like action() (known as
  1697. \l{QWebView::pageAction()}{pageAction}() in QWebView), triggerAction(),
  1698. findText() and settings(). More QWebView-like functions can be found in the
  1699. main frame of QWebPage, obtained via the mainFrame() function. For example,
  1700. the \l{QWebFrame::load()}{load}(), \l{QWebFrame::setUrl()}{setUrl}() and
  1701. \l{QWebFrame::setHtml()}{setHtml}() functions for QWebPage can be accessed
  1702. using QWebFrame.
  1703. The loadStarted() signal is emitted when the page begins to load.The
  1704. loadProgress() signal, on the other hand, is emitted whenever an element
  1705. of the web page completes loading, such as an embedded image, a script,
  1706. etc. Finally, the loadFinished() signal is emitted when the page contents
  1707. are loaded completely, independent of script execution or page rendering.
  1708. Its argument, either true or false, indicates whether or not the load
  1709. operation succeeded.
  1710. \section1 Using QWebPage in a Widget-less Environment
  1711. Before you begin painting a QWebPage object, you need to set the size of
  1712. the viewport by calling setViewportSize(). Then, you invoke the main
  1713. frame's render function (QWebFrame::render()). An example of this
  1714. is shown in the code snippet below.
  1715. Suppose we have a \c Thumbnail class as follows:
  1716. \snippet webkitsnippets/webpage/main.cpp 0
  1717. The \c Thumbnail's constructor takes in a \a url. We connect our QWebPage
  1718. object's \l{QWebPage::}{loadFinished()} signal to our private slot,
  1719. \c render().
  1720. \snippet webkitsnippets/webpage/main.cpp 1
  1721. The \c render() function shows how we can paint a thumbnail using a
  1722. QWebPage object.
  1723. \snippet webkitsnippets/webpage/main.cpp 2
  1724. We begin by setting the \l{QWebPage::viewportSize()}{viewportSize} and
  1725. then we instantiate a QImage object, \c image, with the same size as our
  1726. \l{QWebPage::viewportSize()}{viewportSize}. This image is then sent
  1727. as a parameter to \c painter. Next, we render the contents of the main
  1728. frame and its subframes into \c painter. Finally, we save the scaled image.
  1729. \sa QWebFrame
  1730. */
  1731. /*!
  1732. Constructs an empty QWebPage with parent \a parent.
  1733. */
  1734. QWebPage::QWebPage(QObject *parent)
  1735. : QObject(parent)
  1736. , d(new QWebPagePrivate(this))
  1737. {
  1738. setView(qobject_cast<QWidget*>(parent));
  1739. connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int)));
  1740. #ifndef NDEBUG
  1741. connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages()));
  1742. #endif
  1743. }
  1744. /*!
  1745. Destroys the web page.
  1746. */
  1747. QWebPage::~QWebPage()
  1748. {
  1749. d->createMainFrame();
  1750. FrameLoader *loader = d->mainFrame->d->frame->loader();
  1751. if (loader)
  1752. loader->detachFromParent();
  1753. delete d;
  1754. }
  1755. /*!
  1756. Returns the main frame of the page.
  1757. The main frame provides access to the hierarchy of sub-frames and is also needed if you
  1758. want to explicitly render a web page into a given painter.
  1759. \sa currentFrame()
  1760. */
  1761. QWebFrame *QWebPage::mainFrame() const
  1762. {
  1763. d->createMainFrame();
  1764. return d->mainFrame;
  1765. }
  1766. /*!
  1767. Returns the frame currently active.
  1768. \sa mainFrame(), frameCreated()
  1769. */
  1770. QWebFrame *QWebPage::currentFrame() const
  1771. {
  1772. d->createMainFrame();
  1773. WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
  1774. return qobject_cast<QWebFrame*>(frame->loader()->networkingContext()->originatingObject());
  1775. }
  1776. /*!
  1777. \since 4.6
  1778. Returns the frame at the given point \a pos, or 0 if there is no frame at
  1779. that position.
  1780. \sa mainFrame(), currentFrame()
  1781. */
  1782. QWebFrame* QWebPage::frameAt(const QPoint& pos) const
  1783. {
  1784. QWebFrame* webFrame = mainFrame();
  1785. if (!webFrame->geometry().contains(pos))
  1786. return 0;
  1787. QWebHitTestResult hitTestResult = webFrame->hitTestContent(pos);
  1788. return hitTestResult.frame();
  1789. }
  1790. /*!
  1791. Returns a pointer to the view's history of navigated web pages.
  1792. */
  1793. QWebHistory *QWebPage::history() const
  1794. {
  1795. d->createMainFrame();
  1796. return &d->history;
  1797. }
  1798. /*!
  1799. Sets the \a view that is associated with the web page.
  1800. \sa view()
  1801. */
  1802. void QWebPage::setView(QWidget* view)
  1803. {
  1804. if (this->view() == view)
  1805. return;
  1806. d->view = view;
  1807. setViewportSize(view ? view->size() : QSize(0, 0));
  1808. // If we have no client, we install a special client delegating
  1809. // the responsibility to the QWidget. This is the code path
  1810. // handling a.o. the "legacy" QWebView.
  1811. //
  1812. // If such a special delegate already exist, we substitute the view.
  1813. if (d->client) {
  1814. if (d->client->isQWidgetClient())
  1815. static_cast<PageClientQWidget*>(d->client.get())->view = view;
  1816. return;
  1817. }
  1818. if (view)
  1819. d->client = new PageClientQWidget(view, this);
  1820. }
  1821. /*!
  1822. Returns the view widget that is associated with the web page.
  1823. \sa setView()
  1824. */
  1825. QWidget *QWebPage::view() const
  1826. {
  1827. return d->view.data();
  1828. }
  1829. /*!
  1830. This function is called whenever a JavaScript program tries to print a \a message to the web browser's console.
  1831. For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber.
  1832. The default implementation prints nothing.
  1833. */
  1834. void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID)
  1835. {
  1836. Q_UNUSED(sourceID)
  1837. // Catch plugin logDestroy message for LayoutTests/plugins/open-and-close-window-with-plugin.html
  1838. // At this point DRT's WebPage has already been destroyed
  1839. if (QWebPagePrivate::drtRun) {
  1840. if (message == QLatin1String("PLUGIN: NPP_Destroy"))
  1841. fprintf (stdout, "CONSOLE MESSAGE: line %d: %s\n", lineNumber, message.toUtf8().constData());
  1842. }
  1843. }
  1844. /*!
  1845. This function is called whenever a JavaScript program running inside \a frame calls the alert() function with
  1846. the message \a msg.
  1847. The default implementation shows the message, \a msg, with QMessageBox::information.
  1848. */
  1849. void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
  1850. {
  1851. Q_UNUSED(frame)
  1852. #ifndef QT_NO_MESSAGEBOX
  1853. QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
  1854. QMessageBox::information(parent, tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Ok);
  1855. #endif
  1856. }
  1857. /*!
  1858. This function is called whenever a JavaScript program running inside \a frame calls the confirm() function
  1859. with the message, \a msg. Returns true if the user confirms the message; otherwise returns false.
  1860. The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons.
  1861. */
  1862. bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
  1863. {
  1864. Q_UNUSED(frame)
  1865. #ifdef QT_NO_MESSAGEBOX
  1866. return true;
  1867. #else
  1868. QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
  1869. return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Yes, QMessageBox::No);
  1870. #endif
  1871. }
  1872. /*!
  1873. This function is called whenever a JavaScript program running inside \a frame tries to prompt the user for input.
  1874. The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue.
  1875. If the prompt was cancelled by the user the implementation should return false; otherwise the
  1876. result should be written to \a result and true should be returned. If the prompt was not cancelled by the
  1877. user, the implementation should return true and the result string must not be null.
  1878. The default implementation uses QInputDialog::getText().
  1879. */
  1880. bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
  1881. {
  1882. Q_UNUSED(frame)
  1883. bool ok = false;
  1884. #ifndef QT_NO_INPUTDIALOG
  1885. QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
  1886. QString x = QInputDialog::getText(parent, tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QLineEdit::Normal, defaultValue, &ok);
  1887. if (ok && result)
  1888. *result = x;
  1889. #endif
  1890. return ok;
  1891. }
  1892. /*!
  1893. \fn bool QWebPage::shouldInterruptJavaScript()
  1894. \since 4.6
  1895. This function is called when a JavaScript program is running for a long period of time.
  1896. If the user wanted to stop the JavaScript the implementation should return true; otherwise false.
  1897. The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons.
  1898. \warning Because of binary compatibility constraints, this function is not virtual. If you want to
  1899. provide your own implementation in a QWebPage subclass, reimplement the shouldInterruptJavaScript()
  1900. slot in your subclass instead. QtWebKit will dynamically detect the slot and call it.
  1901. */
  1902. bool QWebPage::shouldInterruptJavaScript()
  1903. {
  1904. #ifdef QT_NO_MESSAGEBOX
  1905. return false;
  1906. #else
  1907. QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
  1908. return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No);
  1909. #endif
  1910. }
  1911. void QWebPage::setFeaturePermission(QWebFrame* frame, Feature feature, PermissionPolicy policy)
  1912. {
  1913. switch (feature) {
  1914. case Notifications:
  1915. #if ENABLE(NOTIFICATIONS)
  1916. if (policy == PermissionGrantedByUser)
  1917. NotificationPresenterClientQt::notificationPresenter()->allowNotificationForFrame(frame->d->frame);
  1918. #endif
  1919. break;
  1920. case Geolocation:
  1921. #if ENABLE(GEOLOCATION)
  1922. GeolocationPermissionClientQt::geolocationPermissionClient()->setPermission(frame, policy);
  1923. #endif
  1924. break;
  1925. default:
  1926. break;
  1927. }
  1928. }
  1929. /*!
  1930. This function is called whenever WebKit wants to create a new window of the given \a type, for
  1931. example when a JavaScript program requests to open a document in a new window.
  1932. If the new window can be created, the new window's QWebPage is returned; otherwise a null pointer is returned.
  1933. If the view associated with the web page is a QWebView object, then the default implementation forwards
  1934. the request to QWebView's createWindow() function; otherwise it returns a null pointer.
  1935. If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window.
  1936. \note In the cases when the window creation is being triggered by JavaScript, apart from
  1937. reimplementing this method application must also set the JavaScriptCanOpenWindows attribute
  1938. of QWebSettings to true in order for it to get called.
  1939. \sa acceptNavigationRequest(), QWebView::createWindow()
  1940. */
  1941. QWebPage *QWebPage::createWindow(WebWindowType type)
  1942. {
  1943. QWebView *webView = qobject_cast<QWebView*>(view());
  1944. if (webView) {
  1945. QWebView *newView = webView->createWindow(type);
  1946. if (newView)
  1947. return newView->page();
  1948. }
  1949. return 0;
  1950. }
  1951. /*!
  1952. This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin". It is
  1953. called regardless of the value of QWebSettings::PluginsEnabled. The \a classid, \a url, \a paramNames and \a paramValues
  1954. correspond to the HTML object element attributes and child elements to configure the embeddable object.
  1955. */
  1956. QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
  1957. {
  1958. Q_UNUSED(classid)
  1959. Q_UNUSED(url)
  1960. Q_UNUSED(paramNames)
  1961. Q_UNUSED(paramValues)
  1962. return 0;
  1963. }
  1964. static void extractContentTypeFromHash(const HashSet<String>& types, QStringList* list)
  1965. {
  1966. if (!list)
  1967. return;
  1968. HashSet<String>::const_iterator endIt = types.end();
  1969. for (HashSet<String>::const_iterator it = types.begin(); it != endIt; ++it)
  1970. *list << *it;
  1971. }
  1972. static void extractContentTypeFromPluginVector(const Vector<PluginPackage*>& plugins, QStringList* list)
  1973. {
  1974. if (!list)
  1975. return;
  1976. for (unsigned int i = 0; i < plugins.size(); ++i) {
  1977. MIMEToDescriptionsMap::const_iterator map_it = plugins[i]->mimeToDescriptions().begin();
  1978. MIMEToDescriptionsMap::const_iterator map_end = plugins[i]->mimeToDescriptions().end();
  1979. for (; map_it != map_end; ++map_it)
  1980. *list << map_it->first;
  1981. }
  1982. }
  1983. /*!
  1984. * Returns the list of all content types supported by QWebPage.
  1985. */
  1986. QStringList QWebPage::supportedContentTypes() const
  1987. {
  1988. QStringList mimeTypes;
  1989. extractContentTypeFromHash(MIMETypeRegistry::getSupportedImageMIMETypes(), &mimeTypes);
  1990. extractContentTypeFromHash(MIMETypeRegistry::getSupportedNonImageMIMETypes(), &mimeTypes);
  1991. if (d->page->settings() && d->page->settings()->arePluginsEnabled())
  1992. extractContentTypeFromPluginVector(PluginDatabase::installedPlugins()->plugins(), &mimeTypes);
  1993. return mimeTypes;
  1994. }
  1995. /*!
  1996. * Returns true if QWebPage can handle the given \a mimeType; otherwise, returns false.
  1997. */
  1998. bool QWebPage::supportsContentType(const QString& mimeType) const
  1999. {
  2000. const String type = mimeType.toLower();
  2001. if (MIMETypeRegistry::isSupportedImageMIMEType(type))
  2002. return true;
  2003. if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
  2004. return true;
  2005. if (d->page->settings() && d->page->settings()->arePluginsEnabled()
  2006. && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type))
  2007. return true;
  2008. return false;
  2009. }
  2010. static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
  2011. {
  2012. return WebCore::FrameLoadRequest(frame->document()->securityOrigin(),
  2013. WebCore::ResourceRequest(url, frame->loader()->outgoingReferrer()));
  2014. }
  2015. static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
  2016. {
  2017. if (Page* oldPage = frame->page()) {
  2018. WindowFeatures features;
  2019. NavigationAction action;
  2020. FrameLoadRequest request = frameLoadRequest(url, frame);
  2021. if (Page* newPage = oldPage->chrome()->createWindow(frame, request, features, action)) {
  2022. newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, SendReferrer);
  2023. newPage->chrome()->show();
  2024. }
  2025. }
  2026. }
  2027. static void collectChildFrames(QWebFrame* frame, QList<QWebFrame*>& list)
  2028. {
  2029. list << frame->childFrames();
  2030. QListIterator<QWebFrame*> it(frame->childFrames());
  2031. while (it.hasNext()) {
  2032. collectChildFrames(it.next(), list);
  2033. }
  2034. }
  2035. /*!
  2036. This function can be called to trigger the specified \a action.
  2037. It is also called by QtWebKit if the user triggers the action, for example
  2038. through a context menu item.
  2039. If \a action is a checkable action then \a checked specified whether the action
  2040. is toggled or not.
  2041. \sa action()
  2042. */
  2043. void QWebPage::triggerAction(WebAction action, bool)
  2044. {
  2045. WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
  2046. if (!frame)
  2047. return;
  2048. WebCore::Editor *editor = frame->editor();
  2049. const char *command = 0;
  2050. switch (action) {
  2051. case OpenLink:
  2052. if (QWebFrame *targetFrame = d->hitTestResult.linkTargetFrame()) {
  2053. WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
  2054. targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()),
  2055. /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0,
  2056. /*FormState*/ 0, SendReferrer);
  2057. break;
  2058. }
  2059. // fall through
  2060. case OpenLinkInNewWindow:
  2061. openNewWindow(d->hitTestResult.linkUrl(), frame);
  2062. break;
  2063. case OpenFrameInNewWindow: {
  2064. KURL url = frame->loader()->documentLoader()->unreachableURL();
  2065. if (url.isEmpty())
  2066. url = frame->loader()->documentLoader()->url();
  2067. openNewWindow(url, frame);
  2068. break;
  2069. }
  2070. case CopyLinkToClipboard: {
  2071. #if defined(Q_WS_X11)
  2072. bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
  2073. Pasteboard::generalPasteboard()->setSelectionMode(true);
  2074. editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText());
  2075. Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
  2076. #endif
  2077. editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText());
  2078. break;
  2079. }
  2080. case OpenImageInNewWindow:
  2081. openNewWindow(d->hitTestResult.imageUrl(), frame);
  2082. break;
  2083. case DownloadImageToDisk:
  2084. frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.imageUrl(), frame->loader()->outgoingReferrer()));
  2085. break;
  2086. case DownloadLinkToDisk:
  2087. frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.linkUrl(), frame->loader()->outgoingReferrer()));
  2088. break;
  2089. #ifndef QT_NO_CLIPBOARD
  2090. case CopyImageToClipboard:
  2091. QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap());
  2092. break;
  2093. case CopyImageUrlToClipboard:
  2094. QApplication::clipboard()->setText(d->hitTestResult.imageUrl().toString());
  2095. break;
  2096. #endif
  2097. case Back:
  2098. d->page->goBack();
  2099. break;
  2100. case Forward:
  2101. d->page->goForward();
  2102. break;
  2103. case Stop:
  2104. mainFrame()->d->frame->loader()->stopForUserCancel();
  2105. d->updateNavigationActions();
  2106. break;
  2107. case Reload:
  2108. mainFrame()->d->frame->loader()->reload(/*endtoendreload*/false);
  2109. break;
  2110. case ReloadAndBypassCache:
  2111. mainFrame()->d->frame->loader()->reload(/*endtoendreload*/true);
  2112. break;
  2113. case SetTextDirectionDefault:
  2114. editor->setBaseWritingDirection(NaturalWritingDirection);
  2115. break;
  2116. case SetTextDirectionLeftToRight:
  2117. editor->setBaseWritingDirection(LeftToRightWritingDirection);
  2118. break;
  2119. case SetTextDirectionRightToLeft:
  2120. editor->setBaseWritingDirection(RightToLeftWritingDirection);
  2121. break;
  2122. case InspectElement: {
  2123. #if ENABLE(INSPECTOR)
  2124. if (!d->hitTestResult.isNull()) {
  2125. d->getOrCreateInspector(); // Make sure the inspector is created
  2126. d->inspector->show(); // The inspector is expected to be shown on inspection
  2127. d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get());
  2128. }
  2129. #endif
  2130. break;
  2131. }
  2132. case StopScheduledPageRefresh: {
  2133. QWebFrame* topFrame = mainFrame();
  2134. topFrame->d->frame->navigationScheduler()->cancel();
  2135. QList<QWebFrame*> childFrames;
  2136. collectChildFrames(topFrame, childFrames);
  2137. QListIterator<QWebFrame*> it(childFrames);
  2138. while (it.hasNext())
  2139. it.next()->d->frame->navigationScheduler()->cancel();
  2140. break;
  2141. }
  2142. default:
  2143. command = QWebPagePrivate::editorCommandForWebActions(action);
  2144. break;
  2145. }
  2146. if (command)
  2147. editor->command(command).execute();
  2148. }
  2149. QSize QWebPage::viewportSize() const
  2150. {
  2151. if (d->mainFrame && d->mainFrame->d->frame->view())
  2152. return d->mainFrame->d->frame->view()->frameRect().size();
  2153. return d->viewportSize;
  2154. }
  2155. /*!
  2156. \property QWebPage::viewportSize
  2157. \brief the size of the viewport
  2158. The size affects for example the visibility of scrollbars
  2159. if the document is larger than the viewport.
  2160. By default, for a newly-created Web page, this property contains a size with
  2161. zero width and height.
  2162. \sa QWebFrame::render(), preferredContentsSize
  2163. */
  2164. void QWebPage::setViewportSize(const QSize &size) const
  2165. {
  2166. d->viewportSize = size;
  2167. QWebFrame *frame = mainFrame();
  2168. if (frame->d->frame && frame->d->frame->view()) {
  2169. WebCore::FrameView* view = frame->d->frame->view();
  2170. view->resize(size);
  2171. view->adjustViewSize();
  2172. }
  2173. }
  2174. static int getintenv(const char* variable)
  2175. {
  2176. bool ok;
  2177. int value = qgetenv(variable).toInt(&ok);
  2178. return (ok) ? value : -1;
  2179. }
  2180. static QSize queryDeviceSizeForScreenContainingWidget(const QWidget* widget)
  2181. {
  2182. QDesktopWidget* desktop = QApplication::desktop();
  2183. if (!desktop)
  2184. return QSize();
  2185. QSize size;
  2186. if (widget) {
  2187. // Returns the available geometry of the screen which contains widget.
  2188. // NOTE: this must be the the full screen size including any fixed status areas etc.
  2189. size = desktop->availableGeometry(widget).size();
  2190. } else
  2191. size = desktop->availableGeometry().size();
  2192. // This must be in portrait mode, adjust if not.
  2193. if (size.width() > size.height()) {
  2194. int width = size.width();
  2195. size.setWidth(size.height());
  2196. size.setHeight(width);
  2197. }
  2198. return size;
  2199. }
  2200. /*!
  2201. Computes the optimal viewport configuration given the \a availableSize, when
  2202. user interface components are disregarded.
  2203. The configuration is also dependent on the device screen size which is obtained
  2204. automatically. For testing purposes the size can be overridden by setting two
  2205. environment variables QTWEBKIT_DEVICE_WIDTH and QTWEBKIT_DEVICE_HEIGHT, which
  2206. both needs to be set.
  2207. The ViewportAttributes includes a pixel density ratio, which will also be exposed to
  2208. the web author though the -webkit-pixel-ratio media feature. This is the ratio
  2209. between 1 density-independent pixel (DPI) and physical pixels.
  2210. A density-independent pixel is equivalent to one physical pixel on a 160 DPI screen,
  2211. so on our platform assumes that as the baseline density.
  2212. The conversion of DIP units to screen pixels is quite simple:
  2213. pixels = DIPs * (density / 160).
  2214. Thus, on a 240 DPI screen, 1 DIPs would equal 1.5 physical pixels.
  2215. An invalid instance will be returned in the case an empty size is passed to the
  2216. method.
  2217. \note The density is automatically obtained from the DPI of the screen where the page
  2218. is being shown, but as many X11 servers are reporting wrong DPI, it is possible to
  2219. override it using QX11Info::setAppDpiY().
  2220. */
  2221. QWebPage::ViewportAttributes QWebPage::viewportAttributesForSize(const QSize& availableSize) const
  2222. {
  2223. static int desktopWidth = 980;
  2224. ViewportAttributes result;
  2225. if (availableSize.isEmpty())
  2226. return result; // Returns an invalid instance.
  2227. int deviceWidth = getintenv("QTWEBKIT_DEVICE_WIDTH");
  2228. int deviceHeight = getintenv("QTWEBKIT_DEVICE_HEIGHT");
  2229. // Both environment variables need to be set - or they will be ignored.
  2230. if (deviceWidth < 0 && deviceHeight < 0) {
  2231. QSize size = queryDeviceSizeForScreenContainingWidget((d->client) ? d->client->ownerWidget() : 0);
  2232. deviceWidth = size.width();
  2233. deviceHeight = size.height();
  2234. }
  2235. WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments(), desktopWidth, deviceWidth, deviceHeight, qt_defaultDpi(), availableSize);
  2236. result.m_isValid = true;
  2237. result.m_size = conf.layoutSize;
  2238. result.m_initialScaleFactor = conf.initialScale;
  2239. result.m_minimumScaleFactor = conf.minimumScale;
  2240. result.m_maximumScaleFactor = conf.maximumScale;
  2241. result.m_devicePixelRatio = conf.devicePixelRatio;
  2242. result.m_isUserScalable = static_cast<bool>(conf.userScalable);
  2243. d->pixelRatio = conf.devicePixelRatio;
  2244. return result;
  2245. }
  2246. QSize QWebPage::preferredContentsSize() const
  2247. {
  2248. QWebFrame* frame = d->mainFrame;
  2249. if (frame) {
  2250. WebCore::FrameView* view = frame->d->frame->view();
  2251. if (view && view->useFixedLayout())
  2252. return d->mainFrame->d->frame->view()->fixedLayoutSize();
  2253. }
  2254. return d->fixedLayoutSize;
  2255. }
  2256. /*!
  2257. \property QWebPage::preferredContentsSize
  2258. \since 4.6
  2259. \brief a custom size used for laying out the page contents.
  2260. By default all pages are laid out using the viewport of the page as the base.
  2261. As pages mostly are designed for desktop usage, they often do not layout properly
  2262. on small devices as the contents require a certain view width. For this reason
  2263. it is common to use a different layout size and then scale the contents to fit
  2264. within the actual view.
  2265. If this property is set to a valid size, this size is used for all layout needs
  2266. instead of the size of the viewport.
  2267. Setting an invalid size, makes the page fall back to using the viewport size for layout.
  2268. \sa viewportSize
  2269. */
  2270. void QWebPage::setPreferredContentsSize(const QSize& size) const
  2271. {
  2272. // FIXME: Rename this method to setCustomLayoutSize
  2273. d->fixedLayoutSize = size;
  2274. QWebFrame* frame = mainFrame();
  2275. if (!frame->d->frame || !frame->d->frame->view())
  2276. return;
  2277. WebCore::FrameView* view = frame->d->frame->view();
  2278. if (size.isValid()) {
  2279. view->setUseFixedLayout(true);
  2280. view->setFixedLayoutSize(size);
  2281. } else if (view->useFixedLayout())
  2282. view->setUseFixedLayout(false);
  2283. view->layout();
  2284. }
  2285. /*
  2286. This function is to be called after any (animated) scroll/pan has ended, in the case the application handles the
  2287. scrolling/panning of the web contents. This is commonly used in combination with tiling where is it common for
  2288. the application to pan the actual view, which then resizes itself to the size of the contents.
  2289. \note Calling this function makes WebKit stop trying to calculate the visibleContentRect. To turn that on
  2290. again, call this method with an empty rect.
  2291. \sa QGraphicsWebView::resizesToContents, QWebSettings::TiledBackingStoreEnabled
  2292. */
  2293. void QWebPage::setActualVisibleContentRect(const QRect& rect) const
  2294. {
  2295. QWebFrame* frame = mainFrame();
  2296. if (!frame->d->frame || !frame->d->frame->view())
  2297. return;
  2298. WebCore::FrameView* view = frame->d->frame->view();
  2299. view->setActualVisibleContentRect(rect);
  2300. }
  2301. /*!
  2302. \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
  2303. This function is called whenever WebKit requests to navigate \a frame to the resource specified by \a request by means of
  2304. the specified navigation type \a type.
  2305. If \a frame is a null pointer then navigation to a new window is requested. If the request is
  2306. accepted createWindow() will be called.
  2307. The default implementation interprets the page's linkDelegationPolicy and emits linkClicked accordingly or returns true
  2308. to let QWebPage handle the navigation itself.
  2309. \sa createWindow()
  2310. */
  2311. bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
  2312. {
  2313. Q_UNUSED(frame)
  2314. if (type == NavigationTypeLinkClicked) {
  2315. switch (d->linkPolicy) {
  2316. case DontDelegateLinks:
  2317. return true;
  2318. case DelegateExternalLinks:
  2319. if (WebCore::SchemeRegistry::shouldTreatURLSchemeAsLocal(request.url().scheme()))
  2320. return true;
  2321. emit linkClicked(request.url());
  2322. return false;
  2323. case DelegateAllLinks:
  2324. emit linkClicked(request.url());
  2325. return false;
  2326. }
  2327. }
  2328. return true;
  2329. }
  2330. /*!
  2331. \property QWebPage::hasSelection
  2332. \brief whether this page contains selected content or not.
  2333. \sa selectionChanged()
  2334. */
  2335. bool QWebPage::hasSelection() const
  2336. {
  2337. d->createMainFrame();
  2338. WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame();
  2339. if (frame)
  2340. return (frame->selection()->selection().selectionType() != VisibleSelection::NoSelection);
  2341. return false;
  2342. }
  2343. /*!
  2344. \property QWebPage::selectedText
  2345. \brief the text currently selected
  2346. By default, this property contains an empty string.
  2347. \sa selectionChanged(), selectedHtml()
  2348. */
  2349. QString QWebPage::selectedText() const
  2350. {
  2351. d->createMainFrame();
  2352. WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame();
  2353. if (frame->selection()->selection().selectionType() == VisibleSelection::NoSelection)
  2354. return QString();
  2355. return frame->editor()->selectedText();
  2356. }
  2357. /*!
  2358. \since 4.8
  2359. \property QWebPage::selectedHtml
  2360. \brief the HTML currently selected
  2361. By default, this property contains an empty string.
  2362. \sa selectionChanged(), selectedText()
  2363. */
  2364. QString QWebPage::selectedHtml() const
  2365. {
  2366. d->createMainFrame();
  2367. return d->page->focusController()->focusedOrMainFrame()->editor()->selectedRange()->toHTML();
  2368. }
  2369. #ifndef QT_NO_ACTION
  2370. /*!
  2371. Returns a QAction for the specified WebAction \a action.
  2372. The action is owned by the QWebPage but you can customize the look by
  2373. changing its properties.
  2374. QWebPage also takes care of implementing the action, so that upon
  2375. triggering the corresponding action is performed on the page.
  2376. \sa triggerAction()
  2377. */
  2378. QAction *QWebPage::action(WebAction action) const
  2379. {
  2380. if (action == QWebPage::NoWebAction) return 0;
  2381. if (d->actions[action])
  2382. return d->actions[action];
  2383. QString text;
  2384. QIcon icon;
  2385. QStyle *style = d->client ? d->client->style() : qApp->style();
  2386. bool checkable = false;
  2387. switch (action) {
  2388. case OpenLink:
  2389. text = contextMenuItemTagOpenLink();
  2390. break;
  2391. case OpenLinkInNewWindow:
  2392. text = contextMenuItemTagOpenLinkInNewWindow();
  2393. break;
  2394. case OpenFrameInNewWindow:
  2395. text = contextMenuItemTagOpenFrameInNewWindow();
  2396. break;
  2397. case DownloadLinkToDisk:
  2398. text = contextMenuItemTagDownloadLinkToDisk();
  2399. break;
  2400. case CopyLinkToClipboard:
  2401. text = contextMenuItemTagCopyLinkToClipboard();
  2402. break;
  2403. case OpenImageInNewWindow:
  2404. text = contextMenuItemTagOpenImageInNewWindow();
  2405. break;
  2406. case DownloadImageToDisk:
  2407. text = contextMenuItemTagDownloadImageToDisk();
  2408. break;
  2409. case CopyImageToClipboard:
  2410. text = contextMenuItemTagCopyImageToClipboard();
  2411. break;
  2412. case CopyImageUrlToClipboard:
  2413. text = contextMenuItemTagCopyImageUrlToClipboard();
  2414. break;
  2415. case Back:
  2416. text = contextMenuItemTagGoBack();
  2417. icon = style->standardIcon(QStyle::SP_ArrowBack);
  2418. break;
  2419. case Forward:
  2420. text = contextMenuItemTagGoForward();
  2421. icon = style->standardIcon(QStyle::SP_ArrowForward);
  2422. break;
  2423. case Stop:
  2424. text = contextMenuItemTagStop();
  2425. icon = style->standardIcon(QStyle::SP_BrowserStop);
  2426. break;
  2427. case Reload:
  2428. text = contextMenuItemTagReload();
  2429. icon = style->standardIcon(QStyle::SP_BrowserReload);
  2430. break;
  2431. case Cut:
  2432. text = contextMenuItemTagCut();
  2433. break;
  2434. case Copy:
  2435. text = contextMenuItemTagCopy();
  2436. break;
  2437. case Paste:
  2438. text = contextMenuItemTagPaste();
  2439. break;
  2440. case SelectAll:
  2441. text = contextMenuItemTagSelectAll();
  2442. break;
  2443. #ifndef QT_NO_UNDOSTACK
  2444. case Undo: {
  2445. QAction *a = undoStack()->createUndoAction(d->q);
  2446. d->actions[action] = a;
  2447. return a;
  2448. }
  2449. case Redo: {
  2450. QAction *a = undoStack()->createRedoAction(d->q);
  2451. d->actions[action] = a;
  2452. return a;
  2453. }
  2454. #endif // QT_NO_UNDOSTACK
  2455. case MoveToNextChar:
  2456. text = tr("Move the cursor to the next character");
  2457. break;
  2458. case MoveToPreviousChar:
  2459. text = tr("Move the cursor to the previous character");
  2460. break;
  2461. case MoveToNextWord:
  2462. text = tr("Move the cursor to the next word");
  2463. break;
  2464. case MoveToPreviousWord:
  2465. text = tr("Move the cursor to the previous word");
  2466. break;
  2467. case MoveToNextLine:
  2468. text = tr("Move the cursor to the next line");
  2469. break;
  2470. case MoveToPreviousLine:
  2471. text = tr("Move the cursor to the previous line");
  2472. break;
  2473. case MoveToStartOfLine:
  2474. text = tr("Move the cursor to the start of the line");
  2475. break;
  2476. case MoveToEndOfLine:
  2477. text = tr("Move the cursor to the end of the line");
  2478. break;
  2479. case MoveToStartOfBlock:
  2480. text = tr("Move the cursor to the start of the block");
  2481. break;
  2482. case MoveToEndOfBlock:
  2483. text = tr("Move the cursor to the end of the block");
  2484. break;
  2485. case MoveToStartOfDocument:
  2486. text = tr("Move the cursor to the start of the document");
  2487. break;
  2488. case MoveToEndOfDocument:
  2489. text = tr("Move the cursor to the end of the document");
  2490. break;
  2491. case SelectNextChar:
  2492. text = tr("Select to the next character");
  2493. break;
  2494. case SelectPreviousChar:
  2495. text = tr("Select to the previous character");
  2496. break;
  2497. case SelectNextWord:
  2498. text = tr("Select to the next word");
  2499. break;
  2500. case SelectPreviousWord:
  2501. text = tr("Select to the previous word");
  2502. break;
  2503. case SelectNextLine:
  2504. text = tr("Select to the next line");
  2505. break;
  2506. case SelectPreviousLine:
  2507. text = tr("Select to the previous line");
  2508. break;
  2509. case SelectStartOfLine:
  2510. text = tr("Select to the start of the line");
  2511. break;
  2512. case SelectEndOfLine:
  2513. text = tr("Select to the end of the line");
  2514. break;
  2515. case SelectStartOfBlock:
  2516. text = tr("Select to the start of the block");
  2517. break;
  2518. case SelectEndOfBlock:
  2519. text = tr("Select to the end of the block");
  2520. break;
  2521. case SelectStartOfDocument:
  2522. text = tr("Select to the start of the document");
  2523. break;
  2524. case SelectEndOfDocument:
  2525. text = tr("Select to the end of the document");
  2526. break;
  2527. case DeleteStartOfWord:
  2528. text = tr("Delete to the start of the word");
  2529. break;
  2530. case DeleteEndOfWord:
  2531. text = tr("Delete to the end of the word");
  2532. break;
  2533. case SetTextDirectionDefault:
  2534. text = contextMenuItemTagDefaultDirection();
  2535. break;
  2536. case SetTextDirectionLeftToRight:
  2537. text = contextMenuItemTagLeftToRight();
  2538. checkable = true;
  2539. break;
  2540. case SetTextDirectionRightToLeft:
  2541. text = contextMenuItemTagRightToLeft();
  2542. checkable = true;
  2543. break;
  2544. case ToggleBold:
  2545. text = contextMenuItemTagBold();
  2546. checkable = true;
  2547. break;
  2548. case ToggleItalic:
  2549. text = contextMenuItemTagItalic();
  2550. checkable = true;
  2551. break;
  2552. case ToggleUnderline:
  2553. text = contextMenuItemTagUnderline();
  2554. checkable = true;
  2555. break;
  2556. case InspectElement:
  2557. text = contextMenuItemTagInspectElement();
  2558. break;
  2559. case InsertParagraphSeparator:
  2560. text = tr("Insert a new paragraph");
  2561. break;
  2562. case InsertLineSeparator:
  2563. text = tr("Insert a new line");
  2564. break;
  2565. case PasteAndMatchStyle:
  2566. text = tr("Paste and Match Style");
  2567. break;
  2568. case RemoveFormat:
  2569. text = tr("Remove formatting");
  2570. break;
  2571. case ToggleStrikethrough:
  2572. text = tr("Strikethrough");
  2573. checkable = true;
  2574. break;
  2575. case ToggleSubscript:
  2576. text = tr("Subscript");
  2577. checkable = true;
  2578. break;
  2579. case ToggleSuperscript:
  2580. text = tr("Superscript");
  2581. checkable = true;
  2582. break;
  2583. case InsertUnorderedList:
  2584. text = tr("Insert Bulleted List");
  2585. checkable = true;
  2586. break;
  2587. case InsertOrderedList:
  2588. text = tr("Insert Numbered List");
  2589. checkable = true;
  2590. break;
  2591. case Indent:
  2592. text = tr("Indent");
  2593. break;
  2594. case Outdent:
  2595. text = tr("Outdent");
  2596. break;
  2597. case AlignCenter:
  2598. text = tr("Center");
  2599. break;
  2600. case AlignJustified:
  2601. text = tr("Justify");
  2602. break;
  2603. case AlignLeft:
  2604. text = tr("Align Left");
  2605. break;
  2606. case AlignRight:
  2607. text = tr("Align Right");
  2608. break;
  2609. case NoWebAction:
  2610. return 0;
  2611. default:
  2612. break;
  2613. }
  2614. if (text.isEmpty())
  2615. return 0;
  2616. QAction *a = new QAction(d->q);
  2617. a->setText(text);
  2618. a->setData(action);
  2619. a->setCheckable(checkable);
  2620. a->setIcon(icon);
  2621. connect(a, SIGNAL(triggered(bool)),
  2622. this, SLOT(_q_webActionTriggered(bool)));
  2623. d->actions[action] = a;
  2624. d->updateAction(action);
  2625. return a;
  2626. }
  2627. #endif // QT_NO_ACTION
  2628. /*!
  2629. \property QWebPage::modified
  2630. \brief whether the page contains unsubmitted form data, or the contents have been changed.
  2631. By default, this property is false.
  2632. \sa contentsChanged(), contentEditable, undoStack()
  2633. */
  2634. bool QWebPage::isModified() const
  2635. {
  2636. #ifdef QT_NO_UNDOSTACK
  2637. return false;
  2638. #else
  2639. if (!d->undoStack)
  2640. return false;
  2641. return d->undoStack->canUndo();
  2642. #endif // QT_NO_UNDOSTACK
  2643. }
  2644. #ifndef QT_NO_UNDOSTACK
  2645. /*!
  2646. Returns a pointer to the undo stack used for editable content.
  2647. \sa modified
  2648. */
  2649. QUndoStack *QWebPage::undoStack() const
  2650. {
  2651. if (!d->undoStack)
  2652. d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
  2653. return d->undoStack;
  2654. }
  2655. #endif // QT_NO_UNDOSTACK
  2656. /*! \reimp
  2657. */
  2658. bool QWebPage::event(QEvent *ev)
  2659. {
  2660. switch (ev->type()) {
  2661. case QEvent::Timer:
  2662. d->timerEvent(static_cast<QTimerEvent*>(ev));
  2663. break;
  2664. case QEvent::MouseMove:
  2665. d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
  2666. break;
  2667. case QEvent::MouseButtonPress:
  2668. d->mousePressEvent(static_cast<QMouseEvent*>(ev));
  2669. break;
  2670. case QEvent::MouseButtonDblClick:
  2671. d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
  2672. break;
  2673. case QEvent::MouseButtonRelease:
  2674. d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
  2675. break;
  2676. #if !defined(QT_NO_GRAPHICSVIEW)
  2677. case QEvent::GraphicsSceneMouseMove:
  2678. d->mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
  2679. break;
  2680. case QEvent::GraphicsSceneMousePress:
  2681. d->mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
  2682. break;
  2683. case QEvent::GraphicsSceneMouseDoubleClick:
  2684. d->mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
  2685. break;
  2686. case QEvent::GraphicsSceneMouseRelease:
  2687. d->mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
  2688. break;
  2689. #endif
  2690. #ifndef QT_NO_CONTEXTMENU
  2691. case QEvent::ContextMenu:
  2692. d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos());
  2693. break;
  2694. #if !defined(QT_NO_GRAPHICSVIEW)
  2695. case QEvent::GraphicsSceneContextMenu:
  2696. d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos());
  2697. break;
  2698. #endif
  2699. #endif
  2700. #ifndef QT_NO_WHEELEVENT
  2701. case QEvent::Wheel:
  2702. d->wheelEvent(static_cast<QWheelEvent*>(ev));
  2703. break;
  2704. #if !defined(QT_NO_GRAPHICSVIEW)
  2705. case QEvent::GraphicsSceneWheel:
  2706. d->wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(ev));
  2707. break;
  2708. #endif
  2709. #endif
  2710. case QEvent::KeyPress:
  2711. d->keyPressEvent(static_cast<QKeyEvent*>(ev));
  2712. break;
  2713. case QEvent::KeyRelease:
  2714. d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
  2715. break;
  2716. case QEvent::FocusIn:
  2717. d->focusInEvent(static_cast<QFocusEvent*>(ev));
  2718. break;
  2719. case QEvent::FocusOut:
  2720. d->focusOutEvent(static_cast<QFocusEvent*>(ev));
  2721. break;
  2722. #ifndef QT_NO_DRAGANDDROP
  2723. case QEvent::DragEnter:
  2724. d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
  2725. break;
  2726. case QEvent::DragLeave:
  2727. d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
  2728. break;
  2729. case QEvent::DragMove:
  2730. d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
  2731. break;
  2732. case QEvent::Drop:
  2733. d->dropEvent(static_cast<QDropEvent*>(ev));
  2734. break;
  2735. #if !defined(QT_NO_GRAPHICSVIEW)
  2736. case QEvent::GraphicsSceneDragEnter:
  2737. d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
  2738. break;
  2739. case QEvent::GraphicsSceneDragMove:
  2740. d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
  2741. break;
  2742. case QEvent::GraphicsSceneDragLeave:
  2743. d->dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
  2744. break;
  2745. case QEvent::GraphicsSceneDrop:
  2746. d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
  2747. break;
  2748. #endif
  2749. #endif
  2750. case QEvent::InputMethod:
  2751. d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev));
  2752. break;
  2753. case QEvent::ShortcutOverride:
  2754. d->shortcutOverrideEvent(static_cast<QKeyEvent*>(ev));
  2755. break;
  2756. case QEvent::Leave:
  2757. d->leaveEvent(ev);
  2758. break;
  2759. case QEvent::TouchBegin:
  2760. case QEvent::TouchUpdate:
  2761. case QEvent::TouchEnd:
  2762. // Return whether the default action was cancelled in the JS event handler
  2763. return d->touchEvent(static_cast<QTouchEvent*>(ev));
  2764. #ifndef QT_NO_PROPERTIES
  2765. case QEvent::DynamicPropertyChange:
  2766. d->dynamicPropertyChangeEvent(static_cast<QDynamicPropertyChangeEvent*>(ev));
  2767. break;
  2768. #endif
  2769. default:
  2770. return QObject::event(ev);
  2771. }
  2772. return true;
  2773. }
  2774. /*!
  2775. Similar to QWidget::focusNextPrevChild() it focuses the next focusable web element
  2776. if \a next is true; otherwise the previous element is focused.
  2777. Returns true if it can find a new focusable element, or false if it can't.
  2778. */
  2779. bool QWebPage::focusNextPrevChild(bool next)
  2780. {
  2781. QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
  2782. d->keyPressEvent(&ev);
  2783. bool hasFocusedNode = false;
  2784. Frame *frame = d->page->focusController()->focusedFrame();
  2785. if (frame) {
  2786. Document *document = frame->document();
  2787. hasFocusedNode = document && document->focusedNode();
  2788. }
  2789. //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode;
  2790. return hasFocusedNode;
  2791. }
  2792. /*!
  2793. \property QWebPage::contentEditable
  2794. \brief whether the content in this QWebPage is editable or not
  2795. \since 4.5
  2796. If this property is enabled the contents of the page can be edited by the user through a visible
  2797. cursor. If disabled (the default) only HTML elements in the web page with their
  2798. \c{contenteditable} attribute set are editable.
  2799. \sa modified, contentsChanged(), WebAction
  2800. */
  2801. void QWebPage::setContentEditable(bool editable)
  2802. {
  2803. if (isContentEditable() != editable) {
  2804. d->page->setEditable(editable);
  2805. d->page->setTabKeyCyclesThroughElements(!editable);
  2806. if (d->mainFrame) {
  2807. WebCore::Frame* frame = d->mainFrame->d->frame;
  2808. if (editable) {
  2809. frame->editor()->applyEditingStyleToBodyElement();
  2810. // FIXME: mac port calls this if there is no selectedDOMRange
  2811. //frame->setSelectionFromNone();
  2812. }
  2813. }
  2814. d->updateEditorActions();
  2815. }
  2816. }
  2817. bool QWebPage::isContentEditable() const
  2818. {
  2819. return d->page->isEditable();
  2820. }
  2821. /*!
  2822. \property QWebPage::forwardUnsupportedContent
  2823. \brief whether QWebPage should forward unsupported content
  2824. If enabled, the unsupportedContent() signal is emitted with a network reply that
  2825. can be used to read the content.
  2826. If disabled, the download of such content is aborted immediately.
  2827. By default unsupported content is not forwarded.
  2828. */
  2829. void QWebPage::setForwardUnsupportedContent(bool forward)
  2830. {
  2831. d->forwardUnsupportedContent = forward;
  2832. }
  2833. bool QWebPage::forwardUnsupportedContent() const
  2834. {
  2835. return d->forwardUnsupportedContent;
  2836. }
  2837. /*!
  2838. \property QWebPage::linkDelegationPolicy
  2839. \brief how QWebPage should delegate the handling of links through the
  2840. linkClicked() signal
  2841. The default is to delegate no links.
  2842. */
  2843. void QWebPage::setLinkDelegationPolicy(LinkDelegationPolicy policy)
  2844. {
  2845. d->linkPolicy = policy;
  2846. }
  2847. QWebPage::LinkDelegationPolicy QWebPage::linkDelegationPolicy() const
  2848. {
  2849. return d->linkPolicy;
  2850. }
  2851. #ifndef QT_NO_CONTEXTMENU
  2852. /*!
  2853. Filters the context menu event, \a event, through handlers for scrollbars and
  2854. custom event handlers in the web page. Returns true if the event was handled;
  2855. otherwise false.
  2856. A web page may swallow a context menu event through a custom event handler, allowing for context
  2857. menus to be implemented in HTML/JavaScript. This is used by \l{http://maps.google.com/}{Google
  2858. Maps}, for example.
  2859. */
  2860. bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event)
  2861. {
  2862. d->page->contextMenuController()->clearContextMenu();
  2863. if (QWebFrame* webFrame = frameAt(event->pos())) {
  2864. Frame* frame = QWebFramePrivate::core(webFrame);
  2865. if (Scrollbar* scrollbar = frame->view()->scrollbarAtPoint(PlatformMouseEvent(event, 1).pos()))
  2866. return scrollbar->contextMenu(PlatformMouseEvent(event, 1));
  2867. }
  2868. WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame();
  2869. focusedFrame->eventHandler()->sendContextMenuEvent(PlatformMouseEvent(event, 1));
  2870. ContextMenu *menu = d->page->contextMenuController()->contextMenu();
  2871. // If the website defines its own handler then sendContextMenuEvent takes care of
  2872. // calling/showing it and the context menu pointer will be zero. This is the case
  2873. // on maps.google.com for example.
  2874. return !menu;
  2875. }
  2876. #endif // QT_NO_CONTEXTMENU
  2877. /*!
  2878. Updates the page's actions depending on the position \a pos. For example if \a pos is over an image
  2879. element the CopyImageToClipboard action is enabled.
  2880. */
  2881. void QWebPage::updatePositionDependentActions(const QPoint &pos)
  2882. {
  2883. #ifndef QT_NO_ACTION
  2884. // First we disable all actions, but keep track of which ones were originally enabled.
  2885. QBitArray originallyEnabledWebActions(QWebPage::WebActionCount);
  2886. for (int i = ContextMenuItemTagNoAction; i < ContextMenuItemBaseApplicationTag; ++i) {
  2887. QWebPage::WebAction action = webActionForContextMenuAction(WebCore::ContextMenuAction(i));
  2888. if (QAction *a = this->action(action)) {
  2889. originallyEnabledWebActions.setBit(action, a->isEnabled());
  2890. a->setEnabled(false);
  2891. }
  2892. }
  2893. #endif // QT_NO_ACTION
  2894. d->createMainFrame();
  2895. WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame();
  2896. HitTestResult result = focusedFrame->eventHandler()->hitTestResultAtPoint(focusedFrame->view()->windowToContents(pos), /*allowShadowContent*/ false);
  2897. if (result.scrollbar())
  2898. d->hitTestResult = QWebHitTestResult();
  2899. else
  2900. d->hitTestResult = QWebHitTestResult(new QWebHitTestResultPrivate(result));
  2901. d->page->contextMenuController()->setHitTestResult(result);
  2902. d->page->contextMenuController()->populate();
  2903. #if ENABLE(INSPECTOR)
  2904. if (d->page->inspectorController()->enabled())
  2905. d->page->contextMenuController()->addInspectElementItem();
  2906. #endif
  2907. QBitArray visitedWebActions(QWebPage::WebActionCount);
  2908. #ifndef QT_NO_CONTEXTMENU
  2909. delete d->currentContextMenu;
  2910. // Then we let createContextMenu() enable the actions that are put into the menu
  2911. d->currentContextMenu = d->createContextMenu(d->page->contextMenuController()->contextMenu(), d->page->contextMenuController()->contextMenu()->platformDescription(), &visitedWebActions);
  2912. #endif // QT_NO_CONTEXTMENU
  2913. #ifndef QT_NO_ACTION
  2914. // Finally, we restore the original enablement for the actions that were not put into the menu.
  2915. originallyEnabledWebActions &= ~visitedWebActions; // Mask out visited actions (they're part of the menu)
  2916. for (int i = 0; i < QWebPage::WebActionCount; ++i) {
  2917. if (originallyEnabledWebActions.at(i)) {
  2918. if (QAction *a = this->action(QWebPage::WebAction(i)))
  2919. a->setEnabled(true);
  2920. }
  2921. }
  2922. #endif // QT_NO_ACTION
  2923. // This whole process ensures that any actions put into to the context menu has the right
  2924. // enablement, while also keeping the correct enablement for actions that were left out of
  2925. // the menu.
  2926. }
  2927. /*!
  2928. \enum QWebPage::Extension
  2929. This enum describes the types of extensions that the page can support. Before using these extensions, you
  2930. should verify that the extension is supported by calling supportsExtension().
  2931. \value ChooseMultipleFilesExtension Whether the web page supports multiple file selection.
  2932. This extension is invoked when the web content requests one or more file names, for example
  2933. as a result of the user clicking on a "file upload" button in a HTML form where multiple
  2934. file selection is allowed.
  2935. \value ErrorPageExtension Whether the web page can provide an error page when loading fails.
  2936. (introduced in Qt 4.6)
  2937. \sa ChooseMultipleFilesExtensionOption, ChooseMultipleFilesExtensionReturn, ErrorPageExtensionOption, ErrorPageExtensionReturn
  2938. */
  2939. /*!
  2940. \enum QWebPage::ErrorDomain
  2941. \since 4.6
  2942. This enum describes the domain of an ErrorPageExtensionOption object (i.e. the layer in which the error occurred).
  2943. \value QtNetwork The error occurred in the QtNetwork layer; the error code is of type QNetworkReply::NetworkError.
  2944. \value Http The error occurred in the HTTP layer; the error code is a HTTP status code (see QNetworkRequest::HttpStatusCodeAttribute).
  2945. \value WebKit The error is an internal WebKit error.
  2946. */
  2947. /*!
  2948. \class QWebPage::ExtensionOption
  2949. \since 4.4
  2950. \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support.
  2951. \inmodule QtWebKit
  2952. \sa QWebPage::extension() QWebPage::ExtensionReturn
  2953. */
  2954. /*!
  2955. \class QWebPage::ExtensionReturn
  2956. \since 4.4
  2957. \brief The ExtensionReturn class provides an output result from a QWebPage's extension.
  2958. \inmodule QtWebKit
  2959. \sa QWebPage::extension() QWebPage::ExtensionOption
  2960. */
  2961. /*!
  2962. \class QWebPage::ErrorPageExtensionOption
  2963. \since 4.6
  2964. \brief The ErrorPageExtensionOption class describes the option
  2965. for the error page extension.
  2966. \inmodule QtWebKit
  2967. The ErrorPageExtensionOption class holds the \a url for which an error occurred as well as
  2968. the associated \a frame.
  2969. The error itself is reported by an error \a domain, the \a error code as well as \a errorString.
  2970. \sa QWebPage::extension() QWebPage::ErrorPageExtensionReturn
  2971. */
  2972. /*!
  2973. \variable QWebPage::ErrorPageExtensionOption::url
  2974. \brief the url for which an error occurred
  2975. */
  2976. /*!
  2977. \variable QWebPage::ErrorPageExtensionOption::frame
  2978. \brief the frame associated with the error
  2979. */
  2980. /*!
  2981. \variable QWebPage::ErrorPageExtensionOption::domain
  2982. \brief the domain that reported the error
  2983. */
  2984. /*!
  2985. \variable QWebPage::ErrorPageExtensionOption::error
  2986. \brief the error code. Interpretation of the value depends on the \a domain
  2987. \sa QWebPage::ErrorDomain
  2988. */
  2989. /*!
  2990. \variable QWebPage::ErrorPageExtensionOption::errorString
  2991. \brief a string that describes the error
  2992. */
  2993. /*!
  2994. \class QWebPage::ErrorPageExtensionReturn
  2995. \since 4.6
  2996. \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the
  2997. frame for which the error occured.
  2998. \inmodule QtWebKit
  2999. The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are
  3000. optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which
  3001. is assumed to be UTF-8 if not indicated otherwise.
  3002. The error page is stored in the \a content byte array, as HTML content. In order to convert a
  3003. QString to a byte array, the QString::toUtf8() method can be used.
  3004. External objects such as stylesheets or images referenced in the HTML are located relative to
  3005. \a baseUrl.
  3006. \sa QWebPage::extension() QWebPage::ErrorPageExtensionOption, QString::toUtf8()
  3007. */
  3008. /*!
  3009. \fn QWebPage::ErrorPageExtensionReturn::ErrorPageExtensionReturn()
  3010. Constructs a new error page object.
  3011. */
  3012. /*!
  3013. \variable QWebPage::ErrorPageExtensionReturn::contentType
  3014. \brief the error page's content type
  3015. */
  3016. /*!
  3017. \variable QWebPage::ErrorPageExtensionReturn::encoding
  3018. \brief the error page encoding
  3019. */
  3020. /*!
  3021. \variable QWebPage::ErrorPageExtensionReturn::baseUrl
  3022. \brief the base url
  3023. External objects such as stylesheets or images referenced in the HTML are located relative to this url.
  3024. */
  3025. /*!
  3026. \variable QWebPage::ErrorPageExtensionReturn::content
  3027. \brief the HTML content of the error page
  3028. */
  3029. /*!
  3030. \class QWebPage::ChooseMultipleFilesExtensionOption
  3031. \since 4.5
  3032. \brief The ChooseMultipleFilesExtensionOption class describes the option
  3033. for the multiple files selection extension.
  3034. \inmodule QtWebKit
  3035. The ChooseMultipleFilesExtensionOption class holds the frame originating the request
  3036. and the suggested filenames which might be provided.
  3037. \sa QWebPage::extension() QWebPage::chooseFile(), QWebPage::ChooseMultipleFilesExtensionReturn
  3038. */
  3039. /*!
  3040. \variable QWebPage::ChooseMultipleFilesExtensionOption::parentFrame
  3041. \brief The frame in which the request originated
  3042. */
  3043. /*!
  3044. \variable QWebPage::ChooseMultipleFilesExtensionOption::suggestedFileNames
  3045. \brief The suggested filenames
  3046. */
  3047. /*!
  3048. \variable QWebPage::ChooseMultipleFilesExtensionReturn::fileNames
  3049. \brief The selected filenames
  3050. */
  3051. /*!
  3052. \class QWebPage::ChooseMultipleFilesExtensionReturn
  3053. \since 4.5
  3054. \brief The ChooseMultipleFilesExtensionReturn describes the return value
  3055. for the multiple files selection extension.
  3056. \inmodule QtWebKit
  3057. The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user
  3058. when the extension is invoked.
  3059. \sa QWebPage::extension() QWebPage::ChooseMultipleFilesExtensionOption
  3060. */
  3061. /*!
  3062. This virtual function can be reimplemented in a QWebPage subclass to provide support for extensions. The \a option
  3063. argument is provided as input to the extension; the output results can be stored in \a output.
  3064. The behavior of this function is determined by \a extension. The \a option
  3065. and \a output values are typically casted to the corresponding types (for
  3066. example, ChooseMultipleFilesExtensionOption and
  3067. ChooseMultipleFilesExtensionReturn for ChooseMultipleFilesExtension).
  3068. You can call supportsExtension() to check if an extension is supported by the page.
  3069. Returns true if the extension was called successfully; otherwise returns false.
  3070. \sa supportsExtension(), Extension
  3071. */
  3072. bool QWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
  3073. {
  3074. #ifndef QT_NO_FILEDIALOG
  3075. if (extension == ChooseMultipleFilesExtension) {
  3076. // FIXME: do not ignore suggestedFiles
  3077. QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames;
  3078. QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
  3079. QStringList names = QFileDialog::getOpenFileNames(parent, QString::null);
  3080. static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
  3081. return true;
  3082. }
  3083. #endif
  3084. return false;
  3085. }
  3086. /*!
  3087. This virtual function returns true if the web page supports \a extension; otherwise false is returned.
  3088. \sa extension()
  3089. */
  3090. bool QWebPage::supportsExtension(Extension extension) const
  3091. {
  3092. #ifndef QT_NO_FILEDIALOG
  3093. return extension == ChooseMultipleFilesExtension;
  3094. #else
  3095. Q_UNUSED(extension);
  3096. return false;
  3097. #endif
  3098. }
  3099. /*!
  3100. Finds the specified string, \a subString, in the page, using the given \a options.
  3101. If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences
  3102. that exist in the page. All subsequent calls will extend the highlight, rather than
  3103. replace it, with occurrences of the new string.
  3104. If the HighlightAllOccurrences flag is not passed, the function will select an occurrence
  3105. and all subsequent calls will replace the current occurrence with the next one.
  3106. To clear the selection, just pass an empty string.
  3107. Returns true if \a subString was found; otherwise returns false.
  3108. */
  3109. bool QWebPage::findText(const QString &subString, FindFlags options)
  3110. {
  3111. ::TextCaseSensitivity caseSensitivity = ::TextCaseInsensitive;
  3112. if (options & FindCaseSensitively)
  3113. caseSensitivity = ::TextCaseSensitive;
  3114. if (options & HighlightAllOccurrences) {
  3115. if (subString.isEmpty()) {
  3116. d->page->unmarkAllTextMatches();
  3117. return true;
  3118. } else
  3119. return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0);
  3120. } else {
  3121. if (subString.isEmpty()) {
  3122. d->page->mainFrame()->selection()->clear();
  3123. Frame* frame = d->page->mainFrame()->tree()->firstChild();
  3124. while (frame) {
  3125. frame->selection()->clear();
  3126. frame = frame->tree()->traverseNextWithWrap(false);
  3127. }
  3128. }
  3129. ::FindDirection direction = ::FindDirectionForward;
  3130. if (options & FindBackward)
  3131. direction = ::FindDirectionBackward;
  3132. const bool shouldWrap = options & FindWrapsAroundDocument;
  3133. return d->page->findString(subString, caseSensitivity, direction, shouldWrap);
  3134. }
  3135. }
  3136. /*!
  3137. Returns a pointer to the page's settings object.
  3138. \sa QWebSettings::globalSettings()
  3139. */
  3140. QWebSettings *QWebPage::settings() const
  3141. {
  3142. return d->settings;
  3143. }
  3144. /*!
  3145. This function is called when the web content requests a file name, for example
  3146. as a result of the user clicking on a "file upload" button in a HTML form.
  3147. A suggested filename may be provided in \a suggestedFile. The frame originating the
  3148. request is provided as \a parentFrame.
  3149. \sa ChooseMultipleFilesExtension
  3150. */
  3151. QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile)
  3152. {
  3153. Q_UNUSED(parentFrame)
  3154. #ifndef QT_NO_FILEDIALOG
  3155. QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
  3156. return QFileDialog::getOpenFileName(parent, QString::null, suggestedFile);
  3157. #else
  3158. return QString::null;
  3159. #endif
  3160. }
  3161. /*!
  3162. Sets the QNetworkAccessManager \a manager responsible for serving network requests for this
  3163. QWebPage.
  3164. \note It is currently not supported to change the network access manager after the
  3165. QWebPage has used it. The results of doing this are undefined.
  3166. \sa networkAccessManager()
  3167. */
  3168. void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
  3169. {
  3170. if (manager == d->networkManager)
  3171. return;
  3172. if (d->networkManager && d->networkManager->parent() == this)
  3173. delete d->networkManager;
  3174. d->networkManager = manager;
  3175. }
  3176. /*!
  3177. Returns the QNetworkAccessManager that is responsible for serving network
  3178. requests for this QWebPage.
  3179. \sa setNetworkAccessManager()
  3180. */
  3181. QNetworkAccessManager *QWebPage::networkAccessManager() const
  3182. {
  3183. if (!d->networkManager) {
  3184. QWebPage *that = const_cast<QWebPage *>(this);
  3185. that->d->networkManager = new QNetworkAccessManager(that);
  3186. }
  3187. return d->networkManager;
  3188. }
  3189. /*!
  3190. Sets the QWebPluginFactory \a factory responsible for creating plugins embedded into this
  3191. QWebPage.
  3192. Note: The plugin factory is only used if the QWebSettings::PluginsEnabled attribute is enabled.
  3193. \sa pluginFactory()
  3194. */
  3195. void QWebPage::setPluginFactory(QWebPluginFactory *factory)
  3196. {
  3197. d->pluginFactory = factory;
  3198. }
  3199. /*!
  3200. Returns the QWebPluginFactory that is responsible for creating plugins embedded into
  3201. this QWebPage. If no plugin factory is installed a null pointer is returned.
  3202. \sa setPluginFactory()
  3203. */
  3204. QWebPluginFactory *QWebPage::pluginFactory() const
  3205. {
  3206. return d->pluginFactory;
  3207. }
  3208. /*!
  3209. This function is called when a user agent for HTTP requests is needed. You can reimplement this
  3210. function to dynamically return different user agents for different URLs, based on the \a url parameter.
  3211. The default implementation returns the following value:
  3212. "Mozilla/5.0 (%Platform%%Security%%Subplatform%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Safari/%WebKitVersion%"
  3213. On mobile platforms such as Symbian S60 and Maemo, "Mobile Safari" is used instead of "Safari".
  3214. In this string the following values are replaced at run-time:
  3215. \list
  3216. \o %Platform% expands to the windowing system followed by "; " if it is not Windows (e.g. "X11; ").
  3217. \o %Security% expands to "N; " if SSL is disabled.
  3218. \o %Subplatform% expands to the operating system version (e.g. "Windows NT 6.1" or "Intel Mac OS X 10.5").
  3219. \o %WebKitVersion% is the version of WebKit the application was compiled against.
  3220. \o %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version.
  3221. \endlist
  3222. */
  3223. QString QWebPage::userAgentForUrl(const QUrl&) const
  3224. {
  3225. // splitting the string in three and user QStringBuilder is better than using QString::arg()
  3226. static QString firstPart;
  3227. static QString secondPart;
  3228. static QString thirdPart;
  3229. if (firstPart.isNull() || secondPart.isNull() || thirdPart.isNull()) {
  3230. QString firstPartTemp;
  3231. firstPartTemp.reserve(150);
  3232. firstPartTemp += QString::fromLatin1("Mozilla/5.0 ("
  3233. // Platform
  3234. #ifdef Q_WS_MAC
  3235. "Macintosh; "
  3236. #elif defined Q_WS_QWS
  3237. "QtEmbedded; "
  3238. #elif defined Q_WS_MAEMO_5
  3239. "Maemo"
  3240. #elif defined Q_WS_MAEMO_6
  3241. "MeeGo"
  3242. #elif defined Q_WS_WIN
  3243. // Nothing
  3244. #elif defined Q_WS_X11
  3245. "X11; "
  3246. #elif defined Q_OS_SYMBIAN
  3247. "Symbian"
  3248. #else
  3249. "Unknown; "
  3250. #endif
  3251. );
  3252. #if defined Q_OS_SYMBIAN
  3253. QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
  3254. switch (symbianVersion) {
  3255. case QSysInfo::SV_9_2:
  3256. firstPartTemp += QString::fromLatin1("OS/9.2; ");
  3257. break;
  3258. case QSysInfo::SV_9_3:
  3259. firstPartTemp += QString::fromLatin1("OS/9.3; ");
  3260. break;
  3261. case QSysInfo::SV_9_4:
  3262. firstPartTemp += QString::fromLatin1("OS/9.4; ");
  3263. break;
  3264. case QSysInfo::SV_SF_2:
  3265. firstPartTemp += QString::fromLatin1("/2; ");
  3266. break;
  3267. case QSysInfo::SV_SF_3:
  3268. firstPartTemp += QString::fromLatin1("/3; ");
  3269. break;
  3270. case QSysInfo::SV_SF_4:
  3271. firstPartTemp += QString::fromLatin1("/4; ");
  3272. break;
  3273. default:
  3274. firstPartTemp += QString::fromLatin1("; ");
  3275. break;
  3276. }
  3277. #endif
  3278. #if defined(QT_NO_OPENSSL)
  3279. // No SSL support
  3280. firstPartTemp += QString::fromLatin1("N; ");
  3281. #endif
  3282. // Operating system
  3283. #ifdef Q_OS_AIX
  3284. firstPartTemp += QString::fromLatin1("AIX");
  3285. #elif defined Q_OS_WIN32
  3286. firstPartTemp += windowsVersionForUAString();
  3287. #elif defined Q_OS_DARWIN
  3288. #ifdef __i386__ || __x86_64__
  3289. firstPartTemp += QString::fromLatin1("Intel Mac OS X");
  3290. #else
  3291. firstPartTemp += QString::fromLatin1("PPC Mac OS X");
  3292. #endif
  3293. #elif defined Q_OS_BSDI
  3294. firstPartTemp += QString::fromLatin1("BSD");
  3295. #elif defined Q_OS_BSD4
  3296. firstPartTemp += QString::fromLatin1("BSD Four");
  3297. #elif defined Q_OS_CYGWIN
  3298. firstPartTemp += QString::fromLatin1("Cygwin");
  3299. #elif defined Q_OS_DGUX
  3300. firstPartTemp += QString::fromLatin1("DG/UX");
  3301. #elif defined Q_OS_DYNIX
  3302. firstPartTemp += QString::fromLatin1("DYNIX/ptx");
  3303. #elif defined Q_OS_FREEBSD
  3304. firstPartTemp += QString::fromLatin1("FreeBSD");
  3305. #elif defined Q_OS_HPUX
  3306. firstPartTemp += QString::fromLatin1("HP-UX");
  3307. #elif defined Q_OS_HURD
  3308. firstPartTemp += QString::fromLatin1("GNU Hurd");
  3309. #elif defined Q_OS_IRIX
  3310. firstPartTemp += QString::fromLatin1("SGI Irix");
  3311. #elif defined Q_OS_LINUX
  3312. #if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6)
  3313. #if defined(__x86_64__)
  3314. firstPartTemp += QString::fromLatin1("Linux x86_64");
  3315. #elif defined(__i386__)
  3316. firstPartTemp += QString::fromLatin1("Linux i686");
  3317. #else
  3318. firstPartTemp += QString::fromLatin1("Linux");
  3319. #endif
  3320. #endif
  3321. #elif defined Q_OS_LYNX
  3322. firstPartTemp += QString::fromLatin1("LynxOS");
  3323. #elif defined Q_OS_NETBSD
  3324. firstPartTemp += QString::fromLatin1("NetBSD");
  3325. #elif defined Q_OS_OS2
  3326. firstPartTemp += QString::fromLatin1("OS/2");
  3327. #elif defined Q_OS_OPENBSD
  3328. firstPartTemp += QString::fromLatin1("OpenBSD");
  3329. #elif defined Q_OS_OS2EMX
  3330. firstPartTemp += QString::fromLatin1("OS/2");
  3331. #elif defined Q_OS_OSF
  3332. firstPartTemp += QString::fromLatin1("HP Tru64 UNIX");
  3333. #elif defined Q_OS_QNX6
  3334. firstPartTemp += QString::fromLatin1("QNX RTP Six");
  3335. #elif defined Q_OS_QNX
  3336. firstPartTemp += QString::fromLatin1("QNX");
  3337. #elif defined Q_OS_RELIANT
  3338. firstPartTemp += QString::fromLatin1("Reliant UNIX");
  3339. #elif defined Q_OS_SCO
  3340. firstPartTemp += QString::fromLatin1("SCO OpenServer");
  3341. #elif defined Q_OS_SOLARIS
  3342. firstPartTemp += QString::fromLatin1("Sun Solaris");
  3343. #elif defined Q_OS_ULTRIX
  3344. firstPartTemp += QString::fromLatin1("DEC Ultrix");
  3345. #elif defined Q_OS_SYMBIAN
  3346. firstPartTemp += QLatin1Char(' ');
  3347. QSysInfo::S60Version s60Version = QSysInfo::s60Version();
  3348. switch (s60Version) {
  3349. case QSysInfo::SV_S60_3_1:
  3350. firstPartTemp += QString::fromLatin1("Series60/3.1");
  3351. break;
  3352. case QSysInfo::SV_S60_3_2:
  3353. firstPartTemp += QString::fromLatin1("Series60/3.2");
  3354. break;
  3355. case QSysInfo::SV_S60_5_0:
  3356. firstPartTemp += QString::fromLatin1("Series60/5.0");
  3357. break;
  3358. default:
  3359. break;
  3360. }
  3361. #elif defined Q_OS_UNIX
  3362. firstPartTemp += QString::fromLatin1("UNIX BSD/SYSV system");
  3363. #elif defined Q_OS_UNIXWARE
  3364. firstPartTemp += QString::fromLatin1("UnixWare Seven, Open UNIX Eight");
  3365. #else
  3366. firstPartTemp += QString::fromLatin1("Unknown");
  3367. #endif
  3368. #if USE(QT_MOBILITY_SYSTEMINFO)
  3369. // adding Model Number
  3370. QtMobility::QSystemDeviceInfo systemDeviceInfo;
  3371. QString model = systemDeviceInfo.model();
  3372. if (!model.isEmpty()) {
  3373. if (!firstPartTemp.endsWith("; "))
  3374. firstPartTemp += QString::fromLatin1("; ");
  3375. firstPartTemp += systemDeviceInfo.model();
  3376. }
  3377. #endif
  3378. firstPartTemp.squeeze();
  3379. firstPart = firstPartTemp;
  3380. QString secondPartTemp;
  3381. secondPartTemp.reserve(150);
  3382. secondPartTemp += QString::fromLatin1(") ");
  3383. // webkit/qt version
  3384. secondPartTemp += QString::fromLatin1("AppleWebKit/");
  3385. secondPartTemp += qWebKitVersion();
  3386. secondPartTemp += QString::fromLatin1(" (KHTML, like Gecko) ");
  3387. // Application name split the third part
  3388. secondPartTemp.squeeze();
  3389. secondPart = secondPartTemp;
  3390. QString thirdPartTemp;
  3391. thirdPartTemp.reserve(150);
  3392. #if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
  3393. thirdPartTemp += QLatin1String(" Mobile Safari/");
  3394. #else
  3395. thirdPartTemp += QLatin1String(" Safari/");
  3396. #endif
  3397. thirdPartTemp += qWebKitVersion();
  3398. thirdPartTemp.squeeze();
  3399. thirdPart = thirdPartTemp;
  3400. Q_ASSERT(!firstPart.isNull());
  3401. Q_ASSERT(!secondPart.isNull());
  3402. Q_ASSERT(!thirdPart.isNull());
  3403. }
  3404. // Application name/version
  3405. QString appName = QCoreApplication::applicationName();
  3406. if (!appName.isEmpty()) {
  3407. QString appVer = QCoreApplication::applicationVersion();
  3408. if (!appVer.isEmpty())
  3409. appName.append(QLatin1Char('/') + appVer);
  3410. } else {
  3411. // Qt version
  3412. appName = QString::fromLatin1("Qt/") + QString::fromLatin1(qVersion());
  3413. }
  3414. return firstPart + secondPart + appName + thirdPart;
  3415. }
  3416. void QWebPagePrivate::_q_onLoadProgressChanged(int)
  3417. {
  3418. m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
  3419. m_bytesReceived = page->progress()->totalBytesReceived();
  3420. }
  3421. /*!
  3422. Returns the total number of bytes that were received from the network to render the current page,
  3423. including extra content such as embedded images.
  3424. \sa bytesReceived()
  3425. */
  3426. quint64 QWebPage::totalBytes() const
  3427. {
  3428. return d->m_totalBytes;
  3429. }
  3430. /*!
  3431. Returns the number of bytes that were received from the network to render the current page.
  3432. \sa totalBytes(), loadProgress()
  3433. */
  3434. quint64 QWebPage::bytesReceived() const
  3435. {
  3436. return d->m_bytesReceived;
  3437. }
  3438. /*!
  3439. \since 4.8
  3440. \fn void QWebPage::viewportChangeRequested()
  3441. Page authors can provide the supplied values by using the viewport meta tag. More information
  3442. about this can be found at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}.
  3443. \sa QWebPage::ViewportAttributes, setPreferredContentsSize(), QGraphicsWebView::setScale()
  3444. */
  3445. /*!
  3446. \fn void QWebPage::loadStarted()
  3447. This signal is emitted when a page starts loading content.
  3448. \sa loadFinished()
  3449. */
  3450. /*!
  3451. \fn void QWebPage::loadProgress(int progress)
  3452. This signal is emitted when the global progress status changes.
  3453. The current value is provided by \a progress and scales from 0 to 100,
  3454. which is the default range of QProgressBar.
  3455. It accumulates changes from all the child frames.
  3456. \sa bytesReceived()
  3457. */
  3458. /*!
  3459. \fn void QWebPage::loadFinished(bool ok)
  3460. This signal is emitted when the page finishes loading content. This signal
  3461. is independant of script execution or page rendering.
  3462. \a ok will indicate whether the load was successful or any error occurred.
  3463. \sa loadStarted(), ErrorPageExtension
  3464. */
  3465. /*!
  3466. \fn void QWebPage::linkHovered(const QString &link, const QString &title, const QString &textContent)
  3467. This signal is emitted when the mouse hovers over a link.
  3468. \a link contains the link url.
  3469. \a title is the link element's title, if it is specified in the markup.
  3470. \a textContent provides text within the link element, e.g., text inside an HTML anchor tag.
  3471. When the mouse leaves the link element the signal is emitted with empty parameters.
  3472. \sa linkClicked()
  3473. */
  3474. /*!
  3475. \fn void QWebPage::statusBarMessage(const QString& text)
  3476. This signal is emitted when the statusbar \a text is changed by the page.
  3477. */
  3478. /*!
  3479. \fn void QWebPage::frameCreated(QWebFrame *frame)
  3480. This signal is emitted whenever the page creates a new \a frame.
  3481. \sa currentFrame()
  3482. */
  3483. /*!
  3484. \fn void QWebPage::selectionChanged()
  3485. This signal is emitted whenever the selection changes, either interactively
  3486. or programmatically (e.g. by calling triggerAction() with a selection action).
  3487. \sa selectedText()
  3488. */
  3489. /*!
  3490. \fn void QWebPage::contentsChanged()
  3491. \since 4.5
  3492. This signal is emitted whenever the text in form elements changes
  3493. as well as other editable content.
  3494. \sa contentEditable, modified, QWebFrame::toHtml(), QWebFrame::toPlainText()
  3495. */
  3496. /*!
  3497. \fn void QWebPage::geometryChangeRequested(const QRect& geom)
  3498. This signal is emitted whenever the document wants to change the position and size of the
  3499. page to \a geom. This can happen for example through JavaScript.
  3500. */
  3501. /*!
  3502. \fn void QWebPage::repaintRequested(const QRect& dirtyRect)
  3503. This signal is emitted whenever this QWebPage should be updated. It's useful
  3504. when rendering a QWebPage without a QWebView or QGraphicsWebView.
  3505. \a dirtyRect contains the area that needs to be updated. To paint the QWebPage get
  3506. the mainFrame() and call the render(QPainter*, const QRegion&) method with the
  3507. \a dirtyRect as the second parameter.
  3508. \sa mainFrame()
  3509. \sa view()
  3510. */
  3511. /*!
  3512. \fn void QWebPage::scrollRequested(int dx, int dy, const QRect& rectToScroll)
  3513. This signal is emitted whenever the content given by \a rectToScroll needs
  3514. to be scrolled \a dx and \a dy downwards and no view was set.
  3515. \sa view()
  3516. */
  3517. /*!
  3518. \fn void QWebPage::windowCloseRequested()
  3519. This signal is emitted whenever the page requests the web browser window to be closed,
  3520. for example through the JavaScript \c{window.close()} call.
  3521. */
  3522. /*!
  3523. \fn void QWebPage::printRequested(QWebFrame *frame)
  3524. This signal is emitted whenever the page requests the web browser to print \a frame,
  3525. for example through the JavaScript \c{window.print()} call.
  3526. \sa QWebFrame::print(), QPrintPreviewDialog
  3527. */
  3528. /*!
  3529. \fn void QWebPage::unsupportedContent(QNetworkReply *reply)
  3530. This signal is emitted when WebKit cannot handle a link the user navigated to or a
  3531. web server's response includes a "Content-Disposition" header with the 'attachment'
  3532. directive. If "Content-Disposition" is present in \a reply, the web server is indicating
  3533. that the client should prompt the user to save the content regardless of content-type.
  3534. See RFC 2616 sections 19.5.1 for details about Content-Disposition.
  3535. At signal emission time the meta-data of the QNetworkReply \a reply is available.
  3536. \note The receiving slot is responsible for deleting the QNetworkReply \a reply.
  3537. \note This signal is only emitted if the forwardUnsupportedContent property is set to true.
  3538. \sa downloadRequested()
  3539. */
  3540. /*!
  3541. \fn void QWebPage::downloadRequested(const QNetworkRequest &request)
  3542. This signal is emitted when the user decides to download a link. The url of
  3543. the link as well as additional meta-information is contained in \a request.
  3544. \sa unsupportedContent()
  3545. */
  3546. /*!
  3547. \fn void QWebPage::microFocusChanged()
  3548. This signal is emitted when for example the position of the cursor in an editable form
  3549. element changes. It is used to inform input methods about the new on-screen position where
  3550. the user is able to enter text. This signal is usually connected to the
  3551. QWidget::updateMicroFocus() slot.
  3552. */
  3553. /*!
  3554. \fn void QWebPage::linkClicked(const QUrl &url)
  3555. This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy
  3556. property is set to delegate the link handling for the specified \a url.
  3557. By default no links are delegated and are handled by QWebPage instead.
  3558. \note This signal possibly won't be emitted for clicked links which use
  3559. JavaScript to trigger navigation.
  3560. \sa linkHovered()
  3561. */
  3562. /*!
  3563. \fn void QWebPage::toolBarVisibilityChangeRequested(bool visible)
  3564. This signal is emitted whenever the visibility of the toolbar in a web browser
  3565. window that hosts QWebPage should be changed to \a visible.
  3566. */
  3567. /*!
  3568. \fn void QWebPage::statusBarVisibilityChangeRequested(bool visible)
  3569. This signal is emitted whenever the visibility of the statusbar in a web browser
  3570. window that hosts QWebPage should be changed to \a visible.
  3571. */
  3572. /*!
  3573. \fn void QWebPage::menuBarVisibilityChangeRequested(bool visible)
  3574. This signal is emitted whenever the visibility of the menubar in a web browser
  3575. window that hosts QWebPage should be changed to \a visible.
  3576. */
  3577. /*!
  3578. \fn void QWebPage::databaseQuotaExceeded(QWebFrame* frame, QString databaseName);
  3579. \since 4.5
  3580. This signal is emitted whenever the web site shown in \a frame is asking to store data
  3581. to the database \a databaseName and the quota allocated to that web site is exceeded.
  3582. \sa QWebDatabase
  3583. */
  3584. /*!
  3585. \fn void QWebPage::applicationCacheQuotaExceeded(QWebSecurityOrigin* origin, quint64 defaultOriginQuota);
  3586. This signal is emitted whenever the web site is asking to store data to the application cache
  3587. database databaseName and the quota allocated to that web site is exceeded.
  3588. */
  3589. /*!
  3590. \since 4.5
  3591. \fn void QWebPage::saveFrameStateRequested(QWebFrame* frame, QWebHistoryItem* item);
  3592. This signal is emitted shortly before the history of navigated pages
  3593. in \a frame is changed, for example when navigating back in the history.
  3594. The provided QWebHistoryItem, \a item, holds the history entry of the frame before
  3595. the change.
  3596. A potential use-case for this signal is to store custom data in
  3597. the QWebHistoryItem associated to the frame, using QWebHistoryItem::setUserData().
  3598. */
  3599. /*!
  3600. \since 4.5
  3601. \fn void QWebPage::restoreFrameStateRequested(QWebFrame* frame);
  3602. This signal is emitted when the load of \a frame is finished and the application may now update its state accordingly.
  3603. */
  3604. /*!
  3605. \fn QWebPagePrivate* QWebPage::handle() const
  3606. \internal
  3607. */
  3608. #include "moc_qwebpage.cpp"