diff options
Diffstat (limited to 'WebKit/qt')
48 files changed, 2511 insertions, 430 deletions
diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp index 7a28f83..3eba058 100644 --- a/WebKit/qt/Api/qwebframe.cpp +++ b/WebKit/qt/Api/qwebframe.cpp @@ -48,6 +48,7 @@ #include "PlatformWheelEvent.h" #include "PrintContext.h" #include "PutPropertySlot.h" +#include "RenderLayer.h" #include "RenderTreeAsText.h" #include "RenderView.h" #include "ResourceRequest.h" @@ -475,7 +476,12 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object JSC::JSLock lock(JSC::SilenceAssertionsOnly); JSDOMWindow* window = toJSDOMWindow(d->frame, mainThreadNormalWorld()); - JSC::Bindings::RootObject* root = d->frame->script()->bindingRootObject(); + JSC::Bindings::RootObject* root; + if (ownership == QScriptEngine::QtOwnership) + root = d->frame->script()->cacheableBindingRootObject(); + else + root = d->frame->script()->bindingRootObject(); + if (!window) { qDebug() << "Warning: couldn't get window object"; return; diff --git a/WebKit/qt/Api/qwebhistory.cpp b/WebKit/qt/Api/qwebhistory.cpp index 06e6cfa..0147f92 100644 --- a/WebKit/qt/Api/qwebhistory.cpp +++ b/WebKit/qt/Api/qwebhistory.cpp @@ -555,3 +555,8 @@ QWebPagePrivate* QWebHistoryPrivate::page() { return QWebFramePrivate::kit(lst->page()->mainFrame())->page()->handle(); } + +WebCore::HistoryItem* QWebHistoryItemPrivate::core(QWebHistoryItem* q) +{ + return q->d->item; +} diff --git a/WebKit/qt/Api/qwebhistory.h b/WebKit/qt/Api/qwebhistory.h index cce4553..3456784 100644 --- a/WebKit/qt/Api/qwebhistory.h +++ b/WebKit/qt/Api/qwebhistory.h @@ -61,6 +61,7 @@ private: friend class QWebPage; friend class WebCore::FrameLoaderClientQt; friend class QWebHistoryItemPrivate; + friend class DumpRenderTreeSupportQt; //friend QDataStream & operator<<(QDataStream& out,const QWebHistoryItem& hist); //friend QDataStream & operator>>(QDataStream& in,QWebHistoryItem& hist); QExplicitlySharedDataPointer<QWebHistoryItemPrivate> d; diff --git a/WebKit/qt/Api/qwebhistory_p.h b/WebKit/qt/Api/qwebhistory_p.h index a6682cd..c9ff91b 100644 --- a/WebKit/qt/Api/qwebhistory_p.h +++ b/WebKit/qt/Api/qwebhistory_p.h @@ -45,6 +45,8 @@ public: item->deref(); } + static WebCore::HistoryItem* core(QWebHistoryItem* q); + WebCore::HistoryItem* item; }; diff --git a/WebKit/qt/Api/qwebkitplatformplugin.h b/WebKit/qt/Api/qwebkitplatformplugin.h index 7d024ae..bac618c 100644 --- a/WebKit/qt/Api/qwebkitplatformplugin.h +++ b/WebKit/qt/Api/qwebkitplatformplugin.h @@ -58,20 +58,43 @@ Q_SIGNALS: void didHide(); }; +class QWebNotificationData +{ +public: + virtual const QString title() const = 0; + virtual const QString message() const = 0; + virtual const QByteArray iconData() const = 0; +}; + +class QWebNotificationPresenter : public QObject +{ + Q_OBJECT +public: + QWebNotificationPresenter() {} + virtual ~QWebNotificationPresenter() {} + + virtual void showNotification(const QWebNotificationData*) = 0; + +Q_SIGNALS: + void notificationClosed(); +}; + class QWebKitPlatformPlugin { public: - inline ~QWebKitPlatformPlugin() {} + virtual ~QWebKitPlatformPlugin() {} enum Extension { - MultipleSelections + MultipleSelections, + Notifications }; - virtual QWebSelectMethod* createSelectInputMethod() const = 0; virtual bool supportsExtension(Extension extension) const = 0; + virtual QWebSelectMethod* createSelectInputMethod() const = 0; + virtual QWebNotificationPresenter* createNotificationPresenter() const = 0; }; -Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.0"); +Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.2"); #endif // QWEBKITPLATFORMPLUGIN_H diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp index 0e9d92f..d49ac14 100644 --- a/WebKit/qt/Api/qwebpage.cpp +++ b/WebKit/qt/Api/qwebpage.cpp @@ -267,6 +267,9 @@ QWebPagePrivate::QWebPagePrivate(QWebPage *qq) JSC::initializeThreading(); WTF::initializeMainThread(); WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData); +#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) + WebCore::Font::setCodePath(WebCore::Font::Complex); +#endif chromeClient = new ChromeClientQt(q); contextMenuClient = new ContextMenuClientQt(); @@ -299,7 +302,7 @@ QWebPagePrivate::QWebPagePrivate(QWebPage *qq) PageGroup::setShouldTrackVisitedLinks(true); #if ENABLE(NOTIFICATIONS) - notificationPresenterClient = new NotificationPresenterClientQt(q); + NotificationPresenterClientQt::notificationPresenter()->addClient(); #endif } @@ -315,7 +318,7 @@ QWebPagePrivate::~QWebPagePrivate() delete page; #if ENABLE(NOTIFICATIONS) - delete notificationPresenterClient; + NotificationPresenterClientQt::notificationPresenter()->removeClient(); #endif } @@ -1008,7 +1011,7 @@ void QWebPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); ev->setDropAction(action); if (action != Qt::IgnoreAction) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1021,7 +1024,7 @@ void QWebPagePrivate::dragEnterEvent(QDragEnterEvent* ev) ev->setDropAction(action); // We must accept this event in order to receive the drag move events that are sent // while the drag and drop action is in progress. - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1051,7 +1054,7 @@ void QWebPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); ev->setDropAction(action); if (action != Qt::IgnoreAction) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1065,7 +1068,7 @@ void QWebPagePrivate::dragMoveEvent(QDragMoveEvent* ev) ev->setDropAction(action); // We must accept this event in order to receive the drag move events that are sent // while the drag and drop action is in progress. - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1075,7 +1078,7 @@ void QWebPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev) DragData dragData(ev->mimeData(), ev->pos().toPoint(), QCursor::pos(), dropActionToDragOp(ev->possibleActions())); if (page->dragController()->performDrag(&dragData)) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1087,7 +1090,7 @@ void QWebPagePrivate::dropEvent(QDropEvent* ev) DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOp(Qt::DropAction(ev->dropAction()))); if (page->dragController()->performDrag(&dragData)) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1203,6 +1206,7 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) ev->accept(); } +#ifndef QT_NO_PROPERTIES void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event) { if (event->propertyName() == "_q_viewMode") { @@ -1257,6 +1261,7 @@ void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* ev } #endif } +#endif void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event) { @@ -1931,6 +1936,30 @@ bool QWebPage::shouldInterruptJavaScript() } /*! + \fn bool QWebPage::allowGeolocationRequest() + \since 4.7 + + This function is called whenever a JavaScript program running inside \a frame tries to access user location through navigator.geolocation. + + If the user wants to allow access to location then it should return true; otherwise false. + + The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons. + + \warning Because of binary compatibility constraints, this function is not virtual. If you want to + provide your own implementation in a QWebPage subclass, reimplement the allowGeolocationRequest() + slot in your subclass instead. QtWebKit will dynamically detect the slot and call it. +*/ +bool QWebPage::allowGeolocationRequest(QWebFrame *frame) +{ +#ifdef QT_NO_MESSAGEBOX + return false; +#else + QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; + return QMessageBox::Yes == QMessageBox::information(parent, tr("Location Request by- %1").arg(frame->url().host()), tr("The page wants to access your location information. Do you want to allow the request?"), QMessageBox::Yes, QMessageBox::No); +#endif +} + +/*! This function is called whenever WebKit wants to create a new window of the given \a type, for example when a JavaScript program requests to open a document in a new window. @@ -2641,9 +2670,11 @@ bool QWebPage::event(QEvent *ev) d->touchEvent(static_cast<QTouchEvent*>(ev)); break; #endif +#ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: d->dynamicPropertyChangeEvent(static_cast<QDynamicPropertyChangeEvent*>(ev)); break; +#endif default: return QObject::event(ev); } @@ -3095,6 +3126,14 @@ bool QWebPage::findText(const QString &subString, FindFlags options) } else return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0); } else { + if (subString.isEmpty()) { + d->page->mainFrame()->selection()->clear(); + Frame* frame = d->page->mainFrame()->tree()->firstChild(); + while (frame) { + frame->selection()->clear(); + frame = frame->tree()->traverseNextWithWrap(false); + } + } ::FindDirection direction = ::FindDirectionForward; if (options & FindBackward) direction = ::FindDirectionBackward; diff --git a/WebKit/qt/Api/qwebpage.h b/WebKit/qt/Api/qwebpage.h index a4b555a..721f4a8 100644 --- a/WebKit/qt/Api/qwebpage.h +++ b/WebKit/qt/Api/qwebpage.h @@ -307,6 +307,7 @@ public: public Q_SLOTS: bool shouldInterruptJavaScript(); + bool allowGeolocationRequest(QWebFrame *frame); Q_SIGNALS: void loadStarted(); diff --git a/WebKit/qt/Api/qwebpage_p.h b/WebKit/qt/Api/qwebpage_p.h index 7414716..272f96b 100644 --- a/WebKit/qt/Api/qwebpage_p.h +++ b/WebKit/qt/Api/qwebpage_p.h @@ -44,7 +44,6 @@ namespace WebCore { class EditorClientQt; class Element; class InspectorController; - class NotificationPresenterClientQt; class Node; class Page; class Frame; @@ -113,7 +112,9 @@ public: void inputMethodEvent(QInputMethodEvent*); +#ifndef QT_NO_PROPERTIES void dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent*); +#endif void shortcutOverrideEvent(QKeyEvent*); void leaveEvent(QEvent*); @@ -191,8 +192,6 @@ public: bool inspectorIsInternalOnly; // True if created through the Inspect context menu action Qt::DropAction m_lastDropAction; - WebCore::NotificationPresenterClientQt* notificationPresenterClient; - QString viewMode; static bool drtRun; diff --git a/WebKit/qt/Api/qwebpluginfactory.cpp b/WebKit/qt/Api/qwebpluginfactory.cpp index f715430..b9180be 100644 --- a/WebKit/qt/Api/qwebpluginfactory.cpp +++ b/WebKit/qt/Api/qwebpluginfactory.cpp @@ -63,7 +63,7 @@ /*! \class QWebPluginFactory::Plugin \since 4.4 - \brief the QWebPluginFactory::Plugin structure describes the properties of a plugin a QWebPluginFactory can create. + \brief The QWebPluginFactory::Plugin structure describes the properties of a plugin a QWebPluginFactory can create. \inmodule QtWebKit */ @@ -147,7 +147,7 @@ QWebPluginFactory::~QWebPluginFactory() supported plugins the factory can create. \note Currently, this function is only called when JavaScript programs - access the global \c plugins or \c mimetypes objects. + access the global \c plugins or \c mimetypes objects. */ /*! diff --git a/WebKit/qt/Api/qwebsettings.cpp b/WebKit/qt/Api/qwebsettings.cpp index a649658..4881bac 100644 --- a/WebKit/qt/Api/qwebsettings.cpp +++ b/WebKit/qt/Api/qwebsettings.cpp @@ -184,9 +184,10 @@ void QWebSettingsPrivate::apply() global->attributes.value(QWebSettings::SpatialNavigationEnabled)); settings->setSpatialNavigationEnabled(value); - value = attributes.value(QWebSettings::DOMPasteAllowed, - global->attributes.value(QWebSettings::DOMPasteAllowed)); + value = attributes.value(QWebSettings::JavascriptCanAccessClipboard, + global->attributes.value(QWebSettings::JavascriptCanAccessClipboard)); settings->setDOMPasteAllowed(value); + settings->setJavaScriptCanAccessClipboard(value); value = attributes.value(QWebSettings::DeveloperExtrasEnabled, global->attributes.value(QWebSettings::DeveloperExtrasEnabled)); @@ -235,10 +236,6 @@ void QWebSettingsPrivate::apply() global->attributes.value(QWebSettings::LocalContentCanAccessFileUrls)); settings->setAllowFileAccessFromFileURLs(value); - value = attributes.value(QWebSettings::JavaScriptCanAccessClipboard, - global->attributes.value(QWebSettings::JavaScriptCanAccessClipboard)); - settings->setJavaScriptCanAccessClipboard(value); - value = attributes.value(QWebSettings::XSSAuditingEnabled, global->attributes.value(QWebSettings::XSSAuditingEnabled)); settings->setXSSAuditorEnabled(value); @@ -249,6 +246,10 @@ void QWebSettingsPrivate::apply() settings->setTiledBackingStoreEnabled(value); #endif + value = attributes.value(QWebSettings::SiteSpecificQuirksEnabled, + global->attributes.value(QWebSettings::SiteSpecificQuirksEnabled)); + settings->setNeedsSiteSpecificQuirks(value); + settings->setUsesPageCache(WebCore::pageCache()->capacity()); } else { QList<QWebSettingsPrivate*> settings = *::allSettings(); @@ -376,8 +377,6 @@ QWebSettings* QWebSettings::globalSettings() recording visited pages in the history and storing web page icons. This is disabled by default. \value JavascriptCanOpenWindows Specifies whether JavaScript programs can open new windows. This is disabled by default. - \value DOMPasteAllowed Specifies whether JavaScript programs can - read clipboard contents. \value JavascriptCanAccessClipboard Specifies whether JavaScript programs can read or write to the clipboard. This is disabled by default. \value DeveloperExtrasEnabled Enables extra tools for Web developers. @@ -433,6 +432,8 @@ QWebSettings* QWebSettings::globalSettings() and at other times scrolling the page itself. For this reason iframes and framesets are barely usable on touch devices. This will flatten all the frames to become one scrollable page. This is disabled by default. + \value SiteSpecificQuirksEnabled This setting enables WebKit's workaround for broken sites. It is + enabled by default. */ /*! @@ -469,6 +470,7 @@ QWebSettings::QWebSettings() d->attributes.insert(QWebSettings::WebGLEnabled, false); d->attributes.insert(QWebSettings::TiledBackingStoreEnabled, false); d->attributes.insert(QWebSettings::FrameFlatteningEnabled, false); + d->attributes.insert(QWebSettings::SiteSpecificQuirksEnabled, true); d->offlineStorageDefaultQuota = 5 * 1024 * 1024; d->defaultTextEncoding = QLatin1String("iso-8859-1"); } diff --git a/WebKit/qt/Api/qwebsettings.h b/WebKit/qt/Api/qwebsettings.h index 040f9b4..c063bcd 100644 --- a/WebKit/qt/Api/qwebsettings.h +++ b/WebKit/qt/Api/qwebsettings.h @@ -55,7 +55,7 @@ public: PluginsEnabled, PrivateBrowsingEnabled, JavascriptCanOpenWindows, - DOMPasteAllowed, + JavascriptCanAccessClipboard, DeveloperExtrasEnabled, LinksIncludedInFocusChain, ZoomTextOnly, @@ -68,14 +68,14 @@ public: #endif LocalContentCanAccessRemoteUrls, DnsPrefetchEnabled, - JavaScriptCanAccessClipboard, XSSAuditingEnabled, AcceleratedCompositingEnabled, SpatialNavigationEnabled, LocalContentCanAccessFileUrls, TiledBackingStoreEnabled, FrameFlatteningEnabled, - WebGLEnabled + WebGLEnabled, + SiteSpecificQuirksEnabled }; enum WebGraphic { MissingImageGraphic, diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog index 14548d9..f83d64d 100644 --- a/WebKit/qt/ChangeLog +++ b/WebKit/qt/ChangeLog @@ -1,3 +1,689 @@ +2010-06-13 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Platform plugin support for Notifications UI + https://bugs.webkit.org/show_bug.cgi?id=40005 + + Add an interface to the platform plugin to display notifications. + Implemented the notification in the example platform plugin. + This interface is enabled by default, but could be turned off with + a build flag. The platform plugin should control its own lifecycle, + so now the close timer applies only when using the QSystemTrayIcon. + That's because QSystemTrayIcon does not inform its caller when it + is closed. + + Changed the way NotificationPresenterClientQt is deleted because it + is being accessed when GC is deleting the Notification objects. + NotificationPresenterClientQt is now detaching itself from the + Notifications before it is deleted. + + * Api/qwebkitplatformplugin.h: + (QWebNotificationPresenter::QWebNotificationPresenter): + (QWebNotificationPresenter::~QWebNotificationPresenter): + (QWebKitPlatformPlugin::): + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationIconWrapper::NotificationIconWrapper): + (WebCore::NotificationIconWrapper::title): + (WebCore::NotificationIconWrapper::message): + (WebCore::NotificationIconWrapper::iconData): + (WebCore::NotificationPresenterClientQt::~NotificationPresenterClientQt): + (WebCore::NotificationIconWrapper::notificationClosed): + (WebCore::NotificationPresenterClientQt::displayNotification): + (WebCore::NotificationPresenterClientQt::cancel): + (WebCore::NotificationPresenterClientQt::notificationForWrapper): + (WebCore::NotificationPresenterClientQt::removeReplacedNotificationFromQueue): + (WebCore::NotificationPresenterClientQt::detachNotification): + * WebCoreSupport/NotificationPresenterClientQt.h: + * WebCoreSupport/QtPlatformPlugin.cpp: + (WebCore::QtPlatformPlugin::createNotificationPresenter): + * WebCoreSupport/QtPlatformPlugin.h: + * examples/platformplugin/WebNotificationPresenter.cpp: Added. + (WebNotificationWidget::WebNotificationWidget): + (WebNotificationWidget::~WebNotificationWidget): + (WebNotificationWidget::showNotification): + (WebNotificationWidget::event): + * examples/platformplugin/WebNotificationPresenter.h: Added. + (WebNotificationPresenter::WebNotificationPresenter): + (WebNotificationPresenter::~WebNotificationPresenter): + (WebNotificationPresenter::showNotification): + * examples/platformplugin/WebPlugin.cpp: + (WebPlugin::supportsExtension): + * examples/platformplugin/WebPlugin.h: + (WebPlugin::createNotificationPresenter): + * examples/platformplugin/platformplugin.pro: + * examples/platformplugin/qwebkitplatformplugin.h: + (QWebNotificationPresenter::QWebNotificationPresenter): + (QWebNotificationPresenter::~QWebNotificationPresenter): + (QWebKitPlatformPlugin::): + +2010-06-14 Mahesh Kulkarni <mahesh.kulkarni@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] navigator.geolocation support for Qt port + https://bugs.webkit.org/show_bug.cgi?id=39724 + + Implement ChromeClientQt::requestGeolocationPermissionForFrame() which delegates call to QWebPage::allowGeolocationRequest + Layout and unit test cases for the are also added. + + * Api/qwebpage.cpp: + (QWebPage::allowGeolocationRequest): + * Api/qwebpage.h: + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::requestGeolocationPermissionForFrame): + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::setMockGeolocationPosition): + (DumpRenderTreeSupportQt::setMockGeolocationError): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + * tests/qwebpage/tst_qwebpage.cpp: + (JSTestPage::shouldInterruptJavaScript): + (JSTestPage::allowGeolocationRequest): + (JSTestPage::setGeolocationPermission): + (tst_QWebPage::geolocationRequestJS): + +2010-06-14 Ilya Tikhonovsky <loislo@chromium.org> + + Reviewed by Pavel Feldman. + + WebInspector: On the way to Remote Debugging we want to transfer dom/timeline/etc + data from inspected page to WebInspector as JSON string via http. The native + serialization to JSON string is supported by InspectorValue's classes. This patch + has the implementation of sendMessageToFrontend function. WebKit version of it still + uses ScriptFunctionCall and will be switched to another transport a little bit later. + https://bugs.webkit.org/show_bug.cgi?id=40134 + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::InspectorClientQt): + (WebCore::InspectorClientQt::openInspectorFrontend): + (WebCore::InspectorClientQt::releaseFrontendPage): + (WebCore::InspectorClientQt::sendMessageToFrontend): + * WebCoreSupport/InspectorClientQt.h: + +2010-06-13 Charles Wei <charles.wei@torchmobile.com.cn> + + Reviewed by George Staikos. + + Fix the QtWebKit which doesn't recognize the MIME type of HTML/TEXT in uppercase + https://bugs.webkit.org/show_bug.cgi?id=39492 + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::canShowMIMEType): + +2010-06-08 Robert Hogan <robert@webkit.org> + + Reviewed by Eric Seidel. + + [Qt] Add support for callShouldCloseOnWebView() to DRT + https://bugs.webkit.org/show_bug.cgi?id=40330 + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::shouldClose): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + +2010-06-12 Dawit Alemayehu <adawit@kde.org> + + Reviewed by Kenneth Rohde Christiansen. + + Added an attribute to enable/disable site specific quirks mode in WebKit. + The attribute is enabled by default. + + https://bugs.webkit.org/show_bug.cgi?id=40073 + + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + (QWebSettings::QWebSettings): + * Api/qwebsettings.h: + +2010-06-12 Robert Hogan <robert@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix tst_qwebframe regression from http://trac.webkit.org/changeset/61062 + + Only use cacheableBindingRootObject() if the object has QtOwnership. + + https://bugs.webkit.org/show_bug.cgi?id=40527 + + * Api/qwebframe.cpp: + (QWebFrame::addToJavaScriptWindowObject): + +2010-06-13 Robert Hogan <robert@webkit.org> + + Reviewed by Alexey Proskuryakov. + + FrameLoader::clear() clears JS objects that cached pages later rely on + + https://bugs.webkit.org/show_bug.cgi?id=37725 + https://bugs.webkit.org/show_bug.cgi?id=31626 + + Fix the following tests for Qt: + + fast/events/pageshow-pagehide-on-back-cached.html + fast/events/pageshow-pagehide-on-back-cached-with-frames.html + fast/loader/input-element-page-cache-crash.html + fast/dom/Window/timer-resume-on-navigation-back.html + loader/go-back-to-different-window-size.html + fast/dom/javascript-url-crash-function.html + fast/dom/location-new-window-no-crash.html + http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-window-open.html + + which currently fail because the page's Qt-bindings runtime objects are + cleared when navigating away from the page containing them. + + Track Qt-bindings objects in a separate ScriptController::cacheableRootBindingObject(). + RuntimeObjects tracked by this root object will not get invalidated on page navigations, + so they will still be available when the pages containing them are retrieved from the + b/f cache. + + This means the Qt bindings objects will only get cleared on Frame::pageDestroyed(). + + * Api/qwebframe.cpp: + (QWebFrame::addToJavaScriptWindowObject): + +2010-06-12 No'am Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add documentation to the QtWebkit bridge + https://bugs.webkit.org/show_bug.cgi?id=35861 + + The previous accepted patch was actually a faulty one; It was hard to trace since it's just a documentation + change. The new patch amends that, with the correct snippets and grammar fixes. + + * docs/qtwebkit-bridge.qdoc: + * docs/webkitsnippets/qtwebkit_bridge_snippets.cpp: + (wrapInFunction): + +2010-06-12 Robert Hogan <robert@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Back-forward list dumping is incorrect + + https://bugs.webkit.org/show_bug.cgi?id=36392 + + Support dumping child history items in DRT. + + Unskip: + + fast/loader/frame-src-change-added-to-history.html + fast/loader/frame-src-change-not-added-to-history.html + fast/loader/frame-location-change-not-added-to-history.html + + * Api/qwebhistory.cpp: + (QWebHistoryItemPrivate::core): + * Api/qwebhistory.h: + * Api/qwebhistory_p.h: + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::isTargetItem): + (DumpRenderTreeSupportQt::historyItemTarget): + (DumpRenderTreeSupportQt::getChildHistoryItems): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + +2010-06-11 Jesus Sanchez-Palencia <jesus@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Typo error in QWebPluginFactory Documentation + https://bugs.webkit.org/show_bug.cgi?id=40490 + + * Api/qwebpluginfactory.cpp: + +2010-06-11 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by nobody, build fix. + + [Qt] Second fix attempt for the build break introduced by r61002. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + +2010-06-11 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by nobody, build fix. + + [Qt] Fix build break introduced by r61002. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + +2010-05-31 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Implement the simple text code path. + https://bugs.webkit.org/show_bug.cgi?id=40077 + + Remove the FONT_FAST_PATH macro and use the Qt's + fast text implementation instead of the one of WebKit. + + The Qt::TextBypassShaping flag is used to tell Qt to + only use the glyph advances. + + Qt 4.7 is needed to get this flag thus the complex path is always + used if QtWebKit is compiled against an earlier version. + + Contrary to the WebKit's implementation, the complex code path + is taken if the text is RightToLeft, justified or is formatted + with non-zero letter or word spacing. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + +2010-06-10 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Support for loading notification icons + https://bugs.webkit.org/show_bug.cgi?id=40004 + + Take into use the icon that was loaded for the notification. + + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationPresenterClientQt::show): + +2010-06-10 Mahesh Kulkarni <mahesh.kulkarni@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Memory leak in qwebpage unit test cases + https://bugs.webkit.org/show_bug.cgi?id=40405 + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::infiniteLoopJS): + +2010-06-10 Raine Makelainen <raine.makelainen@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Impossible to set input method hints based HTML5 input types + https://bugs.webkit.org/show_bug.cgi?id=40107 + + EditorClientQt to set input method hints for "number", "tel", + "email", and "url" HTML input elements. + + Tests for HTML input elements and input method hints added for + QGraphicsWebView and QWebView. + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::setInputMethodState): + * tests/qgraphicswebview/resources/input_types.html: Added. + * tests/qgraphicswebview/tst_qgraphicswebview.cpp: + (GraphicsWebView::GraphicsWebView): + (GraphicsWebView::fireMouseClick): + (tst_QGraphicsWebView::focusInputTypes): + * tests/qgraphicswebview/tst_qgraphicswebview.qrc: Added. + * tests/qwebview/resources/input_types.html: Added. + * tests/qwebview/tst_qwebview.cpp: + (WebView::fireMouseClick): + (tst_QWebView::focusInputTypes): + * tests/qwebview/tst_qwebview.qrc: + +2010-06-10 Eric Seidel <eric@webkit.org> + + Reviewed by Adam Barth. + + Reduce FrameView.h includes to speed up build times + https://bugs.webkit.org/show_bug.cgi?id=40408 + + * Api/qwebframe.cpp: + - Include RenderLayer.h since it's used in this file. + +2010-06-10 Andy Shaw <andy.shaw@nokia.com> + + Reviewed by Simon Hausmann. + + REGRESSION: [Qt] When dragging onto a page that handles the drag in Javascript it will be a move and not a copy by default + https://bugs.webkit.org/show_bug.cgi?id=40401 + + The correct pattern in Qt for Dnd events is to use acceptProposedAction() instead + of accept(). + + * Api/qwebpage.cpp: + (QWebPagePrivate::dragEnterEvent): + (QWebPagePrivate::dragMoveEvent): + (QWebPagePrivate::dropEvent): + +2010-06-09 Pierre Rossi <pierre.rossi@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + QWebPage::findText() does not clear selection when passed empty string + https://bugs.webkit.org/show_bug.cgi?id=31779 + + * Api/qwebpage.cpp: + (QWebPage::findText): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::findText): + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] PageClientQt.h has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40257 + + * WebCoreSupport/PageClientQt.h: + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] InspectorClientQt.cpp has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40255 + + * WebCoreSupport/InspectorClientQt.cpp: + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] FrameLoaderClientQt.h has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40251 + + * WebCoreSupport/FrameLoaderClientQt.h: + (WebCore::FrameLoaderClientQt::dispatchWillSendSubmitEvent): + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] EditorClientQt.h has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40249 + + * WebCoreSupport/EditorClientQt.h: + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] EditCommandQt.cpp/h have coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40248 + + * WebCoreSupport/EditCommandQt.cpp: + (EditCommandQt::EditCommandQt): + (EditCommandQt::~EditCommandQt): + (EditCommandQt::redo): + (EditCommandQt::undo): + * WebCoreSupport/EditCommandQt.h: + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] DumpRenderTreeSupportQt.cpp has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40247 + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::firstRectForCharacterRange): + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] DragClientQt.cpp has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40246 + + * WebCoreSupport/DragClientQt.cpp: + (WebCore::DragClientQt::startDrag): + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by Laszlo Gombos. + + [Qt] ContextMenuClientQt.h has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40242 + + * WebCoreSupport/ContextMenuClientQt.h: + +2010-06-09 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] ChromeClientQt.cpp has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40240 + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::pageRect): + (WebCore::ChromeClientQt::createWindow): + (WebCore::ChromeClientQt::runJavaScriptAlert): + (WebCore::ChromeClientQt::runJavaScriptConfirm): + (WebCore::ChromeClientQt::runJavaScriptPrompt): + (WebCore::ChromeClientQt::print): + (WebCore::ChromeClientQt::attachRootGraphicsLayer): + (WebCore::ChromeClientQt::visibleRectForTiledBackingStore): + +2010-06-09 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r60889. + http://trac.webkit.org/changeset/60889 + https://bugs.webkit.org/show_bug.cgi?id=40365 + + gtk bot has some kind of memory corruption (Requested by + loislo on #webkit). + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::InspectorClientQt): + (WebCore::InspectorClientQt::openInspectorFrontend): + (WebCore::InspectorFrontendClientQt::InspectorFrontendClientQt): + (WebCore::InspectorFrontendClientQt::closeWindow): + * WebCoreSupport/InspectorClientQt.h: + +2010-06-07 Ilya Tikhonovsky <loislo@chromium.org> + + Reviewed by Pavel Feldman. + + WebInspector: On the way to Remote Debugging we want to transfer dom/timeline/etc + data from inspected page to WebInspector as JSON string via http. The native + serialization to JSON string is supported by InspectorValue's classes. This patch + has the implementation of sendMessageToFrontend function. WebKit version of it still + uses ScriptFunctionCall and will be switched to another transport a little bit later. + https://bugs.webkit.org/show_bug.cgi?id=40134 + + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::InspectorClientQt): + (WebCore::InspectorClientQt::openInspectorFrontend): + (WebCore::InspectorClientQt::releaseFrontendPage): + (WebCore::InspectorClientQt::sendMessageToFrontend): + * WebCoreSupport/InspectorClientQt.h: + +2010-06-08 Antonio Gomes <tonikitoo@webkit.org> + + Reviewed by Ojan Vafai and Darin Adler. + + Refactor platform dependent editing behavior code out of Settings + https://bugs.webkit.org/show_bug.cgi?id=39854 + + EditingBehavior enum was renamed to EditingBehaviorTypes and moved out from Settings.h to + EditingBehaviorTypes.h . Call sites in WebKit/ adjusted accordingly. + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::setEditingBehavior): + +2010-06-07 Anders Bakken <agbakken@gmail.com> + + Reviewed by David Levin. + + [Qt] NotificationPresenterClientQt.cpp has coding-style errors + https://bugs.webkit.org/show_bug.cgi?id=40256 + + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationPresenterClientQt::show): + +2010-06-06 Antonio Gomes <tonikitoo@webkit.org>, Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Christiansen, Eric Seidel. + + [Qt] Expose the editing behavior setting in DRT to test all editing code paths + https://bugs.webkit.org/show_bug.cgi?id=39680 + + Make setEditingBehavior() a no-operation if the editingBehavior + argument is not recognized to avoid using an uninitialized variable. + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::setEditingBehavior): + +2010-06-04 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Symbian build fix. + + [Qt] Updated the def file with recent new exports. + + * symbian/eabi/QtWebKitu.def: + +2010-06-03 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] Don't send notifications event after the page was navigated away + https://bugs.webkit.org/show_bug.cgi?id=40127 + + Added a check before sending events to the notification and before logging. + + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationPresenterClientQt::cancel): + (WebCore::NotificationPresenterClientQt::sendEvent): + +2010-06-02 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Shinichiro Hamaji. + + [Qt] Fix compilation with QT_NO_PROPERTIES + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * Api/qwebpage.cpp: + (QWebPage::event): + * Api/qwebpage_p.h: + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::openInspectorFrontend): + +2010-06-02 Luiz Agostini <luiz.agostini@openbossa.org> + + Reviewed by Simon Hausmann. + + [Qt] Shared platform plugin + https://bugs.webkit.org/show_bug.cgi?id=39968 + + Allow several instances of class QtPlatformPlugin to share the QWebKitPlatformPlugin + object provided by a plugin. + + Updated plugin interface version number due to ABI breaking change. + + * Api/qwebkitplatformplugin.h: + (QWebKitPlatformPlugin::~QWebKitPlatformPlugin): + * WebCoreSupport/QtPlatformPlugin.cpp: + (WebCore::QtPlatformPlugin::load): + (WebCore::QtPlatformPlugin::~QtPlatformPlugin): + (WebCore::QtPlatformPlugin::plugin): + * WebCoreSupport/QtPlatformPlugin.h: + * examples/platformplugin/qwebkitplatformplugin.h: + (QWebKitPlatformPlugin::~QWebKitPlatformPlugin): + +2010-06-02 Raine Makelainen <raine.makelainen@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] On Maemo6 platform auto upper case and predictive text input method hints are not disabled for password field. + https://bugs.webkit.org/show_bug.cgi?id=40062 + + Introducing Q_WS_MAEMO_6 for Maemo6 specific code. Enabling code that sets input + method hints Qt::ImhNoAutoUppercase and Qt::ImhNoPredictiveText true for Maemo6. + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::setInputMethodState): + +2010-06-01 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix the lifecycle of notification objects + https://bugs.webkit.org/show_bug.cgi?id=40003 + + Notification objects are not tightly related to the page that created them, + and should be decoupled from the page. + Create one NotificationPresenter that handles all notifications. + Add ref/deref to the notification objects when they are added/removed from + the queue of active notifications. The same technique is used for XMLHttpRequest. + Instead of deleting all notifications associated with a page when the page is navigated, + delete them on a timer, using the same timeout that QSystemTrayIcon is using. + Break up the show() method into smaller methods. + Use OwnPtr instead of raw pointer for QSystemTrayIcon. + Move creating the QIcon to just before showing it in the QSyetemTrayIcon. + + No new tests as this is just a refactoring. Existing notifications test cover the code. + + * Api/qwebpage.cpp: + (QWebPagePrivate::QWebPagePrivate): + (QWebPagePrivate::~QWebPagePrivate): + * Api/qwebpage_p.h: + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::notificationPresenter): + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (DumpRenderTreeSupportQt::setNotificationsReceiver): + (DumpRenderTreeSupportQt::allowNotificationForOrigin): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld): + * WebCoreSupport/NotificationPresenterClientQt.cpp: + (WebCore::NotificationPresenterClientQt::notificationPresenter): + (WebCore::NotificationIconWrapper::NotificationIconWrapper): + (WebCore::NotificationIconWrapper::~NotificationIconWrapper): + (WebCore::NotificationIconWrapper::close): + (WebCore::NotificationPresenterClientQt::NotificationPresenterClientQt): + (WebCore::NotificationPresenterClientQt::removeClient): + (WebCore::NotificationPresenterClientQt::show): + (WebCore::NotificationPresenterClientQt::displayNotification): + (WebCore::NotificationPresenterClientQt::cancel): + (WebCore::NotificationPresenterClientQt::notificationObjectDestroyed): + (WebCore::NotificationPresenterClientQt::requestPermission): + (WebCore::NotificationPresenterClientQt::sendEvent): + (WebCore::NotificationPresenterClientQt::removeReplacedNotificationFromQueue): + (WebCore::NotificationPresenterClientQt::dumpReplacedIdText): + (WebCore::NotificationPresenterClientQt::dumpShowText): + * WebCoreSupport/NotificationPresenterClientQt.h: + (WebCore::NotificationPresenterClientQt::addClient): + +2010-06-01 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add documentation to the QtWebkit bridge + https://bugs.webkit.org/show_bug.cgi?id=35861 + + This patch includes comprehensive qdoc documentation for the QtWebkit bridge. + + * docs/qtwebkit-bridge.qdoc: Added. + * docs/qtwebkit.qdoc: + * docs/webkitsnippets/doc_src_qtscript.qdoc: Added. + * docs/webkitsnippets/qtwebkit_bridge_snippets.cpp: Added. + (wrapInFunction): + +2010-06-01 Raine Makelainen <raine.makelainen@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt]: REGRESSION(r58703): QWebSettings::JavascriptCanAccessClipboard has wrong case in "Javascript" part. + https://bugs.webkit.org/show_bug.cgi?id=39878 + + QWebSettings::JavaScriptCanAccessClipboard reverted back to + QWebSettings::JavascriptCanAccessClipboard. QWebSettings::DOMPasteAllowed enum removed. + + Value of QWebSettings::JavascriptCanAccessClipboard to setDOMPasteAllowed and + setJavaScriptCanAccessClipboard of WebCore::Settings. + + * Api/qwebsettings.cpp: + (QWebSettingsPrivate::apply): + * Api/qwebsettings.h: + +2010-06-01 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] Rename versioning .pri file to what Qt's mkspecs/features/qt.pri expects. + + * qt_webkit_version.pri: Renamed from WebKit/qt/qtwebkit_version.pri. + 2010-05-31 Lyon Chen <liachen@rim.com> Reviewed by Kent Tamura. diff --git a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index bcb07ee..98ffd8a 100644 --- a/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -29,19 +29,20 @@ #include "config.h" #include "ChromeClientQt.h" +#include "DatabaseTracker.h" #include "FileChooser.h" #include "Frame.h" #include "FrameLoadRequest.h" #include "FrameLoader.h" #include "FrameLoaderClientQt.h" #include "FrameView.h" +#include "Geolocation.h" #include "HitTestResult.h" #include "Icon.h" -#include "NotificationPresenterClientQt.h" #include "NotImplemented.h" +#include "NotificationPresenterClientQt.h" #include "ScrollbarTheme.h" #include "WindowFeatures.h" -#include "DatabaseTracker.h" #if defined(Q_WS_MAEMO_5) #include "QtMaemoWebPopup.h" #else @@ -50,18 +51,18 @@ #include "QWebPageClient.h" #include "SecurityOrigin.h" -#include <qdebug.h> -#include <qeventloop.h> -#include <qtextdocument.h> -#include <qtooltip.h> - +#include "qwebframe_p.h" #include "qwebpage.h" #include "qwebpage_p.h" -#include "qwebframe_p.h" #include "qwebsecurityorigin.h" #include "qwebsecurityorigin_p.h" #include "qwebview.h" +#include <qdebug.h> +#include <qeventloop.h> +#include <qtextdocument.h> +#include <qtooltip.h> + #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayerQt.h" #endif @@ -106,7 +107,7 @@ FloatRect ChromeClientQt::pageRect() { if (!m_webPage) return FloatRect(); - return FloatRect(QRectF(QPointF(0,0), m_webPage->viewportSize())); + return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize())); } @@ -163,7 +164,7 @@ void ChromeClientQt::focusedNodeChanged(WebCore::Node*) Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features) { - QWebPage *newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow); + QWebPage* newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow); if (!newPage) return 0; @@ -290,21 +291,21 @@ void ChromeClientQt::closeWindowSoon() void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg) { QString x = msg; - FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client()); + FrameLoaderClientQt* fl = static_cast<FrameLoaderClientQt*>(f->loader()->client()); m_webPage->javaScriptAlert(fl->webFrame(), x); } bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg) { QString x = msg; - FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client()); + FrameLoaderClientQt* fl = static_cast<FrameLoaderClientQt*>(f->loader()->client()); return m_webPage->javaScriptConfirm(fl->webFrame(), x); } bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result) { QString x = result; - FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client()); + FrameLoaderClientQt* fl = static_cast<FrameLoaderClientQt*>(f->loader()->client()); bool rc = m_webPage->javaScriptPrompt(fl->webFrame(), (QString)message, (QString)defaultValue, &x); // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty @@ -459,7 +460,7 @@ void ChromeClientQt::setToolTip(const String &tip, TextDirection) #endif } -void ChromeClientQt::print(Frame *frame) +void ChromeClientQt::print(Frame* frame) { emit m_webPage->printRequested(QWebFramePrivate::kit(frame)); } @@ -487,7 +488,7 @@ void ChromeClientQt::reachedMaxAppCacheSize(int64_t) #if ENABLE(NOTIFICATIONS) NotificationPresenter* ChromeClientQt::notificationPresenter() const { - return m_webPage->d->notificationPresenterClient; + return NotificationPresenterClientQt::notificationPresenter(); } #endif @@ -534,15 +535,17 @@ bool ChromeClientQt::setCursor(PlatformCursorHandle) return false; } -void ChromeClientQt::requestGeolocationPermissionForFrame(Frame*, Geolocation*) +void ChromeClientQt::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation) { - // See the comment in WebCore/page/ChromeClient.h - notImplemented(); + bool allow = false; + QWebFrame* webFrame = QWebFramePrivate::kit(frame); + QMetaObject::invokeMethod(m_webPage, "allowGeolocationRequest", Qt::DirectConnection, Q_RETURN_ARG(bool, allow), Q_ARG(QWebFrame*, webFrame)); + geolocation->setIsAllowed(allow); } #if USE(ACCELERATED_COMPOSITING) void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer) -{ +{ if (platformPageClient()) platformPageClient()->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->nativeLayer() : 0); } @@ -567,10 +570,10 @@ bool ChromeClientQt::allowsAcceleratedCompositing() const } #endif - + #if ENABLE(TILED_BACKING_STORE) IntRect ChromeClientQt::visibleRectForTiledBackingStore() const -{ +{ if (!platformPageClient() || !m_webPage) return IntRect(); diff --git a/WebKit/qt/WebCoreSupport/ContextMenuClientQt.h b/WebKit/qt/WebCoreSupport/ContextMenuClientQt.h index 8440ff5..1b4475f 100644 --- a/WebKit/qt/WebCoreSupport/ContextMenuClientQt.h +++ b/WebKit/qt/WebCoreSupport/ContextMenuClientQt.h @@ -31,23 +31,22 @@ #include <RefCounted.h> namespace WebCore { - class ContextMenu; - - class ContextMenuClientQt : public ContextMenuClient - { - public: - virtual void contextMenuDestroyed(); - - virtual PlatformMenuDescription getCustomMenuFromDefaultItems(ContextMenu*); - virtual void contextMenuItemSelected(ContextMenuItem*, const ContextMenu*); - - virtual void downloadURL(const KURL& url); - virtual void lookUpInDictionary(Frame*); - virtual void speak(const String&); - virtual bool isSpeaking(); - virtual void stopSpeaking(); - virtual void searchWithGoogle(const Frame*); - }; +class ContextMenu; + +class ContextMenuClientQt : public ContextMenuClient { +public: + virtual void contextMenuDestroyed(); + + virtual PlatformMenuDescription getCustomMenuFromDefaultItems(ContextMenu*); + virtual void contextMenuItemSelected(ContextMenuItem*, const ContextMenu*); + + virtual void downloadURL(const KURL& url); + virtual void lookUpInDictionary(Frame*); + virtual void speak(const String&); + virtual bool isSpeaking(); + virtual void stopSpeaking(); + virtual void searchWithGoogle(const Frame*); +}; } #endif diff --git a/WebKit/qt/WebCoreSupport/DragClientQt.cpp b/WebKit/qt/WebCoreSupport/DragClientQt.cpp index e48c3e3..52229dc 100644 --- a/WebKit/qt/WebCoreSupport/DragClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/DragClientQt.cpp @@ -93,7 +93,7 @@ void DragClientQt::startDrag(DragImageRef, const IntPoint&, const IntPoint&, Cli static_cast<ClipboardQt*>(clipboard)->invalidateWritableData(); QWidget* view = m_webPage->view(); if (view) { - QDrag *drag = new QDrag(view); + QDrag* drag = new QDrag(view); if (clipboardData && clipboardData->hasImage()) drag->setPixmap(qvariant_cast<QPixmap>(clipboardData->imageData())); DragOperation dragOperationMask = clipboard->sourceOperation(); diff --git a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp index 0b2e9a5..c92e43f 100644 --- a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp +++ b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp @@ -35,12 +35,17 @@ #include "FrameLoaderClientQt.h" #include "FrameView.h" #include "GCController.h" +#include "Geolocation.h" +#include "GeolocationServiceMock.h" +#include "Geoposition.h" +#include "HistoryItem.h" #include "HTMLInputElement.h" #include "InspectorController.h" #include "NotificationPresenterClientQt.h" #include "Page.h" #include "PageGroup.h" #include "PluginDatabase.h" +#include "PositionError.h" #include "PrintContext.h" #include "RenderListItem.h" #include "RenderTreeAsText.h" @@ -51,10 +56,13 @@ #endif #include "TextIterator.h" #include "WorkerThread.h" +#include <wtf/CurrentTime.h> #include "qwebelement.h" #include "qwebframe.h" #include "qwebframe_p.h" +#include "qwebhistory.h" +#include "qwebhistory_p.h" #include "qwebpage.h" #include "qwebpage_p.h" @@ -437,7 +445,7 @@ QVariantList DumpRenderTreeSupportQt::firstRectForCharacterRange(QWebPage* page, WebCore::Frame* frame = page->handle()->page->focusController()->focusedOrMainFrame(); QVariantList rect; - if ((location + length < location) && (location + length != 0)) + if ((location + length < location) && (location + length)) length = 0; Element* selectionRoot = frame->selection()->rootEditableElement(); @@ -476,18 +484,22 @@ bool DumpRenderTreeSupportQt::elementDoesAutoCompleteForElementWithId(QWebFrame* void DumpRenderTreeSupportQt::setEditingBehavior(QWebPage* page, const QString& editingBehavior) { - WebCore::EditingBehavior coreEditingBehavior; + WebCore::EditingBehaviorType coreEditingBehavior; if (editingBehavior == "win") coreEditingBehavior = EditingWindowsBehavior; else if (editingBehavior == "mac") coreEditingBehavior = EditingMacBehavior; + else { + ASSERT_NOT_REACHED(); + return; + } Page* corePage = QWebPagePrivate::core(page); if (!corePage) return; - corePage->settings()->setEditingBehavior(coreEditingBehavior); + corePage->settings()->setEditingBehaviorType(coreEditingBehavior); } void DumpRenderTreeSupportQt::dumpFrameLoader(bool b) @@ -537,17 +549,33 @@ void DumpRenderTreeSupportQt::dumpNotification(bool b) #endif } -void DumpRenderTreeSupportQt::setNotificationsReceiver(QWebPage* page, QObject* receiver) +void DumpRenderTreeSupportQt::setNotificationsReceiver(QObject* receiver) { #if ENABLE(NOTIFICATIONS) - page->d->notificationPresenterClient->setReceiver(receiver); + NotificationPresenterClientQt::notificationPresenter()->setReceiver(receiver); #endif } -void DumpRenderTreeSupportQt::allowNotificationForOrigin(QWebPage* page, const QString& origin) +void DumpRenderTreeSupportQt::allowNotificationForOrigin(const QString& origin) { #if ENABLE(NOTIFICATIONS) - page->d->notificationPresenterClient->allowNotificationForOrigin(origin); + NotificationPresenterClientQt::notificationPresenter()->allowNotificationForOrigin(origin); +#endif +} + +void DumpRenderTreeSupportQt::setMockGeolocationPosition(double latitude, double longitude, double accuracy) +{ +#if ENABLE(GEOLOCATION) + RefPtr<Geoposition> geoposition = Geoposition::create(Coordinates::create(latitude, longitude, false, 0, accuracy, true, 0, false, 0, false, 0), currentTime() * 1000.0); + GeolocationServiceMock::setPosition(geoposition); +#endif +} + +void DumpRenderTreeSupportQt::setMockGeolocationError(int errorCode, const QString& message) +{ +#if ENABLE(GEOLOCATION) + RefPtr<PositionError> positionError = PositionError::create(static_cast<PositionError::ErrorCode>(errorCode), message); + GeolocationServiceMock::setError(positionError); #endif } @@ -561,6 +589,41 @@ void DumpRenderTreeSupportQt::setRequestPermissionFunction(RequestPermissionFunc requestPermissionFunction = f; } +bool DumpRenderTreeSupportQt::isTargetItem(const QWebHistoryItem& historyItem) +{ + QWebHistoryItem it = historyItem; + if (QWebHistoryItemPrivate::core(&it)->isTargetItem()) + return true; + return false; +} + +QString DumpRenderTreeSupportQt::historyItemTarget(const QWebHistoryItem& historyItem) +{ + QWebHistoryItem it = historyItem; + return (QWebHistoryItemPrivate::core(&it)->target()); +} + +QList<QWebHistoryItem> DumpRenderTreeSupportQt::getChildHistoryItems(const QWebHistoryItem& historyItem) +{ + QWebHistoryItem it = historyItem; + HistoryItem* item = QWebHistoryItemPrivate::core(&it); + const WebCore::HistoryItemVector& children = item->children(); + + unsigned size = children.size(); + QList<QWebHistoryItem> kids; + for (unsigned i = 0; i < size; ++i) { + QWebHistoryItem kid(new QWebHistoryItemPrivate(children[i].get())); + kids.prepend(kid); + } + return kids; +} + +bool DumpRenderTreeSupportQt::shouldClose(QWebFrame* frame) +{ + WebCore::Frame* coreFrame = QWebFramePrivate::core(frame); + return coreFrame->shouldClose(); +} + // Provide a backward compatibility with previously exported private symbols as of QtWebKit 4.6 release void QWEBKIT_EXPORT qt_resumeActiveDOMObjects(QWebFrame* frame) diff --git a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h index 0d348cf..e3408e3 100644 --- a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h +++ b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h @@ -29,6 +29,7 @@ class QWebElement; class QWebFrame; class QWebPage; +class QWebHistoryItem; enum NotificationPermission { NotificationAllowed, @@ -37,7 +38,7 @@ enum NotificationPermission { }; typedef void (CheckPermissionFunctionType) (QObject* receiver, const QUrl&, NotificationPermission&); -typedef void (RequestPermissionFunctionType) (QObject* receiver, QWebPage* page, const QString&); +typedef void (RequestPermissionFunctionType) (QObject* receiver, const QString&); extern CheckPermissionFunctionType* checkPermissionFunction; extern RequestPermissionFunctionType* requestPermissionFunction; @@ -96,6 +97,9 @@ public: static void removeWhiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains); static void resetOriginAccessWhiteLists(); + static void setMockGeolocationPosition(double latitude, double longitude, double accuracy); + static void setMockGeolocationError(int errorCode, const QString& message); + static int workerThreadCount(); static QString markerTextForListItem(const QWebElement& listItem); @@ -114,10 +118,16 @@ public: static void dumpNotification(bool b); // These functions should eventually turn into public API // and the "receiver" concept would go away - static void setNotificationsReceiver(QWebPage* page, QObject* receiver); - static void allowNotificationForOrigin(QWebPage* page, const QString& origin); + static void setNotificationsReceiver(QObject* receiver); + static void allowNotificationForOrigin(const QString& origin); static void setCheckPermissionFunction(CheckPermissionFunctionType*); static void setRequestPermissionFunction(RequestPermissionFunctionType*); + + static QList<QWebHistoryItem> getChildHistoryItems(const QWebHistoryItem& historyItem); + static bool isTargetItem(const QWebHistoryItem& historyItem); + static QString historyItemTarget(const QWebHistoryItem& historyItem); + + static bool shouldClose(QWebFrame* frame); }; #endif diff --git a/WebKit/qt/WebCoreSupport/EditCommandQt.cpp b/WebKit/qt/WebCoreSupport/EditCommandQt.cpp index 756ba4c..9c4ff87 100644 --- a/WebKit/qt/WebCoreSupport/EditCommandQt.cpp +++ b/WebKit/qt/WebCoreSupport/EditCommandQt.cpp @@ -27,30 +27,31 @@ EditCommandQt::EditCommandQt(WTF::RefPtr<EditCommand> cmd, QUndoCommand *parent) #ifndef QT_NO_UNDOCOMMAND QUndoCommand(parent), #endif - _cmd(cmd), _first(true) + m_cmd(cmd), m_first(true) { } -EditCommandQt::~EditCommandQt() { +EditCommandQt::~EditCommandQt() +{ } -void EditCommandQt::redo() { - if (_first) { - _first = false; +void EditCommandQt::redo() +{ + if (m_first) { + m_first = false; return; } - if (_cmd) { - _cmd->reapply(); - } + if (m_cmd) + m_cmd->reapply(); } -void EditCommandQt::undo() { - if (_cmd) { - _cmd->unapply(); - } +void EditCommandQt::undo() +{ + if (m_cmd) + m_cmd->unapply(); } diff --git a/WebKit/qt/WebCoreSupport/EditCommandQt.h b/WebKit/qt/WebCoreSupport/EditCommandQt.h index ae6ea51..e03b9b2 100644 --- a/WebKit/qt/WebCoreSupport/EditCommandQt.h +++ b/WebKit/qt/WebCoreSupport/EditCommandQt.h @@ -17,16 +17,12 @@ Boston, MA 02110-1301, USA. */ -#ifndef EDITCOMMANDQT_H -#define EDITCOMMANDQT_H +#ifndef EditCommandQt_h +#define EditCommandQt_h -#include <qglobal.h> -QT_BEGIN_NAMESPACE -class QUndoCommand; -QT_END_NAMESPACE - -#include <QUndoCommand> #include <EditCommand.h> +#include <QUndoCommand> +#include <qglobal.h> class EditCommandQt #ifndef QT_NO_UNDOCOMMAND @@ -41,8 +37,8 @@ class EditCommandQt void undo(); private: - WTF::RefPtr<WebCore::EditCommand> _cmd; - bool _first; + WTF::RefPtr<WebCore::EditCommand> m_cmd; + bool m_first; }; #endif diff --git a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 0f54e21..93e5745 100644 --- a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -592,25 +592,33 @@ void EditorClientQt::setInputMethodState(bool active) QWebPageClient* webPageClient = m_page->d->client; if (webPageClient) { #if QT_VERSION >= 0x040600 - bool isPasswordField = false; - if (!active) { - // Setting the Qt::WA_InputMethodEnabled attribute true and Qt::ImhHiddenText flag - // for password fields. The Qt platform is responsible for determining which widget - // will receive input method events for password fields. - Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame(); - if (frame && frame->document() && frame->document()->focusedNode()) { - if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { - HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); - active = isPasswordField = inputElement->isPasswordField(); - } + HTMLInputElement* inputElement = 0; + Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame(); + if (frame && frame->document() && frame->document()->focusedNode()) + if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) + inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); + + if (inputElement) { + if (!active) { + // Setting the Qt::WA_InputMethodEnabled attribute true and Qt::ImhHiddenText flag + // for password fields. The Qt platform is responsible for determining which widget + // will receive input method events for password fields. + active = inputElement->isPasswordField(); + webPageClient->setInputMethodHint(Qt::ImhHiddenText, active); + } else { + // Set input method hints for "number", "tel", "email", and "url" input elements. + webPageClient->setInputMethodHint(Qt::ImhDialableCharactersOnly, inputElement->isTelephoneField()); + webPageClient->setInputMethodHint(Qt::ImhDigitsOnly, inputElement->isNumberField()); + webPageClient->setInputMethodHint(Qt::ImhEmailCharactersOnly, inputElement->isEmailField()); + webPageClient->setInputMethodHint(Qt::ImhUrlCharactersOnly, inputElement->isUrlField()); } } - webPageClient->setInputMethodHint(Qt::ImhHiddenText, isPasswordField); -#if defined(Q_WS_MAEMO_5) || defined(Q_OS_SYMBIAN) + +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) || defined(Q_OS_SYMBIAN) // disables auto-uppercase and predictive text for mobile devices webPageClient->setInputMethodHint(Qt::ImhNoAutoUppercase, true); webPageClient->setInputMethodHint(Qt::ImhNoPredictiveText, true); -#endif // Q_WS_MAEMO_5 || Q_OS_SYMBIAN +#endif // Q_WS_MAEMO_5 || Q_WS_MAEMO_6 || Q_OS_SYMBIAN #endif // QT_VERSION check webPageClient->setInputMethodEnabled(active); } diff --git a/WebKit/qt/WebCoreSupport/EditorClientQt.h b/WebKit/qt/WebCoreSupport/EditorClientQt.h index 811298b..a5f6b23 100644 --- a/WebKit/qt/WebCoreSupport/EditorClientQt.h +++ b/WebKit/qt/WebCoreSupport/EditorClientQt.h @@ -27,8 +27,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EditorClientQt_H -#define EditorClientQt_H +#ifndef EditorClientQt_h +#define EditorClientQt_h #include "EditorClient.h" #include "RefCounted.h" diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index 3cf19a6..e86a84a 100644 --- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -51,7 +51,6 @@ #include "HTMLFormElement.h" #include "HTMLPlugInElement.h" #include "HTTPParsers.h" -#include "NotificationPresenterClientQt.h" #include "NotImplemented.h" #include "QNetworkReplyHandler.h" #include "ResourceHandleInternal.h" @@ -543,14 +542,16 @@ void FrameLoaderClientQt::finishedLoading(DocumentLoader* loader) bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const { - if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType)) + String type = MIMEType; + type.makeLower(); + if (MIMETypeRegistry::isSupportedImageMIMEType(type)) return true; - if (MIMETypeRegistry::isSupportedNonImageMIMEType(MIMEType)) + if (MIMETypeRegistry::isSupportedNonImageMIMEType(type)) return true; if (m_frame && m_frame->settings() && m_frame->settings()->arePluginsEnabled() - && PluginDatabase::installedPlugins()->isMIMETypeRegistered(MIMEType)) + && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type)) return true; return false; @@ -641,9 +642,6 @@ void FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* w if (m_webFrame) { emit m_webFrame->javaScriptWindowObjectCleared(); -#if ENABLE(NOTIFICATIONS) - m_webFrame->page()->d->notificationPresenterClient->clearNotificationsList(); -#endif } } diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h index 9aa9344..d858589 100644 --- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h +++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h @@ -27,210 +27,210 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef FrameLoaderClientQt_H -#define FrameLoaderClientQt_H +#ifndef FrameLoaderClientQt_h +#define FrameLoaderClientQt_h -#include <qobject.h> -#include <QUrl> -#include "FrameLoaderClient.h" -#include "KURL.h" #include "Frame.h" #include "FrameLoader.h" +#include "FrameLoaderClient.h" +#include "KURL.h" +#include "PluginView.h" #include "RefCounted.h" #include "ResourceResponse.h" -#include "PluginView.h" +#include <QUrl> +#include <qobject.h> class QWebFrame; namespace WebCore { - class AuthenticationChallenge; - class DocumentLoader; - class Element; - class FormState; - class NavigationAction; - class String; - class ResourceLoader; - - struct LoadErrorResetToken; - - class FrameLoaderClientQt : public QObject, public FrameLoaderClient { - Q_OBJECT - - friend class ::QWebFrame; - void callPolicyFunction(FramePolicyFunction function, PolicyAction action); - void callErrorPageExtension(const ResourceError&); - signals: - void loadStarted(); - void loadProgress(int d); - void loadFinished(bool); - void titleChanged(const QString& title); - - public: - FrameLoaderClientQt(); - ~FrameLoaderClientQt(); - virtual void frameLoaderDestroyed(); - - void setFrame(QWebFrame* webFrame, Frame* frame); - QWebFrame* webFrame() const; - - virtual bool hasWebView() const; // mainly for assertions - - virtual void makeRepresentation(DocumentLoader*); - virtual void forceLayout(); - virtual void forceLayoutForNonHTML(); - - virtual void setCopiesOnScroll(); - - virtual void detachedFromParent2(); - virtual void detachedFromParent3(); - - virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&); - - virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long, WebCore::ResourceRequest&, const WebCore::ResourceResponse&); - virtual bool shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier); - virtual void dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); - virtual void dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); - virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long, const WebCore::ResourceResponse&); - virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int); - virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long); - virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long, const WebCore::ResourceError&); - virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int); - - virtual void dispatchDidHandleOnloadEvents(); - virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); - virtual void dispatchDidCancelClientRedirect(); - virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate); - virtual void dispatchDidChangeLocationWithinPage(); - virtual void dispatchDidPushStateWithinPage(); - virtual void dispatchDidReplaceStateWithinPage(); - virtual void dispatchDidPopStateWithinPage(); - virtual void dispatchWillClose(); - virtual void dispatchDidReceiveIcon(); - virtual void dispatchDidStartProvisionalLoad(); - virtual void dispatchDidReceiveTitle(const String& title); - virtual void dispatchDidChangeIcons(); - virtual void dispatchDidCommitLoad(); - virtual void dispatchDidFailProvisionalLoad(const ResourceError&); - virtual void dispatchDidFailLoad(const WebCore::ResourceError&); - virtual void dispatchDidFinishDocumentLoad(); - virtual void dispatchDidFinishLoad(); - virtual void dispatchDidFirstLayout(); - virtual void dispatchDidFirstVisuallyNonEmptyLayout(); - - virtual WebCore::Frame* dispatchCreatePage(); - virtual void dispatchShow(); - - virtual void dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const WebCore::String&, const WebCore::ResourceRequest&); - virtual void dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<FormState>, const WebCore::String&); - virtual void dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<FormState>); - virtual void cancelPolicyCheck(); - - virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&); - - virtual void dispatchWillSendSubmitEvent(HTMLFormElement*) { } - virtual void dispatchWillSubmitForm(FramePolicyFunction, PassRefPtr<FormState>); - - virtual void dispatchDidLoadMainResource(DocumentLoader*); - virtual void revertToProvisionalState(DocumentLoader*); - virtual void setMainDocumentError(DocumentLoader*, const ResourceError&); - - virtual void postProgressStartedNotification(); - virtual void postProgressEstimateChangedNotification(); - virtual void postProgressFinishedNotification(); - - virtual void setMainFrameDocumentReady(bool); - - virtual void startDownload(const WebCore::ResourceRequest&); - - virtual void willChangeTitle(DocumentLoader*); - virtual void didChangeTitle(DocumentLoader*); - - virtual void committedLoad(WebCore::DocumentLoader*, const char*, int); - virtual void finishedLoading(DocumentLoader*); - - virtual void updateGlobalHistory(); - virtual void updateGlobalHistoryRedirectLinks(); - virtual bool shouldGoToHistoryItem(HistoryItem*) const; - virtual void dispatchDidAddBackForwardItem(HistoryItem*) const; - virtual void dispatchDidRemoveBackForwardItem(HistoryItem*) const; - virtual void dispatchDidChangeBackForwardIndex() const; - virtual void didDisplayInsecureContent(); - virtual void didRunInsecureContent(SecurityOrigin*); - - virtual ResourceError cancelledError(const ResourceRequest&); - virtual ResourceError blockedError(const ResourceRequest&); - virtual ResourceError cannotShowURLError(const ResourceRequest&); - virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&); - - virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&); - virtual ResourceError fileDoesNotExistError(const ResourceResponse&); - virtual ResourceError pluginWillHandleLoadError(const ResourceResponse&); - - virtual bool shouldFallBack(const ResourceError&); - - virtual bool canHandleRequest(const WebCore::ResourceRequest&) const; - virtual bool canShowMIMEType(const String& MIMEType) const; - virtual bool representationExistsForURLScheme(const String& URLScheme) const; - virtual String generatedMIMETypeForURLScheme(const String& URLScheme) const; - - virtual void frameLoadCompleted(); - virtual void saveViewStateToItem(WebCore::HistoryItem*); - virtual void restoreViewState(); - virtual void provisionalLoadStarted(); - virtual void didFinishLoad(); - virtual void prepareForDataSourceReplacement(); - - virtual WTF::PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); - virtual void setTitle(const String& title, const KURL&); - - virtual String userAgent(const WebCore::KURL&); - - virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*); - virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*); - virtual void transitionToCommittedForNewPage(); - - virtual bool canCachePage() const; - virtual void download(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&); - - virtual PassRefPtr<Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, - const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) ; - virtual void didTransferChildFrameToNewDocument(); - virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool); - virtual void redirectDataToPlugin(Widget* pluginWidget); - - virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues); - - virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType); - virtual String overrideMediaType() const; - - virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*); - virtual void documentElementAvailable(); - virtual void didPerformFirstNavigation() const; - - virtual void registerForIconNotification(bool); +class AuthenticationChallenge; +class DocumentLoader; +class Element; +class FormState; +class NavigationAction; +class String; +class ResourceLoader; + +struct LoadErrorResetToken; + +class FrameLoaderClientQt : public QObject, public FrameLoaderClient { + Q_OBJECT + + friend class ::QWebFrame; + void callPolicyFunction(FramePolicyFunction function, PolicyAction action); + void callErrorPageExtension(const ResourceError&); +signals: + void loadStarted(); + void loadProgress(int d); + void loadFinished(bool); + void titleChanged(const QString& title); + +public: + FrameLoaderClientQt(); + ~FrameLoaderClientQt(); + virtual void frameLoaderDestroyed(); + + void setFrame(QWebFrame* webFrame, Frame* frame); + QWebFrame* webFrame() const; + + virtual bool hasWebView() const; // mainly for assertions + + virtual void makeRepresentation(DocumentLoader*); + virtual void forceLayout(); + virtual void forceLayoutForNonHTML(); + + virtual void setCopiesOnScroll(); + + virtual void detachedFromParent2(); + virtual void detachedFromParent3(); + + virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&); + + virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long, WebCore::ResourceRequest&, const WebCore::ResourceResponse&); + virtual bool shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier); + virtual void dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); + virtual void dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); + virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long, const WebCore::ResourceResponse&); + virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int); + virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long); + virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long, const WebCore::ResourceError&); + virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int); + + virtual void dispatchDidHandleOnloadEvents(); + virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); + virtual void dispatchDidCancelClientRedirect(); + virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate); + virtual void dispatchDidChangeLocationWithinPage(); + virtual void dispatchDidPushStateWithinPage(); + virtual void dispatchDidReplaceStateWithinPage(); + virtual void dispatchDidPopStateWithinPage(); + virtual void dispatchWillClose(); + virtual void dispatchDidReceiveIcon(); + virtual void dispatchDidStartProvisionalLoad(); + virtual void dispatchDidReceiveTitle(const String& title); + virtual void dispatchDidChangeIcons(); + virtual void dispatchDidCommitLoad(); + virtual void dispatchDidFailProvisionalLoad(const ResourceError&); + virtual void dispatchDidFailLoad(const WebCore::ResourceError&); + virtual void dispatchDidFinishDocumentLoad(); + virtual void dispatchDidFinishLoad(); + virtual void dispatchDidFirstLayout(); + virtual void dispatchDidFirstVisuallyNonEmptyLayout(); + + virtual WebCore::Frame* dispatchCreatePage(); + virtual void dispatchShow(); + + virtual void dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const WebCore::String&, const WebCore::ResourceRequest&); + virtual void dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<FormState>, const WebCore::String&); + virtual void dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<FormState>); + virtual void cancelPolicyCheck(); + + virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&); + + virtual void dispatchWillSendSubmitEvent(HTMLFormElement*) { } + virtual void dispatchWillSubmitForm(FramePolicyFunction, PassRefPtr<FormState>); + + virtual void dispatchDidLoadMainResource(DocumentLoader*); + virtual void revertToProvisionalState(DocumentLoader*); + virtual void setMainDocumentError(DocumentLoader*, const ResourceError&); + + virtual void postProgressStartedNotification(); + virtual void postProgressEstimateChangedNotification(); + virtual void postProgressFinishedNotification(); + + virtual void setMainFrameDocumentReady(bool); + + virtual void startDownload(const WebCore::ResourceRequest&); + + virtual void willChangeTitle(DocumentLoader*); + virtual void didChangeTitle(DocumentLoader*); + + virtual void committedLoad(WebCore::DocumentLoader*, const char*, int); + virtual void finishedLoading(DocumentLoader*); + + virtual void updateGlobalHistory(); + virtual void updateGlobalHistoryRedirectLinks(); + virtual bool shouldGoToHistoryItem(HistoryItem*) const; + virtual void dispatchDidAddBackForwardItem(HistoryItem*) const; + virtual void dispatchDidRemoveBackForwardItem(HistoryItem*) const; + virtual void dispatchDidChangeBackForwardIndex() const; + virtual void didDisplayInsecureContent(); + virtual void didRunInsecureContent(SecurityOrigin*); + + virtual ResourceError cancelledError(const ResourceRequest&); + virtual ResourceError blockedError(const ResourceRequest&); + virtual ResourceError cannotShowURLError(const ResourceRequest&); + virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&); + + virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&); + virtual ResourceError fileDoesNotExistError(const ResourceResponse&); + virtual ResourceError pluginWillHandleLoadError(const ResourceResponse&); + + virtual bool shouldFallBack(const ResourceError&); + + virtual bool canHandleRequest(const WebCore::ResourceRequest&) const; + virtual bool canShowMIMEType(const String& MIMEType) const; + virtual bool representationExistsForURLScheme(const String& URLScheme) const; + virtual String generatedMIMETypeForURLScheme(const String& URLScheme) const; + + virtual void frameLoadCompleted(); + virtual void saveViewStateToItem(WebCore::HistoryItem*); + virtual void restoreViewState(); + virtual void provisionalLoadStarted(); + virtual void didFinishLoad(); + virtual void prepareForDataSourceReplacement(); + + virtual WTF::PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); + virtual void setTitle(const String& title, const KURL&); + + virtual String userAgent(const WebCore::KURL&); + + virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*); + virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*); + virtual void transitionToCommittedForNewPage(); + + virtual bool canCachePage() const; + virtual void download(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&); + + virtual PassRefPtr<Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, + const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); + virtual void didTransferChildFrameToNewDocument(); + virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool); + virtual void redirectDataToPlugin(Widget* pluginWidget); + + virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues); + + virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType); + virtual String overrideMediaType() const; + + virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*); + virtual void documentElementAvailable(); + virtual void didPerformFirstNavigation() const; + + virtual void registerForIconNotification(bool); - QString chooseFile(const QString& oldFile); + QString chooseFile(const QString& oldFile); - static bool dumpFrameLoaderCallbacks; - static bool dumpResourceLoadCallbacks; - static QString dumpResourceLoadCallbacksPath; - static bool sendRequestReturnsNullOnRedirect; - static bool sendRequestReturnsNull; - static QStringList sendRequestClearHeaders; + static bool dumpFrameLoaderCallbacks; + static bool dumpResourceLoadCallbacks; + static QString dumpResourceLoadCallbacksPath; + static bool sendRequestReturnsNullOnRedirect; + static bool sendRequestReturnsNull; + static QStringList sendRequestClearHeaders; - private: - Frame *m_frame; - QWebFrame *m_webFrame; - ResourceResponse m_response; - bool m_firstData; +private: + Frame *m_frame; + QWebFrame *m_webFrame; + ResourceResponse m_response; + bool m_firstData; - // Plugin view to redirect data to - WebCore::PluginView* m_pluginView; - bool m_hasSentResponseToPlugin; + // Plugin view to redirect data to + WebCore::PluginView* m_pluginView; + bool m_hasSentResponseToPlugin; - ResourceError m_loadError; - }; + ResourceError m_loadError; +}; } diff --git a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp index 725c5fb..fde0556 100644 --- a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp @@ -31,19 +31,19 @@ #include "config.h" #include "InspectorClientQt.h" +#include "Frame.h" +#include "InspectorController.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PlatformString.h" +#include "ScriptController.h" #include "qwebinspector.h" #include "qwebinspector_p.h" #include "qwebpage.h" #include "qwebpage_p.h" #include "qwebview.h" - -#include <QtCore/QSettings> #include <QtCore/QCoreApplication> - -#include "InspectorController.h" -#include "NotImplemented.h" -#include "Page.h" -#include "PlatformString.h" +#include <QtCore/QSettings> namespace WebCore { @@ -74,6 +74,7 @@ public: InspectorClientQt::InspectorClientQt(QWebPage* page) : m_inspectedWebPage(page) + , m_frontendWebPage(0) {} void InspectorClientQt::inspectorDestroyed() @@ -93,14 +94,23 @@ void InspectorClientQt::openInspectorFrontend(WebCore::InspectorController*) // Web inspector. This is used for SDK purposes. Please keep this hook // around and don't remove it. // https://bugs.webkit.org/show_bug.cgi?id=35340 - QUrl inspectorUrl = inspector->property("_q_inspectorUrl").toUrl(); + QUrl inspectorUrl; +#ifndef QT_NO_PROPERTIES + inspectorUrl = inspector->property("_q_inspectorUrl").toUrl(); +#endif if (!inspectorUrl.isValid()) inspectorUrl = QUrl("qrc:/webkit/inspector/inspector.html"); inspectorView->page()->mainFrame()->load(inspectorUrl); m_inspectedWebPage->d->inspectorFrontend = inspectorView; inspector->d->setFrontend(inspectorView); - inspectorView->page()->d->page->inspectorController()->setInspectorFrontendClient(new InspectorFrontendClientQt(m_inspectedWebPage, inspectorView)); + inspectorView->page()->d->page->inspectorController()->setInspectorFrontendClient(new InspectorFrontendClientQt(m_inspectedWebPage, inspectorView, this)); + m_frontendWebPage = inspectorPage; +} + +void InspectorClientQt::releaseFrontendPage() +{ + m_frontendWebPage = 0; } void InspectorClientQt::highlight(Node*) @@ -157,6 +167,30 @@ void InspectorClientQt::storeSetting(const String& key, const String& setting) #endif // QT_NO_SETTINGS } +bool InspectorClientQt::sendMessageToFrontend(const String& message) +{ + if (!m_frontendWebPage) + return false; + + Page* frontendPage = QWebPagePrivate::core(m_frontendWebPage); + if (!frontendPage) + return false; + + Frame* frame = frontendPage->mainFrame(); + if (!frame) + return false; + + ScriptController* scriptController = frame->script(); + if (!scriptController) + return false; + + String dispatchToFrontend("WebInspector.dispatchMessageToFrontend("); + dispatchToFrontend += message; + dispatchToFrontend += ");"; + scriptController->executeScript(dispatchToFrontend); + return true; +} + static String variantToSetting(const QVariant& qvariant) { String retVal; @@ -180,11 +214,12 @@ static QVariant settingToVariant(const String& setting) return retVal; } -InspectorFrontendClientQt::InspectorFrontendClientQt(QWebPage* inspectedWebPage, PassOwnPtr<QWebView> inspectorView) +InspectorFrontendClientQt::InspectorFrontendClientQt(QWebPage* inspectedWebPage, PassOwnPtr<QWebView> inspectorView, InspectorClientQt* inspectorClient) : InspectorFrontendClientLocal(inspectedWebPage->d->page->inspectorController(), inspectorView->page()->d->page) , m_inspectedWebPage(inspectedWebPage) , m_inspectorView(inspectorView) , m_destroyingInspectorView(false) + , m_inspectorClient(inspectorClient) { } @@ -222,6 +257,8 @@ void InspectorFrontendClientQt::closeWindow() #if ENABLE(INSPECTOR) m_inspectedWebPage->d->inspectorController()->disconnectFrontend(); #endif + m_inspectorClient->releaseFrontendPage(); + // Clear pointer before deleting WebView to avoid recursive calls to its destructor. delete m_inspectorView.release(); } diff --git a/WebKit/qt/WebCoreSupport/InspectorClientQt.h b/WebKit/qt/WebCoreSupport/InspectorClientQt.h index 4beadab..c996f55 100644 --- a/WebKit/qt/WebCoreSupport/InspectorClientQt.h +++ b/WebKit/qt/WebCoreSupport/InspectorClientQt.h @@ -58,13 +58,18 @@ public: virtual void populateSetting(const String& key, String* value); virtual void storeSetting(const String& key, const String& value); + virtual bool sendMessageToFrontend(const String&); + + void releaseFrontendPage(); + private: QWebPage* m_inspectedWebPage; + QWebPage* m_frontendWebPage; }; class InspectorFrontendClientQt : public InspectorFrontendClientLocal { public: - InspectorFrontendClientQt(QWebPage* inspectedWebPage, PassOwnPtr<QWebView> inspectorView); + InspectorFrontendClientQt(QWebPage* inspectedWebPage, PassOwnPtr<QWebView> inspectorView, InspectorClientQt* inspectorClient); virtual void frontendLoaded(); @@ -88,6 +93,7 @@ private: OwnPtr<QWebView> m_inspectorView; QString m_inspectedURL; bool m_destroyingInspectorView; + InspectorClientQt* m_inspectorClient; }; } diff --git a/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp b/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp index f76868d..8bde5c4 100644 --- a/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.cpp @@ -32,106 +32,209 @@ #include "config.h" #include "NotificationPresenterClientQt.h" -#include "DumpRenderTreeSupportQt.h" #include "Document.h" +#include "DumpRenderTreeSupportQt.h" #include "EventNames.h" #include "KURL.h" +#include "QtPlatformPlugin.h" #include "SecurityOrigin.h" -#include "qwebframe.h" #include "qwebkitglobal.h" -#include "qwebpage.h" #include <QtGui> - #if ENABLE(NOTIFICATIONS) -using namespace WebCore; +namespace WebCore { + +const double notificationTimeout = 10.0; bool NotificationPresenterClientQt::dumpNotification = false; +NotificationPresenterClientQt* s_notificationPresenter = 0; + +NotificationPresenterClientQt* NotificationPresenterClientQt::notificationPresenter() +{ + if (s_notificationPresenter) + return s_notificationPresenter; + + s_notificationPresenter = new NotificationPresenterClientQt(); + return s_notificationPresenter; +} + NotificationIconWrapper::NotificationIconWrapper() + : m_closeTimer(this, &NotificationIconWrapper::close) { #ifndef QT_NO_SYSTEMTRAYICON m_notificationIcon = 0; #endif + m_presenter = 0; } NotificationIconWrapper::~NotificationIconWrapper() { -#ifndef QT_NO_SYSTEMTRAYICON - delete m_notificationIcon; -#endif } -NotificationPresenterClientQt::NotificationPresenterClientQt(QWebPage* page) : m_page(page) +void NotificationIconWrapper::close(Timer<NotificationIconWrapper>*) { + NotificationPresenterClientQt::notificationPresenter()->cancel(this); } -bool NotificationPresenterClientQt::show(Notification* notification) +const QString NotificationIconWrapper::title() const { - QHash <Notification*, NotificationIconWrapper*>::Iterator end = m_notifications.end(); - QHash <Notification*, NotificationIconWrapper*>::Iterator iter = m_notifications.begin(); + Notification* notification = NotificationPresenterClientQt::notificationPresenter()->notificationForWrapper(this); + if (notification) + return notification->contents().title(); + return QString(); +} - if (!notification->replaceId().isEmpty()) { - while (iter != end) { - Notification* existingNotification = iter.key(); - if (existingNotification->replaceId() == notification->replaceId() && existingNotification->url().protocol() == notification->url().protocol() && existingNotification->url().host() == notification->url().host()) - break; - iter++; - } - } else - iter = end; +const QString NotificationIconWrapper::message() const +{ + Notification* notification = NotificationPresenterClientQt::notificationPresenter()->notificationForWrapper(this); + if (notification) + return notification->contents().body(); + return QString(); +} - if (dumpNotification) { - if (iter != end) { - Notification* oldNotification = iter.key(); - printf("REPLACING NOTIFICATION %s\n", oldNotification->isHTML() ? QString(oldNotification->url().string()).toUtf8().constData() : QString(oldNotification->contents().title()).toUtf8().constData()); - } - if (notification->isHTML()) - printf("DESKTOP NOTIFICATION: contents at %s\n", QString(notification->url().string()).toUtf8().constData()); - else { - printf("DESKTOP NOTIFICATION:%s icon %s, title %s, text %s\n", - notification->dir() == "rtl" ? "(RTL)" : "", - QString(notification->contents().icon().string()).toUtf8().constData(), QString(notification->contents().title()).toUtf8().constData(), - QString(notification->contents().body()).toUtf8().constData()); - } +const QByteArray NotificationIconWrapper::iconData() const +{ + Notification* notification = NotificationPresenterClientQt::notificationPresenter()->notificationForWrapper(this); + QByteArray iconData; + if (notification) { + if (notification->iconData()) + iconData = QByteArray::fromRawData(notification->iconData()->data(), notification->iconData()->size()); } + return iconData; +} - if (iter != end) { - sendEvent(iter.key(), eventNames().closeEvent); - delete m_notifications.take(iter.key()); +NotificationPresenterClientQt::NotificationPresenterClientQt() : m_clientCount(0) +{ +} + +NotificationPresenterClientQt::~NotificationPresenterClientQt() +{ + while (!m_notifications.isEmpty()) { + NotificationsQueue::Iterator iter = m_notifications.begin(); + detachNotification(iter.key()); } +} + +void NotificationPresenterClientQt::removeClient() +{ + m_clientCount--; + if (!m_clientCount) { + s_notificationPresenter = 0; + delete this; + } +} + +void NotificationIconWrapper::notificationClosed() +{ + NotificationPresenterClientQt::notificationPresenter()->cancel(this); +} + +bool NotificationPresenterClientQt::show(Notification* notification) +{ + // FIXME: workers based notifications are not supported yet. + if (notification->scriptExecutionContext()->isWorkerContext()) + return false; + notification->setPendingActivity(notification); + if (!notification->replaceId().isEmpty()) + removeReplacedNotificationFromQueue(notification); + if (dumpNotification) + dumpShowText(notification); + QByteArray iconData; + if (notification->iconData()) + iconData = QByteArray::fromRawData(notification->iconData()->data(), notification->iconData()->size()); + displayNotification(notification, iconData); + notification->releaseIconData(); + return true; +} + +void NotificationPresenterClientQt::displayNotification(Notification* notification, const QByteArray& bytes) +{ NotificationIconWrapper* wrapper = new NotificationIconWrapper(); m_notifications.insert(notification, wrapper); + QString title; + QString message; + // FIXME: download & display HTML notifications + if (notification->isHTML()) + message = notification->url().string(); + else { + title = notification->contents().title(); + message = notification->contents().body(); + } + + if (m_platformPlugin.plugin() && m_platformPlugin.plugin()->supportsExtension(QWebKitPlatformPlugin::Notifications)) + wrapper->m_presenter = m_platformPlugin.createNotificationPresenter(); + + if (!wrapper->m_presenter) { +#ifndef QT_NO_SYSTEMTRAYICON + wrapper->m_closeTimer.startOneShot(notificationTimeout); + QPixmap pixmap; + if (bytes.length() && pixmap.loadFromData(bytes)) { + QIcon icon(pixmap); + wrapper->m_notificationIcon = new QSystemTrayIcon(icon); + } else + wrapper->m_notificationIcon = new QSystemTrayIcon(); +#endif + } + sendEvent(notification, "display"); + // Make sure the notification was not cancelled during handling the display event + if (m_notifications.find(notification) == m_notifications.end()) + return; + + if (wrapper->m_presenter) { + wrapper->connect(wrapper->m_presenter.get(), SIGNAL(notificationClosed()), wrapper, SLOT(notificationClosed()), Qt::QueuedConnection); + wrapper->m_presenter->showNotification(wrapper); + return; + } + #ifndef QT_NO_SYSTEMTRAYICON - wrapper->m_notificationIcon = new QSystemTrayIcon; wrapper->m_notificationIcon->show(); wrapper->m_notificationIcon->showMessage(notification->contents().title(), notification->contents().body()); #endif - return true; } void NotificationPresenterClientQt::cancel(Notification* notification) -{ - if (dumpNotification) { +{ + if (dumpNotification && notification->scriptExecutionContext()) { if (notification->isHTML()) printf("DESKTOP NOTIFICATION CLOSED: %s\n", QString(notification->url().string()).toUtf8().constData()); else printf("DESKTOP NOTIFICATION CLOSED: %s\n", QString(notification->contents().title()).toUtf8().constData()); } - QHash <Notification*, NotificationIconWrapper*>::Iterator iter = m_notifications.find(notification); - if (iter != m_notifications.end()) - sendEvent(iter.key(), eventNames().closeEvent); + NotificationsQueue::Iterator iter = m_notifications.find(notification); + if (iter != m_notifications.end()) { + sendEvent(notification, eventNames().closeEvent); + detachNotification(notification); + } +} + +void NotificationPresenterClientQt::cancel(NotificationIconWrapper* wrapper) +{ + Notification* notification = notificationForWrapper(wrapper); + if (notification) + cancel(notification); +} + +Notification* NotificationPresenterClientQt::notificationForWrapper(const NotificationIconWrapper* wrapper) const +{ + NotificationsQueue::ConstIterator end = m_notifications.end(); + NotificationsQueue::ConstIterator iter = m_notifications.begin(); + while (iter != end && iter.value() != wrapper) + iter++; + if (iter != end) + return iter.key(); + return 0; } void NotificationPresenterClientQt::notificationObjectDestroyed(Notification* notification) { // Called from ~Notification(), Remove the entry from the notifications list and delete the icon. - QHash <Notification*, NotificationIconWrapper*>::Iterator iter = m_notifications.find(notification); + NotificationsQueue::Iterator iter = m_notifications.find(notification); if (iter != m_notifications.end()) delete m_notifications.take(notification); } @@ -139,7 +242,7 @@ void NotificationPresenterClientQt::notificationObjectDestroyed(Notification* no void NotificationPresenterClientQt::requestPermission(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback) { if (dumpNotification) - printf("DESKTOP NOTIFICATION PERMISSION REQUESTED: %s\n", QString(origin->toString()).toUtf8().constData()); + printf("DESKTOP NOTIFICATION PERMISSION REQUESTED: %s\n", QString(origin->toString()).toUtf8().constData()); QString originString = origin->toString(); QHash<QString, QList<RefPtr<VoidCallback> > >::iterator iter = m_pendingPermissionRequests.find(originString); @@ -151,7 +254,7 @@ void NotificationPresenterClientQt::requestPermission(SecurityOrigin* origin, Pa callbacks.append(cb); m_pendingPermissionRequests.insert(originString, callbacks); if (requestPermissionFunction) - requestPermissionFunction(m_receiver, m_page, originString); + requestPermissionFunction(m_receiver, originString); } } @@ -184,19 +287,59 @@ void NotificationPresenterClientQt::allowNotificationForOrigin(const QString& or } } -void NotificationPresenterClientQt::clearNotificationsList() +void NotificationPresenterClientQt::sendEvent(Notification* notification, const AtomicString& eventName) { - m_pendingPermissionRequests.clear(); - while (!m_notifications.isEmpty()) { - QHash <Notification*, NotificationIconWrapper*>::Iterator iter = m_notifications.begin(); - delete m_notifications.take(iter.key()); + if (notification->scriptExecutionContext()) + notification->dispatchEvent(Event::create(eventName, false, true)); +} + +void NotificationPresenterClientQt::removeReplacedNotificationFromQueue(Notification* notification) +{ + Notification* oldNotification = 0; + NotificationsQueue::Iterator end = m_notifications.end(); + NotificationsQueue::Iterator iter = m_notifications.begin(); + + while (iter != end) { + Notification* existingNotification = iter.key(); + if (existingNotification->replaceId() == notification->replaceId() && existingNotification->url().protocol() == notification->url().protocol() && existingNotification->url().host() == notification->url().host()) { + oldNotification = iter.key(); + break; + } + iter++; + } + + if (oldNotification) { + if (dumpNotification) + dumpReplacedIdText(oldNotification); + sendEvent(oldNotification, eventNames().closeEvent); + detachNotification(oldNotification); } } -void NotificationPresenterClientQt::sendEvent(Notification* notification, const AtomicString& eventName) +void NotificationPresenterClientQt::detachNotification(Notification* notification) { - RefPtr<Event> event = Event::create(eventName, false, true); - notification->dispatchEvent(event.release()); + delete m_notifications.take(notification); + notification->detachPresenter(); + notification->unsetPendingActivity(notification); } +void NotificationPresenterClientQt::dumpReplacedIdText(Notification* notification) +{ + if (notification) + printf("REPLACING NOTIFICATION %s\n", notification->isHTML() ? QString(notification->url().string()).toUtf8().constData() : QString(notification->contents().title()).toUtf8().constData()); +} + +void NotificationPresenterClientQt::dumpShowText(Notification* notification) +{ + if (notification->isHTML()) + printf("DESKTOP NOTIFICATION: contents at %s\n", QString(notification->url().string()).toUtf8().constData()); + else { + printf("DESKTOP NOTIFICATION:%s icon %s, title %s, text %s\n", + notification->dir() == "rtl" ? "(RTL)" : "", + QString(notification->contents().icon().string()).toUtf8().constData(), QString(notification->contents().title()).toUtf8().constData(), + QString(notification->contents().body()).toUtf8().constData()); + } +} + +} #endif // ENABLE(NOTIFICATIONS) diff --git a/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h b/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h index c949513..1630cd9 100644 --- a/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h +++ b/WebKit/qt/WebCoreSupport/NotificationPresenterClientQt.h @@ -34,30 +34,51 @@ #include "Notification.h" #include "NotificationPresenter.h" +#include "QtPlatformPlugin.h" +#include "Timer.h" + +#include "qwebkitplatformplugin.h" #include <QMultiHash> #include <QSystemTrayIcon> - -#if ENABLE(NOTIFICATIONS) -class QWebPage; - namespace WebCore { + class Document; class KURL; -struct NotificationIconWrapper { +class NotificationIconWrapper : public QObject, public QWebNotificationData { + Q_OBJECT +public: NotificationIconWrapper(); ~NotificationIconWrapper(); + + void close(); + void close(Timer<NotificationIconWrapper>*); + const QString title() const; + const QString message() const; + const QByteArray iconData() const; + +public Q_SLOTS: + void notificationClosed(); + +public: #ifndef QT_NO_SYSTEMTRAYICON - QSystemTrayIcon* m_notificationIcon; + OwnPtr<QSystemTrayIcon> m_notificationIcon; #endif + + OwnPtr<QWebNotificationPresenter> m_presenter; + Timer<NotificationIconWrapper> m_closeTimer; }; +#if ENABLE(NOTIFICATIONS) + +typedef QHash <Notification*, NotificationIconWrapper*> NotificationsQueue; + class NotificationPresenterClientQt : public NotificationPresenter { public: - NotificationPresenterClientQt(QWebPage*); - ~NotificationPresenterClientQt() {} + NotificationPresenterClientQt(); + ~NotificationPresenterClientQt(); /* WebCore::NotificationPresenter interface */ virtual bool show(Notification*); @@ -66,22 +87,37 @@ public: virtual void requestPermission(SecurityOrigin*, PassRefPtr<VoidCallback>); virtual NotificationPresenter::Permission checkPermission(const KURL&); + void cancel(NotificationIconWrapper*); + void allowNotificationForOrigin(const QString& origin); - void clearNotificationsList(); static bool dumpNotification; void setReceiver(QObject* receiver) { m_receiver = receiver; } + void addClient() { m_clientCount++; } + void removeClient(); + static NotificationPresenterClientQt* notificationPresenter(); + + Notification* notificationForWrapper(const NotificationIconWrapper*) const; + private: void sendEvent(Notification*, const AtomicString& eventName); - QWebPage* m_page; - QMultiHash<QString, QList<RefPtr<VoidCallback> > > m_pendingPermissionRequests; - QHash <Notification*, NotificationIconWrapper*> m_notifications; + void displayNotification(Notification*, const QByteArray&); + void removeReplacedNotificationFromQueue(Notification*); + void detachNotification(Notification*); + void dumpReplacedIdText(Notification*); + void dumpShowText(Notification*); + + int m_clientCount; + QHash<QString, QList<RefPtr<VoidCallback> > > m_pendingPermissionRequests; + NotificationsQueue m_notifications; QObject* m_receiver; + QtPlatformPlugin m_platformPlugin; }; -} #endif -#endif +} + +#endif diff --git a/WebKit/qt/WebCoreSupport/PageClientQt.h b/WebKit/qt/WebCoreSupport/PageClientQt.h index 6dab4e1..818c67a 100644 --- a/WebKit/qt/WebCoreSupport/PageClientQt.h +++ b/WebKit/qt/WebCoreSupport/PageClientQt.h @@ -24,12 +24,12 @@ #include "FrameView.h" #include "GraphicsContext.h" #include "IntRect.h" +#include "QWebPageClient.h" +#include "TiledBackingStore.h" #include "qwebframe.h" #include "qwebframe_p.h" #include "qwebpage.h" #include "qwebpage_p.h" -#include "QWebPageClient.h" -#include "TiledBackingStore.h" #include <QtCore/qmetaobject.h> #include <QtCore/qsharedpointer.h> diff --git a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp index a097bf7..5e7e6d1 100644 --- a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp +++ b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.cpp @@ -85,45 +85,62 @@ void SelectInputMethodWrapper::didHide() // QtPlatformPlugin -static QWebKitPlatformPlugin* getPluginObject() +bool QtPlatformPlugin::load(const QString& file) +{ + m_loader.setFileName(file); + if (!m_loader.load()) + return false; + + QObject* obj = m_loader.instance(); + if (obj) { + m_plugin = qobject_cast<QWebKitPlatformPlugin*>(obj); + if (m_plugin) + return true; + } + + m_loader.unload(); + return false; +} + +bool QtPlatformPlugin::load() { const QLatin1String suffix("/webkit/"); const QStringList paths = QCoreApplication::libraryPaths(); - QObject* obj = 0; - for (int i = 0; !obj && i < paths.count(); ++i) { + + for (int i = 0; i < paths.count(); ++i) { const QDir dir(paths[i] + suffix); if (!dir.exists()) continue; const QStringList files = dir.entryList(QDir::Files); - for (int i = 0; i < files.count(); ++i) { - QPluginLoader pluginLoader(dir.absoluteFilePath(files.at(i))); - if (!pluginLoader.load()) - continue; - obj = pluginLoader.instance(); - if (obj) { - QWebKitPlatformPlugin* result = qobject_cast<QWebKitPlatformPlugin*>(obj); - if (result) - return result; - delete obj; - } - pluginLoader.unload(); + for (int j = 0; j < files.count(); ++j) { + if (load(dir.absoluteFilePath(files.at(j)))) + return true; } } - return 0; + return false; } QtPlatformPlugin::~QtPlatformPlugin() { - delete m_plugin; + m_loader.unload(); } QWebKitPlatformPlugin* QtPlatformPlugin::plugin() { if (m_loaded) return m_plugin; - m_loaded = true; - m_plugin = getPluginObject(); + + // Plugin path is stored in a static variable to avoid searching for the plugin + // more then once. + static QString pluginPath; + + if (pluginPath.isNull()) { + if (load()) + pluginPath = m_loader.fileName(); + } else + load(pluginPath); + return m_plugin; } @@ -140,4 +157,13 @@ QtAbstractWebPopup* QtPlatformPlugin::createSelectInputMethod() return new SelectInputMethodWrapper(selector); } + +QWebNotificationPresenter* QtPlatformPlugin::createNotificationPresenter() +{ + QWebKitPlatformPlugin* p = plugin(); + if (!p) + return 0; + return p->createNotificationPresenter(); +} + } diff --git a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h index 9b73079..ff10d58 100644 --- a/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h +++ b/WebKit/qt/WebCoreSupport/QtPlatformPlugin.h @@ -23,9 +23,11 @@ #include "QtAbstractWebPopup.h" #include <QObject> +#include <QPluginLoader> class QWebSelectMethod; class QWebKitPlatformPlugin; +class QWebNotificationPresenter; namespace WebCore { @@ -51,12 +53,16 @@ public: ~QtPlatformPlugin(); QtAbstractWebPopup* createSelectInputMethod(); + QWebNotificationPresenter* createNotificationPresenter(); + + QWebKitPlatformPlugin* plugin(); private: bool m_loaded; QWebKitPlatformPlugin* m_plugin; - - QWebKitPlatformPlugin* plugin(); + QPluginLoader m_loader; + bool load(); + bool load(const QString& file); }; } diff --git a/WebKit/qt/docs/qtwebkit-bridge.qdoc b/WebKit/qt/docs/qtwebkit-bridge.qdoc new file mode 100644 index 0000000..fa93293 --- /dev/null +++ b/WebKit/qt/docs/qtwebkit-bridge.qdoc @@ -0,0 +1,427 @@ +/*! + \inmodule QtWebKit + \page qtwebkit-bridge.html + \title The QtWebKit Bridge + \contentspage QtWebKit + \section1 Overview + \section2 The technology + + The QtWebKit bridge is a mechanism that extends WebKit's JavaScript environment to access native + objects that are represented as \l{QObject}s. It takes advantage of the \l{QObject} introspection, + a part of the \l{Qt Object Model}, which makes it easy to integrate with the dynamic JavaScript environment, + for example \l{QObject} properties map directly to JavaScript properties. + + For example, both JavaScript and QObjects have properties: a construct that represent a getter/setter + pair under one name. + + \section2 Use Cases + + There are two main use cases for the QtWebKit bridge. Web content in a native application, and Thin Clients. + + \section3 Web Content in a Native Application + + This is a common use case in classic Qt application, and a design pattern used by several modern + applications. For example, an application that contains a media-player, playlist manager, and music store. + The playlist manager is usually best authored as a classic desktop application, + with the native-looking robust \l{QWidget}s helping with producing that application. + The media-player control, which usually looks custom, can be written using \l{The Graphics View framework} + or with in a declarative way with \l{QtDeclarative}. The music store, which shows dynamic content + from the internet and gets modified rapidly, is best authored in HTML and maintained on the server. + + With the QtWebKit bridge, that music store component can interact with native parts of the application, + for example, if a file needs to be saved to a specific location. + + \section3 Thin Client + + Another use case is using Qt as a native backend to a full web application, + referred to here as a thin client. In this use-case, the entire UI is driven by + HTML, JavaScript and CSS, and native Qt-based components are used to allow that application + access to native features not usually exposed to the web, or to enable helper components that + are best written with C++. + + An example for such a client is a UI for a video-on-demand service on a TV. The entire content and + UI can be kept on the server, served dynamically through HTTP and rendered with WebKit, with additional + native components for accessing hardware-specific features like extracting the list of images + out of the video. + + \section2 Difference from Other Bridge Technologies + + Of course QtWebKit is not the only bridge technology out there. NPAPI, for example, + is a long-time standard or web-native bridging. Due to Qt's meta-object system, full applications + built partially with web-technologies are much easier to develop. NPAPI, however, is more geared + towards cross-browser plugins, due to it being an accepted standard. + + When developing a plugin for a browser, NPAPI is recommended. When developing a full application + that utilizes HTML-rendering, the QtWebKit bridge is recommended. + + \section2 Relationship with QtScript + + The QtWebKit bridge is similar to \l{QtScript}, especially to some of the features described in the + \l{Making Applications Scriptable} page. However, as of Qt 4.7, full QtScript API is not supported for web applications. + That is planned as an enhancement for future versions. You might notice that some of the features + described here are an exact copy of the ones described in the \l{Making Applications Scriptable} page. That is because + the QtWebKit bridge is a subset of that functionality, and this page tries to capture the full + capabilities available through the QtWebKit bridge specifically. + + \section1 Accessing QObjects + + \section2 Creating the link via QWebFrame + + By default, no QObjects are accessible through the web environment, for security reasons. + To enable web content access for a native QObject, the application must explicitly grant it access, + using the following call: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 0 + + See \l{QWebFrame::addToJavaScriptWindowObject()} for more information. + + \section2 Using Signals and Slots + + The QtWebKit bridge adapts Qt's central \l{Signals and Slots} feature for + scripting. There are three principal ways to use signals and slots + with the QtWebKit bridge: + + \list + \i \bold{Hybrid C++/script}: C++ application code connects a + signal to a script function. For example, the script function can be + a function that the user has typed in, or one that you have read from a + file. This approach is useful if you have a QObject but don't want + to expose the object itself to the scripting environment; you just + want a script to be able to define how a signal should be reacted + to, and leave it up to the C++ side of your application to establish + the connection. + + \i \bold{Hybrid script/C++}: A script can connect signals and slots + to establish connections between pre-defined objects that the + application exposes to the scripting environment. In this scenario, + the slots themselves are still written in C++, but the definition of + the connections is fully dynamic (script-defined). + + \i \bold{Purely script-defined}: A script can both define signal + handler functions (effectively "slots written in JavaScript"), + \e{and} set up the connections that utilize those handlers. For + example, a script can define a function that will handle the + QLineEdit::returnPressed() signal, and then connect that signal to the + script function. + \endlist + + Note that QtScript functions such as qScriptConnect are unavilable in the web environment. + + \section3 Signal to Function Connections + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 6 + + In this form of connection, the argument to \c{connect()} is the + function to connect to the signal. + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 7 + + The argument can be a JavaScript function, as in the above + example, or it can be a QObject slot, as in + the following example: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 8 + + When the argument is a QObject slot, the argument types of the + signal and slot do not necessarily have to be compatible; + If necessary, the QtWebKit bridge will, perform conversion of the signal + arguments to match the argument types of the slot. + + To disconnect from a signal, you invoke the signal's + \c{disconnect()} function, passing the function to disconnect + as argument: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 9 + + When a script function is invoked in response to a signal, the + \c this object will be the Global Object. + + \section3 Signal to Member Function Connections + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 10 + + In this form of the \c{connect()} function, the first argument + is the object that will be bound to the variable, \c this, when + the function specified using the second argument is invoked. + + If you have a push button in a form, you typically want to do + something involving the form in response to the button's + \c{clicked} signal; passing the form as the \c this object + makes sense in such a case. + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 11 + + To disconnect from the signal, pass the same arguments to \c{disconnect()}: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 12 + + \section3 Signal to Named Member Function Connections + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 14 + + This form of the \c{connect()} function requires that the first argument is + the object that will be bound to the variable \c{this} when a function is + invoked in response to the signal. The second argument specifies the + name of a function that is connected to the signal, and this refers to a + member function of the object passed as the first argument (thisObject + in the above scheme). + + Note that the function is resolved when the connection is made, not + when the signal is emitted. + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 15 + + To disconnect from the signal, pass the same arguments to \c{disconnect()}: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 17 + + \section3 Error Handling + + When \c{connect()} or \c{disconnect()} succeeds, the function will + return \c{undefined}; otherwise, it will throw a script exception. + You can obtain an error message from the resulting \c{Error} object. + Example: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 18 + + \section3 Emitting Signals from Scripts + + To emit a signal from script code, you simply invoke the signal + function, passing the relevant arguments: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 19 + + It is currently not possible to define a new signal in a script; + i.e., all signals must be defined by C++ classes. + + \section3 Overloaded Signals and Slots + + When a signal or slot is overloaded, the QtWebKit bridge will attempt to + pick the right overload based on the actual types of the QScriptValue arguments + involved in the function invocation. For example, if your class has slots + \c{myOverloadedSlot(int)} and \c{myOverloadedSlot(QString)}, the following + script code will behave reasonably: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 20 + + You can specify a particular overload by using array-style property access + with the \l{QMetaObject::normalizedSignature()}{normalized signature} of + the C++ function as the property name: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 21 + + If the overloads have different number of arguments, the QtWebKit bridge will + pick the overload with the argument count that best matches the + actual number of arguments passed to the slot. + + For overloaded signals, JavaScript will throw an error if you try to connect + to the signal by name; you have to refer to the signal with the full + normalized signature of the particular overload you want to connect to. + + \section3 Invokable Methods + + Both slots and signals are invokable from script by default. In addition, it's also + possible to define a method that's invokable from script without it being a signal or a slot. + This is especially useful for functions with return types, as slots normally do not return anything + (it would be meaningless to return values from a slot, as the connected signals don't handle the returned data). + To make a non-slot method invokable, simply add the Q_INVOKABLE macro before its definition: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 22 + + \section2 Accessing Properties + + The properties of the QObject are available as properties + of the corresponding JavaScript object. When you manipulate + a property in script code, the C++ get/set method for that + property will automatically be invoked. For example, if your + C++ class has a property declared as follows: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 23 + + then script code can do things like the following: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 24 + + \section2 Accessing Child QObjects + + Every named child of the QObject (that is, for which + QObject::objectName() is not an empty string) is by default available as + a property of the JavaScript wrapper object. For example, + if you have a QDialog with a child widget whose \c{objectName} property is + \c{"okButton"}, you can access this object in script code through + the expression + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 25 + + Since \c{objectName} is itself a Q_PROPERTY, you can manipulate + the name in script code to, for example, rename an object: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 26 + + \section2 Data types + + When calling slots, receiving signals or accessing properties, usually some payload is involved. + For example, a property "text" might return a \l{QString} parameter. + The QtWebKit bridge does the job of converting between a given JavaScript data-type, and the + expected or given Qt type. Each Qt type has a coresponding set of rules of how JavaScript treats it. + + The data type conversions are also applicable for the data returned from non-void invokable methods. + + \section3 Numbers + + All Qt numeric data types are converted to or from a JavaScript number. These include int, short, float, + double, and the porable Qt types (qreal, qint etc). A special case is \l{QChar}; + If a slot expects a QChar, the QtWebKit bridge would use the unicode value in case of a number, + or the first character in a string. + + Note that non-standard (typedefed) number types are not automatically converted to + or from a JavaScript number - it's advised to use standard number types for signal, slots + and properties. + + When a non-number is passed as an argument to a method or property that expects a number, + the appropriate JavaScript conversion function (parseInt / parseFloat) would be used. + + \section3 Strings + + When JavaScript accesses methods or properties that expect a \l{QString}, the QtWebKit bridge + will automatically convert the value to a string (if it is not already a string), using the + built-in JavaScript toString method. + + When a QString is passed to JavaScript from a signal or a property, The QtWebKit bridge will + convert it into a JavaScript string. + + \section3 Date & Time + + Both \l{QDate}, \l{QTime} and \l{QDateTime} are automatically translated to or from the JavaScript + Date object. If a number were passed as an argument to a method that expects one of the date/time + types, the QtWebKit bridge would treat it as a timestamp. If a sting is passed, QtWebKit would + try different Qt date parsing functions to find the right one. + + \section3 Regular Expressions + + The QtWebKit bridge would automatically convert JavaScript RegEx object to a \l{QRegExp}. + If a string is passed to a method expecting a \l{QRegExp}, the string would be converted + to that \l{QRegExp}. + + \section3 Lists + + The QtWebKit bridge treats several types of lists in a special way: \l{QVariantList}, \l{QStringList}, + \l{QObjectList} and \l{QList}<int>. When a slot or property expects one of those list types, + the QtWebKit bridge would try to convert a JavaScript array into that type, converting each of + the array's elements to the single-element type of the list. + + The most useful type of list is perhaps \l{QVariantList}, which can be converted to from any + JavaScript array. + + \section3 Compound (JSON) objects + + JavaScript compound objects, also known as JSON objects, are variables that hold a list + of key-value pairs, where all the keys are strings and the values can have any type. + This translates very well to \l{QVariantMap}, which is nothing more than a \l{QMap} of \l{QString} + to \l{QVariant}. + + The seamless conversion between JSON objects and \l{QVariantMap} allows for a very convenient + way of passing arbitrary structured data between C++ and the JavaScript environment. The native \l{QObject} has + to make sure that compound values are converted to \l{QVariantMap}s and \l{QVariantList}s, and JavaScript is + guaranteed to receive them in a meaningful way. + + Note that types that are not supported by JSON, such as JavaScript functions and getters/setters, + are not converted. + + \section3 QVariants + + When a slot or property accepts a \l{QVariant}, the QtWebKit bridge would create a \l{QVariant} that best + matches the argument passed by JavaScript. A string, for example, would become a \l{QVariant} holding a \l{QString}, + a normal JSON object would become a \l{QVariantMap}, and a JavaScript array would become a \l{QVariantList}. + + Using \l{QVariant}s generously in C++ in that way makes C++ programming feel a bit more like JavaScript programming, + as it adds another level of indirection. Passing \l{QVariant}s around like this q is very flexible, as the program can figure out + the type of argument in runtime just like JavaScript would do, but it also takes away from the type-safety and robust + nature of C++. It's recommended to use \l{QVariant}s only for convenience high-level functions, and to keep most of your + \l{QObject}s somewhat type-safe. + + \section3 QObjects + + A pointer to a \l{QObject} or a \l{QWidget} can be passed as payload in signals, slots and properties. That object + can then be used like an object that's exposed directly; i.e. its slots can be invoked, its signals connected to etc. + However, this functionality is fairly limited - the type used has to be \l{QObject}* or \l{QWidget}*. If the type + specified is a pointer to a non-\l{QWidget} subclass of \l{QObject}, the QtWebKit bridge would not recognize it to be + a \l{QObject}. + + In general its advised to use care when passing \l{QObject}s as arguments, as those objects don't become owned by + the JavaScript engine; That means that the application developer has to be extra careful not to try to access + \l{QObject}s that have already been deleted by the native environment. + + \section3 Pixmaps and Images + + \since 4.7 + + The QtWebKit bridge handles \l{QPixmap}s and \l{QImage}s in a special way. Since QtWebKit stores \l{QPixmap}s to + represent HTML images, \l{QPixmap}s coming from the native environment can be used directly inside WebKit. + A \l{QImage} or a \l{QPixmap} coming from the Qt environment would convert to an intermediate JavaScript object, + that can be represented like this: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 1 + + The JavaScript environment can then use the pixmap it gets from Qt and display it inside the HTML environment, + by assigning it to an existing <img /> element using assignToHTMLImageElement. It can also use the toDataURL() function, + which allows using the pixmap as the src attribute of an image or as a background-image url. Note that the toDataURL() + function is costly and should be used with caution. + + Example code: + + C++: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 2 + + HTML: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 3 + + When a Qt object expects a \l{QImage} or a \l{QPixmap} as input, and the argument passed is an HTML image element, + the QtWebKit bridge would convert the pixmap assigned to that image element into a \l{QPixmap} or a \l{QImage}. + + \since 4.7 + + \section3 QWebElement + + A signal, slot or property that expects or returns a \l{QWebElement} can work seamlessly with JavaScript references + to DOM elements. The JavaScript environment can select DOM elements, keep them in variables, then pass them to Qt as + a \l{QWebElement}, and receive them back. Example: + + C++: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 4 + + HTML: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 5 + + This is specifically useful to create custom renderers or extensions to the web environment. Instead of forcing Qt + to select the element, the web environment already selects the element and then send the selected element directly to Qt. + + Note that \l{QWebElement}s are not thread safe - an object handling them has to live in the UI thread. + + \section1 Architecture issues + + \section2 Limiting the Scope of the Hybrid Layer + + When using QtWebKit's hybrid features, it is a common pitfall to make the API exposed to JavaScript very rich and + use all its features. This, however, leads to complexity and can create bugs that are hard to trace. + Instead, it is advisable to keep the hybrid layer small and manageable: create a gate only when + there's an actual need for it, i.e. there's a new native enabler that requires a direct interface + to the application layer. Sometimes new functionality is better handled internally in the native layer + or in the web layer; simplicity is your friend. + + This usually becomes more apparent when the hybrid layer can create or destroy objects, or uses + signals slots or properties with a \l{QObject}* argument. It is advised to be very careful and to treat + an exposed \l{QObject} as a system - with careful attention to memory management and object ownership. + + \section2 Internet Security + + When exposing native object to an open web environment, it is importwhichant to understand the security + implications. Think whether the exposed object enables the web environment access to things that + shouldn't be open, and whether the web content loaded by that web page comes from a trusted. In general, when + exposing native QObjects that give the web environment access to private information or to functionality + that's potentially harmful to the client, such exposure should be balanced by limiting the web page's + access to trusted URLs only with HTTPS, and by utilizing other measures as part of a security strategy. + + + +*/ diff --git a/WebKit/qt/docs/qtwebkit.qdoc b/WebKit/qt/docs/qtwebkit.qdoc index c6dd550..d3f5502 100644 --- a/WebKit/qt/docs/qtwebkit.qdoc +++ b/WebKit/qt/docs/qtwebkit.qdoc @@ -20,8 +20,9 @@ scripted with JavaScript. A bridge between the JavaScript execution environment and the Qt object - model makes it possible for custom QObjects to be scripted. Integration - with the Qt networking module enables Web pages to be transparently loaded + model makes it possible for custom QObjects to be scripted. For detailed + documentation see \l{The QtWebkit Bridge}. + Integration with the Qt networking module enables Web pages to be transparently loaded from Web servers, the local file system or even the Qt resource system. In addition to providing pure rendering features, HTML documents can be diff --git a/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp b/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp new file mode 100644 index 0000000..62eeeca --- /dev/null +++ b/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp @@ -0,0 +1,177 @@ + +void wrapInFunction() +{ + + //! [0] + // ... + QWebFrame *frame = myWebPage->mainFrame(); + frame->addToJavaScriptWindowObject("someNameForMyObject", myObject); + // ... + //! [0] +#if 0 + //! [1] + { + width: ..., + height: ..., + toDataURL: function() { ... }, + assignToHTMLImageElement: function(element) { ... } + } + //! [1] +#endif + //! [2] + class MyObject : QObject { + Q_OBJECT + Q_PROPERTY(QPixmap myPixmap READ getPixmap) + + public: + QPixmap getPixmap() const; + }; + + /* ... */ + + MyObject myObject; + myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); + + //! [2] +#if 0 + //! [3] + <html> + <head> + <script> + function loadImage() { + myObject.myPixmap.assignToHTMLImageElement(document.getElementById("imageElement")); + } + </script> + </head> + <body onload="loadImage()"> + <img id="imageElement" width="300" height="200" /> + </body> + </html> + //! [3] +#endif + //! [4] + class MyObject : QObject { + Q_OBJECT + + public slots: + void doSomethingWithWebElement(const QWebElement&); + }; + + /* ... */ + + MyObject myObject; + myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); + + //! [4] +#if 0 + //! [5] + <html> + <head> + <script> + function runExample() { + myObject.doSomethingWithWebElement(document.getElementById("someElement")); + } + </script> + </head> + <body onload="runExample()"> + <span id="someElement">Text</span> + </body> + </html> + //! [5] + //! [6] + connect(function); + //! [6] + //! [7] + function myInterestingScriptFunction() { ... } + ... + myQObject.somethingChanged.connect(myInterestingScriptFunction); + //! [7] + //! [8] + myQObject.somethingChanged.connect(myOtherQObject.doSomething); + //! [8] + //! [9] + myQObject.somethingChanged.disconnect(myInterestingFunction); + myQObject.somethingChanged.disconnect(myOtherQObject.doSomething); + //! [9] + //! [10] + connect(thisObject, function) + //! [10] + //! [11] + var obj = { x: 123 }; + var fun = function() { print(this.x); }; + myQObject.somethingChanged.connect(obj, fun); + //! [11] + //! [12] + myQObject.somethingChanged.disconnect(obj, fun); + //! [12] + //! [13] + connect(function); + //! [13] + //! [14] + connect(thisObject, functionName) + //! [14] + //! [15] + var obj = { x: 123, fun: function() { print(this.x); } }; + myQObject.somethingChanged.connect(obj, "fun"); + //! [15] + //! [16] + connect(function); + //! [16] + //! [17] + myQObject.somethingChanged.disconnect(obj, "fun"); + //! [17] + //! [18] + try { + myQObject.somethingChanged.connect(myQObject, "slotThatDoesntExist"); + } catch (e) { + print(e); + } + //! [18] + //! [19] + myQObject.somethingChanged("hello"); + //! [19] + //! [20] + myQObject.myOverloadedSlot(10); // will call the int overload + myQObject.myOverloadedSlot("10"); // will call the QString overload + //! [20] + //! [21] + myQObject['myOverloadedSlot(int)']("10"); // call int overload; the argument is converted to an int + myQObject['myOverloadedSlot(QString)'](10); // call QString overload; the argument is converted to a string + //! [21] + //! [22] + class MyObject : public QObject + { + Q_OBJECT + + public: + Q_INVOKABLE void thisMethodIsInvokableInQtScript(); + void thisMethodIsNotInvokableInQtScript(); + + ... + }; + //! [22] + //! [23] + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) + //! [23] + //! [24] + myQObject.enabled = true; + + ... + + myQObject.enabled = !myQObject.enabled; + //! [24] + //! [25] + myQObject.enabled = true; + + ... + + myQObject.enabled = !myQObject.enabled; + //! [25] + //! [26] + myDialog.okButton + myDialog.okButton.objectName = "cancelButton"; + // from now on, myDialog.cancelButton references the button + //! [26] +#endif +} + diff --git a/WebKit/qt/examples/platformplugin/WebNotificationPresenter.cpp b/WebKit/qt/examples/platformplugin/WebNotificationPresenter.cpp new file mode 100644 index 0000000..c992236 --- /dev/null +++ b/WebKit/qt/examples/platformplugin/WebNotificationPresenter.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "WebNotificationPresenter.h" + +WebNotificationWidget::WebNotificationWidget() + : QWidget() +{ +} + +WebNotificationWidget::~WebNotificationWidget() +{ +} + +void WebNotificationWidget::showNotification(const QWebNotificationData* data) +{ + QPixmap mask; + QPainter painter(&mask); + painter.fillRect(0, 0, 300, 100, Qt::lightGray); + QBitmap bitmap(mask); + setMask(bitmap); + QGridLayout* layout = new QGridLayout(this); + layout->addWidget(new QLabel(data->title()), 0, 0, 1, 5); + int messagePosition = 0; + QPixmap pixmap; + if (data->iconData().length() && pixmap.loadFromData(data->iconData())) { + QLabel* label = new QLabel; + label->setPixmap(pixmap); + layout->addWidget(label, 1, 0, 1, 1); + messagePosition++; + } + QLabel* messageLabel = new QLabel(data->message()); + messageLabel->setMask(bitmap); + messageLabel->setWordWrap(true); + layout->addWidget(messageLabel, 1, messagePosition, 1, 5 - messagePosition); + setLayout(layout); + setFixedSize(300, 100); + show(); +} + +bool WebNotificationWidget::event(QEvent* ev) +{ + if (ev->type() == QEvent::MouseButtonRelease || ev->type() == QEvent::Close) { + emit notificationClosed(); + return true; + } + return QWidget::event(ev); +} + diff --git a/WebKit/qt/examples/platformplugin/WebNotificationPresenter.h b/WebKit/qt/examples/platformplugin/WebNotificationPresenter.h new file mode 100644 index 0000000..a2563b2 --- /dev/null +++ b/WebKit/qt/examples/platformplugin/WebNotificationPresenter.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef WebNotificationPresenter_h +#define WebNotificationPresenter_h + +#include "qwebkitplatformplugin.h" +#include <QtGui> + +class WebNotificationWidget : public QWidget +{ + Q_OBJECT +public: + WebNotificationWidget(); + virtual ~WebNotificationWidget(); + + void showNotification(const QWebNotificationData*); + bool event(QEvent*); + +Q_SIGNALS: + void notificationClosed(); +}; + +class WebNotificationPresenter : public QWebNotificationPresenter +{ + Q_OBJECT +public: + WebNotificationPresenter() + : QWebNotificationPresenter() + { + m_widget = new WebNotificationWidget(); + connect(m_widget, SIGNAL(notificationClosed()), this, SIGNAL(notificationClosed())); + } + virtual ~WebNotificationPresenter() { m_widget->close(); delete m_widget; } + + void showNotification(const QWebNotificationData* data) { m_widget->showNotification(data); } + +private: + WebNotificationWidget* m_widget; +}; + +#endif // WebNotificationsUi_h diff --git a/WebKit/qt/examples/platformplugin/WebPlugin.cpp b/WebKit/qt/examples/platformplugin/WebPlugin.cpp index 79e583d..1f3877c 100644 --- a/WebKit/qt/examples/platformplugin/WebPlugin.cpp +++ b/WebKit/qt/examples/platformplugin/WebPlugin.cpp @@ -210,7 +210,15 @@ MultipleSelectionPopup::MultipleSelectionPopup(const QWebSelectData& data) bool WebPlugin::supportsExtension(Extension extension) const { - return extension == MultipleSelections; + if (extension == MultipleSelections) + return true; + if (extension == Notifications) +#if ENABLE_NOTIFICATIONS + return true; +#else + return false; +#endif + return false; } Q_EXPORT_PLUGIN2(qwebselectim, WebPlugin) diff --git a/WebKit/qt/examples/platformplugin/WebPlugin.h b/WebKit/qt/examples/platformplugin/WebPlugin.h index a46a07b..9a99d0b 100644 --- a/WebKit/qt/examples/platformplugin/WebPlugin.h +++ b/WebKit/qt/examples/platformplugin/WebPlugin.h @@ -21,6 +21,7 @@ #define WEBPLUGIN_H #include "qwebkitplatformplugin.h" +#include "WebNotificationPresenter.h" #include <QDialog> @@ -88,8 +89,9 @@ class WebPlugin : public QObject, public QWebKitPlatformPlugin public: virtual QWebSelectMethod* createSelectInputMethod() const { return new WebPopup(); } virtual bool supportsExtension(Extension extension) const; + virtual QWebNotificationPresenter* createNotificationPresenter() const { + return new WebNotificationPresenter(); + } }; - - #endif // WEBPLUGIN_H diff --git a/WebKit/qt/examples/platformplugin/platformplugin.pro b/WebKit/qt/examples/platformplugin/platformplugin.pro index c5c665b..9275665 100644 --- a/WebKit/qt/examples/platformplugin/platformplugin.pro +++ b/WebKit/qt/examples/platformplugin/platformplugin.pro @@ -6,8 +6,12 @@ CONFIG += plugin DESTDIR = $$[QT_INSTALL_PLUGINS]/webkit SOURCES += \ - WebPlugin.cpp + WebPlugin.cpp \ + WebNotificationPresenter.cpp HEADERS += \ WebPlugin.h \ - qwebkitplatformplugin.h + qwebkitplatformplugin.h \ + WebNotificationPresenter.h + +!contains(DEFINES, ENABLE_NOTIFICATIONS=.): DEFINES += ENABLE_NOTIFICATIONS=1 diff --git a/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h b/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h index 7d024ae..bac618c 100644 --- a/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h +++ b/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h @@ -58,20 +58,43 @@ Q_SIGNALS: void didHide(); }; +class QWebNotificationData +{ +public: + virtual const QString title() const = 0; + virtual const QString message() const = 0; + virtual const QByteArray iconData() const = 0; +}; + +class QWebNotificationPresenter : public QObject +{ + Q_OBJECT +public: + QWebNotificationPresenter() {} + virtual ~QWebNotificationPresenter() {} + + virtual void showNotification(const QWebNotificationData*) = 0; + +Q_SIGNALS: + void notificationClosed(); +}; + class QWebKitPlatformPlugin { public: - inline ~QWebKitPlatformPlugin() {} + virtual ~QWebKitPlatformPlugin() {} enum Extension { - MultipleSelections + MultipleSelections, + Notifications }; - virtual QWebSelectMethod* createSelectInputMethod() const = 0; virtual bool supportsExtension(Extension extension) const = 0; + virtual QWebSelectMethod* createSelectInputMethod() const = 0; + virtual QWebNotificationPresenter* createNotificationPresenter() const = 0; }; -Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.0"); +Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.2"); #endif // QWEBKITPLATFORMPLUGIN_H diff --git a/WebKit/qt/qtwebkit_version.pri b/WebKit/qt/qt_webkit_version.pri index 1656f2d..1656f2d 100644 --- a/WebKit/qt/qtwebkit_version.pri +++ b/WebKit/qt/qt_webkit_version.pri diff --git a/WebKit/qt/symbian/eabi/QtWebKitu.def b/WebKit/qt/symbian/eabi/QtWebKitu.def index 203261a..93fd33c 100644 --- a/WebKit/qt/symbian/eabi/QtWebKitu.def +++ b/WebKit/qt/symbian/eabi/QtWebKitu.def @@ -770,3 +770,9 @@ EXPORTS _ZN23DumpRenderTreeSupportQt39setWillSendRequestReturnsNullOnRedirectEb @769 NONAME _ZN23DumpRenderTreeSupportQt40garbageCollectorCollectOnAlternateThreadEb @770 NONAME _ZN23DumpRenderTreeSupportQt40setDomainRelaxationForbiddenForURLSchemeEbRK7QString @771 NONAME + _ZN23DumpRenderTreeSupportQt18setEditingBehaviorEP8QWebPageRK7QString @ 772 NONAME + _ZN23DumpRenderTreeSupportQt24setNotificationsReceiverEP7QObject @ 773 NONAME + _ZN23DumpRenderTreeSupportQt26allowNotificationForOriginERK7QString @ 774 NONAME + _ZN23DumpRenderTreeSupportQt26setCheckPermissionFunctionEPFvP7QObjectRK4QUrlR22NotificationPermissionE @ 775 NONAME + _ZN23DumpRenderTreeSupportQt28setRequestPermissionFunctionEPFvP7QObjectRK7QStringE @ 776 NONAME + _ZN23DumpRenderTreeSupportQt31removeWhiteListAccessFromOriginERK7QStringS2_S2_b @ 777 NONAME diff --git a/WebKit/qt/tests/qgraphicswebview/resources/input_types.html b/WebKit/qt/tests/qgraphicswebview/resources/input_types.html new file mode 100644 index 0000000..18ab314 --- /dev/null +++ b/WebKit/qt/tests/qgraphicswebview/resources/input_types.html @@ -0,0 +1,8 @@ +<html><body> +<input type='text' maxlength='20' style='position: absolute; left: 10px; top: 0px; height: 50px; width: 100px;'/><br> +<input type='password' style='position: absolute; left: 10px; top: 50px; height: 50px; width: 100px;'/><br> +<input type='tel' style='position: absolute; left: 10px; top: 100px; height: 50px; width: 100px;'/><br> +<input type='number' style='position: absolute; left: 10px; top: 150px; height: 50px; width: 100px;'/><br> +<input type='email' style='position: absolute; left: 10px; top: 200px; height: 50px; width: 100px;'/><br> +<input type='url' style='position: absolute; left: 10px; top: 250px; height: 50px; width: 100px;'/><br>" +</body></html>
\ No newline at end of file diff --git a/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp index ebe847d..e06524d 100644 --- a/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp +++ b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.cpp @@ -19,6 +19,7 @@ #include "../util.h" #include <QtTest/QtTest> +#include <QGraphicsSceneMouseEvent> #include <QGraphicsView> #include <qgraphicswebview.h> #include <qwebpage.h> @@ -32,6 +33,7 @@ private slots: void qgraphicswebview(); void crashOnViewlessWebPages(); void microFocusCoordinates(); + void focusInputTypes(); }; void tst_QGraphicsWebView::qgraphicswebview() @@ -75,6 +77,29 @@ private slots: } }; +class GraphicsWebView : public QGraphicsWebView +{ + Q_OBJECT + +public: + GraphicsWebView(QGraphicsItem* parent = 0): QGraphicsWebView(parent) + { + } + + void fireMouseClick(QPointF point) { + QGraphicsSceneMouseEvent presEv(QEvent::GraphicsSceneMousePress); + presEv.setPos(point); + presEv.setButton(Qt::LeftButton); + presEv.setButtons(Qt::LeftButton); + QGraphicsSceneMouseEvent relEv(QEvent::GraphicsSceneMouseRelease); + relEv.setPos(point); + relEv.setButton(Qt::LeftButton); + relEv.setButtons(Qt::LeftButton); + QGraphicsWebView::sceneEvent(&presEv); + QGraphicsWebView::sceneEvent(&relEv); + } +}; + void tst_QGraphicsWebView::crashOnViewlessWebPages() { QGraphicsScene scene; @@ -140,6 +165,57 @@ void tst_QGraphicsWebView::microFocusCoordinates() delete view; } +void tst_QGraphicsWebView::focusInputTypes() +{ + QWebPage* page = new QWebPage; + GraphicsWebView* webView = new GraphicsWebView; + webView->setPage( page ); + QGraphicsView* view = new QGraphicsView; + QGraphicsScene* scene = new QGraphicsScene(view); + view->setScene(scene); + scene->addItem(webView); + view->setGeometry(QRect(0,0,500,500)); + QCoreApplication::processEvents(); + QUrl url("qrc:///resources/input_types.html"); + page->mainFrame()->load(url); + page->mainFrame()->setFocus(); + + QVERIFY(waitForSignal(page, SIGNAL(loadFinished(bool)))); + + // 'text' type + webView->fireMouseClick(QPointF(20.0, 10.0)); +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) || defined(Q_OS_SYMBIAN) + QVERIFY(webView->inputMethodHints() & Qt::ImhNoAutoUppercase); + QVERIFY(webView->inputMethodHints() & Qt::ImhNoPredictiveText); +#else + QVERIFY(webView->inputMethodHints() == Qt::ImhNone); +#endif + + // 'password' field + webView->fireMouseClick(QPointF(20.0, 60.0)); + QVERIFY(webView->inputMethodHints() & Qt::ImhHiddenText); + + // 'tel' field + webView->fireMouseClick(QPointF(20.0, 110.0)); + QVERIFY(webView->inputMethodHints() & Qt::ImhDialableCharactersOnly); + + // 'number' field + webView->fireMouseClick(QPointF(20.0, 160.0)); + QVERIFY(webView->inputMethodHints() & Qt::ImhDigitsOnly); + + // 'email' field + webView->fireMouseClick(QPointF(20.0, 210.0)); + QVERIFY(webView->inputMethodHints() & Qt::ImhEmailCharactersOnly); + + // 'url' field + webView->fireMouseClick(QPointF(20.0, 260.0)); + QVERIFY(webView->inputMethodHints() & Qt::ImhUrlCharactersOnly); + + delete webView; + delete view; +} + + QTEST_MAIN(tst_QGraphicsWebView) diff --git a/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.qrc b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.qrc new file mode 100644 index 0000000..c91bb9c --- /dev/null +++ b/WebKit/qt/tests/qgraphicswebview/tst_qgraphicswebview.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>resources/input_types.html</file> +</qresource> +</RCC> + diff --git a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 630ccce..5e6f4e6 100644 --- a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -77,6 +77,7 @@ private slots: void acceptNavigationRequest(); void infiniteLoopJS(); + void geolocationRequestJS(); void loadFinished(); void acceptNavigationRequestWithNewWindow(); void userStyleSheet(); @@ -123,6 +124,7 @@ private slots: void testJSPrompt(); void showModalDialog(); void testStopScheduledPageRefresh(); + void findText(); private: QWebView* m_view; @@ -213,16 +215,52 @@ public: public slots: bool shouldInterruptJavaScript() { - return true; + return true; + } + bool allowGeolocationRequest(QWebFrame *frame) + { + return m_allowGeolocation; + } + +public: + void setGeolocationPermission(bool allow) + { + m_allowGeolocation = allow; } + +private: + bool m_allowGeolocation; }; void tst_QWebPage::infiniteLoopJS() { JSTestPage* newPage = new JSTestPage(m_view); m_view->setPage(newPage); - m_view->setHtml(QString("<html><bodytest</body></html>"), QUrl()); + m_view->setHtml(QString("<html><body>test</body></html>"), QUrl()); m_view->page()->mainFrame()->evaluateJavaScript("var run = true;var a = 1;while(run){a++;}"); + delete newPage; +} + +void tst_QWebPage::geolocationRequestJS() +{ + JSTestPage* newPage = new JSTestPage(m_view); + newPage->setGeolocationPermission(false); + m_view->setPage(newPage); + m_view->setHtml(QString("<html><body>test</body></html>"), QUrl()); + m_view->page()->mainFrame()->evaluateJavaScript("var errorCode = 0; function error(err) { errorCode = err.code; } function success(pos) { } navigator.geolocation.getCurrentPosition(success, error)"); + QTest::qWait(2000); + QVariant empty = m_view->page()->mainFrame()->evaluateJavaScript("errorCode"); + + QVERIFY(empty.type() == QVariant::Double && empty.toInt() != 0); + + newPage->setGeolocationPermission(true); + m_view->page()->mainFrame()->evaluateJavaScript("errorCode = 0; navigator.geolocation.getCurrentPosition(success, error);"); + empty = m_view->page()->mainFrame()->evaluateJavaScript("errorCode"); + + //http://dev.w3.org/geo/api/spec-source.html#position + //PositionError: const unsigned short PERMISSION_DENIED = 1; + QVERIFY(empty.type() == QVariant::Double && empty.toInt() != 1); + delete newPage; } void tst_QWebPage::loadFinished() @@ -2116,5 +2154,21 @@ void tst_QWebPage::testStopScheduledPageRefresh() QCOMPARE(page2.mainFrame()->url().toString(), QString("about:blank")); } +void tst_QWebPage::findText() +{ + m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>")); + m_page->triggerAction(QWebPage::SelectAll); + QVERIFY(!m_page->selectedText().isEmpty()); + m_page->findText(""); + QVERIFY(m_page->selectedText().isEmpty()); + QStringList words = (QStringList() << "foo" << "bar"); + foreach (QString subString, words) { + m_page->findText(subString, QWebPage::FindWrapsAroundDocument); + QCOMPARE(m_page->selectedText(), subString); + m_page->findText(""); + QVERIFY(m_page->selectedText().isEmpty()); + } +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" diff --git a/WebKit/qt/tests/qwebview/resources/input_types.html b/WebKit/qt/tests/qwebview/resources/input_types.html new file mode 100644 index 0000000..18ab314 --- /dev/null +++ b/WebKit/qt/tests/qwebview/resources/input_types.html @@ -0,0 +1,8 @@ +<html><body> +<input type='text' maxlength='20' style='position: absolute; left: 10px; top: 0px; height: 50px; width: 100px;'/><br> +<input type='password' style='position: absolute; left: 10px; top: 50px; height: 50px; width: 100px;'/><br> +<input type='tel' style='position: absolute; left: 10px; top: 100px; height: 50px; width: 100px;'/><br> +<input type='number' style='position: absolute; left: 10px; top: 150px; height: 50px; width: 100px;'/><br> +<input type='email' style='position: absolute; left: 10px; top: 200px; height: 50px; width: 100px;'/><br> +<input type='url' style='position: absolute; left: 10px; top: 250px; height: 50px; width: 100px;'/><br>" +</body></html>
\ No newline at end of file diff --git a/WebKit/qt/tests/qwebview/tst_qwebview.cpp b/WebKit/qt/tests/qwebview/tst_qwebview.cpp index 100399e..835ad82 100644 --- a/WebKit/qt/tests/qwebview/tst_qwebview.cpp +++ b/WebKit/qt/tests/qwebview/tst_qwebview.cpp @@ -30,8 +30,6 @@ #include <qwebkitversion.h> #include <qwebframe.h> -#include <QDebug> - class tst_QWebView : public QObject { Q_OBJECT @@ -49,10 +47,25 @@ private slots: void reusePage_data(); void reusePage(); void microFocusCoordinates(); + void focusInputTypes(); void crashTests(); }; +class WebView : public QWebView +{ + Q_OBJECT + +public: + void fireMouseClick(QPoint point) { + QMouseEvent presEv(QEvent::MouseButtonPress, point, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent relEv(QEvent::MouseButtonRelease, point, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QWebView::mousePressEvent(&presEv); + QWebView::mousePressEvent(&relEv); + } + +}; + // This will be called before the first test function is executed. // It is only called once. void tst_QWebView::initTestCase() @@ -230,6 +243,52 @@ void tst_QWebView::microFocusCoordinates() QCOMPARE(initialMicroFocus.toRect().translated(QPoint(0,-50)), currentMicroFocus.toRect()); } +void tst_QWebView::focusInputTypes() +{ + QWebPage* page = new QWebPage; + WebView* webView = new WebView; + webView->setPage( page ); + + QCoreApplication::processEvents(); + QUrl url("qrc:///resources/input_types.html"); + page->mainFrame()->load(url); + page->mainFrame()->setFocus(); + + QVERIFY(waitForSignal(page, SIGNAL(loadFinished(bool)))); + + // 'text' type + webView->fireMouseClick(QPoint(20, 10)); +#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) || defined(Q_OS_SYMBIAN) + QVERIFY(webView->inputMethodHints() & Qt::ImhNoAutoUppercase); + QVERIFY(webView->inputMethodHints() & Qt::ImhNoPredictiveText); +#else + QVERIFY(webView->inputMethodHints() == Qt::ImhNone); +#endif + + // 'password' field + webView->fireMouseClick(QPoint(20, 60)); + QVERIFY(webView->inputMethodHints() & Qt::ImhHiddenText); + + // 'tel' field + webView->fireMouseClick(QPoint(20, 110)); + QVERIFY(webView->inputMethodHints() & Qt::ImhDialableCharactersOnly); + + // 'number' field + webView->fireMouseClick(QPoint(20, 160)); + QVERIFY(webView->inputMethodHints() & Qt::ImhDigitsOnly); + + // 'email' field + webView->fireMouseClick(QPoint(20, 210)); + QVERIFY(webView->inputMethodHints() & Qt::ImhEmailCharactersOnly); + + // 'url' field + webView->fireMouseClick(QPoint(20, 260)); + QVERIFY(webView->inputMethodHints() & Qt::ImhUrlCharactersOnly); + + delete webView; + +} + QTEST_MAIN(tst_QWebView) #include "tst_qwebview.moc" diff --git a/WebKit/qt/tests/qwebview/tst_qwebview.qrc b/WebKit/qt/tests/qwebview/tst_qwebview.qrc index 5abc64c..8710a9a 100644 --- a/WebKit/qt/tests/qwebview/tst_qwebview.qrc +++ b/WebKit/qt/tests/qwebview/tst_qwebview.qrc @@ -2,6 +2,7 @@ <qresource> <file>resources/index.html</file> <file>resources/frame_a.html</file> + <file>resources/input_types.html</file> </qresource> </RCC> |