Diff
Modified: trunk/Source/WebKit/qt/ChangeLog (153750 => 153751)
--- trunk/Source/WebKit/qt/ChangeLog 2013-08-06 12:52:36 UTC (rev 153750)
+++ trunk/Source/WebKit/qt/ChangeLog 2013-08-06 13:58:39 UTC (rev 153751)
@@ -1,3 +1,23 @@
+2013-08-06 Benjamin Dupont <[email protected]>
+
+ [Qt] Add Page Visibility API support
+ https://bugs.webkit.org/show_bug.cgi?id=109422
+
+ 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):
+
2013-07-27 Mark Rowe <[email protected]>
Logging should be configurable using human-readable channel names rather than crazy bitmasks
Modified: trunk/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp (153750 => 153751)
--- trunk/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp 2013-08-06 12:52:36 UTC (rev 153750)
+++ trunk/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp 2013-08-06 13:58:39 UTC (rev 153751)
@@ -149,6 +149,40 @@
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(),
@@ -280,6 +314,22 @@
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
+{
+ return webCoreVisibilityStateToWebPageVisibilityState(page->visibilityState());
+}
+
void QWebPageAdapter::setNetworkAccessManager(QNetworkAccessManager *manager)
{
if (manager == networkManager)
Modified: trunk/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h (153750 => 153751)
--- trunk/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h 2013-08-06 12:52:36 UTC (rev 153750)
+++ trunk/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.h 2013-08-06 13:58:39 UTC (rev 153751)
@@ -133,6 +133,14 @@
ScrollByDocument
};
+ // Must match with values of QWebPage::VisibilityState enum.
+ enum VisibilityState {
+ VisibilityStateVisible,
+ VisibilityStateHidden,
+ VisibilityStatePrerender,
+ VisibilityStateUnloaded
+ };
+
QWebPageAdapter();
virtual ~QWebPageAdapter();
@@ -247,6 +255,9 @@
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>);
Modified: trunk/Source/WebKit/qt/WidgetApi/qwebpage.cpp (153750 => 153751)
--- trunk/Source/WebKit/qt/WidgetApi/qwebpage.cpp 2013-08-06 12:52:36 UTC (rev 153750)
+++ trunk/Source/WebKit/qt/WidgetApi/qwebpage.cpp 2013-08-06 13:58:39 UTC (rev 153751)
@@ -1056,6 +1056,20 @@
*/
/*!
+ \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
@@ -3138,7 +3152,32 @@
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()
Modified: trunk/Source/WebKit/qt/WidgetApi/qwebpage.h (153750 => 153751)
--- trunk/Source/WebKit/qt/WidgetApi/qwebpage.h 2013-08-06 12:52:36 UTC (rev 153750)
+++ trunk/Source/WebKit/qt/WidgetApi/qwebpage.h 2013-08-06 13:58:39 UTC (rev 153751)
@@ -78,7 +78,8 @@
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,
@@ -216,6 +217,13 @@
Geolocation
};
+ enum VisibilityState {
+ VisibilityStateVisible,
+ VisibilityStateHidden,
+ VisibilityStatePrerender,
+ VisibilityStateUnloaded
+ };
+
class QWEBKITWIDGETS_EXPORT ViewportAttributes {
public:
ViewportAttributes();
@@ -275,6 +283,9 @@
quint64 totalBytes() const;
quint64 bytesReceived() const;
+ VisibilityState visibilityState() const;
+ void setVisibilityState(VisibilityState);
+
bool hasSelection() const;
QString selectedText() const;
QString selectedHtml() const;
Modified: trunk/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp (153750 => 153751)
--- trunk/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp 2013-08-06 12:52:36 UTC (rev 153750)
+++ trunk/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp 2013-08-06 13:58:39 UTC (rev 153751)
@@ -168,6 +168,8 @@
void screenshot_data();
void screenshot();
+ void changeVisibilityState();
+
#if defined(ENABLE_WEBGL) && ENABLE_WEBGL
void acceleratedWebGLScreenshotWithoutView();
void unacceleratedWebGLScreenshotWithoutView();
@@ -3132,6 +3134,82 @@
}
#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;