1 /*
2  * web_context.c - WebKit web context setup and handling
3  *
4  * Copyright © 2016 Aidan Holm <aidanholm@gmail.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "globalconf.h"
22 #include "common/log.h"
23 #include "web_context.h"
24 
25 #include <webkit2/webkit2.h>
26 
27 /** WebKit context common to all web views */
28 static WebKitWebContext *web_context;
29 /** WebKit process count; default to unlimited */
30 static guint process_limit = 0;
31 /** Whether the web context startup function has been run */
32 static gboolean web_context_started = FALSE;
33 
34 /** Defined in widgets/webview/downloads.c */
35 gboolean download_start_cb(WebKitWebContext *, WebKitDownload *, gpointer);
36 
37 WebKitWebContext *
web_context_get(void)38 web_context_get(void)
39 {
40     g_assert(web_context);
41     return web_context;
42 }
43 
44 guint
web_context_process_limit_get(void)45 web_context_process_limit_get(void)
46 {
47     return process_limit;
48 }
49 
50 gboolean
web_context_process_limit_set(guint limit)51 web_context_process_limit_set(guint limit)
52 {
53     if (web_context_started)
54         return FALSE;
55     process_limit = limit;
56     return TRUE;
57 }
58 
59 static void
website_data_dir_init(void)60 website_data_dir_init(void)
61 {
62     g_assert(globalconf.data_dir);
63 
64     gchar *indexeddb_dir = g_build_filename(globalconf.data_dir, "indexeddb", NULL);
65     gchar *local_storage_dir = g_build_filename(globalconf.data_dir, "local_storage", NULL);
66     gchar *applications_dir = g_build_filename(globalconf.data_dir, "applications", NULL);
67     gchar *websql_dir = g_build_filename(globalconf.data_dir, "websql", NULL);
68 
69     WebKitWebsiteDataManager *data_mgr = webkit_website_data_manager_new(
70             "disk-cache-directory", globalconf.cache_dir,
71             "indexeddb-directory", indexeddb_dir,
72             "local-storage-directory", local_storage_dir,
73             "offline-application-cache-directory", applications_dir,
74             "websql-directory", websql_dir,
75             NULL);
76 
77     g_free(indexeddb_dir);
78     g_free(local_storage_dir);
79     g_free(applications_dir);
80     g_free(websql_dir);
81 
82     web_context = webkit_web_context_new_with_website_data_manager(data_mgr);
83 
84     verbose("base_data_directory:                 %s", webkit_website_data_manager_get_base_data_directory(data_mgr));
85     verbose("base_cache_directory:                %s", webkit_website_data_manager_get_base_cache_directory(data_mgr));
86     verbose("disk_cache_directory:                %s", webkit_website_data_manager_get_disk_cache_directory(data_mgr));
87     verbose("indexeddb_directory:                 %s", webkit_website_data_manager_get_indexeddb_directory(data_mgr));
88     verbose("local_storage_directory:             %s", webkit_website_data_manager_get_local_storage_directory(data_mgr));
89     verbose("offline_application_cache_directory: %s", webkit_website_data_manager_get_offline_application_cache_directory(data_mgr));
90     verbose("websql_directory:                    %s", webkit_website_data_manager_get_websql_directory(data_mgr));
91 }
92 
93 static void
web_context_set_default_spelling_language(void)94 web_context_set_default_spelling_language(void)
95 {
96     /* This seems to autodetect spell checking languages */
97     const gchar *null = NULL;
98     webkit_web_context_set_spell_checking_languages(web_context, &null);
99     gchar **ret = (gchar**)webkit_web_context_get_spell_checking_languages(web_context);
100     if (!ret)
101         return;
102     gchar *langs = g_strjoinv(", ", ret);
103     verbose("setting spell check languages: %s", langs);
104     g_free(langs);
105 }
106 
107 void
web_context_init(void)108 web_context_init(void)
109 {
110     website_data_dir_init();
111     webkit_web_context_set_favicon_database_directory(web_context, NULL);
112     g_signal_connect(G_OBJECT(web_context), "download-started",
113             G_CALLBACK(download_start_cb), NULL);
114 
115     /* Set default cookie policy: must match default in clib/soup.c */
116     WebKitCookieManager *cookie_mgr = webkit_web_context_get_cookie_manager(web_context);
117     webkit_cookie_manager_set_accept_policy(cookie_mgr, WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
118 
119     web_context_set_default_spelling_language();
120 }
121 
122 void
web_context_init_finish(void)123 web_context_init_finish(void)
124 {
125     if (web_context_started)
126         return;
127 
128 #if !WEBKIT_CHECK_VERSION(2,26,0)
129     webkit_web_context_set_process_model(web_context, WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES);
130     info("Web process count: %d", process_limit);
131     webkit_web_context_set_web_process_count_limit(web_context, process_limit);
132 #endif
133 
134     web_context_started = TRUE;
135 }
136 
137 // vim: ft=c:et:sw=4:ts=8:sts=4:tw=80
138