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.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
26 #include "qwebframe.h"
27 #include "qwebpage_p.h"
28 #include "qwebframe_p.h"
29 #include "qwebhistory.h"
30 #include "qwebhistory_p.h"
31 #include "qwebinspector.h"
32 #include "qwebinspector_p.h"
33 #include "qwebsettings.h"
34 #include "qwebkitplatformplugin.h"
35 #include "qwebkitversion.h"
37 #include "CSSComputedStyleDeclaration.h"
38 #include "CSSParser.h"
39 #include "ApplicationCacheStorage.h"
40 #include "BackForwardListImpl.h"
41 #include "MemoryCache.h"
43 #include "ChromeClientQt.h"
44 #include "ClientRect.h"
45 #include "ContextMenu.h"
46 #include "ContextMenuClientQt.h"
47 #include "ContextMenuController.h"
48 #include "DeviceMotionClientQt.h"
49 #include "DeviceOrientationClientQt.h"
50 #include "DocumentLoader.h"
51 #include "DragClientQt.h"
52 #include "DragController.h"
55 #include "EditorClientQt.h"
56 #include "FocusController.h"
57 #include "FormState.h"
59 #include "FrameLoadRequest.h"
60 #include "FrameLoader.h"
61 #include "FrameLoader.h"
62 #include "FrameLoaderClientQt.h"
63 #include "FrameTree.h"
64 #include "FrameView.h"
65 #include "GeolocationPermissionClientQt.h"
66 #include "HTMLFormElement.h"
67 #include "HTMLFrameOwnerElement.h"
68 #include "HTMLInputElement.h"
69 #include "HTMLNames.h"
71 #include "HitTestResult.h"
73 #include "InspectorClientQt.h"
74 #include "InspectorController.h"
75 #include "InspectorServerQt.h"
77 #include "LocalizedStrings.h"
79 #include "MIMETypeRegistry.h"
80 #include "NavigationAction.h"
81 #include "NetworkingContext.h"
83 #include "NotificationPresenterClientQt.h"
84 #include "NotImplemented.h"
86 #include "PageClientQt.h"
87 #include "PageGroup.h"
88 #include "Pasteboard.h"
89 #include "PlatformKeyboardEvent.h"
90 #include "PlatformTouchEvent.h"
91 #include "PlatformWheelEvent.h"
92 #include "PluginDatabase.h"
93 #include "PluginDatabase.h"
94 #include "PluginPackage.h"
95 #include "ProgressTracker.h"
96 #include "QtPlatformPlugin.h"
98 #include "RenderTextControl.h"
99 #include "SchemeRegistry.h"
100 #include "Scrollbar.h"
101 #include "SecurityOrigin.h"
102 #include "Settings.h"
103 #include "TextIterator.h"
104 #include "WebPlatformStrategies.h"
105 #include "WindowFeatures.h"
106 #include "WorkerThread.h"
107 #include "runtime/InitializeThreading.h"
108 #include "wtf/Threading.h"
110 #include <QApplication>
111 #include <QBasicTimer>
114 #include <QDesktopWidget>
115 #include <QDragEnterEvent>
116 #include <QDragLeaveEvent>
117 #include <QDragMoveEvent>
118 #include <QDropEvent>
119 #include <QFileDialog>
120 #include <QHttpRequestHeader>
121 #include <QInputDialog>
123 #include <QMessageBox>
124 #include <QNetworkProxy>
125 #include <QUndoStack>
128 #include <QClipboard>
129 #include <QSslSocket>
132 #include <QTextCharFormat>
133 #include <QTextDocument>
134 #include <QTouchEvent>
135 #include <QNetworkAccessManager>
136 #include <QNetworkRequest>
137 #if defined(Q_WS_X11)
142 using namespace WebCore;
144 bool QWebPagePrivate::drtRun = false;
146 // Lookup table mapping QWebPage::WebActions to the associated Editor commands
147 static const char* editorCommandWebActions[] =
151 0, // OpenLinkInNewWindow,
152 0, // OpenFrameInNewWindow,
154 0, // DownloadLinkToDisk,
155 0, // CopyLinkToClipboard,
157 0, // OpenImageInNewWindow,
158 0, // DownloadImageToDisk,
159 0, // CopyImageToClipboard,
172 "MoveForward", // MoveToNextChar,
173 "MoveBackward", // MoveToPreviousChar,
174 "MoveWordForward", // MoveToNextWord,
175 "MoveWordBackward", // MoveToPreviousWord,
176 "MoveDown", // MoveToNextLine,
177 "MoveUp", // MoveToPreviousLine,
178 "MoveToBeginningOfLine", // MoveToStartOfLine,
179 "MoveToEndOfLine", // MoveToEndOfLine,
180 "MoveToBeginningOfParagraph", // MoveToStartOfBlock,
181 "MoveToEndOfParagraph", // MoveToEndOfBlock,
182 "MoveToBeginningOfDocument", // MoveToStartOfDocument,
183 "MoveToEndOfDocument", // MoveToEndOfDocument,
184 "MoveForwardAndModifySelection", // SelectNextChar,
185 "MoveBackwardAndModifySelection", // SelectPreviousChar,
186 "MoveWordForwardAndModifySelection", // SelectNextWord,
187 "MoveWordBackwardAndModifySelection", // SelectPreviousWord,
188 "MoveDownAndModifySelection", // SelectNextLine,
189 "MoveUpAndModifySelection", // SelectPreviousLine,
190 "MoveToBeginningOfLineAndModifySelection", // SelectStartOfLine,
191 "MoveToEndOfLineAndModifySelection", // SelectEndOfLine,
192 "MoveToBeginningOfParagraphAndModifySelection", // SelectStartOfBlock,
193 "MoveToEndOfParagraphAndModifySelection", // SelectEndOfBlock,
194 "MoveToBeginningOfDocumentAndModifySelection", //SelectStartOfDocument,
195 "MoveToEndOfDocumentAndModifySelection", // SelectEndOfDocument,
196 "DeleteWordBackward", // DeleteStartOfWord,
197 "DeleteWordForward", // DeleteEndOfWord,
199 0, // SetTextDirectionDefault,
200 0, // SetTextDirectionLeftToRight,
201 0, // SetTextDirectionRightToLeft,
203 "ToggleBold", // ToggleBold,
204 "ToggleItalic", // ToggleItalic,
205 "ToggleUnderline", // ToggleUnderline,
207 0, // InspectElement,
209 "InsertNewline", // InsertParagraphSeparator
210 "InsertLineBreak", // InsertLineSeparator
212 "SelectAll", // SelectAll
213 0, // ReloadAndBypassCache,
215 "PasteAndMatchStyle", // PasteAndMatchStyle
216 "RemoveFormat", // RemoveFormat
217 "Strikethrough", // ToggleStrikethrough,
218 "Subscript", // ToggleSubscript
219 "Superscript", // ToggleSuperscript
220 "InsertUnorderedList", // InsertUnorderedList
221 "InsertOrderedList", // InsertOrderedList
223 "Outdent", // Outdent,
225 "AlignCenter", // AlignCenter,
226 "AlignJustified", // AlignJustified,
227 "AlignLeft", // AlignLeft,
228 "AlignRight", // AlignRight,
233 // Lookup the appropriate editor command to use for WebAction \a action
234 const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action)
236 if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*))))
237 return editorCommandWebActions[action];
241 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
244 if (actions & Qt::CopyAction)
245 result |= DragOperationCopy;
246 // DragOperationgeneric represents InternetExplorer's equivalent of Move operation,
247 // hence it should be considered as "move"
248 if (actions & Qt::MoveAction)
249 result |= (DragOperationMove | DragOperationGeneric);
250 if (actions & Qt::LinkAction)
251 result |= DragOperationLink;
252 return (DragOperation)result;
255 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
257 Qt::DropAction result = Qt::IgnoreAction;
258 if (actions & DragOperationCopy)
259 result = Qt::CopyAction;
260 else if (actions & DragOperationMove)
261 result = Qt::MoveAction;
262 // DragOperationgeneric represents InternetExplorer's equivalent of Move operation,
263 // hence it should be considered as "move"
264 else if (actions & DragOperationGeneric)
265 result = Qt::MoveAction;
266 else if (actions & DragOperationLink)
267 result = Qt::LinkAction;
271 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
276 #ifndef QT_NO_UNDOSTACK
279 , insideOpenCall(false)
282 , clickCausedFocus(false)
284 , forwardUnsupportedContent(false)
285 , smartInsertDeleteEnabled(true)
286 , selectTrailingWhitespaceEnabled(false)
287 , linkPolicy(QWebPage::DontDelegateLinks)
288 , viewportSize(QSize(0, 0))
289 #ifndef QT_NO_CONTEXTMENU
290 , currentContextMenu(0)
294 , useFixedLayout(false)
296 , inspectorFrontend(0)
298 , inspectorIsInternalOnly(false)
300 WebCore::InitializeLoggingChannelsIfNecessary();
301 ScriptController::initializeThreading();
302 WTF::initializeMainThread();
303 WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);
304 #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
305 WebCore::Font::setCodePath(WebCore::Font::Complex);
308 WebPlatformStrategies::initialize();
310 Page::PageClients pageClients;
311 pageClients.chromeClient = new ChromeClientQt(q);
312 pageClients.contextMenuClient = new ContextMenuClientQt();
313 pageClients.editorClient = new EditorClientQt(q);
314 pageClients.dragClient = new DragClientQt(q);
315 pageClients.inspectorClient = new InspectorClientQt(q);
316 #if ENABLE(DEVICE_ORIENTATION)
317 pageClients.deviceOrientationClient = new DeviceOrientationClientQt(q);
318 pageClients.deviceMotionClient = new DeviceMotionClientQt(q);
320 page = new Page(pageClients);
322 settings = new QWebSettings(page->settings());
324 history.d = new QWebHistoryPrivate(static_cast<WebCore::BackForwardListImpl*>(page->backForwardList()));
325 memset(actions, 0, sizeof(actions));
327 PageGroup::setShouldTrackVisitedLinks(true);
329 #if ENABLE(NOTIFICATIONS)
330 NotificationPresenterClientQt::notificationPresenter()->addClient();
334 QWebPagePrivate::~QWebPagePrivate()
336 if (inspector && inspectorIsInternalOnly) {
337 // Since we have to delete an internal inspector,
338 // call setInspector(0) directly to prevent potential crashes
341 #ifndef QT_NO_CONTEXTMENU
342 delete currentContextMenu;
344 #ifndef QT_NO_UNDOSTACK
351 inspector->setPage(0);
353 #if ENABLE(NOTIFICATIONS)
354 NotificationPresenterClientQt::notificationPresenter()->removeClient();
358 WebCore::ViewportArguments QWebPagePrivate::viewportArguments()
360 return page ? page->viewportArguments() : WebCore::ViewportArguments();
363 WebCore::Page* QWebPagePrivate::core(const QWebPage* page)
365 return page->d->page;
368 QWebPagePrivate* QWebPagePrivate::priv(QWebPage* page)
373 bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
376 && frame == mainFrame)
378 return q->acceptNavigationRequest(frame, request, type);
381 void QWebPagePrivate::createMainFrame()
384 QWebFrameData frameData(page);
385 mainFrame = new QWebFrame(q, &frameData);
387 emit q->frameCreated(mainFrame);
391 static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
394 case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
395 case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
396 case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
397 case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
398 case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
399 case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
400 case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
401 case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
402 case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
403 case WebCore::ContextMenuItemTagGoBack: return QWebPage::Back;
404 case WebCore::ContextMenuItemTagGoForward: return QWebPage::Forward;
405 case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
406 case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
407 case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
408 case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
409 case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault;
410 case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight;
411 case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft;
412 case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold;
413 case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic;
414 case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline;
415 #if ENABLE(INSPECTOR)
416 case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement;
420 return QWebPage::NoWebAction;
423 #ifndef QT_NO_CONTEXTMENU
424 QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu,
425 const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions)
430 QMenu* menu = new QMenu(client->ownerWidget());
431 for (int i = 0; i < items->count(); ++i) {
432 const ContextMenuItem &item = items->at(i);
433 switch (item.type()) {
434 case WebCore::CheckableActionType: /* fall through */
435 case WebCore::ActionType: {
436 QWebPage::WebAction action = webActionForContextMenuAction(item.action());
437 QAction *a = q->action(action);
439 ContextMenuItem it(item);
440 webcoreMenu->checkOrEnableIfNeeded(it);
441 PlatformMenuItemDescription desc = it.releasePlatformDescription();
442 a->setEnabled(desc.enabled);
443 a->setChecked(desc.checked);
444 a->setCheckable(item.type() == WebCore::CheckableActionType);
447 visitedWebActions->setBit(action);
451 case WebCore::SeparatorType:
452 menu->addSeparator();
454 case WebCore::SubmenuType: {
455 QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu(), visitedWebActions);
457 bool anyEnabledAction = false;
459 QList<QAction *> actions = subMenu->actions();
460 for (int i = 0; i < actions.count(); ++i) {
461 if (actions.at(i)->isVisible())
462 anyEnabledAction |= actions.at(i)->isEnabled();
465 // don't show sub-menus with just disabled actions
466 if (anyEnabledAction) {
467 subMenu->setTitle(item.title());
468 menu->addAction(subMenu->menuAction());
477 #endif // QT_NO_CONTEXTMENU
480 void QWebPagePrivate::_q_webActionTriggered(bool checked)
482 QAction *a = qobject_cast<QAction *>(q->sender());
485 QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
486 q->triggerAction(action, checked);
488 #endif // QT_NO_ACTION
490 void QWebPagePrivate::_q_cleanupLeakMessages()
493 // Need this to make leak messages accurate.
494 cache()->setCapacities(0, 0, 0);
498 void QWebPagePrivate::updateAction(QWebPage::WebAction action)
503 QAction *a = actions[action];
504 if (!a || !mainFrame)
507 WebCore::FrameLoader *loader = mainFrame->d->frame->loader();
508 WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
510 bool enabled = a->isEnabled();
511 bool checked = a->isChecked();
515 enabled = page->canGoBackOrForward(-1);
517 case QWebPage::Forward:
518 enabled = page->canGoBackOrForward(1);
521 enabled = loader->isLoading();
523 case QWebPage::Reload:
524 case QWebPage::ReloadAndBypassCache:
525 enabled = !loader->isLoading();
527 #ifndef QT_NO_UNDOSTACK
530 // those two are handled by QUndoStack
532 #endif // QT_NO_UNDOSTACK
533 case QWebPage::SelectAll: // editor command is always enabled
535 case QWebPage::SetTextDirectionDefault:
536 case QWebPage::SetTextDirectionLeftToRight:
537 case QWebPage::SetTextDirectionRightToLeft:
538 enabled = editor->canEdit();
542 // see if it's an editor command
543 const char* commandName = editorCommandForWebActions(action);
545 // if it's an editor command, let it's logic determine state
547 Editor::Command command = editor->command(commandName);
548 enabled = command.isEnabled();
550 checked = command.state() != FalseTriState;
558 a->setEnabled(enabled);
560 if (a->isCheckable())
561 a->setChecked(checked);
562 #endif // QT_NO_ACTION
565 void QWebPagePrivate::updateNavigationActions()
567 updateAction(QWebPage::Back);
568 updateAction(QWebPage::Forward);
569 updateAction(QWebPage::Stop);
570 updateAction(QWebPage::Reload);
571 updateAction(QWebPage::ReloadAndBypassCache);
574 void QWebPagePrivate::updateEditorActions()
576 updateAction(QWebPage::Cut);
577 updateAction(QWebPage::Copy);
578 updateAction(QWebPage::Paste);
579 updateAction(QWebPage::MoveToNextChar);
580 updateAction(QWebPage::MoveToPreviousChar);
581 updateAction(QWebPage::MoveToNextWord);
582 updateAction(QWebPage::MoveToPreviousWord);
583 updateAction(QWebPage::MoveToNextLine);
584 updateAction(QWebPage::MoveToPreviousLine);
585 updateAction(QWebPage::MoveToStartOfLine);
586 updateAction(QWebPage::MoveToEndOfLine);
587 updateAction(QWebPage::MoveToStartOfBlock);
588 updateAction(QWebPage::MoveToEndOfBlock);
589 updateAction(QWebPage::MoveToStartOfDocument);
590 updateAction(QWebPage::MoveToEndOfDocument);
591 updateAction(QWebPage::SelectNextChar);
592 updateAction(QWebPage::SelectPreviousChar);
593 updateAction(QWebPage::SelectNextWord);
594 updateAction(QWebPage::SelectPreviousWord);
595 updateAction(QWebPage::SelectNextLine);
596 updateAction(QWebPage::SelectPreviousLine);
597 updateAction(QWebPage::SelectStartOfLine);
598 updateAction(QWebPage::SelectEndOfLine);
599 updateAction(QWebPage::SelectStartOfBlock);
600 updateAction(QWebPage::SelectEndOfBlock);
601 updateAction(QWebPage::SelectStartOfDocument);
602 updateAction(QWebPage::SelectEndOfDocument);
603 updateAction(QWebPage::DeleteStartOfWord);
604 updateAction(QWebPage::DeleteEndOfWord);
605 updateAction(QWebPage::SetTextDirectionDefault);
606 updateAction(QWebPage::SetTextDirectionLeftToRight);
607 updateAction(QWebPage::SetTextDirectionRightToLeft);
608 updateAction(QWebPage::ToggleBold);
609 updateAction(QWebPage::ToggleItalic);
610 updateAction(QWebPage::ToggleUnderline);
611 updateAction(QWebPage::InsertParagraphSeparator);
612 updateAction(QWebPage::InsertLineSeparator);
613 updateAction(QWebPage::PasteAndMatchStyle);
614 updateAction(QWebPage::RemoveFormat);
615 updateAction(QWebPage::ToggleStrikethrough);
616 updateAction(QWebPage::ToggleSubscript);
617 updateAction(QWebPage::ToggleSuperscript);
618 updateAction(QWebPage::InsertUnorderedList);
619 updateAction(QWebPage::InsertOrderedList);
620 updateAction(QWebPage::Indent);
621 updateAction(QWebPage::Outdent);
622 updateAction(QWebPage::AlignCenter);
623 updateAction(QWebPage::AlignJustified);
624 updateAction(QWebPage::AlignLeft);
625 updateAction(QWebPage::AlignRight);
628 void QWebPagePrivate::timerEvent(QTimerEvent *ev)
630 int timerId = ev->timerId();
631 if (timerId == tripleClickTimer.timerId())
632 tripleClickTimer.stop();
638 void QWebPagePrivate::mouseMoveEvent(T* ev)
640 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
644 bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0));
645 ev->setAccepted(accepted);
649 void QWebPagePrivate::mousePressEvent(T* ev)
651 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
655 RefPtr<WebCore::Node> oldNode;
656 Frame* focusedFrame = page->focusController()->focusedFrame();
657 if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
658 oldNode = focusedDocument->focusedNode();
660 if (tripleClickTimer.isActive()
661 && (ev->pos() - tripleClick).manhattanLength()
662 < QApplication::startDragDistance()) {
663 mouseTripleClickEvent(ev);
667 bool accepted = false;
668 adjustPointForClicking(ev);
669 PlatformMouseEvent mev(ev, 1);
670 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
671 if (mev.button() != NoButton)
672 accepted = frame->eventHandler()->handleMousePressEvent(mev);
673 ev->setAccepted(accepted);
675 RefPtr<WebCore::Node> newNode;
676 focusedFrame = page->focusController()->focusedFrame();
677 if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0)
678 newNode = focusedDocument->focusedNode();
680 if (newNode && oldNode != newNode)
681 clickCausedFocus = true;
685 void QWebPagePrivate::mouseDoubleClickEvent(T *ev)
687 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
691 bool accepted = false;
692 PlatformMouseEvent mev(ev, 2);
693 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
694 if (mev.button() != NoButton)
695 accepted = frame->eventHandler()->handleMousePressEvent(mev);
696 ev->setAccepted(accepted);
698 tripleClickTimer.start(QApplication::doubleClickInterval(), q);
699 tripleClick = QPointF(ev->pos()).toPoint();
703 void QWebPagePrivate::mouseTripleClickEvent(T *ev)
705 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
709 bool accepted = false;
710 PlatformMouseEvent mev(ev, 3);
711 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
712 if (mev.button() != NoButton)
713 accepted = frame->eventHandler()->handleMousePressEvent(mev);
714 ev->setAccepted(accepted);
717 void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button)
719 #ifndef QT_NO_CLIPBOARD
720 if (QApplication::clipboard()->supportsSelection()) {
721 bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
722 Pasteboard::generalPasteboard()->setSelectionMode(true);
723 WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame();
724 if (button == Qt::LeftButton) {
725 if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) {
726 focusFrame->editor()->copy();
727 ev->setAccepted(true);
729 } else if (button == Qt::MidButton) {
730 if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) {
731 focusFrame->editor()->paste();
732 ev->setAccepted(true);
735 Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
741 void QWebPagePrivate::mouseReleaseEvent(T *ev)
743 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
747 bool accepted = false;
748 adjustPointForClicking(ev);
749 PlatformMouseEvent mev(ev, 0);
750 // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton
751 if (mev.button() != NoButton)
752 accepted = frame->eventHandler()->handleMouseReleaseEvent(mev);
753 ev->setAccepted(accepted);
755 handleClipboard(ev, ev->button());
756 handleSoftwareInputPanel(ev->button());
759 void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button)
761 Frame* frame = page->focusController()->focusedFrame();
765 if (client && client->inputMethodEnabled()
766 && frame->document()->focusedNode()
767 && button == Qt::LeftButton && qApp->autoSipEnabled()) {
768 QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
769 client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
770 if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
771 QEvent event(QEvent::RequestSoftwareInputPanel);
772 QApplication::sendEvent(client->ownerWidget(), &event);
776 clickCausedFocus = false;
779 #ifndef QT_NO_CONTEXTMENU
780 void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos)
782 QMenu *menu = q->createStandardContextMenu();
784 menu->exec(globalPos);
788 #endif // QT_NO_CONTEXTMENU
792 This function creates the standard context menu which is shown when
793 the user clicks on the web page with the right mouse button. It is
794 called from the default contextMenuEvent() handler. The popup menu's
795 ownership is transferred to the caller.
797 QMenu *QWebPage::createStandardContextMenu()
799 #ifndef QT_NO_CONTEXTMENU
800 QMenu *menu = d->currentContextMenu;
801 d->currentContextMenu = 0;
808 #ifndef QT_NO_WHEELEVENT
810 void QWebPagePrivate::wheelEvent(T *ev)
812 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
816 WebCore::PlatformWheelEvent pev(ev);
817 bool accepted = frame->eventHandler()->handleWheelEvent(pev);
818 ev->setAccepted(accepted);
820 #endif // QT_NO_WHEELEVENT
822 #ifndef QT_NO_SHORTCUT
823 QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event)
826 QKeySequence::StandardKey standardKey;
827 QWebPage::WebAction action;
828 } editorActions[] = {
829 { QKeySequence::Cut, QWebPage::Cut },
830 { QKeySequence::Copy, QWebPage::Copy },
831 { QKeySequence::Paste, QWebPage::Paste },
832 { QKeySequence::Undo, QWebPage::Undo },
833 { QKeySequence::Redo, QWebPage::Redo },
834 { QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar },
835 { QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar },
836 { QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord },
837 { QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord },
838 { QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine },
839 { QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine },
840 { QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine },
841 { QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine },
842 { QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock },
843 { QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock },
844 { QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument },
845 { QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument },
846 { QKeySequence::SelectNextChar, QWebPage::SelectNextChar },
847 { QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar },
848 { QKeySequence::SelectNextWord, QWebPage::SelectNextWord },
849 { QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord },
850 { QKeySequence::SelectNextLine, QWebPage::SelectNextLine },
851 { QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine },
852 { QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine },
853 { QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine },
854 { QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock },
855 { QKeySequence::SelectEndOfBlock, QWebPage::SelectEndOfBlock },
856 { QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument },
857 { QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument },
858 { QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord },
859 { QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord },
860 { QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator },
861 { QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator },
862 { QKeySequence::SelectAll, QWebPage::SelectAll },
863 { QKeySequence::UnknownKey, QWebPage::NoWebAction }
866 for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i)
867 if (event == editorActions[i].standardKey)
868 return editorActions[i].action;
870 return QWebPage::NoWebAction;
872 #endif // QT_NO_SHORTCUT
874 void QWebPagePrivate::keyPressEvent(QKeyEvent *ev)
876 bool handled = false;
877 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
878 // we forward the key event to WebCore first to handle potential DOM
879 // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent
880 // to trigger editor commands via triggerAction().
882 handled = frame->eventHandler()->keyEvent(ev);
885 if (!handleScrolling(ev, frame)) {
888 q->triggerAction(QWebPage::Back);
890 case Qt::Key_Forward:
891 q->triggerAction(QWebPage::Forward);
894 q->triggerAction(QWebPage::Stop);
896 case Qt::Key_Refresh:
897 q->triggerAction(QWebPage::Reload);
899 case Qt::Key_Backspace:
900 if (ev->modifiers() == Qt::ShiftModifier)
901 q->triggerAction(QWebPage::Forward);
903 q->triggerAction(QWebPage::Back);
912 ev->setAccepted(handled);
915 void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev)
917 if (ev->isAutoRepeat()) {
918 ev->setAccepted(true);
922 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
923 bool handled = frame->eventHandler()->keyEvent(ev);
924 ev->setAccepted(handled);
927 void QWebPagePrivate::focusInEvent(QFocusEvent*)
929 FocusController *focusController = page->focusController();
930 focusController->setActive(true);
931 focusController->setFocused(true);
932 if (!focusController->focusedFrame())
933 focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame));
936 void QWebPagePrivate::focusOutEvent(QFocusEvent*)
938 // only set the focused frame inactive so that we stop painting the caret
939 // and the focus frame. But don't tell the focus controller so that upon
940 // focusInEvent() we can re-activate the frame.
941 FocusController *focusController = page->focusController();
942 // Call setFocused first so that window.onblur doesn't get called twice
943 focusController->setFocused(false);
944 focusController->setActive(false);
948 void QWebPagePrivate::dragEnterEvent(T* ev)
950 #ifndef QT_NO_DRAGANDDROP
951 DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
952 QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
953 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData));
954 ev->setDropAction(action);
955 if (action != Qt::IgnoreAction)
956 ev->acceptProposedAction();
961 void QWebPagePrivate::dragLeaveEvent(T *ev)
963 #ifndef QT_NO_DRAGANDDROP
964 DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
965 page->dragController()->dragExited(&dragData);
971 void QWebPagePrivate::dragMoveEvent(T *ev)
973 #ifndef QT_NO_DRAGANDDROP
974 DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
975 QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
976 Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData));
977 ev->setDropAction(action);
978 if (action != Qt::IgnoreAction)
979 ev->acceptProposedAction();
984 void QWebPagePrivate::dropEvent(T *ev)
986 #ifndef QT_NO_DRAGANDDROP
987 DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(),
988 QCursor::pos(), dropActionToDragOp(ev->possibleActions()));
989 if (page->dragController()->performDrag(&dragData))
990 ev->acceptProposedAction();
994 void QWebPagePrivate::leaveEvent(QEvent*)
996 // Fake a mouse move event just outside of the widget, since all
997 // the interesting mouse-out behavior like invalidating scrollbars
998 // is handled by the WebKit event handler's mouseMoved function.
999 QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
1000 mouseMoveEvent(&fakeEvent);
1004 \property QWebPage::palette
1005 \brief the page's palette
1007 The base brush of the palette is used to draw the background of the main frame.
1009 By default, this property contains the application's default palette.
1011 void QWebPage::setPalette(const QPalette &pal)
1014 if (!d->mainFrame || !d->mainFrame->d->frame->view())
1017 QBrush brush = pal.brush(QPalette::Base);
1018 QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
1019 QWebFramePrivate::core(d->mainFrame)->view()->updateBackgroundRecursively(backgroundColor, !backgroundColor.alpha());
1022 QPalette QWebPage::palette() const
1027 void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
1029 WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
1030 WebCore::Editor *editor = frame->editor();
1032 if (!editor->canEdit()) {
1038 if (frame->selection()->rootEditableElement())
1039 node = frame->selection()->rootEditableElement()->shadowAncestorNode();
1041 Vector<CompositionUnderline> underlines;
1042 bool hasSelection = false;
1044 for (int i = 0; i < ev->attributes().size(); ++i) {
1045 const QInputMethodEvent::Attribute& a = ev->attributes().at(i);
1047 case QInputMethodEvent::TextFormat: {
1048 QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat();
1049 QColor qcolor = textCharFormat.underlineColor();
1050 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));
1053 case QInputMethodEvent::Cursor: {
1054 frame->selection()->setCaretVisible(a.length); //if length is 0 cursor is invisible
1056 RenderObject* caretRenderer = frame->selection()->caretRenderer();
1057 if (caretRenderer) {
1058 QColor qcolor = a.value.value<QColor>();
1059 caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())));
1064 case QInputMethodEvent::Selection: {
1065 hasSelection = true;
1066 // A selection in the inputMethodEvent is always reflected in the visible text
1068 setSelectionRange(node, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)));
1070 if (!ev->preeditString().isEmpty()) {
1071 editor->setComposition(ev->preeditString(), underlines,
1072 (a.length < 0) ? a.start + a.length : a.start,
1073 (a.length < 0) ? a.start : a.start + a.length);
1075 // If we are in the middle of a composition, an empty pre-edit string and a selection of zero
1076 // cancels the current composition
1077 if (editor->hasComposition() && (a.start + a.length == 0))
1078 editor->setComposition(QString(), underlines, 0, 0);
1085 if (!ev->commitString().isEmpty())
1086 editor->confirmComposition(ev->commitString());
1087 else if (!hasSelection && !ev->preeditString().isEmpty())
1088 editor->setComposition(ev->preeditString(), underlines, 0, ev->preeditString().length());
1093 #ifndef QT_NO_PROPERTIES
1096 double deferredRepaintDelay;
1097 double initialDeferredRepaintDelayDuringLoading;
1098 double maxDeferredRepaintDelayDuringLoading;
1099 double deferredRepaintDelayIncrementDuringLoading;
1100 } QRepaintThrottlingPreset;
1102 void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event)
1104 if (event->propertyName() == "_q_viewMode") {
1105 page->setViewMode(Page::stringToViewMode(q->property("_q_viewMode").toString()));
1106 } else if (event->propertyName() == "_q_HTMLTokenizerChunkSize") {
1107 int chunkSize = q->property("_q_HTMLTokenizerChunkSize").toInt();
1108 q->handle()->page->setCustomHTMLTokenizerChunkSize(chunkSize);
1109 } else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") {
1110 double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble();
1111 q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay);
1112 } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") {
1113 double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble();
1114 FrameView::setRepaintThrottlingDeferredRepaintDelay(p);
1115 } else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") {
1116 double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble();
1117 FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p);
1118 } else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") {
1119 double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble();
1120 FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p);
1121 } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") {
1122 double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble();
1123 FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p);
1124 } else if (event->propertyName() == "_q_RepaintThrottlingPreset") {
1125 static const QRepaintThrottlingPreset presets[] = {
1126 { "NoThrottling", 0, 0, 0, 0 },
1127 { "Legacy", 0.025, 0, 2.5, 0.5 },
1128 { "Minimal", 0.01, 0, 1, 0.2 },
1129 { "Medium", 0.025, 1, 5, 0.5 },
1130 { "Heavy", 0.1, 2, 10, 1 }
1133 QString p = q->property("_q_RepaintThrottlingPreset").toString();
1134 for(int i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) {
1135 if(p == presets[i].name) {
1136 FrameView::setRepaintThrottlingDeferredRepaintDelay(
1137 presets[i].deferredRepaintDelay);
1138 FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(
1139 presets[i].initialDeferredRepaintDelayDuringLoading);
1140 FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(
1141 presets[i].maxDeferredRepaintDelayDuringLoading);
1142 FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(
1143 presets[i].deferredRepaintDelayIncrementDuringLoading);
1148 #if ENABLE(TILED_BACKING_STORE)
1149 else if (event->propertyName() == "_q_TiledBackingStoreTileSize") {
1150 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
1151 if (!frame->tiledBackingStore())
1153 QSize tileSize = q->property("_q_TiledBackingStoreTileSize").toSize();
1154 frame->tiledBackingStore()->setTileSize(tileSize);
1155 } else if (event->propertyName() == "_q_TiledBackingStoreTileCreationDelay") {
1156 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
1157 if (!frame->tiledBackingStore())
1159 int tileCreationDelay = q->property("_q_TiledBackingStoreTileCreationDelay").toInt();
1160 frame->tiledBackingStore()->setTileCreationDelay(static_cast<double>(tileCreationDelay) / 1000.);
1161 } else if (event->propertyName() == "_q_TiledBackingStoreKeepAreaMultiplier") {
1162 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
1163 if (!frame->tiledBackingStore())
1165 FloatSize keepMultiplier;
1166 FloatSize coverMultiplier;
1167 frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
1168 QSizeF qSize = q->property("_q_TiledBackingStoreKeepAreaMultiplier").toSizeF();
1169 keepMultiplier = FloatSize(qSize.width(), qSize.height());
1170 frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
1171 } else if (event->propertyName() == "_q_TiledBackingStoreCoverAreaMultiplier") {
1172 WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
1173 if (!frame->tiledBackingStore())
1175 FloatSize keepMultiplier;
1176 FloatSize coverMultiplier;
1177 frame->tiledBackingStore()->getKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
1178 QSizeF qSize = q->property("_q_TiledBackingStoreCoverAreaMultiplier").toSizeF();
1179 coverMultiplier = FloatSize(qSize.width(), qSize.height());
1180 frame->tiledBackingStore()->setKeepAndCoverAreaMultipliers(keepMultiplier, coverMultiplier);
1183 else if (event->propertyName() == "_q_webInspectorServerPort") {
1184 InspectorServerQt* inspectorServer = InspectorServerQt::server();
1185 inspectorServer->listen(inspectorServerPort());
1190 void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event)
1192 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame();
1193 WebCore::Editor* editor = frame->editor();
1194 if (editor->canEdit()) {
1195 if (event->modifiers() == Qt::NoModifier
1196 || event->modifiers() == Qt::ShiftModifier
1197 || event->modifiers() == Qt::KeypadModifier) {
1198 if (event->key() < Qt::Key_Escape) {
1201 switch (event->key()) {
1202 case Qt::Key_Return:
1204 case Qt::Key_Delete:
1207 case Qt::Key_Backspace:
1219 #ifndef QT_NO_SHORTCUT
1220 else if (editorActionForKeyEvent(event) != QWebPage::NoWebAction)
1226 bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame)
1228 ScrollDirection direction;
1229 ScrollGranularity granularity;
1231 #ifndef QT_NO_SHORTCUT
1232 if (ev == QKeySequence::MoveToNextPage
1233 || (ev->key() == Qt::Key_Space && !(ev->modifiers() & Qt::ShiftModifier))) {
1234 granularity = ScrollByPage;
1235 direction = ScrollDown;
1236 } else if (ev == QKeySequence::MoveToPreviousPage
1237 || ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) {
1238 granularity = ScrollByPage;
1239 direction = ScrollUp;
1241 #endif // QT_NO_SHORTCUT
1242 if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier)
1243 || ev->key() == Qt::Key_Home) {
1244 granularity = ScrollByDocument;
1245 direction = ScrollUp;
1246 } else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier)
1247 || ev->key() == Qt::Key_End) {
1248 granularity = ScrollByDocument;
1249 direction = ScrollDown;
1251 switch (ev->key()) {
1253 granularity = ScrollByLine;
1254 direction = ScrollUp;
1257 granularity = ScrollByLine;
1258 direction = ScrollDown;
1261 granularity = ScrollByLine;
1262 direction = ScrollLeft;
1265 granularity = ScrollByLine;
1266 direction = ScrollRight;
1273 return frame->eventHandler()->scrollRecursively(direction, granularity);
1276 void QWebPagePrivate::adjustPointForClicking(QMouseEvent*)
1281 void QWebPagePrivate::adjustPointForClicking(QGraphicsSceneMouseEvent* ev)
1283 QtPlatformPlugin platformPlugin;
1284 QWebTouchModifier* touchModifier = platformPlugin.createTouchModifier();
1288 unsigned topPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Up);
1289 unsigned rightPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Right);
1290 unsigned bottomPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Down);
1291 unsigned leftPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Left);
1293 delete touchModifier;
1296 if (!topPadding && !rightPadding && !bottomPadding && !leftPadding)
1299 Document* startingDocument = page->mainFrame()->document();
1300 if (!startingDocument)
1303 IntPoint originalPoint(QPointF(ev->pos()).toPoint());
1304 TouchAdjuster touchAdjuster(topPadding, rightPadding, bottomPadding, leftPadding);
1305 IntPoint adjustedPoint = touchAdjuster.findCandidatePointForTouch(originalPoint, startingDocument);
1306 if (adjustedPoint == IntPoint::zero())
1309 ev->setPos(QPointF(adjustedPoint));
1312 bool QWebPagePrivate::touchEvent(QTouchEvent* event)
1314 WebCore::Frame* frame = QWebFramePrivate::core(mainFrame);
1318 // Always accept the QTouchEvent so that we'll receive also TouchUpdate and TouchEnd events
1319 event->setAccepted(true);
1321 // Return whether the default action was cancelled in the JS event handler
1322 return frame->eventHandler()->handleTouchEvent(PlatformTouchEvent(event));
1326 This method is used by the input method to query a set of properties of the page
1327 to be able to support complex input method operations as support for surrounding
1328 text and reconversions.
1330 \a property specifies which property is queried.
1332 \sa QWidget::inputMethodEvent(), QInputMethodEvent, QInputContext
1334 QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const
1336 Frame* frame = d->page->focusController()->focusedFrame();
1340 WebCore::Editor* editor = frame->editor();
1342 RenderObject* renderer = 0;
1343 RenderTextControl* renderTextControl = 0;
1345 if (frame->selection()->rootEditableElement())
1346 renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer();
1348 if (renderer && renderer->isTextControl())
1349 renderTextControl = toRenderTextControl(renderer);
1352 case Qt::ImMicroFocus: {
1353 WebCore::FrameView* view = frame->view();
1354 if (view && view->needsLayout()) {
1355 // We can't access absoluteCaretBounds() while the view needs to layout.
1358 return QVariant(view->contentsToWindow(frame->selection()->absoluteCaretBounds()));
1361 if (renderTextControl) {
1362 RenderStyle* renderStyle = renderTextControl->style();
1363 return QVariant(QFont(renderStyle->font().font()));
1365 return QVariant(QFont());
1367 case Qt::ImCursorPosition: {
1368 if (editor->hasComposition()) {
1369 RefPtr<Range> range = editor->compositionRange();
1370 return QVariant(frame->selection()->end().offsetInContainerNode() - TextIterator::rangeLength(range.get()));
1372 return QVariant(frame->selection()->extent().offsetInContainerNode());
1374 case Qt::ImSurroundingText: {
1375 if (renderTextControl) {
1376 QString text = renderTextControl->text();
1377 RefPtr<Range> range = editor->compositionRange();
1379 text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get()));
1380 return QVariant(text);
1384 case Qt::ImCurrentSelection: {
1385 if (renderTextControl) {
1386 int start = frame->selection()->start().offsetInContainerNode();
1387 int end = frame->selection()->end().offsetInContainerNode();
1389 return QVariant(QString(renderTextControl->text()).mid(start, end - start));
1394 case Qt::ImAnchorPosition: {
1395 if (editor->hasComposition()) {
1396 RefPtr<Range> range = editor->compositionRange();
1397 return QVariant(frame->selection()->start().offsetInContainerNode() - TextIterator::rangeLength(range.get()));
1399 return QVariant(frame->selection()->base().offsetInContainerNode());
1401 case Qt::ImMaximumTextLength: {
1402 if (frame->selection()->isContentEditable()) {
1403 if (frame->document() && frame->document()->focusedNode()) {
1404 if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) {
1405 HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode());
1406 return QVariant(inputElement->maxLength());
1409 return QVariant(InputElement::s_maximumLength);
1421 void QWebPagePrivate::setInspector(QWebInspector* insp)
1424 inspector->d->setFrontend(0);
1426 if (inspectorIsInternalOnly) {
1427 QWebInspector* inspToDelete = inspector;
1429 inspectorIsInternalOnly = false;
1430 delete inspToDelete; // Delete after to prevent infinite recursion
1435 // Give inspector frontend web view if previously created
1436 if (inspector && inspectorFrontend)
1437 inspector->d->setFrontend(inspectorFrontend);
1442 Returns the inspector and creates it if it wasn't created yet.
1443 The instance created here will not be available through QWebPage's API.
1445 QWebInspector* QWebPagePrivate::getOrCreateInspector()
1447 #if ENABLE(INSPECTOR)
1449 QWebInspector* insp = new QWebInspector;
1451 inspectorIsInternalOnly = true;
1453 Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q)
1460 InspectorController* QWebPagePrivate::inspectorController()
1462 #if ENABLE(INSPECTOR)
1463 return page->inspectorController();
1469 quint16 QWebPagePrivate::inspectorServerPort()
1471 #if ENABLE(INSPECTOR) && !defined(QT_NO_PROPERTIES)
1472 if (q && q->property("_q_webInspectorServerPort").isValid())
1473 return q->property("_q_webInspectorServerPort").toInt();
1478 static bool hasMouseListener(Element* element)
1481 return element->hasEventListeners(eventNames().clickEvent)
1482 || element->hasEventListeners(eventNames().mousedownEvent)
1483 || element->hasEventListeners(eventNames().mouseupEvent);
1486 static bool isClickableElement(Element* element, RefPtr<NodeList> list)
1489 bool isClickable = hasMouseListener(element);
1490 if (!isClickable && list) {
1491 Element* parent = element->parentElement();
1492 unsigned count = list->length();
1493 for (unsigned i = 0; i < count && parent; i++) {
1494 if (list->item(i) != parent)
1497 isClickable = hasMouseListener(parent);
1501 parent = parent->parentElement();
1505 ExceptionCode ec = 0;
1507 || element->webkitMatchesSelector("a,*:link,*:visited,*[role=button],button,input,select,label", ec)
1508 || computedStyle(element)->getPropertyValue(cssPropertyID("cursor")) == "pointer";
1511 static bool isValidFrameOwner(Element* element)
1514 return element->isFrameOwnerElement() && static_cast<HTMLFrameOwnerElement*>(element)->contentFrame();
1517 static Element* nodeToElement(Node* node)
1519 if (node && node->isElementNode())
1520 return static_cast<Element*>(node);
1524 QWebPagePrivate::TouchAdjuster::TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
1525 : m_topPadding(topPadding)
1526 , m_rightPadding(rightPadding)
1527 , m_bottomPadding(bottomPadding)
1528 , m_leftPadding(leftPadding)
1532 IntPoint QWebPagePrivate::TouchAdjuster::findCandidatePointForTouch(const IntPoint& touchPoint, Document* document) const
1537 int x = touchPoint.x();
1538 int y = touchPoint.y();
1540 RefPtr<NodeList> intersectedNodes = document->nodesFromRect(x, y, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding, false);
1541 if (!intersectedNodes)
1544 Element* closestClickableElement = 0;
1545 IntRect largestIntersectionRect;
1546 FrameView* view = document->frame()->view();
1548 // Touch rect in contents coordinates.
1549 IntRect touchRect(HitTestResult::rectForPoint(view->windowToContents(IntPoint(x, y)), m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding));
1551 // Iterate over the list of nodes hit looking for the one whose bounding area
1552 // has largest intersection with the touch area (point + padding).
1553 for (unsigned i = 0; i < intersectedNodes->length(); i++) {
1554 Node* currentNode = intersectedNodes->item(i);
1556 Element* currentElement = nodeToElement(currentNode);
1557 if (!currentElement || (!isClickableElement(currentElement, 0) && !isValidFrameOwner(currentElement)))
1560 IntRect currentElementBoundingRect = currentElement->getRect();
1561 currentElementBoundingRect.intersect(touchRect);
1563 if (currentElementBoundingRect.isEmpty())
1566 int currentIntersectionRectArea = currentElementBoundingRect.width() * currentElementBoundingRect.height();
1567 int largestIntersectionRectArea = largestIntersectionRect.width() * largestIntersectionRect.height();
1568 if (currentIntersectionRectArea > largestIntersectionRectArea) {
1569 closestClickableElement = currentElement;
1570 largestIntersectionRect = currentElementBoundingRect;
1574 if (largestIntersectionRect.isEmpty())
1577 // Handle the case when user taps a inner frame. It is done in three steps:
1578 // 1) Transform the original touch point to the inner document coordinates;
1579 // 1) Call nodesFromRect for the inner document in case;
1580 // 3) Re-add the inner frame offset (location) before passing the new clicking
1581 // position to WebCore.
1582 if (closestClickableElement->isFrameOwnerElement()) {
1583 // Adjust client coordinates' origin to be top left of inner frame viewport.
1584 PassRefPtr<ClientRect> rect = closestClickableElement->getBoundingClientRect();
1585 IntPoint newTouchPoint = touchPoint;
1586 IntSize offset = IntSize(rect->left(), rect->top());
1587 newTouchPoint -= offset;
1589 HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(closestClickableElement);
1590 Document* childDocument = owner->contentFrame()->document();
1591 return findCandidatePointForTouch(newTouchPoint, childDocument);
1593 return view->contentsToWindow(largestIntersectionRect).center();
1597 \enum QWebPage::FindFlag
1599 This enum describes the options available to the findText() function. The options
1600 can be OR-ed together from the following list:
1602 \value FindBackward Searches backwards instead of forwards.
1603 \value FindCaseSensitively By default findText() works case insensitive. Specifying this option
1604 changes the behaviour to a case sensitive find operation.
1605 \value FindWrapsAroundDocument Makes findText() restart from the beginning of the document if the end
1606 was reached and the text was not found.
1607 \value HighlightAllOccurrences Highlights all existing occurrences of a specific string.
1611 \enum QWebPage::LinkDelegationPolicy
1613 This enum defines the delegation policies a webpage can have when activating links and emitting
1614 the linkClicked() signal.
1616 \value DontDelegateLinks No links are delegated. Instead, QWebPage tries to handle them all.
1617 \value DelegateExternalLinks When activating links that point to documents not stored on the
1618 local filesystem or an equivalent - such as the Qt resource system - then linkClicked() is emitted.
1619 \value DelegateAllLinks Whenever a link is activated the linkClicked() signal is emitted.
1621 \sa QWebPage::linkDelegationPolicy
1625 \enum QWebPage::NavigationType
1627 This enum describes the types of navigation available when browsing through hyperlinked
1630 \value NavigationTypeLinkClicked The user clicked on a link or pressed return on a focused link.
1631 \value NavigationTypeFormSubmitted The user activated a submit button for an HTML form.
1632 \value NavigationTypeBackOrForward Navigation to a previously shown document in the back or forward history is requested.
1633 \value NavigationTypeReload The user activated the reload action.
1634 \value NavigationTypeFormResubmitted An HTML form was submitted a second time.
1635 \value NavigationTypeOther A navigation to another document using a method not listed above.
1637 \sa acceptNavigationRequest()
1641 \enum QWebPage::WebAction
1643 This enum describes the types of action which can be performed on the web page.
1645 Actions only have an effect when they are applicable. The availability of
1646 actions can be be determined by checking \l{QAction::}{isEnabled()} on the
1647 action returned by action().
1649 One method of enabling the text editing, cursor movement, and text selection actions
1650 is by setting \l contentEditable to true.
1652 \value NoWebAction No action is triggered.
1653 \value OpenLink Open the current link.
1654 \value OpenLinkInNewWindow Open the current link in a new window.
1655 \value OpenFrameInNewWindow Replicate the current frame in a new window.
1656 \value DownloadLinkToDisk Download the current link to the disk.
1657 \value CopyLinkToClipboard Copy the current link to the clipboard.
1658 \value OpenImageInNewWindow Open the highlighted image in a new window.
1659 \value DownloadImageToDisk Download the highlighted image to the disk.
1660 \value CopyImageToClipboard Copy the highlighted image to the clipboard.
1661 \value Back Navigate back in the history of navigated links.
1662 \value Forward Navigate forward in the history of navigated links.
1663 \value Stop Stop loading the current page.
1664 \value StopScheduledPageRefresh Stop all pending page refresh/redirect requests.
1665 \value Reload Reload the current page.
1666 \value ReloadAndBypassCache Reload the current page, but do not use any local cache. (Added in Qt 4.6)
1667 \value Cut Cut the content currently selected into the clipboard.
1668 \value Copy Copy the content currently selected into the clipboard.
1669 \value Paste Paste content from the clipboard.
1670 \value Undo Undo the last editing action.
1671 \value Redo Redo the last editing action.
1672 \value MoveToNextChar Move the cursor to the next character.
1673 \value MoveToPreviousChar Move the cursor to the previous character.
1674 \value MoveToNextWord Move the cursor to the next word.
1675 \value MoveToPreviousWord Move the cursor to the previous word.
1676 \value MoveToNextLine Move the cursor to the next line.
1677 \value MoveToPreviousLine Move the cursor to the previous line.
1678 \value MoveToStartOfLine Move the cursor to the start of the line.
1679 \value MoveToEndOfLine Move the cursor to the end of the line.
1680 \value MoveToStartOfBlock Move the cursor to the start of the block.
1681 \value MoveToEndOfBlock Move the cursor to the end of the block.
1682 \value MoveToStartOfDocument Move the cursor to the start of the document.
1683 \value MoveToEndOfDocument Move the cursor to the end of the document.
1684 \value SelectNextChar Select to the next character.
1685 \value SelectPreviousChar Select to the previous character.
1686 \value SelectNextWord Select to the next word.
1687 \value SelectPreviousWord Select to the previous word.
1688 \value SelectNextLine Select to the next line.
1689 \value SelectPreviousLine Select to the previous line.
1690 \value SelectStartOfLine Select to the start of the line.
1691 \value SelectEndOfLine Select to the end of the line.
1692 \value SelectStartOfBlock Select to the start of the block.
1693 \value SelectEndOfBlock Select to the end of the block.
1694 \value SelectStartOfDocument Select to the start of the document.
1695 \value SelectEndOfDocument Select to the end of the document.
1696 \value DeleteStartOfWord Delete to the start of the word.
1697 \value DeleteEndOfWord Delete to the end of the word.
1698 \value SetTextDirectionDefault Set the text direction to the default direction.
1699 \value SetTextDirectionLeftToRight Set the text direction to left-to-right.
1700 \value SetTextDirectionRightToLeft Set the text direction to right-to-left.
1701 \value ToggleBold Toggle the formatting between bold and normal weight.
1702 \value ToggleItalic Toggle the formatting between italic and normal style.
1703 \value ToggleUnderline Toggle underlining.
1704 \value InspectElement Show the Web Inspector with the currently highlighted HTML element.
1705 \value InsertParagraphSeparator Insert a new paragraph.
1706 \value InsertLineSeparator Insert a new line.
1707 \value SelectAll Selects all content.
1708 \value PasteAndMatchStyle Paste content from the clipboard with current style.
1709 \value RemoveFormat Removes formatting and style.
1710 \value ToggleStrikethrough Toggle the formatting between strikethrough and normal style.
1711 \value ToggleSubscript Toggle the formatting between subscript and baseline.
1712 \value ToggleSuperscript Toggle the formatting between supercript and baseline.
1713 \value InsertUnorderedList Toggles the selection between an ordered list and a normal block.
1714 \value InsertOrderedList Toggles the selection between an ordered list and a normal block.
1715 \value Indent Increases the indentation of the currently selected format block by one increment.
1716 \value Outdent Decreases the indentation of the currently selected format block by one increment.
1717 \value AlignCenter Applies center alignment to content.
1718 \value AlignJustified Applies full justification to content.
1719 \value AlignLeft Applies left justification to content.
1720 \value AlignRight Applies right justification to content.
1723 \omitvalue WebActionCount
1728 \enum QWebPage::WebWindowType
1730 This enum describes the types of window that can be created by the createWindow() function.
1732 \value WebBrowserWindow The window is a regular web browser window.
1733 \value WebModalDialog The window acts as modal dialog.
1738 \class QWebPage::ViewportAttributes
1740 \brief The QWebPage::ViewportAttributes class describes hints that can be applied to a viewport.
1742 QWebPage::ViewportAttributes provides a description of a viewport, such as viewport geometry,
1743 initial scale factor with limits, plus information about whether a user should be able
1744 to scale the contents in the viewport or not, ie. by zooming.
1746 ViewportAttributes can be set by a web author using the viewport meta tag extension, documented
1747 at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}.
1749 All values might not be set, as such when dealing with the hints, the developer needs to
1750 check whether the values are valid. Negative values denote an invalid qreal value.
1756 Constructs an empty QWebPage::ViewportAttributes.
1758 QWebPage::ViewportAttributes::ViewportAttributes()
1760 , m_initialScaleFactor(-1.0)
1761 , m_minimumScaleFactor(-1.0)
1762 , m_maximumScaleFactor(-1.0)
1763 , m_devicePixelRatio(-1.0)
1764 , m_isUserScalable(true)
1771 Constructs a QWebPage::ViewportAttributes which is a copy from \a other .
1773 QWebPage::ViewportAttributes::ViewportAttributes(const QWebPage::ViewportAttributes& other)
1775 , m_initialScaleFactor(other.m_initialScaleFactor)
1776 , m_minimumScaleFactor(other.m_minimumScaleFactor)
1777 , m_maximumScaleFactor(other.m_maximumScaleFactor)
1778 , m_devicePixelRatio(other.m_devicePixelRatio)
1779 , m_isUserScalable(other.m_isUserScalable)
1780 , m_isValid(other.m_isValid)
1781 , m_size(other.m_size)
1787 Destroys the QWebPage::ViewportAttributes.
1789 QWebPage::ViewportAttributes::~ViewportAttributes()
1795 Assigns the given QWebPage::ViewportAttributes to this viewport hints and returns a
1798 QWebPage::ViewportAttributes& QWebPage::ViewportAttributes::operator=(const QWebPage::ViewportAttributes& other)
1800 if (this != &other) {
1802 m_initialScaleFactor = other.m_initialScaleFactor;
1803 m_minimumScaleFactor = other.m_minimumScaleFactor;
1804 m_maximumScaleFactor = other.m_maximumScaleFactor;
1805 m_isUserScalable = other.m_isUserScalable;
1806 m_isValid = other.m_isValid;
1807 m_size = other.m_size;
1813 /*! \fn inline bool QWebPage::ViewportAttributes::isValid() const
1814 Returns whether this is a valid ViewportAttributes or not.
1816 An invalid ViewportAttributes will have an empty QSize, negative values for scale factors and
1817 true for the boolean isUserScalable.
1820 /*! \fn inline QSize QWebPage::ViewportAttributes::size() const
1821 Returns the size of the viewport.
1824 /*! \fn inline qreal QWebPage::ViewportAttributes::initialScaleFactor() const
1825 Returns the initial scale of the viewport as a multiplier.
1828 /*! \fn inline qreal QWebPage::ViewportAttributes::minimumScaleFactor() const
1829 Returns the minimum scale value of the viewport as a multiplier.
1832 /*! \fn inline qreal QWebPage::ViewportAttributes::maximumScaleFactor() const
1833 Returns the maximum scale value of the viewport as a multiplier.
1836 /*! \fn inline bool QWebPage::ViewportAttributes::isUserScalable() const
1837 Determines whether or not the scale can be modified by the user.
1844 \brief The QWebPage class provides an object to view and edit web documents.
1848 QWebPage holds a main frame responsible for web content, settings, the history
1849 of navigated links and actions. This class can be used, together with QWebFrame,
1850 to provide functionality like QWebView in a widget-less environment.
1852 QWebPage's API is very similar to QWebView, as you are still provided with
1853 common functions like action() (known as
1854 \l{QWebView::pageAction()}{pageAction}() in QWebView), triggerAction(),
1855 findText() and settings(). More QWebView-like functions can be found in the
1856 main frame of QWebPage, obtained via the mainFrame() function. For example,
1857 the \l{QWebFrame::load()}{load}(), \l{QWebFrame::setUrl()}{setUrl}() and
1858 \l{QWebFrame::setHtml()}{setHtml}() functions for QWebPage can be accessed
1861 The loadStarted() signal is emitted when the page begins to load.The
1862 loadProgress() signal, on the other hand, is emitted whenever an element
1863 of the web page completes loading, such as an embedded image, a script,
1864 etc. Finally, the loadFinished() signal is emitted when the page has
1865 loaded completely. Its argument, either true or false, indicates whether
1866 or not the load operation succeeded.
1868 \section1 Using QWebPage in a Widget-less Environment
1870 Before you begin painting a QWebPage object, you need to set the size of
1871 the viewport by calling setViewportSize(). Then, you invoke the main
1872 frame's render function (QWebFrame::render()). An example of this
1873 is shown in the code snippet below.
1875 Suppose we have a \c Thumbnail class as follows:
1877 \snippet webkitsnippets/webpage/main.cpp 0
1879 The \c Thumbnail's constructor takes in a \a url. We connect our QWebPage
1880 object's \l{QWebPage::}{loadFinished()} signal to our private slot,
1883 \snippet webkitsnippets/webpage/main.cpp 1
1885 The \c render() function shows how we can paint a thumbnail using a
1888 \snippet webkitsnippets/webpage/main.cpp 2
1890 We begin by setting the \l{QWebPage::viewportSize()}{viewportSize} and
1891 then we instantiate a QImage object, \c image, with the same size as our
1892 \l{QWebPage::viewportSize()}{viewportSize}. This image is then sent
1893 as a parameter to \c painter. Next, we render the contents of the main
1894 frame and its subframes into \c painter. Finally, we save the scaled image.
1900 Constructs an empty QWebPage with parent \a parent.
1902 QWebPage::QWebPage(QObject *parent)
1904 , d(new QWebPagePrivate(this))
1906 setView(qobject_cast<QWidget*>(parent));
1908 connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int)));
1910 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages()));
1915 Destroys the web page.
1917 QWebPage::~QWebPage()
1919 d->createMainFrame();
1920 FrameLoader *loader = d->mainFrame->d->frame->loader();
1922 loader->detachFromParent();
1927 Returns the main frame of the page.
1929 The main frame provides access to the hierarchy of sub-frames and is also needed if you
1930 want to explicitly render a web page into a given painter.
1934 QWebFrame *QWebPage::mainFrame() const
1936 d->createMainFrame();
1937 return d->mainFrame;
1941 Returns the frame currently active.
1943 \sa mainFrame(), frameCreated()
1945 QWebFrame *QWebPage::currentFrame() const
1947 d->createMainFrame();
1948 WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
1949 return qobject_cast<QWebFrame*>(frame->loader()->networkingContext()->originatingObject());
1956 Returns the frame at the given point \a pos, or 0 if there is no frame at
1959 \sa mainFrame(), currentFrame()
1961 QWebFrame* QWebPage::frameAt(const QPoint& pos) const
1963 QWebFrame* webFrame = mainFrame();
1964 if (!webFrame->geometry().contains(pos))
1966 QWebHitTestResult hitTestResult = webFrame->hitTestContent(pos);
1967 return hitTestResult.frame();
1971 Returns a pointer to the view's history of navigated web pages.
1973 QWebHistory *QWebPage::history() const
1975 d->createMainFrame();
1980 Sets the \a view that is associated with the web page.
1984 void QWebPage::setView(QWidget* view)
1986 if (this->view() == view)
1990 setViewportSize(view ? view->size() : QSize(0, 0));
1992 // If we have no client, we install a special client delegating
1993 // the responsibility to the QWidget. This is the code path
1994 // handling a.o. the "legacy" QWebView.
1996 // If such a special delegate already exist, we substitute the view.
1999 if (d->client->isQWidgetClient())
2000 static_cast<PageClientQWidget*>(d->client)->view = view;
2005 d->client = new PageClientQWidget(view, this);
2009 Returns the view widget that is associated with the web page.
2013 QWidget *QWebPage::view() const
2015 return d->view.data();
2019 This function is called whenever a JavaScript program tries to print a \a message to the web browser's console.
2021 For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber.
2023 The default implementation prints nothing.
2025 void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID)
2029 // Catch plugin logDestroy message for LayoutTests/plugins/open-and-close-window-with-plugin.html
2030 // At this point DRT's WebPage has already been destroyed
2031 if (QWebPagePrivate::drtRun) {
2032 if (message == "PLUGIN: NPP_Destroy")
2033 fprintf (stdout, "CONSOLE MESSAGE: line %d: %s\n", lineNumber, message.toUtf8().constData());
2038 This function is called whenever a JavaScript program running inside \a frame calls the alert() function with
2041 The default implementation shows the message, \a msg, with QMessageBox::information.
2043 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
2046 #ifndef QT_NO_MESSAGEBOX
2047 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
2048 QMessageBox::information(parent, tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Ok);
2053 This function is called whenever a JavaScript program running inside \a frame calls the confirm() function
2054 with the message, \a msg. Returns true if the user confirms the message; otherwise returns false.
2056 The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons.
2058 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
2061 #ifdef QT_NO_MESSAGEBOX
2064 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
2065 return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Confirm - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QMessageBox::Yes, QMessageBox::No);
2070 This function is called whenever a JavaScript program running inside \a frame tries to prompt the user for input.
2071 The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue.
2073 If the prompt was cancelled by the user the implementation should return false; otherwise the
2074 result should be written to \a result and true should be returned. If the prompt was not cancelled by the
2075 user, the implementation should return true and the result string must not be null.
2077 The default implementation uses QInputDialog::getText().
2079 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
2083 #ifndef QT_NO_INPUTDIALOG
2084 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
2085 QString x = QInputDialog::getText(parent, tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), Qt::escape(msg), QLineEdit::Normal, defaultValue, &ok);
2093 \fn bool QWebPage::shouldInterruptJavaScript()
2095 This function is called when a JavaScript program is running for a long period of time.
2097 If the user wanted to stop the JavaScript the implementation should return true; otherwise false.
2099 The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons.
2101 \warning Because of binary compatibility constraints, this function is not virtual. If you want to
2102 provide your own implementation in a QWebPage subclass, reimplement the shouldInterruptJavaScript()
2103 slot in your subclass instead. QtWebKit will dynamically detect the slot and call it.
2105 bool QWebPage::shouldInterruptJavaScript()
2107 #ifdef QT_NO_MESSAGEBOX
2110 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
2111 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);
2115 void QWebPage::setUserPermission(QWebFrame* frame, PermissionDomain domain, PermissionPolicy policy)
2118 case NotificationsPermissionDomain:
2119 #if ENABLE(NOTIFICATIONS)
2120 if (policy == PermissionGranted)
2121 NotificationPresenterClientQt::notificationPresenter()->allowNotificationForFrame(frame);
2124 case GeolocationPermissionDomain:
2125 #if ENABLE(GEOLOCATION)
2126 GeolocationPermissionClientQt::geolocationPermissionClient()->setPermission(frame, policy);
2136 This function is called whenever WebKit wants to create a new window of the given \a type, for
2137 example when a JavaScript program requests to open a document in a new window.
2139 If the new window can be created, the new window's QWebPage is returned; otherwise a null pointer is returned.
2141 If the view associated with the web page is a QWebView object, then the default implementation forwards
2142 the request to QWebView's createWindow() function; otherwise it returns a null pointer.
2144 If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window.
2146 \note In the cases when the window creation is being triggered by JavaScript, apart from
2147 reimplementing this method application must also set the JavaScriptCanOpenWindows attribute
2148 of QWebSettings to true in order for it to get called.
2150 \sa acceptNavigationRequest(), QWebView::createWindow()
2152 QWebPage *QWebPage::createWindow(WebWindowType type)
2154 QWebView *webView = qobject_cast<QWebView*>(view());
2156 QWebView *newView = webView->createWindow(type);
2158 return newView->page();
2164 This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin". It is
2165 called regardless of the value of QWebSettings::PluginsEnabled. The \a classid, \a url, \a paramNames and \a paramValues
2166 correspond to the HTML object element attributes and child elements to configure the embeddable object.
2168 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
2172 Q_UNUSED(paramNames)
2173 Q_UNUSED(paramValues)
2177 static void extractContentTypeFromHash(const HashSet<String>& types, QStringList* list)
2182 HashSet<String>::const_iterator endIt = types.end();
2183 for (HashSet<String>::const_iterator it = types.begin(); it != endIt; ++it)
2187 static void extractContentTypeFromPluginVector(const Vector<PluginPackage*>& plugins, QStringList* list)
2192 for (unsigned int i = 0; i < plugins.size(); ++i) {
2193 MIMEToDescriptionsMap::const_iterator map_it = plugins[i]->mimeToDescriptions().begin();
2194 MIMEToDescriptionsMap::const_iterator map_end = plugins[i]->mimeToDescriptions().end();
2195 for (; map_it != map_end; ++map_it)
2196 *list << map_it->first;
2201 * Returns the list of all content types supported by QWebPage.
2203 QStringList QWebPage::supportedContentTypes() const
2205 QStringList mimeTypes;
2207 extractContentTypeFromHash(MIMETypeRegistry::getSupportedImageMIMETypes(), &mimeTypes);
2208 extractContentTypeFromHash(MIMETypeRegistry::getSupportedNonImageMIMETypes(), &mimeTypes);
2209 if (d->page->settings() && d->page->settings()->arePluginsEnabled())
2210 extractContentTypeFromPluginVector(PluginDatabase::installedPlugins()->plugins(), &mimeTypes);
2216 * Returns true if QWebPage can handle the given \a mimeType; otherwise, returns false.
2218 bool QWebPage::supportsContentType(const QString& mimeType) const
2220 const String type = mimeType.toLower();
2221 if (MIMETypeRegistry::isSupportedImageMIMEType(type))
2224 if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
2227 if (d->page->settings() && d->page->settings()->arePluginsEnabled()
2228 && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type))
2234 static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
2236 WebCore::ResourceRequest rr(url, frame->loader()->outgoingReferrer());
2237 return WebCore::FrameLoadRequest(rr);
2240 static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
2242 if (Page* oldPage = frame->page()) {
2243 WindowFeatures features;
2244 NavigationAction action;
2245 if (Page* newPage = oldPage->chrome()->createWindow(frame,
2246 frameLoadRequest(url, frame), features, action))
2247 newPage->chrome()->show();
2251 static void collectChildFrames(QWebFrame* frame, QList<QWebFrame*>& list)
2253 list << frame->childFrames();
2254 QListIterator<QWebFrame*> it(frame->childFrames());
2255 while (it.hasNext()) {
2256 collectChildFrames(it.next(), list);
2261 This function can be called to trigger the specified \a action.
2262 It is also called by QtWebKit if the user triggers the action, for example
2263 through a context menu item.
2265 If \a action is a checkable action then \a checked specified whether the action
2270 void QWebPage::triggerAction(WebAction action, bool)
2272 WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
2275 WebCore::Editor *editor = frame->editor();
2276 const char *command = 0;
2280 if (QWebFrame *targetFrame = d->hitTestResult.linkTargetFrame()) {
2281 WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
2282 targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()),
2283 /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0,
2284 /*FormState*/ 0, SendReferrer);
2288 case OpenLinkInNewWindow:
2289 openNewWindow(d->hitTestResult.linkUrl(), frame);
2291 case OpenFrameInNewWindow: {
2292 KURL url = frame->loader()->documentLoader()->unreachableURL();
2294 url = frame->loader()->documentLoader()->url();
2295 openNewWindow(url, frame);
2298 case CopyLinkToClipboard: {
2299 #if defined(Q_WS_X11)
2300 bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
2301 Pasteboard::generalPasteboard()->setSelectionMode(true);
2302 editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText());
2303 Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
2305 editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText());
2308 case OpenImageInNewWindow:
2309 openNewWindow(d->hitTestResult.imageUrl(), frame);
2311 case DownloadImageToDisk:
2312 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.imageUrl(), frame->loader()->outgoingReferrer()));
2314 case DownloadLinkToDisk:
2315 frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.linkUrl(), frame->loader()->outgoingReferrer()));
2317 #ifndef QT_NO_CLIPBOARD
2318 case CopyImageToClipboard:
2319 QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap());
2326 d->page->goForward();
2329 mainFrame()->d->frame->loader()->stopForUserCancel();
2330 d->updateNavigationActions();
2333 mainFrame()->d->frame->loader()->reload(/*endtoendreload*/false);
2335 case ReloadAndBypassCache:
2336 mainFrame()->d->frame->loader()->reload(/*endtoendreload*/true);
2338 case SetTextDirectionDefault:
2339 editor->setBaseWritingDirection(NaturalWritingDirection);
2341 case SetTextDirectionLeftToRight:
2342 editor->setBaseWritingDirection(LeftToRightWritingDirection);
2344 case SetTextDirectionRightToLeft:
2345 editor->setBaseWritingDirection(RightToLeftWritingDirection);
2347 case InspectElement: {
2348 #if ENABLE(INSPECTOR)
2349 if (!d->hitTestResult.isNull()) {
2350 d->getOrCreateInspector(); // Make sure the inspector is created
2351 d->inspector->show(); // The inspector is expected to be shown on inspection
2352 d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get());
2357 case StopScheduledPageRefresh: {
2358 QWebFrame* topFrame = mainFrame();
2359 topFrame->d->frame->navigationScheduler()->cancel();
2360 QList<QWebFrame*> childFrames;
2361 collectChildFrames(topFrame, childFrames);
2362 QListIterator<QWebFrame*> it(childFrames);
2363 while (it.hasNext())
2364 it.next()->d->frame->navigationScheduler()->cancel();
2368 command = QWebPagePrivate::editorCommandForWebActions(action);
2373 editor->command(command).execute();
2376 QSize QWebPage::viewportSize() const
2378 if (d->mainFrame && d->mainFrame->d->frame->view())
2379 return d->mainFrame->d->frame->view()->frameRect().size();
2381 return d->viewportSize;
2385 \property QWebPage::viewportSize
2386 \brief the size of the viewport
2388 The size affects for example the visibility of scrollbars
2389 if the document is larger than the viewport.
2391 By default, for a newly-created Web page, this property contains a size with
2392 zero width and height.
2394 \sa QWebFrame::render(), preferredContentsSize
2396 void QWebPage::setViewportSize(const QSize &size) const
2398 d->viewportSize = size;
2400 QWebFrame *frame = mainFrame();
2401 if (frame->d->frame && frame->d->frame->view()) {
2402 WebCore::FrameView* view = frame->d->frame->view();
2403 view->setFrameRect(QRect(QPoint(0, 0), size));
2404 view->adjustViewSize();
2408 static int getintenv(const char* variable)
2411 int value = qgetenv(variable).toInt(&ok);
2412 return (ok) ? value : -1;
2415 static QSize queryDeviceSizeForScreenContainingWidget(const QWidget* widget)
2417 QDesktopWidget* desktop = QApplication::desktop();
2424 // Returns the available geometry of the screen which contains widget.
2425 // NOTE: this must be the the full screen size including any fixed status areas etc.
2426 size = desktop->availableGeometry(widget).size();
2428 size = desktop->availableGeometry().size();
2430 // This must be in portrait mode, adjust if not.
2431 if (size.width() > size.height()) {
2432 int width = size.width();
2433 size.setWidth(size.height());
2434 size.setHeight(width);
2441 Computes the optimal viewport configuration given the \a availableSize, when
2442 user interface components are disregarded.
2444 The configuration is also dependent on the device screen size which is obtained
2445 automatically. For testing purposes the size can be overridden by setting two
2446 environment variables QTWEBKIT_DEVICE_WIDTH and QTWEBKIT_DEVICE_HEIGHT, which
2447 both needs to be set.
2449 An invalid instance will be returned in the case an empty size is passed to the
2453 QWebPage::ViewportAttributes QWebPage::viewportAttributesForSize(const QSize& availableSize) const
2455 static int desktopWidth = 980;
2456 static int deviceDPI = 160;
2458 ViewportAttributes result;
2460 if (availableSize.isEmpty())
2461 return result; // Returns an invalid instance.
2463 int deviceWidth = getintenv("QTWEBKIT_DEVICE_WIDTH");
2464 int deviceHeight = getintenv("QTWEBKIT_DEVICE_HEIGHT");
2466 // Both environment variables need to be set - or they will be ignored.
2467 if (deviceWidth < 0 && deviceHeight < 0) {
2468 QSize size = queryDeviceSizeForScreenContainingWidget((d->client) ? d->client->ownerWidget() : 0);
2469 deviceWidth = size.width();
2470 deviceHeight = size.height();
2473 WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments(), desktopWidth, deviceWidth, deviceHeight, deviceDPI, availableSize);
2475 result.m_isValid = true;
2476 result.m_size = conf.layoutSize;
2477 result.m_initialScaleFactor = conf.initialScale;
2478 result.m_minimumScaleFactor = conf.minimumScale;
2479 result.m_maximumScaleFactor = conf.maximumScale;
2480 result.m_devicePixelRatio = conf.devicePixelRatio;
2481 result.m_isUserScalable = conf.userScalable;
2486 QSize QWebPage::preferredContentsSize() const
2488 QWebFrame* frame = d->mainFrame;
2490 WebCore::FrameView* view = frame->d->frame->view();
2491 if (view && view->useFixedLayout())
2492 return d->mainFrame->d->frame->view()->fixedLayoutSize();
2495 return d->fixedLayoutSize;
2499 \property QWebPage::preferredContentsSize
2501 \brief a custom size used for laying out the page contents.
2503 By default all pages are laid out using the viewport of the page as the base.
2505 As pages mostly are designed for desktop usage, they often do not layout properly
2506 on small devices as the contents require a certain view width. For this reason
2507 it is common to use a different layout size and then scale the contents to fit
2508 within the actual view.
2510 If this property is set to a valid size, this size is used for all layout needs
2511 instead of the size of the viewport.
2513 Setting an invalid size, makes the page fall back to using the viewport size for layout.
2517 void QWebPage::setPreferredContentsSize(const QSize& size) const
2519 // FIXME: Rename this method to setCustomLayoutSize
2521 d->fixedLayoutSize = size;
2523 QWebFrame* frame = mainFrame();
2524 if (!frame->d->frame || !frame->d->frame->view())
2527 WebCore::FrameView* view = frame->d->frame->view();
2529 if (size.isValid()) {
2530 view->setUseFixedLayout(true);
2531 view->setFixedLayoutSize(size);
2532 } else if (view->useFixedLayout())
2533 view->setUseFixedLayout(false);
2539 \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
2541 This function is called whenever WebKit requests to navigate \a frame to the resource specified by \a request by means of
2542 the specified navigation type \a type.
2544 If \a frame is a null pointer then navigation to a new window is requested. If the request is
2545 accepted createWindow() will be called.
2547 The default implementation interprets the page's linkDelegationPolicy and emits linkClicked accordingly or returns true
2548 to let QWebPage handle the navigation itself.
2552 bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type)
2555 if (type == NavigationTypeLinkClicked) {
2556 switch (d->linkPolicy) {
2557 case DontDelegateLinks:
2560 case DelegateExternalLinks:
2561 if (WebCore::SchemeRegistry::shouldTreatURLSchemeAsLocal(request.url().scheme()))
2563 emit linkClicked(request.url());
2566 case DelegateAllLinks:
2567 emit linkClicked(request.url());
2575 \property QWebPage::selectedText
2576 \brief the text currently selected
2578 By default, this property contains an empty string.
2580 \sa selectionChanged()
2582 QString QWebPage::selectedText() const
2584 d->createMainFrame();
2585 WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame();
2586 if (frame->selection()->selection().selectionType() == VisibleSelection::NoSelection)
2588 return frame->editor()->selectedText();
2591 #ifndef QT_NO_ACTION
2593 Returns a QAction for the specified WebAction \a action.
2595 The action is owned by the QWebPage but you can customize the look by
2596 changing its properties.
2598 QWebPage also takes care of implementing the action, so that upon
2599 triggering the corresponding action is performed on the page.
2603 QAction *QWebPage::action(WebAction action) const
2605 if (action == QWebPage::NoWebAction) return 0;
2606 if (d->actions[action])
2607 return d->actions[action];
2611 QStyle *style = d->client ? d->client->style() : qApp->style();
2612 bool checkable = false;
2616 text = contextMenuItemTagOpenLink();
2618 case OpenLinkInNewWindow:
2619 text = contextMenuItemTagOpenLinkInNewWindow();
2621 case OpenFrameInNewWindow:
2622 text = contextMenuItemTagOpenFrameInNewWindow();
2625 case DownloadLinkToDisk:
2626 text = contextMenuItemTagDownloadLinkToDisk();
2628 case CopyLinkToClipboard:
2629 text = contextMenuItemTagCopyLinkToClipboard();
2632 case OpenImageInNewWindow:
2633 text = contextMenuItemTagOpenImageInNewWindow();
2635 case DownloadImageToDisk:
2636 text = contextMenuItemTagDownloadImageToDisk();
2638 case CopyImageToClipboard:
2639 text = contextMenuItemTagCopyImageToClipboard();
2643 text = contextMenuItemTagGoBack();
2644 icon = style->standardIcon(QStyle::SP_ArrowBack);
2647 text = contextMenuItemTagGoForward();
2648 icon = style->standardIcon(QStyle::SP_ArrowForward);
2651 text = contextMenuItemTagStop();
2652 icon = style->standardIcon(QStyle::SP_BrowserStop);
2655 text = contextMenuItemTagReload();
2656 icon = style->standardIcon(QStyle::SP_BrowserReload);
2660 text = contextMenuItemTagCut();
2663 text = contextMenuItemTagCopy();
2666 text = contextMenuItemTagPaste();
2668 #ifndef QT_NO_UNDOSTACK
2670 QAction *a = undoStack()->createUndoAction(d->q);
2671 d->actions[action] = a;
2675 QAction *a = undoStack()->createRedoAction(d->q);
2676 d->actions[action] = a;
2679 #endif // QT_NO_UNDOSTACK
2680 case MoveToNextChar:
2681 text = tr("Move the cursor to the next character");
2683 case MoveToPreviousChar:
2684 text = tr("Move the cursor to the previous character");
2686 case MoveToNextWord:
2687 text = tr("Move the cursor to the next word");
2689 case MoveToPreviousWord:
2690 text = tr("Move the cursor to the previous word");
2692 case MoveToNextLine:
2693 text = tr("Move the cursor to the next line");
2695 case MoveToPreviousLine:
2696 text = tr("Move the cursor to the previous line");
2698 case MoveToStartOfLine:
2699 text = tr("Move the cursor to the start of the line");
2701 case MoveToEndOfLine:
2702 text = tr("Move the cursor to the end of the line");
2704 case MoveToStartOfBlock:
2705 text = tr("Move the cursor to the start of the block");
2707 case MoveToEndOfBlock:
2708 text = tr("Move the cursor to the end of the block");
2710 case MoveToStartOfDocument:
2711 text = tr("Move the cursor to the start of the document");
2713 case MoveToEndOfDocument:
2714 text = tr("Move the cursor to the end of the document");
2717 text = tr("Select all");
2719 case SelectNextChar:
2720 text = tr("Select to the next character");
2722 case SelectPreviousChar:
2723 text = tr("Select to the previous character");
2725 case SelectNextWord:
2726 text = tr("Select to the next word");
2728 case SelectPreviousWord:
2729 text = tr("Select to the previous word");
2731 case SelectNextLine:
2732 text = tr("Select to the next line");
2734 case SelectPreviousLine:
2735 text = tr("Select to the previous line");
2737 case SelectStartOfLine:
2738 text = tr("Select to the start of the line");
2740 case SelectEndOfLine:
2741 text = tr("Select to the end of the line");
2743 case SelectStartOfBlock:
2744 text = tr("Select to the start of the block");
2746 case SelectEndOfBlock:
2747 text = tr("Select to the end of the block");
2749 case SelectStartOfDocument:
2750 text = tr("Select to the start of the document");
2752 case SelectEndOfDocument:
2753 text = tr("Select to the end of the document");
2755 case DeleteStartOfWord:
2756 text = tr("Delete to the start of the word");
2758 case DeleteEndOfWord:
2759 text = tr("Delete to the end of the word");
2762 case SetTextDirectionDefault:
2763 text = contextMenuItemTagDefaultDirection();
2765 case SetTextDirectionLeftToRight:
2766 text = contextMenuItemTagLeftToRight();
2769 case SetTextDirectionRightToLeft:
2770 text = contextMenuItemTagRightToLeft();
2775 text = contextMenuItemTagBold();
2779 text = contextMenuItemTagItalic();
2782 case ToggleUnderline:
2783 text = contextMenuItemTagUnderline();
2787 case InspectElement:
2788 text = contextMenuItemTagInspectElement();
2791 case InsertParagraphSeparator:
2792 text = tr("Insert a new paragraph");
2794 case InsertLineSeparator:
2795 text = tr("Insert a new line");
2798 case PasteAndMatchStyle:
2799 text = tr("Paste and Match Style");
2802 text = tr("Remove formatting");
2805 case ToggleStrikethrough:
2806 text = tr("Strikethrough");
2809 case ToggleSubscript:
2810 text = tr("Subscript");
2813 case ToggleSuperscript:
2814 text = tr("Superscript");
2817 case InsertUnorderedList:
2818 text = tr("Insert Bulleted List");
2821 case InsertOrderedList:
2822 text = tr("Insert Numbered List");
2826 text = tr("Indent");
2829 text = tr("Outdent");
2832 text = tr("Center");
2834 case AlignJustified:
2835 text = tr("Justify");
2838 text = tr("Align Left");
2841 text = tr("Align Right");
2851 QAction *a = new QAction(d->q);
2854 a->setCheckable(checkable);
2857 connect(a, SIGNAL(triggered(bool)),
2858 this, SLOT(_q_webActionTriggered(bool)));
2860 d->actions[action] = a;
2861 d->updateAction(action);
2864 #endif // QT_NO_ACTION
2867 \property QWebPage::modified
2868 \brief whether the page contains unsubmitted form data, or the contents have been changed.
2870 By default, this property is false.
2872 \sa contentsChanged(), contentEditable, undoStack()
2874 bool QWebPage::isModified() const
2876 #ifdef QT_NO_UNDOSTACK
2881 return d->undoStack->canUndo();
2882 #endif // QT_NO_UNDOSTACK
2885 #ifndef QT_NO_UNDOSTACK
2887 Returns a pointer to the undo stack used for editable content.
2891 QUndoStack *QWebPage::undoStack() const
2894 d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
2896 return d->undoStack;
2898 #endif // QT_NO_UNDOSTACK
2902 bool QWebPage::event(QEvent *ev)
2904 switch (ev->type()) {
2906 d->timerEvent(static_cast<QTimerEvent*>(ev));
2908 case QEvent::MouseMove:
2909 d->mouseMoveEvent(static_cast<QMouseEvent*>(ev));
2911 case QEvent::GraphicsSceneMouseMove:
2912 d->mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
2914 case QEvent::MouseButtonPress:
2915 d->mousePressEvent(static_cast<QMouseEvent*>(ev));
2917 case QEvent::GraphicsSceneMousePress:
2918 d->mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
2920 case QEvent::MouseButtonDblClick:
2921 d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
2923 case QEvent::GraphicsSceneMouseDoubleClick:
2924 d->mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
2926 case QEvent::MouseButtonRelease:
2927 d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
2929 case QEvent::GraphicsSceneMouseRelease:
2930 d->mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(ev));
2932 #ifndef QT_NO_CONTEXTMENU
2933 case QEvent::ContextMenu:
2934 d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos());
2936 case QEvent::GraphicsSceneContextMenu:
2937 d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos());
2940 #ifndef QT_NO_WHEELEVENT
2942 d->wheelEvent(static_cast<QWheelEvent*>(ev));
2944 case QEvent::GraphicsSceneWheel:
2945 d->wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(ev));
2948 case QEvent::KeyPress:
2949 d->keyPressEvent(static_cast<QKeyEvent*>(ev));
2951 case QEvent::KeyRelease:
2952 d->keyReleaseEvent(static_cast<QKeyEvent*>(ev));
2954 case QEvent::FocusIn:
2955 d->focusInEvent(static_cast<QFocusEvent*>(ev));
2957 case QEvent::FocusOut:
2958 d->focusOutEvent(static_cast<QFocusEvent*>(ev));
2960 #ifndef QT_NO_DRAGANDDROP
2961 case QEvent::DragEnter:
2962 d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
2964 case QEvent::GraphicsSceneDragEnter:
2965 d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2967 case QEvent::DragLeave:
2968 d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
2970 case QEvent::GraphicsSceneDragLeave:
2971 d->dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2973 case QEvent::DragMove:
2974 d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
2976 case QEvent::GraphicsSceneDragMove:
2977 d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2980 d->dropEvent(static_cast<QDropEvent*>(ev));
2982 case QEvent::GraphicsSceneDrop:
2983 d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev));
2986 case QEvent::InputMethod:
2987 d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev));
2989 case QEvent::ShortcutOverride:
2990 d->shortcutOverrideEvent(static_cast<QKeyEvent*>(ev));
2995 case QEvent::TouchBegin:
2996 case QEvent::TouchUpdate:
2997 case QEvent::TouchEnd:
2998 // Return whether the default action was cancelled in the JS event handler
2999 return d->touchEvent(static_cast<QTouchEvent*>(ev));
3000 #ifndef QT_NO_PROPERTIES
3001 case QEvent::DynamicPropertyChange:
3002 d->dynamicPropertyChangeEvent(static_cast<QDynamicPropertyChangeEvent*>(ev));
3006 return QObject::event(ev);
3013 Similar to QWidget::focusNextPrevChild() it focuses the next focusable web element
3014 if \a next is true; otherwise the previous element is focused.
3016 Returns true if it can find a new focusable element, or false if it can't.
3018 bool QWebPage::focusNextPrevChild(bool next)
3020 QKeyEvent ev(QEvent::KeyPress, Qt::Key_Tab, Qt::KeyboardModifiers(next ? Qt::NoModifier : Qt::ShiftModifier));
3021 d->keyPressEvent(&ev);
3022 bool hasFocusedNode = false;
3023 Frame *frame = d->page->focusController()->focusedFrame();
3025 Document *document = frame->document();
3026 hasFocusedNode = document && document->focusedNode();
3028 //qDebug() << "focusNextPrevChild(" << next << ") =" << ev.isAccepted() << "focusedNode?" << hasFocusedNode;
3029 return hasFocusedNode;
3033 \property QWebPage::contentEditable
3034 \brief whether the content in this QWebPage is editable or not
3037 If this property is enabled the contents of the page can be edited by the user through a visible
3038 cursor. If disabled (the default) only HTML elements in the web page with their
3039 \c{contenteditable} attribute set are editable.
3041 \sa modified, contentsChanged(), WebAction
3043 void QWebPage::setContentEditable(bool editable)
3045 if (d->editable != editable) {
3046 d->editable = editable;
3047 d->page->setTabKeyCyclesThroughElements(!editable);
3049 WebCore::Frame* frame = d->mainFrame->d->frame;
3051 frame->editor()->applyEditingStyleToBodyElement();
3052 // FIXME: mac port calls this if there is no selectedDOMRange
3053 //frame->setSelectionFromNone();
3057 d->updateEditorActions();
3061 bool QWebPage::isContentEditable() const
3067 \property QWebPage::forwardUnsupportedContent
3068 \brief whether QWebPage should forward unsupported content
3070 If enabled, the unsupportedContent() signal is emitted with a network reply that
3071 can be used to read the content.
3073 If disabled, the download of such content is aborted immediately.
3075 By default unsupported content is not forwarded.
3078 void QWebPage::setForwardUnsupportedContent(bool forward)
3080 d->forwardUnsupportedContent = forward;
3083 bool QWebPage::forwardUnsupportedContent() const
3085 return d->forwardUnsupportedContent;
3089 \property QWebPage::linkDelegationPolicy
3090 \brief how QWebPage should delegate the handling of links through the
3091 linkClicked() signal
3093 The default is to delegate no links.
3096 void QWebPage::setLinkDelegationPolicy(LinkDelegationPolicy policy)
3098 d->linkPolicy = policy;
3101 QWebPage::LinkDelegationPolicy QWebPage::linkDelegationPolicy() const
3103 return d->linkPolicy;
3106 #ifndef QT_NO_CONTEXTMENU
3108 Filters the context menu event, \a event, through handlers for scrollbars and
3109 custom event handlers in the web page. Returns true if the event was handled;
3112 A web page may swallow a context menu event through a custom event handler, allowing for context
3113 menus to be implemented in HTML/JavaScript. This is used by \l{http://maps.google.com/}{Google
3116 bool QWebPage::swallowContextMenuEvent(QContextMenuEvent *event)
3118 d->page->contextMenuController()->clearContextMenu();
3120 if (QWebFrame* webFrame = frameAt(event->pos())) {
3121 Frame* frame = QWebFramePrivate::core(webFrame);
3122 if (Scrollbar* scrollbar = frame->view()->scrollbarAtPoint(PlatformMouseEvent(event, 1).pos()))
3123 return scrollbar->contextMenu(PlatformMouseEvent(event, 1));
3126 WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame();
3127 focusedFrame->eventHandler()->sendContextMenuEvent(PlatformMouseEvent(event, 1));
3128 ContextMenu *menu = d->page->contextMenuController()->contextMenu();
3129 // If the website defines its own handler then sendContextMenuEvent takes care of
3130 // calling/showing it and the context menu pointer will be zero. This is the case
3131 // on maps.google.com for example.
3135 #endif // QT_NO_CONTEXTMENU
3138 Updates the page's actions depending on the position \a pos. For example if \a pos is over an image
3139 element the CopyImageToClipboard action is enabled.
3141 void QWebPage::updatePositionDependentActions(const QPoint &pos)
3143 #ifndef QT_NO_ACTION
3144 // First we disable all actions, but keep track of which ones were originally enabled.
3145 QBitArray originallyEnabledWebActions(QWebPage::WebActionCount);
3146 for (int i = ContextMenuItemTagNoAction; i < ContextMenuItemBaseApplicationTag; ++i) {
3147 QWebPage::WebAction action = webActionForContextMenuAction(WebCore::ContextMenuAction(i));
3148 if (QAction *a = this->action(action)) {
3149 originallyEnabledWebActions.setBit(action, a->isEnabled());
3150 a->setEnabled(false);
3153 #endif // QT_NO_ACTION
3155 d->createMainFrame();
3156 WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame();
3157 HitTestResult result = focusedFrame->eventHandler()->hitTestResultAtPoint(focusedFrame->view()->windowToContents(pos), /*allowShadowContent*/ false);
3159 if (result.scrollbar())
3160 d->hitTestResult = QWebHitTestResult();
3162 d->hitTestResult = QWebHitTestResult(new QWebHitTestResultPrivate(result));
3163 WebCore::ContextMenu menu(result);
3166 #if ENABLE(INSPECTOR)
3167 if (d->page->inspectorController()->enabled())
3168 menu.addInspectElementItem();
3171 QBitArray visitedWebActions(QWebPage::WebActionCount);
3173 #ifndef QT_NO_CONTEXTMENU
3174 delete d->currentContextMenu;
3176 // Then we let createContextMenu() enable the actions that are put into the menu
3177 d->currentContextMenu = d->createContextMenu(&menu, menu.platformDescription(), &visitedWebActions);
3178 #endif // QT_NO_CONTEXTMENU
3180 #ifndef QT_NO_ACTION
3181 // Finally, we restore the original enablement for the actions that were not put into the menu.
3182 originallyEnabledWebActions &= ~visitedWebActions; // Mask out visited actions (they're part of the menu)
3183 for (int i = 0; i < QWebPage::WebActionCount; ++i) {
3184 if (originallyEnabledWebActions.at(i)) {
3185 if (QAction *a = this->action(QWebPage::WebAction(i)))
3186 a->setEnabled(true);
3189 #endif // QT_NO_ACTION
3191 // This whole process ensures that any actions put into to the context menu has the right
3192 // enablement, while also keeping the correct enablement for actions that were left out of
3200 \enum QWebPage::Extension
3202 This enum describes the types of extensions that the page can support. Before using these extensions, you
3203 should verify that the extension is supported by calling supportsExtension().
3205 \value ChooseMultipleFilesExtension Whether the web page supports multiple file selection.
3206 This extension is invoked when the web content requests one or more file names, for example
3207 as a result of the user clicking on a "file upload" button in a HTML form where multiple
3208 file selection is allowed.
3210 \value ErrorPageExtension Whether the web page can provide an error page when loading fails.
3211 (introduced in Qt 4.6)
3213 \sa ChooseMultipleFilesExtensionOption, ChooseMultipleFilesExtensionReturn, ErrorPageExtensionOption, ErrorPageExtensionReturn
3217 \enum QWebPage::ErrorDomain
3220 This enum describes the domain of an ErrorPageExtensionOption object (i.e. the layer in which the error occurred).
3222 \value QtNetwork The error occurred in the QtNetwork layer; the error code is of type QNetworkReply::NetworkError.
3223 \value Http The error occurred in the HTTP layer; the error code is a HTTP status code (see QNetworkRequest::HttpStatusCodeAttribute).
3224 \value WebKit The error is an internal WebKit error.
3228 \class QWebPage::ExtensionOption
3230 \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support.
3234 \sa QWebPage::extension() QWebPage::ExtensionReturn
3239 \class QWebPage::ExtensionReturn
3241 \brief The ExtensionReturn class provides an output result from a QWebPage's extension.
3245 \sa QWebPage::extension() QWebPage::ExtensionOption
3249 \class QWebPage::ErrorPageExtensionOption
3251 \brief The ErrorPageExtensionOption class describes the option
3252 for the error page extension.
3256 The ErrorPageExtensionOption class holds the \a url for which an error occurred as well as
3257 the associated \a frame.
3259 The error itself is reported by an error \a domain, the \a error code as well as \a errorString.
3261 \sa QWebPage::extension() QWebPage::ErrorPageExtensionReturn
3265 \variable QWebPage::ErrorPageExtensionOption::url
3266 \brief the url for which an error occurred
3270 \variable QWebPage::ErrorPageExtensionOption::frame
3271 \brief the frame associated with the error
3275 \variable QWebPage::ErrorPageExtensionOption::domain
3276 \brief the domain that reported the error
3280 \variable QWebPage::ErrorPageExtensionOption::error
3281 \brief the error code. Interpretation of the value depends on the \a domain
3282 \sa QWebPage::ErrorDomain
3286 \variable QWebPage::ErrorPageExtensionOption::errorString
3287 \brief a string that describes the error
3291 \class QWebPage::ErrorPageExtensionReturn
3293 \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the
3294 frame for which the error occured.
3298 The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are
3299 optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which
3300 is assumed to be UTF-8 if not indicated otherwise.
3302 The error page is stored in the \a content byte array, as HTML content. In order to convert a
3303 QString to a byte array, the QString::toUtf8() method can be used.
3305 External objects such as stylesheets or images referenced in the HTML are located relative to
3308 \sa QWebPage::extension() QWebPage::ErrorPageExtensionOption, QString::toUtf8()
3312 \fn QWebPage::ErrorPageExtensionReturn::ErrorPageExtensionReturn()
3314 Constructs a new error page object.
3319 \variable QWebPage::ErrorPageExtensionReturn::contentType
3320 \brief the error page's content type
3324 \variable QWebPage::ErrorPageExtensionReturn::encoding
3325 \brief the error page encoding
3329 \variable QWebPage::ErrorPageExtensionReturn::baseUrl
3332 External objects such as stylesheets or images referenced in the HTML are located relative to this url.
3336 \variable QWebPage::ErrorPageExtensionReturn::content
3337 \brief the HTML content of the error page
3341 \class QWebPage::ChooseMultipleFilesExtensionOption
3343 \brief The ChooseMultipleFilesExtensionOption class describes the option
3344 for the multiple files selection extension.
3348 The ChooseMultipleFilesExtensionOption class holds the frame originating the request
3349 and the suggested filenames which might be provided.
3351 \sa QWebPage::extension() QWebPage::chooseFile(), QWebPage::ChooseMultipleFilesExtensionReturn
3355 \variable QWebPage::ChooseMultipleFilesExtensionOption::parentFrame
3356 \brief The frame in which the request originated
3360 \variable QWebPage::ChooseMultipleFilesExtensionOption::suggestedFileNames
3361 \brief The suggested filenames
3365 \variable QWebPage::ChooseMultipleFilesExtensionReturn::fileNames
3366 \brief The selected filenames
3370 \class QWebPage::ChooseMultipleFilesExtensionReturn
3372 \brief The ChooseMultipleFilesExtensionReturn describes the return value
3373 for the multiple files selection extension.
3377 The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user
3378 when the extension is invoked.
3380 \sa QWebPage::extension() QWebPage::ChooseMultipleFilesExtensionOption
3384 This virtual function can be reimplemented in a QWebPage subclass to provide support for extensions. The \a option
3385 argument is provided as input to the extension; the output results can be stored in \a output.
3387 The behavior of this function is determined by \a extension. The \a option
3388 and \a output values are typically casted to the corresponding types (for
3389 example, ChooseMultipleFilesExtensionOption and
3390 ChooseMultipleFilesExtensionReturn for ChooseMultipleFilesExtension).
3392 You can call supportsExtension() to check if an extension is supported by the page.
3394 Returns true if the extension was called successfully; otherwise returns false.
3396 \sa supportsExtension(), Extension
3398 bool QWebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
3400 #ifndef QT_NO_FILEDIALOG
3401 if (extension == ChooseMultipleFilesExtension) {
3402 // FIXME: do not ignore suggestedFiles
3403 QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames;
3404 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
3405 QStringList names = QFileDialog::getOpenFileNames(parent, QString::null);
3406 static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
3415 This virtual function returns true if the web page supports \a extension; otherwise false is returned.
3419 bool QWebPage::supportsExtension(Extension extension) const
3421 #ifndef QT_NO_FILEDIALOG
3422 return extension == ChooseMultipleFilesExtension;
3424 Q_UNUSED(extension);
3430 Finds the specified string, \a subString, in the page, using the given \a options.
3432 If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences
3433 that exist in the page. All subsequent calls will extend the highlight, rather than
3434 replace it, with occurrences of the new string.
3436 If the HighlightAllOccurrences flag is not passed, the function will select an occurrence
3437 and all subsequent calls will replace the current occurrence with the next one.
3439 To clear the selection, just pass an empty string.
3441 Returns true if \a subString was found; otherwise returns false.
3443 bool QWebPage::findText(const QString &subString, FindFlags options)
3445 ::TextCaseSensitivity caseSensitivity = ::TextCaseInsensitive;
3446 if (options & FindCaseSensitively)
3447 caseSensitivity = ::TextCaseSensitive;
3449 if (options & HighlightAllOccurrences) {
3450 if (subString.isEmpty()) {
3451 d->page->unmarkAllTextMatches();
3454 return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0);
3456 if (subString.isEmpty()) {
3457 d->page->mainFrame()->selection()->clear();
3458 Frame* frame = d->page->mainFrame()->tree()->firstChild();
3460 frame->selection()->clear();
3461 frame = frame->tree()->traverseNextWithWrap(false);
3464 ::FindDirection direction = ::FindDirectionForward;
3465 if (options & FindBackward)
3466 direction = ::FindDirectionBackward;
3468 const bool shouldWrap = options & FindWrapsAroundDocument;
3470 return d->page->findString(subString, caseSensitivity, direction, shouldWrap);
3475 Returns a pointer to the page's settings object.
3477 \sa QWebSettings::globalSettings()
3479 QWebSettings *QWebPage::settings() const
3485 This function is called when the web content requests a file name, for example
3486 as a result of the user clicking on a "file upload" button in a HTML form.
3488 A suggested filename may be provided in \a suggestedFile. The frame originating the
3489 request is provided as \a parentFrame.
3491 \sa ChooseMultipleFilesExtension
3493 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile)
3495 Q_UNUSED(parentFrame)
3496 #ifndef QT_NO_FILEDIALOG
3497 QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
3498 return QFileDialog::getOpenFileName(parent, QString::null, suggestedFile);
3500 return QString::null;
3505 Sets the QNetworkAccessManager \a manager responsible for serving network requests for this
3508 \note It is currently not supported to change the network access manager after the
3509 QWebPage has used it. The results of doing this are undefined.
3511 \sa networkAccessManager()
3513 void QWebPage::setNetworkAccessManager(QNetworkAccessManager *manager)
3515 if (manager == d->networkManager)
3517 if (d->networkManager && d->networkManager->parent() == this)
3518 delete d->networkManager;
3519 d->networkManager = manager;
3523 Returns the QNetworkAccessManager that is responsible for serving network
3524 requests for this QWebPage.
3526 \sa setNetworkAccessManager()
3528 QNetworkAccessManager *QWebPage::networkAccessManager() const
3530 if (!d->networkManager) {
3531 QWebPage *that = const_cast<QWebPage *>(this);
3532 that->d->networkManager = new QNetworkAccessManager(that);
3534 return d->networkManager;
3538 Sets the QWebPluginFactory \a factory responsible for creating plugins embedded into this
3541 Note: The plugin factory is only used if the QWebSettings::PluginsEnabled attribute is enabled.
3545 void QWebPage::setPluginFactory(QWebPluginFactory *factory)
3547 d->pluginFactory = factory;
3551 Returns the QWebPluginFactory that is responsible for creating plugins embedded into
3552 this QWebPage. If no plugin factory is installed a null pointer is returned.
3554 \sa setPluginFactory()
3556 QWebPluginFactory *QWebPage::pluginFactory() const
3558 return d->pluginFactory;
3562 This function is called when a user agent for HTTP requests is needed. You can reimplement this
3563 function to dynamically return different user agents for different URLs, based on the \a url parameter.
3565 The default implementation returns the following value:
3567 "Mozilla/5.0 (%Platform%; %Security%; %Subplatform%; %Locale%) AppleWebKit/%WebKitVersion% (KHTML, like Gecko) %AppVersion Safari/%WebKitVersion%"
3569 On mobile platforms such as Symbian S60 and Maemo, "Mobile Safari" is used instead of "Safari".
3571 In this string the following values are replaced at run-time:
3573 \o %Platform% and %Subplatform% are expanded to the windowing system and the operation system.
3574 \o %Security% expands to U if SSL is enabled, otherwise N. SSL is enabled if QSslSocket::supportsSsl() returns true.
3575 \o %Locale% is replaced with QLocale::name(). The locale is determined from the view of the QWebPage. If no view is set on the QWebPage,
3576 then a default constructed QLocale is used instead.
3577 \o %WebKitVersion% is the version of WebKit the application was compiled against.
3578 \o %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version.
3581 QString QWebPage::userAgentForUrl(const QUrl&) const
3583 // splitting the string in three and user QStringBuilder is better than using QString::arg()
3584 static QString firstPart;
3585 static QString secondPart;
3586 static QString thirdPart;
3588 if (firstPart.isNull() || secondPart.isNull() || thirdPart.isNull()) {
3589 QString firstPartTemp;
3590 firstPartTemp.reserve(150);
3591 firstPartTemp += QString::fromLatin1("Mozilla/5.0 ("
3596 #elif defined Q_WS_QWS
3598 #elif defined Q_WS_WIN
3600 #elif defined Q_WS_X11
3602 #elif defined Q_OS_SYMBIAN
3609 #if defined Q_OS_SYMBIAN
3610 QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
3611 switch (symbianVersion) {
3612 case QSysInfo::SV_9_2:
3613 firstPartTemp += QString::fromLatin1("OS/9.2");
3615 case QSysInfo::SV_9_3:
3616 firstPartTemp += QString::fromLatin1("OS/9.3");
3618 case QSysInfo::SV_9_4:
3619 firstPartTemp += QString::fromLatin1("OS/9.4");
3621 case QSysInfo::SV_SF_2:
3622 firstPartTemp += QString::fromLatin1("/2");
3624 case QSysInfo::SV_SF_3:
3625 firstPartTemp += QString::fromLatin1("/3");
3627 case QSysInfo::SV_SF_4:
3628 firstPartTemp += QString::fromLatin1("/4");
3634 firstPartTemp += QString::fromLatin1("; ");
3637 #if !defined(QT_NO_OPENSSL)
3638 // we could check QSslSocket::supportsSsl() here, but this makes
3639 // OpenSSL, certificates etc being loaded in all cases were QWebPage
3640 // is used. This loading is not needed for non-https.
3641 firstPartTemp += QString::fromLatin1("U; ");
3642 // this may lead to a false positive: We indicate SSL since it is
3643 // compiled in even though supportsSsl() might return false
3645 firstPartTemp += QString::fromLatin1("N; ");
3650 firstPartTemp += QString::fromLatin1("AIX");
3651 #elif defined Q_OS_WIN32
3653 switch (QSysInfo::WindowsVersion) {
3654 case QSysInfo::WV_32s:
3655 firstPartTemp += QString::fromLatin1("Windows 3.1");
3657 case QSysInfo::WV_95:
3658 firstPartTemp += QString::fromLatin1("Windows 95");
3660 case QSysInfo::WV_98:
3661 firstPartTemp += QString::fromLatin1("Windows 98");
3663 case QSysInfo::WV_Me:
3664 firstPartTemp += QString::fromLatin1("Windows 98; Win 9x 4.90");
3666 case QSysInfo::WV_NT:
3667 firstPartTemp += QString::fromLatin1("WinNT4.0");
3669 case QSysInfo::WV_2000:
3670 firstPartTemp += QString::fromLatin1("Windows NT 5.0");
3672 case QSysInfo::WV_XP:
3673 firstPartTemp += QString::fromLatin1("Windows NT 5.1");
3675 case QSysInfo::WV_2003:
3676 firstPartTemp += QString::fromLatin1("Windows NT 5.2");
3678 case QSysInfo::WV_VISTA:
3679 firstPartTemp += QString::fromLatin1("Windows NT 6.0");
3681 case QSysInfo::WV_WINDOWS7:
3682 firstPartTemp += QString::fromLatin1("Windows NT 6.1");
3684 case QSysInfo::WV_CE:
3685 firstPartTemp += QString::fromLatin1("Windows CE");
3687 case QSysInfo::WV_CENET:
3688 firstPartTemp += QString::fromLatin1("Windows CE .NET");
3690 case QSysInfo::WV_CE_5:
3691 firstPartTemp += QString::fromLatin1("Windows CE 5.x");
3693 case QSysInfo::WV_CE_6:
3694 firstPartTemp += QString::fromLatin1("Windows CE 6.x");
3698 #elif defined Q_OS_DARWIN
3699 #ifdef __i386__ || __x86_64__
3700 firstPartTemp += QString::fromLatin1("Intel Mac OS X");
3702 firstPartTemp += QString::fromLatin1("PPC Mac OS X");
3705 #elif defined Q_OS_BSDI
3706 firstPartTemp += QString::fromLatin1("BSD");
3707 #elif defined Q_OS_BSD4
3708 firstPartTemp += QString::fromLatin1("BSD Four");
3709 #elif defined Q_OS_CYGWIN
3710 firstPartTemp += QString::fromLatin1("Cygwin");
3711 #elif defined Q_OS_DGUX
3712 firstPartTemp += QString::fromLatin1("DG/UX");
3713 #elif defined Q_OS_DYNIX
3714 firstPartTemp += QString::fromLatin1("DYNIX/ptx");
3715 #elif defined Q_OS_FREEBSD
3716 firstPartTemp += QString::fromLatin1("FreeBSD");
3717 #elif defined Q_OS_HPUX
3718 firstPartTemp += QString::fromLatin1("HP-UX");
3719 #elif defined Q_OS_HURD
3720 firstPartTemp += QString::fromLatin1("GNU Hurd");
3721 #elif defined Q_OS_IRIX
3722 firstPartTemp += QString::fromLatin1("SGI Irix");
3723 #elif defined Q_OS_LINUX
3725 #if defined(__x86_64__)
3726 firstPartTemp += QString::fromLatin1("Linux x86_64");
3727 #elif defined(__i386__)
3728 firstPartTemp += QString::fromLatin1("Linux i686");
3730 firstPartTemp += QString::fromLatin1("Linux");
3733 #elif defined Q_OS_LYNX
3734 firstPartTemp += QString::fromLatin1("LynxOS");
3735 #elif defined Q_OS_NETBSD
3736 firstPartTemp += QString::fromLatin1("NetBSD");
3737 #elif defined Q_OS_OS2
3738 firstPartTemp += QString::fromLatin1("OS/2");
3739 #elif defined Q_OS_OPENBSD
3740 firstPartTemp += QString::fromLatin1("OpenBSD");
3741 #elif defined Q_OS_OS2EMX
3742 firstPartTemp += QString::fromLatin1("OS/2");
3743 #elif defined Q_OS_OSF
3744 firstPartTemp += QString::fromLatin1("HP Tru64 UNIX");
3745 #elif defined Q_OS_QNX6
3746 firstPartTemp += QString::fromLatin1("QNX RTP Six");
3747 #elif defined Q_OS_QNX
3748 firstPartTemp += QString::fromLatin1("QNX");
3749 #elif defined Q_OS_RELIANT
3750 firstPartTemp += QString::fromLatin1("Reliant UNIX");
3751 #elif defined Q_OS_SCO
3752 firstPartTemp += QString::fromLatin1("SCO OpenServer");
3753 #elif defined Q_OS_SOLARIS
3754 firstPartTemp += QString::fromLatin1("Sun Solaris");
3755 #elif defined Q_OS_ULTRIX
3756 firstPartTemp += QString::fromLatin1("DEC Ultrix");
3757 #elif defined Q_OS_SYMBIAN
3758 firstPartTemp += QLatin1Char(' ');
3759 QSysInfo::S60Version s60Version = QSysInfo::s60Version();
3760 switch (s60Version) {
3761 case QSysInfo::SV_S60_3_1:
3762 firstPartTemp += QString::fromLatin1("Series60/3.1");
3764 case QSysInfo::SV_S60_3_2:
3765 firstPartTemp += QString::fromLatin1("Series60/3.2");
3767 case QSysInfo::SV_S60_5_0:
3768 firstPartTemp += QString::fromLatin1("Series60/5.0");
3773 #elif defined Q_OS_UNIX
3774 firstPartTemp += QString::fromLatin1("UNIX BSD/SYSV system");
3775 #elif defined Q_OS_UNIXWARE
3776 firstPartTemp += QString::fromLatin1("UnixWare Seven, Open UNIX Eight");
3778 firstPartTemp += QString::fromLatin1("Unknown");
3781 // language is the split
3782 firstPartTemp += QString::fromLatin1("; ");
3783 firstPartTemp.squeeze();
3784 firstPart = firstPartTemp;
3786 QString secondPartTemp;
3787 secondPartTemp.reserve(150);
3788 secondPartTemp += QString::fromLatin1(") ");
3790 // webkit/qt version
3791 secondPartTemp += QString::fromLatin1("AppleWebKit/");
3792 secondPartTemp += qWebKitVersion();
3793 secondPartTemp += QString::fromLatin1(" (KHTML, like Gecko) ");
3796 // Application name split the third part
3797 secondPartTemp.squeeze();
3798 secondPart = secondPartTemp;
3800 QString thirdPartTemp;
3801 thirdPartTemp.reserve(150);
3802 #if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
3803 thirdPartTemp += QLatin1String(" Mobile Safari/");
3805 thirdPartTemp += QLatin1String(" Safari/");
3807 thirdPartTemp += qWebKitVersion();
3808 thirdPartTemp.squeeze();
3809 thirdPart = thirdPartTemp;
3810 Q_ASSERT(!firstPart.isNull());
3811 Q_ASSERT(!secondPart.isNull());
3812 Q_ASSERT(!thirdPart.isNull());
3816 QString languageName;
3817 if (d->client && d->client->ownerWidget())
3818 languageName = d->client->ownerWidget()->locale().name();
3820 languageName = QLocale().name();
3821 languageName.replace(QLatin1Char('_'), QLatin1Char('-'));
3823 // Application name/version
3824 QString appName = QCoreApplication::applicationName();
3825 if (!appName.isEmpty()) {
3826 QString appVer = QCoreApplication::applicationVersion();
3827 if (!appVer.isEmpty())
3828 appName.append(QLatin1Char('/') + appVer);
3831 appName = QString::fromLatin1("Qt/") + QString::fromLatin1(qVersion());
3834 return firstPart + languageName + secondPart + appName + thirdPart;
3838 void QWebPagePrivate::_q_onLoadProgressChanged(int)
3840 m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
3841 m_bytesReceived = page->progress()->totalBytesReceived();
3846 Returns the total number of bytes that were received from the network to render the current page,
3847 including extra content such as embedded images.
3851 quint64 QWebPage::totalBytes() const
3853 return d->m_totalBytes;
3858 Returns the number of bytes that were received from the network to render the current page.
3860 \sa totalBytes(), loadProgress()
3862 quint64 QWebPage::bytesReceived() const
3864 return d->m_bytesReceived;
3869 \fn void QWebPage::viewportChangeRequested()
3871 Page authors can provide the supplied values by using the viewport meta tag. More information
3872 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}.
3874 \sa QWebPage::ViewportAttributes, setPreferredContentsSize(), QGraphicsWebView::setScale()
3878 \fn void QWebPage::loadStarted()
3880 This signal is emitted when a new load of the page is started.
3886 \fn void QWebPage::loadProgress(int progress)
3888 This signal is emitted when the global progress status changes.
3889 The current value is provided by \a progress and scales from 0 to 100,
3890 which is the default range of QProgressBar.
3891 It accumulates changes from all the child frames.
3897 \fn void QWebPage::loadFinished(bool ok)
3899 This signal is emitted when a load of the page is finished.
3900 \a ok will indicate whether the load was successful or any error occurred.
3902 \sa loadStarted(), ErrorPageExtension
3906 \fn void QWebPage::linkHovered(const QString &link, const QString &title, const QString &textContent)
3908 This signal is emitted when the mouse hovers over a link.
3910 \a link contains the link url.
3911 \a title is the link element's title, if it is specified in the markup.
3912 \a textContent provides text within the link element, e.g., text inside an HTML anchor tag.
3914 When the mouse leaves the link element the signal is emitted with empty parameters.
3920 \fn void QWebPage::statusBarMessage(const QString& text)
3922 This signal is emitted when the statusbar \a text is changed by the page.
3926 \fn void QWebPage::frameCreated(QWebFrame *frame)
3928 This signal is emitted whenever the page creates a new \a frame.
3934 \fn void QWebPage::selectionChanged()
3936 This signal is emitted whenever the selection changes, either interactively
3937 or programmatically (e.g. by calling triggerAction() with a selection action).
3943 \fn void QWebPage::contentsChanged()
3946 This signal is emitted whenever the text in form elements changes
3947 as well as other editable content.
3949 \sa contentEditable, modified, QWebFrame::toHtml(), QWebFrame::toPlainText()
3953 \fn void QWebPage::geometryChangeRequested(const QRect& geom)
3955 This signal is emitted whenever the document wants to change the position and size of the
3956 page to \a geom. This can happen for example through JavaScript.
3960 \fn void QWebPage::repaintRequested(const QRect& dirtyRect)
3962 This signal is emitted whenever this QWebPage should be updated and no view was set.
3963 \a dirtyRect contains the area that needs to be updated. To paint the QWebPage get
3964 the mainFrame() and call the render(QPainter*, const QRegion&) method with the
3965 \a dirtyRect as the second parameter.
3972 \fn void QWebPage::scrollRequested(int dx, int dy, const QRect& rectToScroll)
3974 This signal is emitted whenever the content given by \a rectToScroll needs
3975 to be scrolled \a dx and \a dy downwards and no view was set.
3981 \fn void QWebPage::windowCloseRequested()
3983 This signal is emitted whenever the page requests the web browser window to be closed,
3984 for example through the JavaScript \c{window.close()} call.
3988 \fn void QWebPage::printRequested(QWebFrame *frame)
3990 This signal is emitted whenever the page requests the web browser to print \a frame,
3991 for example through the JavaScript \c{window.print()} call.
3993 \sa QWebFrame::print(), QPrintPreviewDialog
3997 \fn void QWebPage::unsupportedContent(QNetworkReply *reply)
3999 This signal is emitted when WebKit cannot handle a link the user navigated to or a
4000 web server's response includes a "Content-Disposition" header with the 'attachment'
4001 directive. If "Content-Disposition" is present in \a reply, the web server is indicating
4002 that the client should prompt the user to save the content regardless of content-type.
4003 See RFC 2616 sections 19.5.1 for details about Content-Disposition.
4005 At signal emission time the meta-data of the QNetworkReply \a reply is available.
4007 \note This signal is only emitted if the forwardUnsupportedContent property is set to true.
4009 \sa downloadRequested()
4013 \fn void QWebPage::downloadRequested(const QNetworkRequest &request)
4015 This signal is emitted when the user decides to download a link. The url of
4016 the link as well as additional meta-information is contained in \a request.
4018 \sa unsupportedContent()
4022 \fn void QWebPage::microFocusChanged()
4024 This signal is emitted when for example the position of the cursor in an editable form
4025 element changes. It is used to inform input methods about the new on-screen position where
4026 the user is able to enter text. This signal is usually connected to the
4027 QWidget::updateMicroFocus() slot.
4031 \fn void QWebPage::linkClicked(const QUrl &url)
4033 This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy
4034 property is set to delegate the link handling for the specified \a url.
4036 By default no links are delegated and are handled by QWebPage instead.
4038 \note This signal possibly won't be emitted for clicked links which use
4039 JavaScript to trigger navigation.
4045 \fn void QWebPage::toolBarVisibilityChangeRequested(bool visible)
4047 This signal is emitted whenever the visibility of the toolbar in a web browser
4048 window that hosts QWebPage should be changed to \a visible.
4052 \fn void QWebPage::statusBarVisibilityChangeRequested(bool visible)
4054 This signal is emitted whenever the visibility of the statusbar in a web browser
4055 window that hosts QWebPage should be changed to \a visible.
4059 \fn void QWebPage::menuBarVisibilityChangeRequested(bool visible)
4061 This signal is emitted whenever the visibility of the menubar in a web browser
4062 window that hosts QWebPage should be changed to \a visible.
4066 \fn void QWebPage::databaseQuotaExceeded(QWebFrame* frame, QString databaseName);
4069 This signal is emitted whenever the web site shown in \a frame is asking to store data
4070 to the database \a databaseName and the quota allocated to that web site is exceeded.
4077 \fn void QWebPage::saveFrameStateRequested(QWebFrame* frame, QWebHistoryItem* item);
4079 This signal is emitted shortly before the history of navigated pages
4080 in \a frame is changed, for example when navigating back in the history.
4082 The provided QWebHistoryItem, \a item, holds the history entry of the frame before
4085 A potential use-case for this signal is to store custom data in
4086 the QWebHistoryItem associated to the frame, using QWebHistoryItem::setUserData().
4091 \fn void QWebPage::restoreFrameStateRequested(QWebFrame* frame);
4093 This signal is emitted when the load of \a frame is finished and the application may now update its state accordingly.
4097 \fn QWebPagePrivate* QWebPage::handle() const
4101 #include "moc_qwebpage.cpp"