1 /*
2  * Copyright © 2016 Aidan Holm <aidanholm@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program 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
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #include "clib/stylesheet.h"
20 
21 static gboolean inside_stylesheet_cb = FALSE;
22 
23 void
webview_stylesheets_regenerate_stylesheet(widget_t * w,lstylesheet_t * stylesheet)24 webview_stylesheets_regenerate_stylesheet(widget_t *w, lstylesheet_t *stylesheet) {
25     webview_data_t *d = w->data;
26 
27     /* If this styleheet was enabled, it needs to be re-added to the user
28      * content manager, since its internal WebKitUserStyleSheet pointer has
29      * changed: mark for refresh */
30     if (g_list_find(d->stylesheets, stylesheet))
31         d->stylesheet_refreshed = TRUE;
32 }
33 
34 void
webview_stylesheets_regenerate(widget_t * w)35 webview_stylesheets_regenerate(widget_t *w) {
36     webview_data_t *d = w->data;
37 
38     /* Re-add the user content manager stylesheets, if necessary
39      * Always fully rebuild, because there's no remove_style_sheet(),
40      * it's not currently easy to tell if a stylesheet has already been
41      * added, and a full rebuild is required anyway fairly often */
42 
43     if (d->stylesheet_added || d->stylesheet_removed || d->stylesheet_refreshed) {
44         webkit_user_content_manager_remove_all_style_sheets(d->user_content);
45 
46         GList *l;
47         for (l = d->stylesheets; l; l = l->next) {
48             lstylesheet_t *stylesheet = l->data;
49             webkit_user_content_manager_add_style_sheet(d->user_content, stylesheet->stylesheet);
50         }
51 
52         d->stylesheet_added   = FALSE;
53         d->stylesheet_removed = FALSE;
54     }
55 }
56 
57 int
webview_stylesheet_set_enabled(widget_t * w,lstylesheet_t * stylesheet,gboolean enable)58 webview_stylesheet_set_enabled(widget_t *w, lstylesheet_t *stylesheet, gboolean enable)
59 {
60     webview_data_t *d = w->data;
61     GList *item = g_list_find(d->stylesheets, stylesheet);
62 
63     /* Return early if nothing to do */
64     if (enable == (item != NULL))
65         return 0;
66 
67     if (enable) {
68         d->stylesheets = g_list_prepend(d->stylesheets, stylesheet);
69         d->stylesheet_added = TRUE;
70     } else {
71         d->stylesheets = g_list_remove_link(d->stylesheets, item);
72         d->stylesheet_removed = TRUE;
73     }
74 
75     if (!inside_stylesheet_cb)
76         webview_stylesheets_regenerate(w);
77 
78     return 0;
79 }
80 
81 static gint
luaH_webview_stylesheets_index(lua_State * L)82 luaH_webview_stylesheets_index(lua_State *L)
83 {
84     webview_data_t *d = luaH_checkwvdata(L, lua_upvalueindex(1));
85     lstylesheet_t *stylesheet = luaH_checkstylesheet(L, 2);
86 
87     gboolean enabled = g_list_find(d->stylesheets, stylesheet) != NULL;
88     lua_pushboolean(L, enabled);
89 
90     return 1;
91 }
92 
93 static gint
luaH_webview_stylesheets_newindex(lua_State * L)94 luaH_webview_stylesheets_newindex(lua_State *L)
95 {
96     webview_data_t *d = luaH_checkwvdata(L, lua_upvalueindex(1));
97     lstylesheet_t *stylesheet = luaH_checkstylesheet(L, 2);
98     gboolean enable = lua_toboolean(L, 3);
99 
100     webview_stylesheet_set_enabled(d->widget, stylesheet,  enable);
101 
102     return 0;
103 }
104 
105 static gint
luaH_webview_push_stylesheets_table(lua_State * L)106 luaH_webview_push_stylesheets_table(lua_State *L)
107 {
108     /* create scroll table */
109     lua_newtable(L);
110     /* setup metatable */
111     lua_createtable(L, 0, 2);
112     /* push __index metafunction */
113     lua_pushliteral(L, "__index");
114     lua_pushvalue(L, 1); /* copy webview userdata */
115     lua_pushcclosure(L, luaH_webview_stylesheets_index, 1);
116     lua_rawset(L, -3);
117     /* push __newindex metafunction */
118     lua_pushliteral(L, "__newindex");
119     lua_pushvalue(L, 1); /* copy webview userdata */
120     lua_pushcclosure(L, luaH_webview_stylesheets_newindex, 1);
121     lua_rawset(L, -3);
122     lua_setmetatable(L, -2);
123     return 1;
124 }
125 
126 static void
webview_update_stylesheets(lua_State * L,widget_t * w)127 webview_update_stylesheets(lua_State *L, widget_t *w)
128 {
129     webview_data_t *d = w->data;
130 
131     d->stylesheet_added   = FALSE;
132     d->stylesheet_removed = FALSE;
133 
134     inside_stylesheet_cb = TRUE;
135     luaH_object_push(L, w->ref);
136     luaH_object_emit_signal(L, -1, "stylesheet", 0, 0);
137     lua_pop(L, 1);
138     inside_stylesheet_cb = FALSE;
139 
140     webview_stylesheets_regenerate(w);
141 }
142 
143 // vim: ft=c:et:sw=4:ts=8:sts=4:tw=80
144