diff options
Diffstat (limited to 'WebKit/gtk/webkit/webkitviewportattributes.cpp')
| -rw-r--r-- | WebKit/gtk/webkit/webkitviewportattributes.cpp | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/WebKit/gtk/webkit/webkitviewportattributes.cpp b/WebKit/gtk/webkit/webkitviewportattributes.cpp new file mode 100644 index 0000000..c2de5c1 --- /dev/null +++ b/WebKit/gtk/webkit/webkitviewportattributes.cpp @@ -0,0 +1,569 @@ +/* + * Copyright (C) 2010 Joone Hur <joone@kldp.org> + * Copyright (C) 2010 Collabora Ltd. + * + * 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 "config.h" +#include "webkitviewportattributes.h" + +#include "Chrome.h" +#include "webkitprivate.h" +#include "webkitviewportattributesprivate.h" +#include "webkitwebviewprivate.h" +#include <glib/gi18n-lib.h> + +/** + * SECTION:webkitviewportattributes + * @short_description: Represents the viewport properties of a web page + * @see_also: #WebKitWebView::viewport-attributes-recompute-requested + * @see_also: #WebKitWebView::viewport-attributes-changed + * + * #WebKitViewportAttributes offers the viewport properties to user agents to + * control the viewport layout. It contains the viewport size, initial scale with limits, + * and information about whether a user is able to scale the contents in the viewport. + * This makes a web page fit the device screen. + * + * The #WebKitWebView::viewport-attributes-changed signal will be emitted with #WebKitViewportAttributes + * when the viewport attributes are updated in the case of loading web pages contain + * the viewport properties and calling webkit_viewport_attributes_recompute. + * + * If the device size, available size, desktop width, or device DPI needs to be changed due to + * a consequence of an explicit browser request (caused by screen rotation, resizing, or similar reasons), + * You should call #webkit_viewport_attributes_recompute to recompute the viewport properties and + * override those values in the handler of #WebKitWebView::viewport-attributes-recompute-requested signal. + * + * For more information on the viewport properties, refer to the Safari reference library at + * http://developer.apple.com/safari/library/documentation/appleapplications/reference/safarihtmlref/articles/metatags.html + * + * <informalexample><programlisting> + * /<!-- -->* Connect to the viewport-attributes-changes signal *<!-- -->/ + * WebKitViewportAttributes* attributes = webkit_web_view_get_viewport_attributes (web_view); + * g_signal_connect (web_view, "viewport-attributes-recompute-requested", G_CALLBACK (viewport_recompute_cb), window); + * g_signal_connect (web_view, "viewport-attributes-changed", G_CALLBACK (viewport_changed_cb), window); + * g_signal_connect (attributes, "notify::valid", G_CALLBACK (viewport_valid_changed_cb), web_view); + * + * /<!-- -->* Handle the viewport-attributes-recompute-requested signal to override the device width *<!-- -->/ + * static void + * viewport_recompute_cb (WebKitWebView* web_view, WebKitViewportAttributes* attributes, GtkWidget* window) + * { + * int override_available_width = 480; + * g_object_set (G_OBJECT(attributes), "available-width", override_available_width, NULL); + * } + * + * /<!-- -->* Handle the viewport-attributes-changed signal to recompute the initial scale factor *<!-- -->/ + * static void + * viewport_changed_cb (WebKitWebView* web_view, WebKitViewportAttributes* attributes, gpointer data) + * { + * gfloat initialScale; + * g_object_get (G_OBJECT (atributes), "initial-scale-factor", &initialScale, NULL); + * webkit_web_view_set_zoom_level (web_view, initialScale); + * } + * + * /<!-- -->* Handle the notify::valid signal to initialize the zoom level *<!-- -->/ + * static void + * viewport_valid_changed_cb (WebKitViewportAttributes* attributes, GParamSpec* pspec, WebKitWebView* web_view) + * { + * gboolean is_valid; + * g_object_get (attributes, "valid", &is_valid, NULL); + * if (!is_valid) + * webkit_web_view_set_zoom_level (web_view, 1.0); + * } + * </programlisting></informalexample> + */ + +using namespace WebKit; +using namespace WebCore; + +enum { + PROP_0, + + PROP_DEVICE_WIDTH, + PROP_DEVICE_HEIGHT, + PROP_AVAILABLE_WIDTH, + PROP_AVAILABLE_HEIGHT, + PROP_DESKTOP_WIDTH, + PROP_DEVICE_DPI, + PROP_WIDTH, + PROP_HEIGHT, + PROP_INITIAL_SCALE_FACTOR, + PROP_MINIMUM_SCALE_FACTOR, + PROP_MAXIMUM_SCALE_FACTOR, + PROP_DEVICE_PIXEL_RATIO, + PROP_USER_SCALABLE, + PROP_VALID +}; + +G_DEFINE_TYPE(WebKitViewportAttributes, webkit_viewport_attributes, G_TYPE_OBJECT); + +static void webkit_viewport_attributes_get_property(GObject* object, guint propertyID, GValue* value, GParamSpec* paramSpec); +static void webkit_viewport_attributes_set_property(GObject* object, guint propertyID, const GValue* value, GParamSpec* paramSpec); + +static void webkit_viewport_attributes_class_init(WebKitViewportAttributesClass* kclass) +{ + GObjectClass* gobjectClass = G_OBJECT_CLASS(kclass); + gobjectClass->get_property = webkit_viewport_attributes_get_property; + gobjectClass->set_property = webkit_viewport_attributes_set_property; + + /** + * WebKitViewportAttributs:device-width: + * + * The width of the screen. This value is always automatically + * pre-computed during a viewport attributes recomputation, and + * can be overridden by the handler of + * WebKitWebView::viewport-attributes-recompute-requested. You + * should not do that unless you have a very good reason. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_DEVICE_WIDTH, + g_param_spec_int( + "device-width", + _("Device Width"), + _("The width of the screen."), + 0, + G_MAXINT, + 0, + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitViewportAttributs:device-height: + * + * The height of the screen. This value is always automatically + * pre-computed during a viewport attributes recomputation, and + * can be overriden by the handler of + * WebKitWebView::viewport-attributes-recompute-requested. You + * should not do that unless you have a very good reason. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_DEVICE_HEIGHT, + g_param_spec_int( + "device-height", + _("Device Height"), + _("The height of the screen."), + 0, + G_MAXINT, + 0, + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitViewportAttributs:available-width: + * + * The width of the current visible area. This will usually be the + * same as the space allocated to the widget, but in some cases + * you may have decided to make the widget bigger than the visible + * area. This value is by default initialized to the size + * allocated by the widget, but you can override it in the handler + * of WebKitWebView::viewport-attributes-recompute-requested to + * let the engine know what the visible area is. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_AVAILABLE_WIDTH, + g_param_spec_int( + "available-width", + _("Available Width"), + _("The width of the visible area."), + 0, + G_MAXINT, + 0, + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitViewportAttributs:available-height: + * + * The height of the current visible area. This will usually be the + * same as the space allocated to the widget, but in some cases + * you may have decided to make the widget bigger than the visible + * area. This value is by default initialized to the size + * allocated by the widget, but you can override it in the handler + * of WebKitWebView::viewport-attributes-recompute-requested to + * let the engine know what the visible area is. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_AVAILABLE_HEIGHT, + g_param_spec_int( + "available-height", + _("Available Height"), + _("The height of the visible area."), + 0, + G_MAXINT, + 0, + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitViewportAttributs:desktop-width: + * + * The width of viewport that works well for most web pages designed for + * desktop. This value is initialized to 980 pixels by default and used + * during a viewport attributes recomputation. Also, it can be overriden by + * the handler of WebKitWebView::viewport-attributes-recompute-requested. + * You should not do that unless you have a very good reason. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_DESKTOP_WIDTH, + g_param_spec_int( + "desktop-width", + _("Desktop Width"), + _("The width of viewport that works well for most web pages designed for desktop."), + 0, + G_MAXINT, + 980, + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitViewportAttributs:device-dpi: + * + * The number of dots per inch of the screen. This value is + * initialized to 160 dpi by default and used during a viewport + * attributes recomputation, because it is the dpi of the original + * iPhone and Android devices. Also, it can be overriden by the + * handler of WebKitWebView::viewport-attributes-recompute-requested. + * You should not do that unless you have a very good reason. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_DEVICE_DPI, + g_param_spec_int( + "device-dpi", + _("Device DPI"), + _("The number of dots per inch of the screen."), + 0, + G_MAXINT, + 160, + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitViewportAttributs:width: + * + * The width of the viewport. Before getting this property, + * you need to make sure that #WebKitViewportAttributes is valid. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_WIDTH, + g_param_spec_int( + "width", + _("Width"), + _("The width of the viewport."), + 0, + G_MAXINT, + 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitViewportAttributs:height: + * + * The height of the viewport. Before getting this property, + * you need to make sure that #WebKitViewportAttributes is valid. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_HEIGHT, + g_param_spec_int( + "height", + _("Height"), + _("The height of the viewport."), + 0, + G_MAXINT, + 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitViewportAttributs:initial-scale-factor: + * + * The initial scale of the viewport. Before getting this property, + * you need to make sure that #WebKitViewportAttributes is valid. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_INITIAL_SCALE_FACTOR, + g_param_spec_float( + "initial-scale-factor", + _("Initial Scale Factor"), + _("The initial scale of the viewport."), + -1, + G_MAXFLOAT, + -1, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitViewportAttributs:minimum-scale-factor: + * + * The minimum scale of the viewport. Before getting this property, + * you need to make sure that #WebKitViewportAttributes is valid. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_MINIMUM_SCALE_FACTOR, + g_param_spec_float( + "minimum-scale-factor", + _("Minimum Scale Factor"), + _("The minimum scale of the viewport."), + -1, + G_MAXFLOAT, + -1, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitViewportAttributs:maximum-scale-factor: + * + * The maximum scale of the viewport. Before getting this property, + * you need to make sure that #WebKitViewportAttributes is valid. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_MAXIMUM_SCALE_FACTOR, + g_param_spec_float( + "maximum-scale-factor", + _("Maximum Scale Factor"), + _("The maximum scale of the viewport."), + -1, + G_MAXFLOAT, + -1, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitViewportAttributs:device-pixel-ratio: + * + * The device pixel ratio of the viewport. Before getting this property, + * you need to make sure that #WebKitViewportAttributes is valid. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_DEVICE_PIXEL_RATIO, + g_param_spec_float( + "device-pixel-ratio", + _("Device Pixel Ratio"), + _("The device pixel ratio of the viewport."), + -1, + G_MAXFLOAT, + -1, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitViewportAttributs:user-scalable: + * + * Determines whether or not the user can zoom in and out. + * Before getting this property, you need to make sure that + * #WebKitViewportAttributes is valid. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_USER_SCALABLE, + g_param_spec_boolean( + _("user-scalable"), + _("User Scalable"), + _("Determines whether or not the user can zoom in and out."), + TRUE, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitViewportAttributs:valid: + * + * Determines whether or not the attributes are valid. + * #WebKitViewportAttributes are only valid on pages + * which have a viewport meta tag, and have already + * had the attributes calculated. + * + * Since: 1.3.8 + */ + g_object_class_install_property(gobjectClass, + PROP_VALID, + g_param_spec_boolean( + _("valid"), + _("Valid"), + _("Determines whether or not the attributes are valid, and can be used."), + FALSE, + WEBKIT_PARAM_READABLE)); + + g_type_class_add_private(kclass, sizeof(WebKitViewportAttributesPrivate)); +} + +static void webkit_viewport_attributes_init(WebKitViewportAttributes* viewport) +{ + viewport->priv = G_TYPE_INSTANCE_GET_PRIVATE(viewport, WEBKIT_TYPE_VIEWPORT_ATTRIBUTES, WebKitViewportAttributesPrivate); + + viewport->priv->deviceWidth = 0; + viewport->priv->deviceHeight = 0; + viewport->priv->availableWidth = 0; + viewport->priv->availableHeight = 0; + viewport->priv->desktopWidth = 980; // This value works well for most web pages designed for desktop browsers. + viewport->priv->deviceDPI = 160; // It is the dpi of the original iPhone and Android devices. + viewport->priv->width = 0; + viewport->priv->height = 0; + viewport->priv->initialScaleFactor = -1; + viewport->priv->minimumScaleFactor = -1; + viewport->priv->maximumScaleFactor = -1; + viewport->priv->devicePixelRatio = -1; + viewport->priv->userScalable = TRUE; + viewport->priv->isValid = FALSE; +} + +static void webkit_viewport_attributes_get_property(GObject* object, guint propertyID, GValue* value, GParamSpec* paramSpec) +{ + WebKitViewportAttributes* viewportAttributes = WEBKIT_VIEWPORT_ATTRIBUTES(object); + WebKitViewportAttributesPrivate* priv = viewportAttributes->priv; + + switch (propertyID) { + case PROP_DEVICE_WIDTH: + g_value_set_int(value, priv->deviceWidth); + break; + case PROP_DEVICE_HEIGHT: + g_value_set_int(value, priv->deviceHeight); + break; + case PROP_AVAILABLE_WIDTH: + g_value_set_int(value, priv->availableWidth); + break; + case PROP_AVAILABLE_HEIGHT: + g_value_set_int(value, priv->availableHeight); + break; + case PROP_DESKTOP_WIDTH: + g_value_set_int(value, priv->desktopWidth); + break; + case PROP_DEVICE_DPI: + g_value_set_int(value, priv->deviceDPI); + break; + case PROP_WIDTH: + g_value_set_int(value, priv->width); + break; + case PROP_HEIGHT: + g_value_set_int(value, priv->height); + break; + case PROP_INITIAL_SCALE_FACTOR: + g_value_set_float(value, priv->initialScaleFactor); + break; + case PROP_MINIMUM_SCALE_FACTOR: + g_value_set_float(value, priv->minimumScaleFactor); + break; + case PROP_MAXIMUM_SCALE_FACTOR: + g_value_set_float(value, priv->maximumScaleFactor); + break; + case PROP_DEVICE_PIXEL_RATIO: + g_value_set_float(value, priv->devicePixelRatio); + break; + case PROP_USER_SCALABLE: + g_value_set_boolean(value, priv->userScalable); + break; + case PROP_VALID: + g_value_set_boolean(value, priv->isValid); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, paramSpec); + break; + } +} + +static void webkit_viewport_attributes_set_property(GObject* object, guint propertyID, const GValue* value, GParamSpec* paramSpec) +{ + WebKitViewportAttributes* viewportAttributes = WEBKIT_VIEWPORT_ATTRIBUTES(object); + WebKitViewportAttributesPrivate* priv = viewportAttributes->priv; + + switch (propertyID) { + case PROP_DEVICE_WIDTH: + priv->deviceWidth = g_value_get_int(value); + break; + case PROP_DEVICE_HEIGHT: + priv->deviceHeight = g_value_get_int(value); + break; + case PROP_AVAILABLE_WIDTH: + priv->availableWidth = g_value_get_int(value); + break; + case PROP_AVAILABLE_HEIGHT: + priv->availableHeight = g_value_get_int(value); + break; + case PROP_DESKTOP_WIDTH: + priv->desktopWidth = g_value_get_int(value); + break; + case PROP_DEVICE_DPI: + priv->deviceDPI = g_value_get_int(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, paramSpec); + break; + } +} + +void webkitViewportAttributesRecompute(WebKitViewportAttributes* viewportAttributes) +{ + WebKitViewportAttributesPrivate* priv = viewportAttributes->priv; + WebKitWebView* webView = priv->webView; + + IntRect windowRect(webView->priv->corePage->chrome()->windowRect()); + priv->deviceWidth = windowRect.width(); + priv->deviceHeight = windowRect.height(); + + IntRect rect(webView->priv->corePage->chrome()->pageRect()); + priv->availableWidth = rect.width(); + priv->availableHeight = rect.height(); + + // First of all, we give the application an opportunity to override some of the values. + g_signal_emit_by_name(webView, "viewport-attributes-recompute-requested", viewportAttributes); + + ViewportArguments arguments = webView->priv->corePage->mainFrame()->document()->viewportArguments(); + + ViewportAttributes attributes = computeViewportAttributes(arguments, priv->desktopWidth, priv->deviceWidth, priv->deviceHeight, priv->deviceDPI, IntSize(priv->availableWidth, priv->availableHeight)); + + priv->width = attributes.layoutSize.width(); + priv->height = attributes.layoutSize.height(); + priv->initialScaleFactor = attributes.initialScale; + priv->minimumScaleFactor = attributes.minimumScale; + priv->maximumScaleFactor = attributes.maximumScale; + priv->devicePixelRatio = attributes.devicePixelRatio; + priv->userScalable = arguments.userScalable; + + if (!priv->isValid) { + priv->isValid = TRUE; + g_object_notify(G_OBJECT(viewportAttributes), "valid"); + } + + // Now let the application know it is safe to use the new values. + g_signal_emit_by_name(webView, "viewport-attributes-changed", viewportAttributes); +} + +/** + * webkit_viewport_attributes_recompute: + * @viewportAttributes: a #WebKitViewportAttributes + * + * Recompute the optimal viewport attributes and emit the viewport-attribute-changed signal. + * The viewport-attributes-recompute-requested signal also will be handled to override + * the device size, available size, desktop width, or device DPI. + * + * Since: 1.3.8 + */ +void webkit_viewport_attributes_recompute(WebKitViewportAttributes* viewportAttributes) +{ + if (!viewportAttributes->priv->isValid) + return; + webkitViewportAttributesRecompute(viewportAttributes); +} |
