diff options
| author | Benjamin Dupont <bdupont@nds.com> | 2013-08-06 13:58:39 +0000 |
|---|---|---|
| committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-09 16:26:24 +0200 |
| commit | a8257e82b8a4c41a0a0788943a2346d169a737a6 (patch) | |
| tree | 03aabcb57ea8800c08519c0763289c4161732327 | |
| parent | f3484678deb631b7d994dd400b609dcb7bbbc04b (diff) | |
| download | qtwebkit-a8257e82b8a4c41a0a0788943a2346d169a737a6.tar.gz | |
[Qt] Add Page Visibility API support
https://bugs.webkit.org/show_bug.cgi?id=109422
Patch by Benjamin Dupont <bdupont@nds.com> on 2013-08-06
Reviewed by Simon Hausmann.
* WebCoreSupport/QWebPageAdapter.cpp:
(webPageVisibilityStateToWebCoreVisibilityState):
(webCoreVisibilityStateToWebPageVisibilityState):
(QWebPageAdapter::setVisibilityState):
(QWebPageAdapter::visibilityState):
* WebCoreSupport/QWebPageAdapter.h:
* WidgetApi/qwebpage.cpp:
(QWebPage::setVisibilityState):
(QWebPage::visibilityState):
* WidgetApi/qwebpage.h:
* tests/qwebpage/tst_qwebpage.cpp:
(tst_QWebPage::changeVisibilityState):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153751 268f45cc-cd09-0410-ab3c-d52691b4dbfc
[Qt] Build fix after r153751
Unreviewed build fix.
Fix build when PAGE_VISIBILITY_API is disabled.
* WebCoreSupport/QWebPageAdapter.cpp:
(QWebPageAdapter::visibilityState):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153782 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Change-Id: I7c99337a902d7d06cde03107ebf71e3fce430fdf
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
| -rw-r--r-- | Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp | 54 | ||||
| -rw-r--r-- | Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h | 11 | ||||
| -rw-r--r-- | Source/WebKit/qt/WidgetApi/qwebpage.cpp | 39 | ||||
| -rw-r--r-- | Source/WebKit/qt/WidgetApi/qwebpage.h | 13 | ||||
| -rw-r--r-- | Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 78 |
5 files changed, 194 insertions, 1 deletions
diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp index ae01f4b1e..ddedbd185 100644 --- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp +++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp @@ -136,6 +136,40 @@ static inline Qt::DropAction dragOpToDropAction(unsigned actions) return result; } +static inline WebCore::PageVisibilityState webPageVisibilityStateToWebCoreVisibilityState(QWebPageAdapter::VisibilityState state) +{ + switch (state) { + case QWebPageAdapter::VisibilityStatePrerender: + return WebCore::PageVisibilityStatePrerender; + case QWebPageAdapter::VisibilityStateUnloaded: + return WebCore::PageVisibilityStateUnloaded; + case QWebPageAdapter::VisibilityStateVisible: + return WebCore::PageVisibilityStateVisible; + case QWebPageAdapter::VisibilityStateHidden: + return WebCore::PageVisibilityStateHidden; + default: + ASSERT(false); + return WebCore::PageVisibilityStateHidden; + } +} + +static inline QWebPageAdapter::VisibilityState webCoreVisibilityStateToWebPageVisibilityState(WebCore::PageVisibilityState state) +{ + switch (state) { + case WebCore::PageVisibilityStatePrerender: + return QWebPageAdapter::VisibilityStatePrerender; + case WebCore::PageVisibilityStateUnloaded: + return QWebPageAdapter::VisibilityStateUnloaded; + case WebCore::PageVisibilityStateVisible: + return QWebPageAdapter::VisibilityStateVisible; + case WebCore::PageVisibilityStateHidden: + return QWebPageAdapter::VisibilityStateHidden; + default: + ASSERT(false); + return QWebPageAdapter::VisibilityStateHidden; + } +} + static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame) { return WebCore::FrameLoadRequest(frame->document()->securityOrigin(), @@ -254,6 +288,26 @@ void QWebPageAdapter::registerUndoStep(WTF::PassRefPtr<WebCore::UndoStep> step) createUndoStep(QSharedPointer<UndoStepQt>(new UndoStepQt(step))); } +void QWebPageAdapter::setVisibilityState(VisibilityState state) +{ +#if ENABLE(PAGE_VISIBILITY_API) + if (!page) + return; + page->setVisibilityState(webPageVisibilityStateToWebCoreVisibilityState(state), false); +#else + Q_UNUSED(state); +#endif +} + +QWebPageAdapter::VisibilityState QWebPageAdapter::visibilityState() const +{ +#if ENABLE(PAGE_VISIBILITY_API) + return webCoreVisibilityStateToWebPageVisibilityState(page->visibilityState()); +#else + return QWebPageAdapter::VisibilityStateVisible; +#endif +} + void QWebPageAdapter::setNetworkAccessManager(QNetworkAccessManager *manager) { if (manager == networkManager) diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h index 438a7651d..575a6954f 100644 --- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h +++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h @@ -129,6 +129,14 @@ public: ScrollByDocument }; + // Must match with values of QWebPage::VisibilityState enum. + enum VisibilityState { + VisibilityStateVisible, + VisibilityStateHidden, + VisibilityStatePrerender, + VisibilityStateUnloaded + }; + QWebPageAdapter(); virtual ~QWebPageAdapter(); @@ -243,6 +251,9 @@ public: virtual void createAndSetCurrentContextMenu(const QList<MenuItemDescription>&, QBitArray*) = 0; virtual bool handleScrollbarContextMenuEvent(QContextMenuEvent*, bool, ScrollDirection*, ScrollGranularity*) = 0; + void setVisibilityState(VisibilityState); + VisibilityState visibilityState() const; + static QWebPageAdapter* kit(WebCore::Page*); WebCore::ViewportArguments viewportArguments() const; void registerUndoStep(WTF::PassRefPtr<WebCore::UndoStep>); diff --git a/Source/WebKit/qt/WidgetApi/qwebpage.cpp b/Source/WebKit/qt/WidgetApi/qwebpage.cpp index 4931a4854..d6cdb013b 100644 --- a/Source/WebKit/qt/WidgetApi/qwebpage.cpp +++ b/Source/WebKit/qt/WidgetApi/qwebpage.cpp @@ -1054,6 +1054,20 @@ QWebInspector* QWebPagePrivate::getOrCreateInspector() */ /*! + \enum QWebPage::VisibilityState + + This enum defines visibility states that a webpage can take. + + \value VisibilityStateVisible The webpage is at least partially visible at on at least one screen. + \value VisibilityStateHidden The webpage is not visible at all on any screen. + \value VisibilityStatePrerender The webpage is loaded off-screen and is not visible. + \value VisibilityStateUnloaded The webpage is unloading its content. + More information about this values can be found at \l{ http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate}{W3C Recommendation: Page Visibility: visibilityState attribute}. + + \sa QWebPage::visibilityState +*/ + +/*! \enum QWebPage::LinkDelegationPolicy This enum defines the delegation policies a webpage can have when activating links and emitting @@ -3136,6 +3150,31 @@ quint64 QWebPage::bytesReceived() const return d->m_bytesReceived; } + +/*! + \property QWebPage::visibilityState + \brief the page's visibility state + + This property should be changed by Qt applications who want to notify the JavaScript application + that the visibility state has changed (e.g. by reimplementing QWidget::setVisible). + The visibility state will be updated with the \a state parameter value only if it's different from the previous set. + Then, HTML DOM Document Object attributes 'hidden' and 'visibilityState' + will be updated to the correct value and a 'visiblitychange' event will be fired. + More information about this HTML5 API can be found at \l{http://www.w3.org/TR/page-visibility/}{W3C Recommendation: Page Visibility}. + + By default, this property is set to VisibilityStateVisible. +*/ +void QWebPage::setVisibilityState(VisibilityState state) +{ + d->setVisibilityState(static_cast<QWebPageAdapter::VisibilityState>(state)); +} + +QWebPage::VisibilityState QWebPage::visibilityState() const +{ + return static_cast<VisibilityState>(d->visibilityState()); +} + + /*! \since 4.8 \fn void QWebPage::viewportChangeRequested() diff --git a/Source/WebKit/qt/WidgetApi/qwebpage.h b/Source/WebKit/qt/WidgetApi/qwebpage.h index 6aa303b5c..7c23bf39d 100644 --- a/Source/WebKit/qt/WidgetApi/qwebpage.h +++ b/Source/WebKit/qt/WidgetApi/qwebpage.h @@ -78,7 +78,8 @@ class QWEBKITWIDGETS_EXPORT QWebPage : public QObject { Q_PROPERTY(LinkDelegationPolicy linkDelegationPolicy READ linkDelegationPolicy WRITE setLinkDelegationPolicy) Q_PROPERTY(QPalette palette READ palette WRITE setPalette) Q_PROPERTY(bool contentEditable READ isContentEditable WRITE setContentEditable) - Q_ENUMS(LinkDelegationPolicy NavigationType WebAction) + Q_PROPERTY(VisibilityState visibilityState READ visibilityState WRITE setVisibilityState) + Q_ENUMS(LinkDelegationPolicy NavigationType VisibilityState WebAction) public: enum NavigationType { NavigationTypeLinkClicked, @@ -213,6 +214,13 @@ public: Geolocation }; + enum VisibilityState { + VisibilityStateVisible, + VisibilityStateHidden, + VisibilityStatePrerender, + VisibilityStateUnloaded + }; + class QWEBKITWIDGETS_EXPORT ViewportAttributes { public: ViewportAttributes(); @@ -272,6 +280,9 @@ public: quint64 totalBytes() const; quint64 bytesReceived() const; + VisibilityState visibilityState() const; + void setVisibilityState(VisibilityState); + bool hasSelection() const; QString selectedText() const; QString selectedHtml() const; diff --git a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index fe0332042..5d2255624 100644 --- a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -168,6 +168,8 @@ private Q_SLOTS: void screenshot_data(); void screenshot(); + void changeVisibilityState(); + #if defined(ENABLE_WEBGL) && ENABLE_WEBGL void acceleratedWebGLScreenshotWithoutView(); void unacceleratedWebGLScreenshotWithoutView(); @@ -3128,6 +3130,82 @@ void tst_QWebPage::macCopyUnicodeToClipboard() } #endif +void tst_QWebPage::changeVisibilityState() +{ +#if ENABLE_PAGE_VISIBILITY_API + QVariant stateBool, stateString, cpt; + + m_page->mainFrame()->setHtml("<html><body></body></html>"); + m_page->mainFrame()->evaluateJavaScript("var stateBool = undefined, stateString = undefined, cpt = 0; var visibilityCallBack = function () {stateBool = document['hidden']; stateString = document['visibilityState']; cpt++;};document.addEventListener('visibilitychange', visibilityCallBack, false);"); + + // The visibility state should be initialised to visible. + QCOMPARE(m_page->visibilityState(), QWebPage::VisibilityStateVisible); + stateBool = m_page->mainFrame()->evaluateJavaScript("document['hidden']"); + QVERIFY(stateBool.type() == QVariant::Bool && !stateBool.toBool()); + stateString = m_page->mainFrame()->evaluateJavaScript("document['visibilityState']"); + QVERIFY(stateString.type() == QVariant::String && stateString.toString() == QString("visible")); + + // Try to change with the same value. + m_page->setVisibilityState(QWebPage::VisibilityStateVisible); + QVERIFY(m_page->visibilityState() == QWebPage::VisibilityStateVisible); + // We check that there isn't any JS event that has been fired and + // visibility properties are still equals to visible. + stateBool = m_page->mainFrame()->evaluateJavaScript("document['hidden']"); + QVERIFY(stateBool.type() == QVariant::Bool && !stateBool.toBool()); + stateString = m_page->mainFrame()->evaluateJavaScript("document['visibilityState']"); + QVERIFY(stateString.type() == QVariant::String && stateString.toString() == QString("visible")); + cpt = m_page->mainFrame()->evaluateJavaScript("cpt"); + QVERIFY(cpt.type() == QVariant::Double && !cpt.toDouble()); + + // Try to change to with different values then check if a JS event has been fired + // and visibility properties have been updated correctly. + m_page->setVisibilityState(QWebPage::VisibilityStatePrerender); + QCOMPARE(m_page->visibilityState(), QWebPage::VisibilityStatePrerender); + stateBool = m_page->mainFrame()->evaluateJavaScript("stateBool"); + QVERIFY(stateBool.type() == QVariant::Bool && stateBool.toBool()); + stateString = m_page->mainFrame()->evaluateJavaScript("stateString"); + QVERIFY(stateString.type() == QVariant::String && stateString.toString() == QString("prerender")); + cpt = m_page->mainFrame()->evaluateJavaScript("cpt"); + QVERIFY(cpt.type() == QVariant::Double && cpt.toDouble() == 1); + + m_page->setVisibilityState(QWebPage::VisibilityStateUnloaded); + QCOMPARE(m_page->visibilityState(), QWebPage::VisibilityStateUnloaded); + stateBool = m_page->mainFrame()->evaluateJavaScript("stateBool"); + QVERIFY(stateBool.type() == QVariant::Bool && stateBool.toBool()); + stateString = m_page->mainFrame()->evaluateJavaScript("stateString"); + QVERIFY(stateString.type() == QVariant::String && stateString.toString() == QString("unloaded")); + cpt = m_page->mainFrame()->evaluateJavaScript("cpt"); + QVERIFY(cpt.type() == QVariant::Double && cpt.toDouble() == 2); + + m_page->setVisibilityState(QWebPage::VisibilityStateVisible); + QCOMPARE(m_page->visibilityState(), QWebPage::VisibilityStateVisible); + stateBool = m_page->mainFrame()->evaluateJavaScript("stateBool"); + QVERIFY(stateBool.type() == QVariant::Bool && !stateBool.toBool()); + stateString = m_page->mainFrame()->evaluateJavaScript("stateString"); + QVERIFY(stateString.type() == QVariant::String && stateString.toString() == QString("visible")); + cpt = m_page->mainFrame()->evaluateJavaScript("cpt"); + QVERIFY(cpt.type() == QVariant::Double && cpt.toDouble() == 3); + + m_page->setVisibilityState(QWebPage::VisibilityStateHidden); + QCOMPARE(m_page->visibilityState(), QWebPage::VisibilityStateHidden); + stateBool = m_page->mainFrame()->evaluateJavaScript("stateBool"); + QVERIFY(stateBool.type() == QVariant::Bool && stateBool.toBool()); + stateString = m_page->mainFrame()->evaluateJavaScript("stateString"); + QVERIFY(stateString.type() == QVariant::String && stateString.toString() == QString("hidden")); + cpt = m_page->mainFrame()->evaluateJavaScript("cpt"); + QVERIFY(cpt.type() == QVariant::Double && cpt.toDouble() == 4); + + m_page->setVisibilityState(QWebPage::VisibilityStateVisible); + QCOMPARE(m_page->visibilityState(), QWebPage::VisibilityStateVisible); + stateBool = m_page->mainFrame()->evaluateJavaScript("stateBool"); + QVERIFY(stateBool.type() == QVariant::Bool && !stateBool.toBool()); + stateString = m_page->mainFrame()->evaluateJavaScript("stateString"); + QVERIFY(stateString.type() == QVariant::String && stateString.toString() == QString("visible")); + cpt = m_page->mainFrame()->evaluateJavaScript("cpt"); + QVERIFY(cpt.type() == QVariant::Double && cpt.toDouble() == 5); +#endif +} + void tst_QWebPage::contextMenuCopy() { QWebView view; |
