[Qt] QtWebKit does not support viewport meta tag
https://bugs.webkit.org/show_bug.cgi?id=39902
Patch by Jesus Sanchez-Palencia <jesus@webkit.org>, Kenneth Rohde Christiansen <kenneth@webkit.org> on 2010-06-01
Reviewed by Simon Hausmann.
WebCore:
Add windowRect() to page client.
* platform/qt/QWebPageClient.h:
WebKit/qt:
This implements didReceiveViewportArguments in our ChromeClientQt
which is hooked up with QWebPage::viewportChangeRequested().
This signal does not affect the current default behavior.
The documentation of the signal explains how to make use of this new feature.
* Api/qwebframe_p.h:
(QWebFramePrivate::QWebFramePrivate):
Store information about whether the page has been laid out or not.
* Api/qwebpage.cpp:
(QWebPage::viewportChangeRequested):
* Api/qwebpage_p.h:
Added class QtViewportHintsPrivate.
* Api/qwebpage.h:
(QWebPage::setPreferredContentsSize):
Improved documentation and now only layout if the page had already
passed layout phase.
Added class QWebPage::ViewportHints.
* WebCoreSupport/ChromeClientQt.cpp:
(WebCore::ChromeClientQt::windowRect):
Modified to work as intended by the DOM, for both QWebView
and QGraphicsWebView.
(WebCore::ChromeClientQt::didReceiveViewportArguments):
Emits the signal QWebPage::viewportChangeRequested.
* WebCoreSupport/ChromeClientQt.h:
* WebCoreSupport/FrameLoaderClientQt.cpp:
(WebCore::FrameLoaderClientQt::dispatchDidCommitLoad):
(WebCore::FrameLoaderClientQt::dispatchDidFirstLayout):
Update information about whether the page has been laid out or not.
If the page has been laid out we ignore any further viewport meta data.
* WebCoreSupport/PageClientQt.cpp:
(WebCore::PageClientQWidget::windowRect):
(WebCore::PageClientQGraphicsWidget::windowRect):
(WebCore::PageClientQGraphicsWidget::graphicsItemVisibleRect):
* WebCoreSupport/PageClientQt.h:
The PageClient is now responsible for providing the right window rect.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@61342
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2010-06-17 Jesus Sanchez-Palencia <jesus@webkit.org>, Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] QtWebKit does not support viewport meta tag
+ https://bugs.webkit.org/show_bug.cgi?id=39902
+
+ Add windowRect() to page client.
+
+ * platform/qt/QWebPageClient.h:
+
2010-06-17 Stephen White <senorblanco@chromium.org>
Reviewed by David Levin.
virtual QObject* pluginParent() const = 0;
virtual QStyle* style() const = 0;
-
+
virtual QRectF graphicsItemVisibleRect() const { return QRectF(); }
-
+
virtual bool viewResizesToContentsEnabled() const = 0;
+ virtual QRectF windowRect() const = 0;
+
protected:
#ifndef QT_NO_CURSOR
virtual QCursor cursor() const = 0;
, allowsScrolling(true)
, marginWidth(-1)
, marginHeight(-1)
+ , initialLayoutComplete(false)
{}
void init(QWebFrame* qframe, QWebFrameData* frameData);
void setPage(QWebPage*);
bool allowsScrolling;
int marginWidth;
int marginHeight;
+ bool initialLayoutComplete;
};
class QWebHitTestResultPrivate {
\value WebModalDialog The window acts as modal dialog.
*/
+
+/*!
+ \class QWebPage::ViewportHints
+ \since 4.7
+ \brief The QWebPage::ViewportHints class describes hints that can be applied to a viewport.
+
+ QWebPage::ViewportHints provides a description of a viewport, such as viewport geometry,
+ initial scale factor with limits, plus information about whether a user should be able
+ to scale the contents in the viewport or not, ie. by zooming.
+
+ ViewportHints can be set by a web author using the viewport meta tag extension, documented
+ at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}.
+
+ All values might not be set, as such when dealing with the hints, the developer needs to
+ check whether the values are valid. Negative values denote an invalid qreal value.
+
+ \inmodule QtWebKit
+*/
+
+/*!
+ Constructs an empty QWebPage::ViewportHints.
+*/
+QWebPage::ViewportHints::ViewportHints()
+ : d(0)
+ , m_initialScaleFactor(-1.0)
+ , m_minimumScaleFactor(-1.0)
+ , m_maximumScaleFactor(-1.0)
+ , m_isUserScalable(true)
+ , m_isValid(false)
+{
+
+}
+
+/*!
+ Constructs a QWebPage::ViewportHints which is a copy from \a other .
+*/
+QWebPage::ViewportHints::ViewportHints(const QWebPage::ViewportHints& other)
+ : d(other.d)
+ , m_initialScaleFactor(other.m_initialScaleFactor)
+ , m_minimumScaleFactor(other.m_minimumScaleFactor)
+ , m_maximumScaleFactor(other.m_maximumScaleFactor)
+ , m_isUserScalable(other.m_isUserScalable)
+ , m_isValid(other.m_isValid)
+ , m_size(other.m_size)
+{
+
+}
+
+/*!
+ Destroys the QWebPage::ViewportHints.
+*/
+QWebPage::ViewportHints::~ViewportHints()
+{
+
+}
+
+/*!
+ Assigns the given QWebPage::ViewportHints to this viewport hints and returns a
+ reference to this.
+*/
+QWebPage::ViewportHints& QWebPage::ViewportHints::operator=(const QWebPage::ViewportHints& other)
+{
+ if (this != &other) {
+ d = other.d;
+ m_initialScaleFactor = other.m_initialScaleFactor;
+ m_minimumScaleFactor = other.m_minimumScaleFactor;
+ m_maximumScaleFactor = other.m_maximumScaleFactor;
+ m_isUserScalable = other.m_isUserScalable;
+ m_isValid = other.m_isValid;
+ m_size = other.m_size;
+ }
+
+ return *this;
+}
+
+/*! \fn inline bool QWebPage::ViewportHints::isValid() const
+ Returns whether this is a valid ViewportHints or not.
+
+ An invalid ViewportHints will have an empty QSize, negative values for scale factors and
+ true for the boolean isUserScalable.
+*/
+
+/*! \fn inline QSize QWebPage::ViewportHints::size() const
+ Returns the size of the viewport.
+*/
+
+/*! \fn inline qreal QWebPage::ViewportHints::initialScaleFactor() const
+ Returns the initial scale of the viewport as a multiplier.
+*/
+
+/*! \fn inline qreal QWebPage::ViewportHints::minimumScaleFactor() const
+ Returns the minimum scale value of the viewport as a multiplier.
+*/
+
+/*! \fn inline qreal QWebPage::ViewportHints::maximumScaleFactor() const
+ Returns the maximum scale value of the viewport as a multiplier.
+*/
+
+/*! \fn inline bool QWebPage::ViewportHints::isUserScalable() const
+ Determines whether or not the scale can be modified by the user.
+*/
+
+
/*!
\class QWebPage
\since 4.4
/*!
\property QWebPage::preferredContentsSize
\since 4.6
- \brief the preferred size of the contents
+ \brief a custom size used for laying out the page contents.
+
+ By default all pages are laid out using the viewport of the page as the base.
- If this property is set to a valid size, it is used to lay out the page.
- If it is not set (the default), the viewport size is used instead.
+ As pages mostly are designed for desktop usage, they often do not layout properly
+ on small devices as the contents require a certain view width. For this reason
+ it is common to use a different layout size and then scale the contents to fit
+ within the actual view.
+
+ If this property is set to a valid size, this size is used for all layout needs
+ instead of the size of the viewport.
+
+ Setting an invalid size, makes the page fall back to using the viewport size for layout.
\sa viewportSize
*/
-void QWebPage::setPreferredContentsSize(const QSize &size) const
+void QWebPage::setPreferredContentsSize(const QSize& size) const
{
+ // FIXME: Rename this method to setCustomLayoutSize
+
d->fixedLayoutSize = size;
- QWebFrame *frame = mainFrame();
- if (frame->d->frame && frame->d->frame->view()) {
- WebCore::FrameView* view = frame->d->frame->view();
+ QWebFrame* frame = mainFrame();
+ if (!frame->d->frame || !frame->d->frame->view())
+ return;
- if (size.isValid()) {
- view->setUseFixedLayout(true);
- view->setFixedLayoutSize(size);
- view->layout();
- } else if (view->useFixedLayout()) {
- view->setUseFixedLayout(false);
- view->layout();
- }
- }
+ WebCore::FrameView* view = frame->d->frame->view();
+
+ if (size.isValid()) {
+ view->setUseFixedLayout(true);
+ view->setFixedLayoutSize(size);
+ } else if (view->useFixedLayout())
+ view->setUseFixedLayout(false);
+
+ if (frame->d->initialLayoutComplete)
+ view->layout();
}
/*!
}
/*!
+ \since 4.7
+ \fn void QWebPage::viewportChangeRequested(const QWebPage::ViewportHints& hints)
+
+ This signal is emitted before any layout of the contents, giving you the viewport \a arguments
+ the web page would like you to use when laying out its contents, including elements fixed to the
+ viewport. This viewport might be larger that your actual viewport, meaning that a initialScaleFactor
+ should be applied. When no scale is given, it is assumed that the contents should be scaled
+ such that the width of the scaled contents fits within the actual viewport.
+
+ The minimum and maximum allowed scale represents the min and max values that the page
+ allows for scaling, and thus, affects the ability to zoom in on the page.
+
+ Invalid values are supplied for the values not explicitly set by the web author; thus an
+ invalid viewport size, and negative values for scale factor and limits. The boolean
+ ViewportHints::isUserScalable is set to true.
+
+ Page authors can provide the supplied values by using the viewport meta tag. More information
+ about this can be found at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}.
+
+ \sa QWebPage::ViewportHints, setPreferredContentsSize(), QGraphicsWebView::setScale()
+*/
+
+/*!
\fn void QWebPage::loadStarted()
This signal is emitted when a new load of the page is started.
class QWebNetworkRequest;
class QWebHistory;
-class QWebPagePrivate;
class QWebFrameData;
+class QWebHistoryItem;
+class QWebHitTestResult;
class QWebNetworkInterface;
+class QWebPagePrivate;
class QWebPluginFactory;
-class QWebHitTestResult;
-class QWebHistoryItem;
+class QtViewportHintsPrivate;
namespace WebCore {
class ChromeClientQt;
WebModalDialog
};
+ class ViewportHints {
+ public:
+ ViewportHints();
+ ViewportHints(const QWebPage::ViewportHints& other);
+
+ ~ViewportHints();
+
+ QWebPage::ViewportHints& operator=(const QWebPage::ViewportHints& other);
+
+ inline qreal initialScaleFactor() const { return m_initialScaleFactor; };
+ inline qreal minimumScaleFactor() const { return m_minimumScaleFactor; };
+ inline qreal maximumScaleFactor() const { return m_maximumScaleFactor; };
+ inline bool isUserScalable() const { return m_isUserScalable; };
+ inline bool isValid() const { return m_isValid; };
+ inline QSize size() const { return m_size; };
+
+ private:
+ QSharedDataPointer<QtViewportHintsPrivate> d;
+ qreal m_initialScaleFactor;
+ qreal m_minimumScaleFactor;
+ qreal m_maximumScaleFactor;
+ bool m_isUserScalable;
+ bool m_isValid;
+ QSize m_size;
+
+ friend class WebCore::ChromeClientQt;
+ };
+
+
explicit QWebPage(QObject *parent = 0);
~QWebPage();
void saveFrameStateRequested(QWebFrame* frame, QWebHistoryItem* item);
void restoreFrameStateRequested(QWebFrame* frame);
+ void viewportChangeRequested(const QWebPage::ViewportHints& hints);
+
protected:
virtual QWebPage *createWindow(WebWindowType type);
virtual QObject *createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues);
class QWebInspector;
class QWebPageClient;
+class QtViewportHintsPrivate : public QSharedData {
+public:
+ QtViewportHintsPrivate(QWebPage::ViewportHints* qq)
+ : q(qq)
+ { }
+
+ QWebPage::ViewportHints* q;
+};
+
class QWebPagePrivate {
public:
QWebPagePrivate(QWebPage*);
+2010-06-17 Jesus Sanchez-Palencia <jesus@webkit.org>, Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] QtWebKit does not support viewport meta tag
+ https://bugs.webkit.org/show_bug.cgi?id=39902
+
+ Add viewport meta tag support to QtWebKit API layer.
+
+ This implements didReceiveViewportArguments in our ChromeClientQt
+ which is hooked up with QWebPage::viewportChangeRequested().
+ This signal does not affect the current default behavior.
+ The documentation of the signal explains how to make use of this new feature.
+
+ * Api/qwebframe_p.h:
+ (QWebFramePrivate::QWebFramePrivate):
+ Store information about whether the page has been laid out or not.
+ * Api/qwebpage.cpp:
+ (QWebPage::viewportChangeRequested):
+ * Api/qwebpage_p.h:
+ Added class QtViewportHintsPrivate.
+ * Api/qwebpage.h:
+ (QWebPage::setPreferredContentsSize):
+ Improved documentation and now only layout if the page had already
+ passed layout phase.
+ Added class QWebPage::ViewportHints.
+ * WebCoreSupport/ChromeClientQt.cpp:
+ (WebCore::ChromeClientQt::windowRect):
+ Modified to work as intended by the DOM, for both QWebView
+ and QGraphicsWebView.
+ (WebCore::ChromeClientQt::didReceiveViewportArguments):
+ Emits the signal QWebPage::viewportChangeRequested.
+ * WebCoreSupport/ChromeClientQt.h:
+ * WebCoreSupport/FrameLoaderClientQt.cpp:
+ (WebCore::FrameLoaderClientQt::dispatchDidCommitLoad):
+ (WebCore::FrameLoaderClientQt::dispatchDidFirstLayout):
+ Update information about whether the page has been laid out or not.
+ If the page has been laid out we ignore any further viewport meta data.
+ * WebCoreSupport/PageClientQt.cpp:
+ (WebCore::PageClientQWidget::windowRect):
+ (WebCore::PageClientQGraphicsWidget::windowRect):
+ (WebCore::PageClientQGraphicsWidget::graphicsItemVisibleRect):
+ * WebCoreSupport/PageClientQt.h:
+ The PageClient is now responsible for providing the right window rect.
+
2010-06-17 Alexis Menard <alexis.menard@nokia.com>
Reviewed by Kenneth Rohde Christiansen.
#include "FrameLoaderClientQt.h"
#include "FrameView.h"
#include "Geolocation.h"
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayerQt.h"
+#endif
#include "HitTestResult.h"
#include "Icon.h"
#include "NotImplemented.h"
#include "NotificationPresenterClientQt.h"
-#include "ScrollbarTheme.h"
-#include "WindowFeatures.h"
+#include "PageClientQt.h"
#if defined(Q_WS_MAEMO_5)
#include "QtMaemoWebPopup.h"
#else
#include "QtFallbackWebPopup.h"
#endif
#include "QWebPageClient.h"
+#include "ScrollbarTheme.h"
#include "SecurityOrigin.h"
+#include "ViewportArguments.h"
+#include "WindowFeatures.h"
+#include "qgraphicswebview.h"
#include "qwebframe_p.h"
#include "qwebpage.h"
#include "qwebpage_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
-
namespace WebCore {
ChromeClientQt::ChromeClientQt(QWebPage* webPage)
qRound(rect.width()), qRound(rect.height())));
}
-
+/*!
+ windowRect represents the rect of the Window, including all interface elements
+ like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
+ by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
+*/
FloatRect ChromeClientQt::windowRect()
{
- if (!m_webPage)
- return FloatRect();
-
- QWidget* view = m_webPage->view();
- if (!view)
+ if (!platformPageClient())
return FloatRect();
- return IntRect(view->window()->geometry());
+ return platformPageClient()->windowRect();
}
-
FloatRect ChromeClientQt::pageRect()
{
if (!m_webPage)
}
#endif
+void ChromeClientQt::didReceiveViewportArguments(Frame* frame, const ViewportArguments& arguments) const
+{
+ if (m_webPage->mainFrame()->d->initialLayoutComplete)
+ return;
+
+ QSize viewportSize(arguments.width, arguments.height);
+ bool isUserScalable = arguments.userScalable == 1;
+
+ QWebPage::ViewportHints hints;
+ hints.m_isValid = true;
+ hints.m_size = viewportSize;
+ hints.m_initialScaleFactor = arguments.initialScale;
+ hints.m_minimumScaleFactor = arguments.minimumScale;
+ hints.m_maximumScaleFactor = arguments.maximumScale;
+ hints.m_isUserScalable = isUserScalable;
+
+ emit m_webPage->viewportChangeRequested(hints);
}
+
+} // namespace WebCore
class Page;
struct FrameLoadRequest;
class QtAbstractWebPopup;
+ struct ViewportArguments;
class ChromeClientQt : public ChromeClient
{
QtAbstractWebPopup* createSelectPopup();
+ virtual void didReceiveViewportArguments(Frame*, const ViewportArguments&) const;
+
QWebPage* m_webPage;
WebCore::KURL lastHoverURL;
WebCore::String lastHoverTitle;
if (m_frame->tree()->parent() || !m_webFrame)
return;
+ m_webFrame->d->initialLayoutComplete = false;
+
emit m_webFrame->urlChanged(m_webFrame->url());
m_webFrame->page()->d->updateNavigationActions();
// will be called very soon with the correct title.
// This properly resets the title when we navigate to a URI without a title.
emit titleChanged(String());
+
+ bool isMainFrame = (m_frame == m_frame->page()->mainFrame());
+ if (!isMainFrame)
+ return;
+
+ emit m_webFrame->page()->viewportChangeRequested(QWebPage::ViewportHints());
}
void FrameLoaderClientQt::dispatchDidFirstLayout()
{
- notImplemented();
+ m_webFrame->d->initialLayoutComplete = true;
}
void FrameLoaderClientQt::dispatchDidFirstVisuallyNonEmptyLayout()
return view->style();
}
+QRectF PageClientQWidget::windowRect() const
+{
+ return QRectF(view->window()->geometry());
+}
+
PageClientQGraphicsWidget::~PageClientQGraphicsWidget()
{
#if USE(ACCELERATED_COMPOSITING)
#if ENABLE(TILED_BACKING_STORE)
QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const
-{
+{
if (!view->scene())
return QRectF();
QList<QGraphicsView*> views = view->scene()->views();
if (views.isEmpty())
return QRectF();
-
+
QGraphicsView* graphicsView = views.at(0);
int xOffset = graphicsView->horizontalScrollBar()->value();
int yOffset = graphicsView->verticalScrollBar()->value();
return view->style();
}
+QRectF PageClientQGraphicsWidget::windowRect() const
+{
+ if (!view->scene())
+ return QRectF();
-
+ // The sceneRect is a good approximation of the size of the application, independent of the view.
+ return view->scene()->sceneRect();
}
+
+} // namespace WebCore
virtual QObject* pluginParent() const;
virtual QStyle* style() const;
-
+
virtual bool viewResizesToContentsEnabled() const { return false; }
+ virtual QRectF windowRect() const;
+
QWidget* view;
};
virtual bool allowsAcceleratedCompositing() const { return true; }
#endif
+ virtual QRectF windowRect() const;
+
QGraphicsWidget* view;
QWebPage* page;
bool viewResizesToContents;