1/*
2 * Copyright (C) 2013 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitWebViewGroup.h"
22
23#include "APIArray.h"
24#include "APIString.h"
25#include "WebKitPrivate.h"
26#include "WebKitSettingsPrivate.h"
27#include "WebKitWebViewGroupPrivate.h"
28#include <glib/gi18n-lib.h>
29#include <wtf/gobject/GRefPtr.h>
30#include <wtf/text/CString.h>
31
32using namespace WebKit;
33
34/**
35 * SECTION: WebKitWebViewGroup
36 * @Short_description: Group of web views
37 * @Title: WebKitWebViewGroup
38 * @See_also: #WebKitWebView, #WebKitSettings
39 *
40 * A WebKitWebViewGroup represents a group of #WebKitWebView<!-- -->s that
41 * share things like settings. There's a default WebKitWebViewGroup where
42 * all #WebKitWebView<!-- -->s of the same #WebKitWebContext are added by default.
43 * To create a #WebKitWebView in a different WebKitWebViewGroup you can use
44 * webkit_web_view_new_with_group().
45 *
46 * WebKitWebViewGroups are identified by a unique name given when the group is
47 * created with webkit_web_view_group_new().
48 * WebKitWebViewGroups have a #WebKitSettings to control the settings of all
49 * #WebKitWebView<!-- -->s of the group. You can get the settings with
50 * webkit_web_view_group_get_settings() to handle the settings, or you can set
51 * your own #WebKitSettings with webkit_web_view_group_set_settings(). When
52 * the #WebKitSettings of a WebKitWebViewGroup changes, the signal notify::settings
53 * is emitted on the group.
54 */
55
56enum {
57    PROP_0,
58
59    PROP_SETTINGS
60};
61
62struct _WebKitWebViewGroupPrivate {
63    RefPtr<WebPageGroup> pageGroup;
64    CString name;
65    GRefPtr<WebKitSettings> settings;
66};
67
68WEBKIT_DEFINE_TYPE(WebKitWebViewGroup, webkit_web_view_group, G_TYPE_OBJECT)
69
70static inline WebCore::UserContentInjectedFrames toWebCoreUserContentInjectedFrames(WebKitInjectedContentFrames kitFrames)
71{
72    switch (kitFrames) {
73    case WEBKIT_INJECTED_CONTENT_FRAMES_ALL:
74        return WebCore::InjectInAllFrames;
75    case WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY:
76        return WebCore::InjectInTopFrameOnly;
77    default:
78        ASSERT_NOT_REACHED();
79        return WebCore::InjectInAllFrames;
80    }
81}
82
83static void webkitWebViewGroupSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
84{
85    WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(object);
86
87    switch (propId) {
88    case PROP_SETTINGS:
89        webkit_web_view_group_set_settings(group, WEBKIT_SETTINGS(g_value_get_object(value)));
90        break;
91    default:
92        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
93    }
94}
95
96static void webkitWebViewGroupGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
97{
98    WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(object);
99
100    switch (propId) {
101    case PROP_SETTINGS:
102        g_value_set_object(value, webkit_web_view_group_get_settings(group));
103        break;
104    default:
105        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
106    }
107}
108
109static void webkitWebViewGroupConstructed(GObject* object)
110{
111    G_OBJECT_CLASS(webkit_web_view_group_parent_class)->constructed(object);
112
113    WebKitWebViewGroupPrivate* priv = WEBKIT_WEB_VIEW_GROUP(object)->priv;
114    priv->settings = adoptGRef(webkit_settings_new());
115}
116
117static void webkit_web_view_group_class_init(WebKitWebViewGroupClass* hitTestResultClass)
118{
119    GObjectClass* objectClass = G_OBJECT_CLASS(hitTestResultClass);
120    objectClass->set_property = webkitWebViewGroupSetProperty;
121    objectClass->get_property = webkitWebViewGroupGetProperty;
122    objectClass->constructed = webkitWebViewGroupConstructed;
123
124    /**
125     * WebKitWebViewGroup:settings:
126     *
127     * The #WebKitSettings of the web view group.
128     */
129    g_object_class_install_property(
130        objectClass,
131        PROP_SETTINGS,
132        g_param_spec_object(
133            "settings",
134            _("Settings"),
135            _("The settings of the web view group"),
136            WEBKIT_TYPE_SETTINGS,
137            WEBKIT_PARAM_READWRITE));
138}
139
140static void webkitWebViewGroupAttachSettingsToPageGroup(WebKitWebViewGroup* group)
141{
142    group->priv->pageGroup->setPreferences(webkitSettingsGetPreferences(group->priv->settings.get()));
143}
144
145WebKitWebViewGroup* webkitWebViewGroupCreate(WebPageGroup* pageGroup)
146{
147    WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(g_object_new(WEBKIT_TYPE_WEB_VIEW_GROUP, NULL));
148    group->priv->pageGroup = pageGroup;
149    webkitWebViewGroupAttachSettingsToPageGroup(group);
150    return group;
151}
152
153WebPageGroup* webkitWebViewGroupGetPageGroup(WebKitWebViewGroup* group)
154{
155    return group->priv->pageGroup.get();
156}
157
158/**
159 * webkit_web_view_group_new:
160 * @name: (allow-none): the name of the group
161 *
162 * Creates a new #WebKitWebViewGroup with the given @name.
163 * If @name is %NULL a unique identifier name will be created
164 * automatically.
165 * The newly created #WebKitWebViewGroup doesn't contain any
166 * #WebKitWebView, web views are added to the new group when created
167 * with webkit_web_view_new_with_group() passing the group.
168 *
169 * Returns: (transfer full): a new #WebKitWebViewGroup
170 */
171WebKitWebViewGroup* webkit_web_view_group_new(const char* name)
172{
173    WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(g_object_new(WEBKIT_TYPE_WEB_VIEW_GROUP, NULL));
174    group->priv->pageGroup = WebPageGroup::create(name ? String::fromUTF8(name) : String());
175    webkitWebViewGroupAttachSettingsToPageGroup(group);
176    return group;
177}
178
179/**
180 * webkit_web_view_group_get_name:
181 * @group: a #WebKitWebViewGroup
182 *
183 * Gets the name that uniquely identifies the #WebKitWebViewGroup.
184 *
185 * Returns: the name of @group
186 */
187const char* webkit_web_view_group_get_name(WebKitWebViewGroup* group)
188{
189    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0);
190
191    WebKitWebViewGroupPrivate* priv = group->priv;
192    if (priv->name.isNull())
193        priv->name = priv->pageGroup->identifier().utf8();
194
195    return priv->name.data();
196}
197
198/**
199 * webkit_web_view_group_get_settings:
200 * @group: a #WebKitWebViewGroup
201 *
202 * Gets the #WebKitSettings of the #WebKitWebViewGroup.
203 *
204 * Returns: (transfer none): the settings of @group
205 */
206WebKitSettings* webkit_web_view_group_get_settings(WebKitWebViewGroup* group)
207{
208    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0);
209
210    return group->priv->settings.get();
211}
212
213/**
214 * webkit_web_view_group_set_settings:
215 * @group: a #WebKitWebViewGroup
216 * @settings: a #WebKitSettings
217 *
218 * Sets a new #WebKitSettings for the #WebKitWebViewGroup. The settings will
219 * affect to all the #WebKitWebView<!-- -->s of the group.
220 * #WebKitWebViewGroup<!-- -->s always have a #WebKitSettings so if you just want to
221 * modify a setting you can use webkit_web_view_group_get_settings() and modify the
222 * returned #WebKitSettings instead.
223 * Setting the same #WebKitSettings multiple times doesn't have any effect.
224 * You can monitor the settings of a #WebKitWebViewGroup by connecting to the
225 * notify::settings signal of @group.
226 */
227void webkit_web_view_group_set_settings(WebKitWebViewGroup* group, WebKitSettings* settings)
228{
229    g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group));
230    g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
231
232    if (group->priv->settings == settings)
233        return;
234
235    group->priv->settings = settings;
236    webkitWebViewGroupAttachSettingsToPageGroup(group);
237    g_object_notify(G_OBJECT(group), "settings");
238}
239