diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index bf0e80be9a1b6949eab17864db4009ad75d6dca7..9a29a1e0f4f8c6dda2e775389b73ff073b6fafab 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -629,7 +629,9 @@ bool RenderWidgetHostViewQt::HasAcceleratedSurface(const gfx::Size&)
 void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame)
 {
     bool scrollOffsetChanged = (m_lastScrollOffset != frame->metadata.root_scroll_offset);
+    bool contentsSizeChanged = (m_lastContentsSize != frame->metadata.root_layer_size);
     m_lastScrollOffset = frame->metadata.root_scroll_offset;
+    m_lastContentsSize = frame->metadata.root_layer_size;
     Q_ASSERT(!m_needsDelegatedFrameAck);
     m_needsDelegatedFrameAck = true;
     m_pendingOutputSurfaceId = output_surface_id;
@@ -652,6 +654,8 @@ void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, sco
 
     if (scrollOffsetChanged)
         m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset));
+    if (contentsSizeChanged)
+        m_adapterClient->updateContentsSize(toQt(m_lastContentsSize));
 }
 
 void RenderWidgetHostViewQt::GetScreenInfo(blink::WebScreenInfo* results)
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 274138dcf53178d38477605be7f78f62c08f0fd9..a8b93bd95cc87be2bed03e2e71248f0031d63c39 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -202,6 +202,8 @@ public:
 #endif // QT_NO_ACCESSIBILITY
     void didFirstVisuallyNonEmptyLayout();
 
+    gfx::SizeF lastContentsSize() const { return m_lastContentsSize; }
+
 private:
     void sendDelegatedFrameAck();
     void processMotionEvent(const ui::MotionEvent &motionEvent);
@@ -235,6 +237,7 @@ private:
     bool m_initPending;
 
     gfx::Vector2dF m_lastScrollOffset;
+    gfx::SizeF m_lastContentsSize;
 };
 
 } // namespace QtWebEngineCore
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 8f69fb92c5999113cb2a33abb866f4e76a5eeafa..aa9a2cf10374b029e697207da3d63e0ec50c70c4 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -837,6 +837,14 @@ QPointF WebContentsAdapter::lastScrollOffset() const
     return QPointF();
 }
 
+QSizeF WebContentsAdapter::lastContentsSize() const
+{
+    Q_D(const WebContentsAdapter);
+    if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt *>(d->webContents->GetRenderWidgetHostView()))
+        return toQt(rwhv->lastContentsSize());
+    return QSizeF();
+}
+
 void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags)
 {
     Q_D(WebContentsAdapter);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 39cc48834357828dd7d1b2a8120c9afa5dd5661e..9de22c133d76ed14895ce1d82c1f6ee80de58824 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -144,6 +144,7 @@ public:
     void setWebChannel(QWebChannel *);
 
     QPointF lastScrollOffset() const;
+    QSizeF lastContentsSize() const;
 
     // meant to be used within WebEngineCore only
     content::WebContents *webContents() const;
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 94c6835ed3b132498ddc637d6e0603dc0cc961c0..42e3e45004c951823bd562e93c17c528e2761893 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -237,6 +237,7 @@ public:
 
     virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0;
     virtual void updateScrollPosition(const QPointF &position) = 0;
+    virtual void updateContentsSize(const QSizeF &size) = 0;
 
     virtual BrowserContextAdapter* browserContextAdapter() = 0;
 
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 1a8a19993df69e6ed6fc29fdfa56ceba16b582fa..431d33c932d76c0ac9a6c71166dbfa4cc41a2675 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -899,6 +899,12 @@ void QQuickWebEngineViewPrivate::updateScrollPosition(const QPointF &position)
     Q_EMIT q->scrollPositionChanged(position);
 }
 
+void QQuickWebEngineViewPrivate::updateContentsSize(const QSizeF &size)
+{
+    Q_Q(QQuickWebEngineView);
+    Q_EMIT q->contentsSizeChanged(size);
+}
+
 void QQuickWebEngineViewPrivate::renderProcessTerminated(
         RenderProcessTerminationStatus terminationStatus, int exitCode)
 {
@@ -1308,6 +1314,12 @@ void QQuickWebEngineView::triggerWebAction(WebAction action)
     }
 }
 
+QSizeF QQuickWebEngineView::contentsSize() const
+{
+    Q_D(const QQuickWebEngineView);
+    return d->adapter->lastContentsSize();
+}
+
 QPointF QQuickWebEngineView::scrollPosition() const
 {
     Q_D(const QQuickWebEngineView);
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index aaf4c4bcf197e8649f1d6aef1b00e9a06e4f811b..eff9b031e76b19fdf06806426c349c103d6955d9 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -104,6 +104,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
     Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 1)
     Q_PROPERTY(bool activeFocusOnPress READ activeFocusOnPress WRITE setActiveFocusOnPress NOTIFY activeFocusOnPressChanged REVISION 2)
     Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged REVISION 2)
