Merge lp:~midori/midori/per-site-preferences into lp:midori
- per-site-preferences
- Merge into trunk
Proposed by
André Stösel
Status: | Work in progress |
---|---|
Proposed branch: | lp:~midori/midori/per-site-preferences |
Merge into: | lp:midori |
Diff against target: |
332 lines (+328/-0) 1 file modified
extensions/per-site-preferences.vala (+328/-0) |
To merge this branch: | bzr merge lp:~midori/midori/per-site-preferences |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Midori Devs | Pending | ||
Review via email: mp+200608@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Unmerged revisions
- 6530. By André Stösel
-
add old per-site-
preferences extension (doesn't build)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'extensions/per-site-preferences.vala' | |||
2 | --- extensions/per-site-preferences.vala 1970-01-01 00:00:00 +0000 | |||
3 | +++ extensions/per-site-preferences.vala 2014-01-06 23:18:23 +0000 | |||
4 | @@ -0,0 +1,328 @@ | |||
5 | 1 | /* | ||
6 | 2 | Copyright (C) 2011 André Stösel <andre@stoesel.de> | ||
7 | 3 | |||
8 | 4 | This library is free software; you can redistribute it and/or | ||
9 | 5 | modify it under the terms of the GNU Lesser General Public | ||
10 | 6 | License as published by the Free Software Foundation; either | ||
11 | 7 | version 2.1 of the License, or (at your option) any later version. | ||
12 | 8 | |||
13 | 9 | See the file COPYING for the full license text. | ||
14 | 10 | */ | ||
15 | 11 | |||
16 | 12 | using Gtk; | ||
17 | 13 | using Soup; | ||
18 | 14 | using WebKit; | ||
19 | 15 | using Midori; | ||
20 | 16 | |||
21 | 17 | /* | ||
22 | 18 | ToDo: it's possible that the request is reused (404 for favicon) | ||
23 | 19 | */ | ||
24 | 20 | |||
25 | 21 | private PSP.Manager? PSPMI; // var name "PSPManager" causes some vala error -> todo: report it | ||
26 | 22 | |||
27 | 23 | namespace PSP { | ||
28 | 24 | namespace Actions { | ||
29 | 25 | } | ||
30 | 26 | |||
31 | 27 | namespace Conditions { | ||
32 | 28 | private interface NavigationPolicyDescision : GLib.Object { | ||
33 | 29 | public abstract bool match_navdes (WebKit.WebFrame p0, WebKit.NetworkRequest p1, WebKit.WebNavigationAction p2, WebKit.WebPolicyDecision p3); | ||
34 | 30 | } | ||
35 | 31 | |||
36 | 32 | private interface NewWindowsPolicyDescision : GLib.Object { | ||
37 | 33 | public abstract bool match_windes (WebKit.WebFrame p0, WebKit.NetworkRequest p1, WebKit.WebNavigationAction p2, WebKit.WebPolicyDecision p3); | ||
38 | 34 | } | ||
39 | 35 | |||
40 | 36 | private interface ResourceRequestStarting : GLib.Object { | ||
41 | 37 | public abstract bool match_resreq (WebFrame p0, WebResource p1, NetworkRequest p2, NetworkResponse? p3); | ||
42 | 38 | } | ||
43 | 39 | |||
44 | 40 | |||
45 | 41 | private abstract class Base : GLib.Object { | ||
46 | 42 | public string key; // unique! ToDo: check with some kind of metaclass or something like that | GType-Name? | ||
47 | 43 | public string name; | ||
48 | 44 | public string description; | ||
49 | 45 | |||
50 | 46 | public abstract bool is_ready (); | ||
51 | 47 | } | ||
52 | 48 | |||
53 | 49 | private class Uri : Base, NavigationPolicyDescision { | ||
54 | 50 | public string key = "uri-match"; | ||
55 | 51 | |||
56 | 52 | private GLib.Regex? regex; | ||
57 | 53 | |||
58 | 54 | public override bool is_ready () { | ||
59 | 55 | if (this.regex != null) { | ||
60 | 56 | return true; | ||
61 | 57 | } | ||
62 | 58 | return false; | ||
63 | 59 | } | ||
64 | 60 | |||
65 | 61 | public void set_pattern (string pattern) { | ||
66 | 62 | this.regex = new GLib.Regex (pattern, GLib.RegexCompileFlags.CASELESS); | ||
67 | 63 | } | ||
68 | 64 | |||
69 | 65 | public bool match_navdes (WebKit.WebFrame p0, WebKit.NetworkRequest p1, WebKit.WebNavigationAction p2, WebKit.WebPolicyDecision p3) { | ||
70 | 66 | return this.regex.match (p1.uri); | ||
71 | 67 | } | ||
72 | 68 | } | ||
73 | 69 | } | ||
74 | 70 | |||
75 | 71 | enum RuleOperator { | ||
76 | 72 | OR, | ||
77 | 73 | AND, | ||
78 | 74 | AND_NOT | ||
79 | 75 | } | ||
80 | 76 | |||
81 | 77 | private errordomain RuleError { | ||
82 | 78 | TYPE_ALREADY_DEFINED, | ||
83 | 79 | UNKNOWN_CONDITION_TYPE, | ||
84 | 80 | ILLEGAL_CONDITION_TYPE, | ||
85 | 81 | UNREADY_CONDITION | ||
86 | 82 | } | ||
87 | 83 | |||
88 | 84 | private class Rule : GLib.Object { | ||
89 | 85 | private GLib.Type? condition_type; | ||
90 | 86 | private RuleOperator operator; | ||
91 | 87 | private GLib.PtrArray actions; | ||
92 | 88 | private GLib.PtrArray conditions; | ||
93 | 89 | |||
94 | 90 | public void set_condition_type (GLib.Type type) throws RuleError { | ||
95 | 91 | if (this.condition_type == null) { | ||
96 | 92 | if ( | ||
97 | 93 | type == typeof (Conditions.NavigationPolicyDescision) || | ||
98 | 94 | type == typeof (Conditions.NewWindowsPolicyDescision) || | ||
99 | 95 | type == typeof (Conditions.ResourceRequestStarting) | ||
100 | 96 | ) { | ||
101 | 97 | this.condition_type = type; | ||
102 | 98 | } else { | ||
103 | 99 | throw new RuleError.UNKNOWN_CONDITION_TYPE ("Can't set unknown condition type!"); | ||
104 | 100 | } | ||
105 | 101 | } else { | ||
106 | 102 | throw new RuleError.TYPE_ALREADY_DEFINED ("Condition type is already defined and can't be changed!"); | ||
107 | 103 | } | ||
108 | 104 | } | ||
109 | 105 | |||
110 | 106 | public void add_condition (PSP.Conditions.Base condition) throws RuleError { | ||
111 | 107 | if (condition.is_ready () == true) { | ||
112 | 108 | if (Type.from_instance (condition).is_a (this.condition_type)) { | ||
113 | 109 | condition.ref (); | ||
114 | 110 | this.conditions.add (condition); | ||
115 | 111 | } else { | ||
116 | 112 | throw new RuleError.ILLEGAL_CONDITION_TYPE ("One rule can only contain one type of conditions!"); | ||
117 | 113 | } | ||
118 | 114 | } else { | ||
119 | 115 | throw new RuleError.UNREADY_CONDITION ("The condition must be fully initialized before it can be added to a rule!"); | ||
120 | 116 | } | ||
121 | 117 | } | ||
122 | 118 | |||
123 | 119 | public void connect (Midori.View view) throws RuleError { | ||
124 | 120 | unowned WebKit.WebView web_view = view.web_view; | ||
125 | 121 | if (this.condition_type == typeof(Conditions.NavigationPolicyDescision)) { | ||
126 | 122 | web_view.navigation_policy_decision_requested.connect (this.navigation_policy_decision_requested); | ||
127 | 123 | } else { | ||
128 | 124 | throw new RuleError.UNKNOWN_CONDITION_TYPE ("Can't connect unknown condition type!"); | ||
129 | 125 | } | ||
130 | 126 | } | ||
131 | 127 | |||
132 | 128 | public void disconnect (Midori.View view) throws RuleError { | ||
133 | 129 | unowned WebKit.WebView web_view = view.web_view; | ||
134 | 130 | if (this.condition_type == typeof(Conditions.NavigationPolicyDescision)) { | ||
135 | 131 | web_view.navigation_policy_decision_requested.disconnect (this.navigation_policy_decision_requested); | ||
136 | 132 | } else { | ||
137 | 133 | throw new RuleError.UNKNOWN_CONDITION_TYPE ("Can't disconnect unknown condition type!"); | ||
138 | 134 | } | ||
139 | 135 | } | ||
140 | 136 | |||
141 | 137 | /* if return is true: decision was made -> break the loop */ | ||
142 | 138 | private bool evaluate_match (bool condition, int index, ref bool rule) { | ||
143 | 139 | if (this.operator == RuleOperator.AND_NOT) { | ||
144 | 140 | if (condition == true && index == 0) { | ||
145 | 141 | rule = true; | ||
146 | 142 | } else if(condition == true) { | ||
147 | 143 | rule = false; | ||
148 | 144 | return true; | ||
149 | 145 | } | ||
150 | 146 | } else if (this.operator == RuleOperator.AND) { | ||
151 | 147 | if (condition) { | ||
152 | 148 | rule = true; | ||
153 | 149 | } else { | ||
154 | 150 | rule = false; | ||
155 | 151 | return true; | ||
156 | 152 | } | ||
157 | 153 | } else if (condition == true) { // RuleOperator is OR | ||
158 | 154 | rule = true; | ||
159 | 155 | return true; | ||
160 | 156 | } | ||
161 | 157 | return false; | ||
162 | 158 | } | ||
163 | 159 | |||
164 | 160 | public bool navigation_policy_decision_requested (WebKit.WebFrame p0, WebKit.NetworkRequest p1, WebKit.WebNavigationAction p2, WebKit.WebPolicyDecision p3) { | ||
165 | 161 | bool match_rule = false; | ||
166 | 162 | for (int i = 0; i < this.conditions.len; i++) { | ||
167 | 163 | Conditions.NavigationPolicyDescision condition = this.conditions.index (i) as Conditions.NavigationPolicyDescision; | ||
168 | 164 | bool match_condition = condition.match_navdes (p0, p1, p2, p3); | ||
169 | 165 | if (this.evaluate_match (match_condition, i, ref match_rule)) | ||
170 | 166 | break; | ||
171 | 167 | } | ||
172 | 168 | |||
173 | 169 | if (match_rule) { | ||
174 | 170 | stdout.printf("Rule matches!\n"); | ||
175 | 171 | // do stuff | ||
176 | 172 | } | ||
177 | 173 | |||
178 | 174 | return false; | ||
179 | 175 | } | ||
180 | 176 | |||
181 | 177 | construct { | ||
182 | 178 | this.conditions = new GLib.PtrArray (); | ||
183 | 179 | } | ||
184 | 180 | } | ||
185 | 181 | |||
186 | 182 | private class Manager : GLib.Object { | ||
187 | 183 | private Midori.App app; | ||
188 | 184 | private GLib.PtrArray rules; | ||
189 | 185 | public void add_rules (GLib.PtrArray rules) { | ||
190 | 186 | foreach (var browser in this.app.get_browsers ()) { | ||
191 | 187 | foreach (var tab in browser.get_tabs ()) { | ||
192 | 188 | this.tab_add_rules (tab, rules); | ||
193 | 189 | } | ||
194 | 190 | } | ||
195 | 191 | |||
196 | 192 | for (int i = 0; i < rules.len; i++) { | ||
197 | 193 | this.rules.add (rules.index (i)); | ||
198 | 194 | } | ||
199 | 195 | } | ||
200 | 196 | |||
201 | 197 | public void remove_rules (GLib.PtrArray rules) { | ||
202 | 198 | foreach (var browser in this.app.get_browsers ()) { | ||
203 | 199 | foreach (var tab in browser.get_tabs ()) { | ||
204 | 200 | this.tab_remove_rules (tab, rules); | ||
205 | 201 | } | ||
206 | 202 | } | ||
207 | 203 | |||
208 | 204 | for (int i = 0; i < rules.len; i++) { | ||
209 | 205 | this.rules.remove (rules.index (i)); | ||
210 | 206 | } | ||
211 | 207 | } | ||
212 | 208 | |||
213 | 209 | private void tab_add_rules (Midori.View view, GLib.PtrArray rules) { | ||
214 | 210 | for (int i = 0; i < rules.len; i++) { | ||
215 | 211 | PSP.Rule rule = rules.index (i) as PSP.Rule; | ||
216 | 212 | rule.connect (view); | ||
217 | 213 | } | ||
218 | 214 | } | ||
219 | 215 | |||
220 | 216 | private void tab_remove_rules (Midori.View view, GLib.PtrArray rules) { | ||
221 | 217 | for (int i = 0; i < rules.len; i++) { | ||
222 | 218 | PSP.Rule rule = rules.index (i) as PSP.Rule; | ||
223 | 219 | rule.disconnect (view); | ||
224 | 220 | } | ||
225 | 221 | } | ||
226 | 222 | |||
227 | 223 | private void tab_added (Midori.Browser browser, Midori.View view) { | ||
228 | 224 | this.tab_add_rules (view, this.rules); | ||
229 | 225 | } | ||
230 | 226 | |||
231 | 227 | private void tab_removed (Midori.Browser browser, Midori.View view) { | ||
232 | 228 | this.tab_remove_rules (view, this.rules); | ||
233 | 229 | } | ||
234 | 230 | |||
235 | 231 | private void browser_added (Midori.Browser browser) { | ||
236 | 232 | foreach (var tab in browser.get_tabs ()) { | ||
237 | 233 | this.tab_added (browser, tab); | ||
238 | 234 | } | ||
239 | 235 | browser.add_tab.connect (this.tab_added); | ||
240 | 236 | browser.remove_tab.connect (tab_removed); | ||
241 | 237 | } | ||
242 | 238 | |||
243 | 239 | private void browser_removed (Midori.Browser browser) { | ||
244 | 240 | foreach (var tab in browser.get_tabs ()) { | ||
245 | 241 | tab_removed (browser, tab); | ||
246 | 242 | } | ||
247 | 243 | browser.add_tab.disconnect (tab_added); | ||
248 | 244 | browser.remove_tab.disconnect (tab_removed); | ||
249 | 245 | } | ||
250 | 246 | |||
251 | 247 | public void activated (Midori.App app) { | ||
252 | 248 | this.app = app; | ||
253 | 249 | foreach (var browser in app.get_browsers ()) { | ||
254 | 250 | browser_added (browser); | ||
255 | 251 | } | ||
256 | 252 | app.add_browser.connect (browser_added); | ||
257 | 253 | } | ||
258 | 254 | |||
259 | 255 | public void deactivated () { | ||
260 | 256 | foreach (var browser in this.app.get_browsers ()) { | ||
261 | 257 | browser_removed (browser); | ||
262 | 258 | } | ||
263 | 259 | this.app.add_browser.disconnect (browser_added); | ||
264 | 260 | } | ||
265 | 261 | |||
266 | 262 | construct { | ||
267 | 263 | this.rules = new GLib.PtrArray (); | ||
268 | 264 | } | ||
269 | 265 | } | ||
270 | 266 | } | ||
271 | 267 | |||
272 | 268 | namespace PSPExtensions { | ||
273 | 269 | private class Base : Midori.Extension { | ||
274 | 270 | private GLib.PtrArray rules; | ||
275 | 271 | |||
276 | 272 | public void activated (Midori.App app) { | ||
277 | 273 | if (PSPMI == null) { | ||
278 | 274 | PSPMI = new PSP.Manager (); | ||
279 | 275 | PSPMI.activated (app); | ||
280 | 276 | } else { | ||
281 | 277 | PSPMI.ref (); | ||
282 | 278 | } | ||
283 | 279 | |||
284 | 280 | PSPMI.add_rules (this.rules); | ||
285 | 281 | } | ||
286 | 282 | |||
287 | 283 | public void deactivated () { | ||
288 | 284 | uint rcount = PSPMI.ref_count; | ||
289 | 285 | PSPMI.remove_rules (this.rules); | ||
290 | 286 | if (rcount == 1) { | ||
291 | 287 | PSPMI.deactivated (); | ||
292 | 288 | PSPMI = null; | ||
293 | 289 | } else { | ||
294 | 290 | PSPMI.unref (); | ||
295 | 291 | } | ||
296 | 292 | } | ||
297 | 293 | |||
298 | 294 | public void add_rule (PSP.Rule rule) { | ||
299 | 295 | rule.ref (); | ||
300 | 296 | this.rules.add (rule); | ||
301 | 297 | } | ||
302 | 298 | |||
303 | 299 | construct { | ||
304 | 300 | this.rules = new GLib.PtrArray (); | ||
305 | 301 | } | ||
306 | 302 | } | ||
307 | 303 | |||
308 | 304 | private class Test : Base { | ||
309 | 305 | internal Test () { | ||
310 | 306 | GLib.Object (name: _("Just a test"), | ||
311 | 307 | description: _("...."), | ||
312 | 308 | version: "0.1", | ||
313 | 309 | authors: "André Stösel <andre@stoesel.de>"); | ||
314 | 310 | |||
315 | 311 | activate.connect (this.activated); | ||
316 | 312 | deactivate.connect (this.deactivated); | ||
317 | 313 | |||
318 | 314 | PSP.Rule rule = new PSP.Rule (); | ||
319 | 315 | rule.set_condition_type (typeof (PSP.Conditions.NavigationPolicyDescision)); | ||
320 | 316 | var c1 = new PSP.Conditions.Uri (); | ||
321 | 317 | c1.set_pattern ("pyit\\.de"); | ||
322 | 318 | rule.add_condition (c1); | ||
323 | 319 | |||
324 | 320 | this.add_rule (rule); | ||
325 | 321 | } | ||
326 | 322 | } | ||
327 | 323 | } | ||
328 | 324 | |||
329 | 325 | public Midori.Extension extension_init () { | ||
330 | 326 | return new PSPExtensions.Test (); | ||
331 | 327 | } | ||
332 | 328 |