+    Q_PROPERTY(QSizeF contentsSize READ contentsSize NOTIFY contentsSizeChanged FINAL REVISION 3)
     Q_PROPERTY(QPointF scrollPosition READ scrollPosition NOTIFY scrollPositionChanged FINAL REVISION 3)
 
 #ifdef ENABLE_QML_TESTSUPPORT_API
@@ -138,6 +139,7 @@ public:
     void setZoomFactor(qreal arg);
     QColor backgroundColor() const;
     void setBackgroundColor(const QColor &color);
+    QSizeF contentsSize() const;
     QPointF scrollPosition() const;
 
     QQuickWebEngineViewExperimental *experimental() const;
@@ -307,6 +309,7 @@ Q_SIGNALS:
     Q_REVISION(2) void activeFocusOnPressChanged(bool);
     Q_REVISION(2) void backgroundColorChanged();
     Q_REVISION(2) void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
+    Q_REVISION(3) void contentsSizeChanged(const QSizeF& size);
     Q_REVISION(3) void scrollPositionChanged(const QPointF& position);
 
 protected:
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 3e6aa6317ef47efba13f466740cd19a97b78dc14..08d5841924dd9cbae4ab5814727cee913d2be337 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -170,6 +170,7 @@ public:
     virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
                                      int exitCode) Q_DECL_OVERRIDE;
     virtual void updateScrollPosition(const QPointF &position) Q_DECL_OVERRIDE;
+    virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE;
 
     virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
 
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 434667e4951e9c55d811d5cadfcad3dfd7e5758c..3798371590e1e9d7ee12e2f08749ef46e828fbee 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -373,6 +373,12 @@ void QWebEnginePagePrivate::updateScrollPosition(const QPointF &position)
     Q_EMIT q->scrollPositionChanged(position);
 }
 
+void QWebEnginePagePrivate::updateContentsSize(const QSizeF &size)
+{
+    Q_Q(QWebEnginePage);
+    Q_EMIT q->contentsSizeChanged(size);
+}
+
 BrowserContextAdapter *QWebEnginePagePrivate::browserContextAdapter()
 {
     return profile->d_ptr->browserContext();
@@ -1307,6 +1313,17 @@ QPointF QWebEnginePage::scrollPosition() const
     return d->adapter->lastScrollOffset();
 }
 
+/*!
+    \since 5.7
+
+    Returns the size of the page contents.
+*/
+QSizeF QWebEnginePage::contentsSize() const
+{
+    Q_D(const QWebEnginePage);
+    return d->adapter->lastContentsSize();
+}
+
 QT_END_NAMESPACE
 
 #include "moc_qwebenginepage.cpp"
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 13d6b49352a8fe7f2dd8e73412c457eec53978d0..ae616aaed97f437671345f941640bb7579554e9b 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -69,6 +69,7 @@ class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject {
     Q_PROPERTY(QUrl url READ url WRITE setUrl)
     Q_PROPERTY(QUrl iconUrl READ iconUrl)
     Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
+    Q_PROPERTY(QSizeF contentsSize READ contentsSize NOTIFY contentsSizeChanged)
     Q_PROPERTY(QPointF scrollPosition READ scrollPosition NOTIFY scrollPositionChanged)
 
 public:
@@ -226,6 +227,7 @@ public:
     void setZoomFactor(qreal factor);
 
     QPointF scrollPosition() const;
+    QSizeF contentsSize() const;
 
     void runJavaScript(const QString& scriptSource);
 #ifdef Q_QDOC
@@ -267,6 +269,7 @@ Q_SIGNALS:
     void iconUrlChanged(const QUrl &url);
 
     void scrollPositionChanged(const QPointF &position);
+    void contentsSizeChanged(const QSizeF &size);
 
 protected:
     virtual QWebEnginePage *createWindow(WebWindowType type);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index e67e6303edeef162a848fb65d081255de724e075..d05f76b1a195da4bd7591cd7f97593bdd9e30c3b 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -121,7 +121,8 @@ public:
     virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
     virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
                                      int exitCode) Q_DECL_OVERRIDE;
-    virtual void updateScrollPosition(const QPointF &position);
+    virtual void updateScrollPosition(const QPointF &position) Q_DECL_OVERRIDE;
+    virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE;
 
     virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;