Merge lp:~midori/midori/addingDefaultsAndFilters into lp:midori
- addingDefaultsAndFilters
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Cris Dywan | ||||||||
Approved revision: | 6610 | ||||||||
Merged at revision: | 6594 | ||||||||
Proposed branch: | lp:~midori/midori/addingDefaultsAndFilters | ||||||||
Merge into: | lp:midori | ||||||||
Diff against target: |
1852 lines (+1095/-298) 14 files modified
data/adblock.list (+1/-0) data/adblock/blocked.svg (+46/-0) data/adblock/disabled.svg (+46/-0) data/adblock/enabled.svg (+80/-0) extensions/adblock/config.vala (+78/-39) extensions/adblock/extension.vala (+421/-210) extensions/adblock/subscriptions.vala (+48/-10) extensions/adblock/updater.vala (+47/-31) extensions/adblock/widgets.vala (+310/-0) katze/midori-paths.vala (+12/-4) midori/midori-app.c (+1/-1) midori/midori-browser.c (+1/-1) midori/midori-download.vala (+3/-2) po/POTFILES.in (+1/-0) |
||||||||
To merge this branch: | bzr merge lp:~midori/midori/addingDefaultsAndFilters | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cris Dywan | Approve | ||
Review via email:
|
Commit message
Add filters and defaults
Description of the change
TODO:
- Statusbar icon [x] Debug Matching
- Edit/ view custom rules
- Check checksum hash of the subscription after downloading
- Open local files in editor
- Ability to disable adblock for the current domain
- Save pre-parsed pre filtered ruleset into file as .preparsed
- Save matched/ cached uris from previous runs
[https:/
enabled=1
expires=
retries=1
homepage=https:/
title=EasyList
Test cases https:/
- 6582. By Cris Dywan
-
Only truncate filters string if there's a trailing ;
- 6583. By Cris Dywan
-
Get browser from app instead of get_for_widget
We don't actually get a window we could use as a reference
- 6584. By Paweł Forysiuk
-
Don't show scarry warning if 'disabled' setting is not found
- 6585. By Paweł Forysiuk
-
Don't bother downloading local files
- 6586. By Cris Dywan
-
Refactor Updater properties and show update in treeview
- 6587. By Cris Dywan
-
Handling presets within Config and add first unit tests
- 6588. By Cris Dywan
-
Move enabled switch into Config and add unit tests
- 6589. By Cris Dywan
-
Unit test parsing of subscriptions in Config
- 6590. By Paweł Forysiuk
-
Toggle displaying of hidden elements from adblock icon
- 6591. By Paweł Forysiuk
-
Display current adblock state in a tooltip
- 6592. By Paweł Forysiuk
-
Fix building with older vala version
- 6593. By Paweł Forysiuk
-
Don't reuse menu item variables
- 6594. By Cris Dywan
-
Unit test that saving and loading gives back the same results
- 6595. By Cris Dywan
-
Add adblock:parse for patt/ got messages
- 6596. By Cris Dywan
-
Add fallback to empty string to debug variable checks
- 6597. By Cris Dywan
-
Unit test init, add, remove and request on the whole Extension
- 6598. By Cris Dywan
-
Correct request_handled test case and custom rule test
- 6599. By Cris Dywan
-
Check header parts more carefully in Subscription.
parse_header - 6600. By Cris Dywan
-
Implement a notion of validity in subscriptions if there're no date headers
- 6601. By Cris Dywan
-
Fix and unit test writing of disabled URLs with dashes
- 6602. By Cris Dywan
-
Consider a subscription valid if anything at all gets picked up
There's no requirement to have any update or expiry header.
- 6603. By Cris Dywan
-
Merge lp:midori
- 6604. By Paweł Forysiuk
-
Extract widgets into separate file
- 6605. By Cris Dywan
-
preset_filename needs to fallback to build folder
- 6606. By Paweł Forysiuk
-
Parse subscription uris with a helper function
- 6607. By Paweł Forysiuk
-
Separate subscription parsing helper from subscription manager
- 6608. By Paweł Forysiuk
-
Split preparing hider css into helper functions
- 6609. By Paweł Forysiuk
-
Return if there is no blocked element to hide
- 6610. By Paweł Forysiuk
-
Split getting domains for uri into a separate function
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) : | # |
Preview Diff
1 | === added directory 'data/adblock' | |||
2 | === modified file 'data/adblock.list' | |||
3 | --- data/adblock.list 2014-02-17 20:43:55 +0000 | |||
4 | +++ data/adblock.list 2014-03-10 10:27:25 +0000 | |||
5 | @@ -7,6 +7,7 @@ | |||
6 | 7 | ! Licence: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt | 7 | ! Licence: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt |
7 | 8 | ! Copyright (C) 2014 Christian Dywan <christian@twotoasts.de> | 8 | ! Copyright (C) 2014 Christian Dywan <christian@twotoasts.de> |
8 | 9 | ! | 9 | ! |
9 | 10 | ! Some freeform text: | ||
10 | 10 | ! Yadayada http://example.com/ e-mail (somebody@example.com). | 11 | ! Yadayada http://example.com/ e-mail (somebody@example.com). |
11 | 11 | ! | 12 | ! |
12 | 12 | !-----Spam eggs--------! | 13 | !-----Spam eggs--------! |
13 | 13 | 14 | ||
14 | === added file 'data/adblock/blocked.svg' | |||
15 | --- data/adblock/blocked.svg 1970-01-01 00:00:00 +0000 | |||
16 | +++ data/adblock/blocked.svg 2014-03-10 10:27:25 +0000 | |||
17 | @@ -0,0 +1,46 @@ | |||
18 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
19 | 2 | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
20 | 3 | |||
21 | 4 | <svg | ||
22 | 5 | xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
23 | 6 | xmlns:cc="http://creativecommons.org/ns#" | ||
24 | 7 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
25 | 8 | xmlns:svg="http://www.w3.org/2000/svg" | ||
26 | 9 | xmlns="http://www.w3.org/2000/svg" | ||
27 | 10 | version="1.1" | ||
28 | 11 | width="16" | ||
29 | 12 | height="16" | ||
30 | 13 | id="svg7384"> | ||
31 | 14 | <title | ||
32 | 15 | id="title9167">Gnome Symbolic Icon Theme</title> | ||
33 | 16 | <defs | ||
34 | 17 | id="defs10" /> | ||
35 | 18 | <metadata | ||
36 | 19 | id="metadata90"> | ||
37 | 20 | <rdf:RDF> | ||
38 | 21 | <cc:Work | ||
39 | 22 | rdf:about=""> | ||
40 | 23 | <dc:format>image/svg+xml</dc:format> | ||
41 | 24 | <dc:type | ||
42 | 25 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
43 | 26 | <dc:title>Gnome Symbolic Icon Theme</dc:title> | ||
44 | 27 | </cc:Work> | ||
45 | 28 | </rdf:RDF> | ||
46 | 29 | </metadata> | ||
47 | 30 | <g | ||
48 | 31 | transform="translate(-111.61542,-601.4038)" | ||
49 | 32 | id="layer12"> | ||
50 | 33 | <path | ||
51 | 34 | d="m 228.01,607.02 c -3.86,0 -7.0073,3.166 -7.0073,7.0103 0,3.8443 3.1472,6.9787 7.0073,6.9787 3.86,0 7.0073,-3.1344 7.0073,-6.9787 0,-3.8443 -3.1472,-7.0103 -7.0073,-7.0103 z m 0,2.021 c 2.7769,0 5.0097,2.2237 5.0097,4.9893 0,2.7656 -2.2328,4.9577 -5.0097,4.9577 -2.777,0 -5.0097,-2.1921 -5.0097,-4.9577 0,-2.7656 2.2328,-4.9893 5.0097,-4.9893 z" | ||
52 | 35 | id="path4222" | ||
53 | 36 | style="text-indent:0;text-transform:none;block-progression:tb;color:#000000;fill:#bebebe" /> | ||
54 | 37 | <path | ||
55 | 38 | d="m 231.41,609.44 -8,8 1.4062,1.4062 8,-8 -1.4062,-1.4062 z" | ||
56 | 39 | id="path4992" | ||
57 | 40 | style="text-indent:0;text-transform:none;block-progression:tb;color:#000000;fill:#bebebe" /> | ||
58 | 41 | </g> | ||
59 | 42 | <path | ||
60 | 43 | d="m 7.96875,0.6875 c -2.8420838,0 -2.8771973,1.9949742 -6.625,2.3125 0,0 -0.98752557,2.5363552 0.34375,6 0.8399195,2.18526 4.3935259,5.981297 6.1875,6 l 0.25,0 C 9.9189736,14.9813 13.472581,11.18526 14.3125,9 15.643775,5.5363552 14.65625,3 14.65625,3 10.908448,2.6824742 10.873333,0.6875 8.03125,0.6875 l -0.0625,0 z m -0.625,2 c 0.1719617,-0.02159 0.3665606,0 0.625,0 l 0.0625,0 c 1.0337572,0 1.1746055,0.1513488 2.03125,0.625 0.133299,0.073703 0.361318,0.1808693 0.53125,0.28125 L 4.0625,9.25 C 3.8118632,8.860346 3.6127069,8.4931804 3.53125,8.28125 2.8541774,6.5196771 2.8806279,5.4183698 3,4.65625 4.2800363,4.3579974 5.3166759,3.6557627 5.9375,3.3125 6.5799833,2.9572616 6.8278648,2.7522692 7.34375,2.6875 z m 5.21875,1.84375 c 0.146121,0.046432 0.28409,0.089255 0.4375,0.125 0.119372,0.7621199 0.145822,1.863427 -0.53125,3.625 -0.223946,0.5826518 -1.210812,2.079776 -2.28125,3.15625 -0.535219,0.538237 -1.0931989,0.993886 -1.53125,1.28125 -0.2903916,0.190498 -0.5086712,0.283423 -0.5625,0.3125 l -0.15625,0 C 7.9117131,13.007739 7.6583409,12.925123 7.34375,12.71875 6.905699,12.431386 6.3477189,11.975737 5.8125,11.4375 5.6307383,11.254713 5.4548666,11.044257 5.28125,10.84375 l 7.28125,-6.3125 z" | ||
61 | 44 | id="path3016-2" | ||
62 | 45 | style="color:#000000;fill:#ffa500;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||
63 | 46 | </svg> | ||
64 | 0 | 47 | ||
65 | === added file 'data/adblock/disabled.svg' | |||
66 | --- data/adblock/disabled.svg 1970-01-01 00:00:00 +0000 | |||
67 | +++ data/adblock/disabled.svg 2014-03-10 10:27:25 +0000 | |||
68 | @@ -0,0 +1,46 @@ | |||
69 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
70 | 2 | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
71 | 3 | |||
72 | 4 | <svg | ||
73 | 5 | xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
74 | 6 | xmlns:cc="http://creativecommons.org/ns#" | ||
75 | 7 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
76 | 8 | xmlns:svg="http://www.w3.org/2000/svg" | ||
77 | 9 | xmlns="http://www.w3.org/2000/svg" | ||
78 | 10 | version="1.1" | ||
79 | 11 | width="16" | ||
80 | 12 | height="16" | ||
81 | 13 | id="svg7384"> | ||
82 | 14 | <title | ||
83 | 15 | id="title9167">Gnome Symbolic Icon Theme</title> | ||
84 | 16 | <defs | ||
85 | 17 | id="defs10" /> | ||
86 | 18 | <metadata | ||
87 | 19 | id="metadata90"> | ||
88 | 20 | <rdf:RDF> | ||
89 | 21 | <cc:Work | ||
90 | 22 | rdf:about=""> | ||
91 | 23 | <dc:format>image/svg+xml</dc:format> | ||
92 | 24 | <dc:type | ||
93 | 25 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
94 | 26 | <dc:title>Gnome Symbolic Icon Theme</dc:title> | ||
95 | 27 | </cc:Work> | ||
96 | 28 | </rdf:RDF> | ||
97 | 29 | </metadata> | ||
98 | 30 | <g | ||
99 | 31 | transform="translate(-111.61542,-601.4038)" | ||
100 | 32 | id="layer12"> | ||
101 | 33 | <path | ||
102 | 34 | d="m 228.01,607.02 c -3.86,0 -7.0073,3.166 -7.0073,7.0103 0,3.8443 3.1472,6.9787 7.0073,6.9787 3.86,0 7.0073,-3.1344 7.0073,-6.9787 0,-3.8443 -3.1472,-7.0103 -7.0073,-7.0103 z m 0,2.021 c 2.7769,0 5.0097,2.2237 5.0097,4.9893 0,2.7656 -2.2328,4.9577 -5.0097,4.9577 -2.777,0 -5.0097,-2.1921 -5.0097,-4.9577 0,-2.7656 2.2328,-4.9893 5.0097,-4.9893 z" | ||
103 | 35 | id="path4222" | ||
104 | 36 | style="text-indent:0;text-transform:none;block-progression:tb;color:#000000;fill:#bebebe" /> | ||
105 | 37 | <path | ||
106 | 38 | d="m 231.41,609.44 -8,8 1.4062,1.4062 8,-8 -1.4062,-1.4062 z" | ||
107 | 39 | id="path4992" | ||
108 | 40 | style="text-indent:0;text-transform:none;block-progression:tb;color:#000000;fill:#bebebe" /> | ||
109 | 41 | </g> | ||
110 | 42 | <path | ||
111 | 43 | d="m 7.96875,0.6875 c -2.8420838,0 -2.8771973,1.9949742 -6.625,2.3125 0,0 -0.98752557,2.5363552 0.34375,6 0.8399195,2.18526 4.3935259,5.981297 6.1875,6 l 0.25,0 C 9.9189736,14.9813 13.472581,11.18526 14.3125,9 15.643775,5.5363552 14.65625,3 14.65625,3 10.908448,2.6824742 10.873333,0.6875 8.03125,0.6875 l -0.0625,0 z m -0.625,2 c 0.1719617,-0.02159 0.3665606,0 0.625,0 l 0.0625,0 c 1.0337572,0 1.1746055,0.1513488 2.03125,0.625 0.133299,0.073703 0.361318,0.1808693 0.53125,0.28125 L 4.0625,9.25 C 3.8118632,8.860346 3.6127069,8.4931804 3.53125,8.28125 2.8541774,6.5196771 2.8806279,5.4183698 3,4.65625 4.2800363,4.3579974 5.3166759,3.6557627 5.9375,3.3125 6.5799833,2.9572616 6.8278648,2.7522692 7.34375,2.6875 z m 5.21875,1.84375 c 0.146121,0.046432 0.28409,0.089255 0.4375,0.125 0.119372,0.7621199 0.145822,1.863427 -0.53125,3.625 -0.223946,0.5826518 -1.210812,2.079776 -2.28125,3.15625 -0.535219,0.538237 -1.0931989,0.993886 -1.53125,1.28125 -0.2903916,0.190498 -0.5086712,0.283423 -0.5625,0.3125 l -0.15625,0 C 7.9117131,13.007739 7.6583409,12.925123 7.34375,12.71875 6.905699,12.431386 6.3477189,11.975737 5.8125,11.4375 5.6307383,11.254713 5.4548666,11.044257 5.28125,10.84375 l 7.28125,-6.3125 z" | ||
112 | 44 | id="path3016-2" | ||
113 | 45 | style="color:#000000;fill:#cc0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||
114 | 46 | </svg> | ||
115 | 0 | 47 | ||
116 | === added file 'data/adblock/enabled.svg' | |||
117 | --- data/adblock/enabled.svg 1970-01-01 00:00:00 +0000 | |||
118 | +++ data/adblock/enabled.svg 2014-03-10 10:27:25 +0000 | |||
119 | @@ -0,0 +1,80 @@ | |||
120 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
121 | 2 | <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
122 | 3 | |||
123 | 4 | <svg | ||
124 | 5 | xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
125 | 6 | xmlns:cc="http://creativecommons.org/ns#" | ||
126 | 7 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
127 | 8 | xmlns:svg="http://www.w3.org/2000/svg" | ||
128 | 9 | xmlns="http://www.w3.org/2000/svg" | ||
129 | 10 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||
130 | 11 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||
131 | 12 | version="1.1" | ||
132 | 13 | width="16" | ||
133 | 14 | height="16" | ||
134 | 15 | id="svg7384" | ||
135 | 16 | inkscape:version="0.48.4 r9939" | ||
136 | 17 | sodipodi:docname="adblock-enabled.svg"> | ||
137 | 18 | <sodipodi:namedview | ||
138 | 19 | pagecolor="#ffffff" | ||
139 | 20 | bordercolor="#666666" | ||
140 | 21 | borderopacity="1" | ||
141 | 22 | objecttolerance="10" | ||
142 | 23 | gridtolerance="10" | ||
143 | 24 | guidetolerance="10" | ||
144 | 25 | inkscape:pageopacity="0" | ||
145 | 26 | inkscape:pageshadow="2" | ||
146 | 27 | inkscape:window-width="1920" | ||
147 | 28 | inkscape:window-height="1026" | ||
148 | 29 | id="namedview10" | ||
149 | 30 | showgrid="false" | ||
150 | 31 | inkscape:zoom="14.75" | ||
151 | 32 | inkscape:cx="8" | ||
152 | 33 | inkscape:cy="8" | ||
153 | 34 | inkscape:window-x="0" | ||
154 | 35 | inkscape:window-y="32" | ||
155 | 36 | inkscape:window-maximized="1" | ||
156 | 37 | inkscape:current-layer="svg7384" /> | ||
157 | 38 | <title | ||
158 | 39 | id="title9167">Gnome Symbolic Icon Theme</title> | ||
159 | 40 | <defs | ||
160 | 41 | id="defs10" /> | ||
161 | 42 | <metadata | ||
162 | 43 | id="metadata90"> | ||
163 | 44 | <rdf:RDF> | ||
164 | 45 | <cc:Work | ||
165 | 46 | rdf:about=""> | ||
166 | 47 | <dc:format>image/svg+xml</dc:format> | ||
167 | 48 | <dc:type | ||
168 | 49 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
169 | 50 | <dc:title>Gnome Symbolic Icon Theme</dc:title> | ||
170 | 51 | </cc:Work> | ||
171 | 52 | </rdf:RDF> | ||
172 | 53 | </metadata> | ||
173 | 54 | <g | ||
174 | 55 | transform="translate(-111.61542,-601.4038)" | ||
175 | 56 | id="layer12"> | ||
176 | 57 | <path | ||
177 | 58 | d="m 228.01,607.02 c -3.86,0 -7.0073,3.166 -7.0073,7.0103 0,3.8443 3.1472,6.9787 7.0073,6.9787 3.86,0 7.0073,-3.1344 7.0073,-6.9787 0,-3.8443 -3.1472,-7.0103 -7.0073,-7.0103 z m 0,2.021 c 2.7769,0 5.0097,2.2237 5.0097,4.9893 0,2.7656 -2.2328,4.9577 -5.0097,4.9577 -2.777,0 -5.0097,-2.1921 -5.0097,-4.9577 0,-2.7656 2.2328,-4.9893 5.0097,-4.9893 z" | ||
178 | 59 | id="path4222" | ||
179 | 60 | style="text-indent:0;text-transform:none;block-progression:tb;color:#000000;fill:#bebebe" /> | ||
180 | 61 | <path | ||
181 | 62 | d="m 231.41,609.44 -8,8 1.4062,1.4062 8,-8 -1.4062,-1.4062 z" | ||
182 | 63 | id="path4992" | ||
183 | 64 | style="text-indent:0;text-transform:none;block-progression:tb;color:#000000;fill:#bebebe" /> | ||
184 | 65 | </g> | ||
185 | 66 | <path | ||
186 | 67 | d="m 7.96875,0.6875 c -2.8420838,0 -2.8771973,1.9949742 -6.625,2.3125 0,0 -0.98752557,2.5363552 0.34375,6 0.8399195,2.18526 4.3935259,5.981297 6.1875,6 l 0.25,0 C 9.9189736,14.9813 13.472581,11.18526 14.3125,9 15.643775,5.5363552 14.65625,3 14.65625,3 10.908448,2.6824742 10.873333,0.6875 8.03125,0.6875 l -0.0625,0 z m -0.625,2 c 0.1719617,-0.02159 0.3665606,0 0.625,0 l 0.0625,0 c 1.0337572,0 1.1746055,0.1513488 2.03125,0.625 0.133299,0.073703 0.361318,0.1808693 0.53125,0.28125 L 4.0625,9.25 C 3.8118632,8.860346 3.6127069,8.4931804 3.53125,8.28125 2.8541774,6.5196771 2.8806279,5.4183698 3,4.65625 4.2800363,4.3579974 5.3166759,3.6557627 5.9375,3.3125 6.5799833,2.9572616 6.8278648,2.7522692 7.34375,2.6875 z m 5.21875,1.84375 c 0.146121,0.046432 0.28409,0.089255 0.4375,0.125 0.119372,0.7621199 0.145822,1.863427 -0.53125,3.625 -0.223946,0.5826518 -1.210812,2.079776 -2.28125,3.15625 -0.535219,0.538237 -1.0931989,0.993886 -1.53125,1.28125 -0.2903916,0.190498 -0.5086712,0.283423 -0.5625,0.3125 l -0.15625,0 C 7.9117131,13.007739 7.6583409,12.925123 7.34375,12.71875 6.905699,12.431386 6.3477189,11.975737 5.8125,11.4375 5.6307383,11.254713 5.4548666,11.044257 5.28125,10.84375 l 7.28125,-6.3125 z" | ||
187 | 68 | id="path3016-2" | ||
188 | 69 | style="color:#000000;fill:#4e9a06;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> | ||
189 | 70 | <path | ||
190 | 71 | style="fill:#000000;fill-opacity:0" | ||
191 | 72 | d="M 3.8914706,8.8841635 C 3.4103263,8.1221753 3.0583616,6.8749414 3.003735,5.7383534 2.9786317,5.2160416 2.9904131,4.8722447 3.036357,4.7863976 3.0800139,4.7048241 3.2418563,4.6177843 3.4482218,4.5648944 3.8914458,4.4512995 4.5265161,4.1442388 5.8961843,3.3812883 L 7.0127075,2.7593478 7.7697676,2.7353155 C 8.6627475,2.7069685 9.052772,2.7983017 9.8276868,3.2172249 10.1089,3.3692502 10.375652,3.52161 10.420468,3.5558023 10.491273,3.609822 8.8213493,5.090833 4.1912034,9.0803713 4.0886836,9.1687069 4.0587803,9.149132 3.8914706,8.8841635 l 0,0 z" | ||
192 | 73 | id="path2987" | ||
193 | 74 | inkscape:connector-curvature="0" /> | ||
194 | 75 | <path | ||
195 | 76 | style="fill:#000000;fill-opacity:0" | ||
196 | 77 | d="M 7.5676774,12.795393 C 7.0256619,12.469009 6.4290755,11.979639 5.8305085,11.370422 5.33023,10.861243 5.3242581,10.851054 5.4600194,10.738315 5.5359114,10.675293 7.1641368,9.2661017 9.0782981,7.6067797 11.684369,5.3476641 12.594872,4.5953246 12.703024,4.6117025 c 0.291451,0.044135 0.329784,0.1886522 0.290923,1.0967721 -0.07204,1.6834953 -0.589725,2.9526655 -1.866622,4.5762714 -0.495094,0.629525 -1.366327,1.526375 -1.8854314,1.94087 C 8.8466967,12.541173 8.091686,13.030508 8,13.030508 c -0.023031,0 -0.2175765,-0.105802 -0.4323226,-0.235115 z" | ||
197 | 78 | id="path2989" | ||
198 | 79 | inkscape:connector-curvature="0" /> | ||
199 | 80 | </svg> | ||
200 | 0 | 81 | ||
201 | === modified file 'extensions/adblock/config.vala' | |||
202 | --- extensions/adblock/config.vala 2014-02-20 18:27:01 +0000 | |||
203 | +++ extensions/adblock/config.vala 2014-03-10 10:27:25 +0000 | |||
204 | @@ -12,27 +12,26 @@ | |||
205 | 12 | namespace Adblock { | 12 | namespace Adblock { |
206 | 13 | public class Config : GLib.Object { | 13 | public class Config : GLib.Object { |
207 | 14 | List<Subscription> subscriptions; | 14 | List<Subscription> subscriptions; |
209 | 15 | string? path; | 15 | public string? path { get; private set; } |
210 | 16 | KeyFile keyfile; | 16 | KeyFile keyfile; |
212 | 17 | Subscription? custom; | 17 | bool should_save; |
213 | 18 | public bool enabled { get; set; } | ||
214 | 18 | 19 | ||
216 | 19 | public Config (string? path) { | 20 | public Config (string? path, string? presets) { |
217 | 21 | should_save = false; | ||
218 | 20 | subscriptions = new GLib.List<Subscription> (); | 22 | subscriptions = new GLib.List<Subscription> (); |
220 | 21 | 23 | enabled = true; | |
221 | 22 | this.path = path; | 24 | this.path = path; |
223 | 23 | if (path == null) | 25 | size = 0; |
224 | 26 | load_file (path); | ||
225 | 27 | load_file (presets); | ||
226 | 28 | should_save = true; | ||
227 | 29 | } | ||
228 | 30 | |||
229 | 31 | void load_file (string? filename) { | ||
230 | 32 | if (filename == null) | ||
231 | 24 | return; | 33 | return; |
232 | 25 | 34 | ||
233 | 26 | string custom_list = GLib.Path.build_filename (path, "custom.list"); | ||
234 | 27 | try { | ||
235 | 28 | custom = new Subscription (Filename.to_uri (custom_list, null)); | ||
236 | 29 | subscriptions.append (custom); | ||
237 | 30 | } catch (Error error) { | ||
238 | 31 | custom = null; | ||
239 | 32 | warning ("Failed to add custom list %s: %s", custom_list, error.message); | ||
240 | 33 | } | ||
241 | 34 | |||
242 | 35 | string filename = GLib.Path.build_filename (path, "config"); | ||
243 | 36 | keyfile = new GLib.KeyFile (); | 35 | keyfile = new GLib.KeyFile (); |
244 | 37 | try { | 36 | try { |
245 | 38 | keyfile.load_from_file (filename, GLib.KeyFileFlags.NONE); | 37 | keyfile.load_from_file (filename, GLib.KeyFileFlags.NONE); |
246 | @@ -40,68 +39,108 @@ | |||
247 | 40 | foreach (string filter in filters) { | 39 | foreach (string filter in filters) { |
248 | 41 | bool active = false; | 40 | bool active = false; |
249 | 42 | string uri = filter; | 41 | string uri = filter; |
256 | 43 | if (filter.has_prefix ("http-")) | 42 | if (filter.has_prefix ("http-/")) |
257 | 44 | uri = "http:" + filter.substring (6); | 43 | uri = "http:" + filter.substring (5); |
258 | 45 | else if (filter.has_prefix ("file-")) | 44 | else if (filter.has_prefix ("file-/")) |
259 | 46 | uri = "file:" + filter.substring (6); | 45 | uri = "file:" + filter.substring (5); |
260 | 47 | else if (filter.has_prefix ("https-")) | 46 | else if (filter.has_prefix ("http-:")) |
261 | 48 | uri = "https:" + filter.substring (7); | 47 | uri = "https" + filter.substring (5); |
262 | 49 | else | 48 | else |
263 | 50 | active = true; | 49 | active = true; |
264 | 51 | Subscription sub = new Subscription (uri); | 50 | Subscription sub = new Subscription (uri); |
265 | 52 | sub.active = active; | 51 | sub.active = active; |
266 | 53 | sub.add_feature (new Updater ()); | 52 | sub.add_feature (new Updater ()); |
269 | 54 | sub.notify["active"].connect (active_changed); | 53 | add (sub); |
268 | 55 | subscriptions.append (sub); | ||
270 | 56 | } | 54 | } |
271 | 55 | enabled = !keyfile.get_boolean ("settings", "disabled"); | ||
272 | 56 | } catch (KeyFileError.KEY_NOT_FOUND key_error) { | ||
273 | 57 | /* It's no error if a key is missing */ | ||
274 | 58 | } catch (KeyFileError.GROUP_NOT_FOUND group_error) { | ||
275 | 59 | /* It's no error if a group is missing */ | ||
276 | 57 | } catch (FileError.NOENT exist_error) { | 60 | } catch (FileError.NOENT exist_error) { |
277 | 58 | /* It's no error if no config file exists */ | 61 | /* It's no error if no config file exists */ |
278 | 59 | } catch (GLib.Error settings_error) { | 62 | } catch (GLib.Error settings_error) { |
279 | 60 | warning ("Error reading settings from %s: %s\n", filename, settings_error.message); | 63 | warning ("Error reading settings from %s: %s\n", filename, settings_error.message); |
280 | 61 | } | 64 | } |
281 | 62 | 65 | ||
283 | 63 | size = subscriptions.length (); | 66 | notify["enabled"].connect (enabled_changed); |
284 | 67 | } | ||
285 | 68 | |||
286 | 69 | void enabled_changed (ParamSpec pspec) { | ||
287 | 70 | keyfile.set_boolean ("settings", "disabled", !enabled); | ||
288 | 71 | save (); | ||
289 | 64 | } | 72 | } |
290 | 65 | 73 | ||
291 | 66 | void active_changed (Object subscription, ParamSpec pspec) { | 74 | void active_changed (Object subscription, ParamSpec pspec) { |
292 | 75 | update_filters (); | ||
293 | 76 | } | ||
294 | 77 | |||
295 | 78 | void update_filters () { | ||
296 | 67 | var filters = new StringBuilder (); | 79 | var filters = new StringBuilder (); |
297 | 68 | foreach (var sub in subscriptions) { | 80 | foreach (var sub in subscriptions) { |
299 | 69 | if (sub == custom) | 81 | if (!sub.mutable) |
300 | 70 | continue; | 82 | continue; |
301 | 71 | if (sub.uri.has_prefix ("http:") && !sub.active) | 83 | if (sub.uri.has_prefix ("http:") && !sub.active) |
302 | 72 | filters.append ("http-" + sub.uri.substring (4)); | 84 | filters.append ("http-" + sub.uri.substring (4)); |
303 | 73 | else if (sub.uri.has_prefix ("file:") && !sub.active) | 85 | else if (sub.uri.has_prefix ("file:") && !sub.active) |
305 | 74 | filters.append ("file-" + sub.uri.substring (4)); | 86 | filters.append ("file-" + sub.uri.substring (5)); |
306 | 75 | else if (sub.uri.has_prefix ("https:") && !sub.active) | 87 | else if (sub.uri.has_prefix ("https:") && !sub.active) |
308 | 76 | filters.append ("https-" + sub.uri.substring (5)); | 88 | filters.append ("http-" + sub.uri.substring (5)); |
309 | 77 | else | 89 | else |
310 | 78 | filters.append (sub.uri); | 90 | filters.append (sub.uri); |
311 | 79 | filters.append_c (';'); | 91 | filters.append_c (';'); |
312 | 80 | } | 92 | } |
313 | 81 | 93 | ||
315 | 82 | string[] list = (filters.str.slice (0, -1)).split (";"); | 94 | if (filters.str.has_suffix (";")) |
316 | 95 | filters.truncate (filters.len - 1); | ||
317 | 96 | string[] list = filters.str.split (";"); | ||
318 | 83 | keyfile.set_string_list ("settings", "filters", list); | 97 | keyfile.set_string_list ("settings", "filters", list); |
319 | 98 | |||
320 | 99 | save (); | ||
321 | 100 | } | ||
322 | 101 | |||
323 | 102 | |||
324 | 103 | public void save () { | ||
325 | 84 | try { | 104 | try { |
328 | 85 | string filename = GLib.Path.build_filename (path, "config"); | 105 | FileUtils.set_contents (path, keyfile.to_data ()); |
327 | 86 | FileUtils.set_contents (filename, keyfile.to_data ()); | ||
329 | 87 | } catch (Error error) { | 106 | } catch (Error error) { |
330 | 88 | warning ("Failed to save settings: %s", error.message); | 107 | warning ("Failed to save settings: %s", error.message); |
331 | 89 | } | 108 | } |
332 | 90 | } | 109 | } |
333 | 91 | 110 | ||
334 | 92 | public void add_custom_rule (string rule) { | ||
335 | 93 | try { | ||
336 | 94 | var file = File.new_for_uri (custom.uri); | ||
337 | 95 | file.append_to (FileCreateFlags.NONE).write (("%s\n".printf (rule)).data); | ||
338 | 96 | } catch (Error error) { | ||
339 | 97 | warning ("Failed to add custom rule: %s", error.message); | ||
340 | 98 | } | ||
341 | 99 | } | ||
342 | 100 | |||
343 | 101 | /* foreach support */ | 111 | /* foreach support */ |
344 | 102 | public new Subscription? get (uint index) { | 112 | public new Subscription? get (uint index) { |
345 | 103 | return subscriptions.nth_data (index); | 113 | return subscriptions.nth_data (index); |
346 | 104 | } | 114 | } |
347 | 105 | public uint size { get; private set; } | 115 | public uint size { get; private set; } |
348 | 116 | |||
349 | 117 | bool contains (Subscription subscription) { | ||
350 | 118 | foreach (var sub in subscriptions) | ||
351 | 119 | if (sub.uri == subscription.uri) | ||
352 | 120 | return true; | ||
353 | 121 | return false; | ||
354 | 122 | } | ||
355 | 123 | |||
356 | 124 | public bool add (Subscription sub) { | ||
357 | 125 | if (contains (sub)) | ||
358 | 126 | return false; | ||
359 | 127 | |||
360 | 128 | sub.notify["active"].connect (active_changed); | ||
361 | 129 | subscriptions.append (sub); | ||
362 | 130 | size++; | ||
363 | 131 | if (should_save) | ||
364 | 132 | update_filters (); | ||
365 | 133 | return true; | ||
366 | 134 | } | ||
367 | 135 | |||
368 | 136 | public void remove (Subscription sub) { | ||
369 | 137 | if (!contains (sub)) | ||
370 | 138 | return; | ||
371 | 139 | |||
372 | 140 | subscriptions.remove (sub); | ||
373 | 141 | sub.notify["active"].disconnect (active_changed); | ||
374 | 142 | update_filters (); | ||
375 | 143 | size--; | ||
376 | 144 | } | ||
377 | 106 | } | 145 | } |
378 | 107 | } | 146 | } |
379 | 108 | 147 | ||
380 | === modified file 'extensions/adblock/extension.vala' | |||
381 | --- extensions/adblock/extension.vala 2014-02-24 00:06:18 +0000 | |||
382 | +++ extensions/adblock/extension.vala 2014-03-10 10:27:25 +0000 | |||
383 | @@ -16,9 +16,42 @@ | |||
384 | 16 | BLOCK | 16 | BLOCK |
385 | 17 | } | 17 | } |
386 | 18 | 18 | ||
387 | 19 | public enum State { | ||
388 | 20 | ENABLED, | ||
389 | 21 | DISABLED, | ||
390 | 22 | BLOCKED | ||
391 | 23 | } | ||
392 | 24 | |||
393 | 25 | public string? parse_subscription_uri (string? uri) { | ||
394 | 26 | if (uri == null) | ||
395 | 27 | return null; | ||
396 | 28 | |||
397 | 29 | if (uri.has_prefix ("http") || uri.has_prefix ("abp") || uri.has_prefix ("file")) | ||
398 | 30 | { | ||
399 | 31 | string sub_uri = uri; | ||
400 | 32 | if (uri.has_prefix ("abp:")) { | ||
401 | 33 | uri.replace ("abp://", "abp:"); | ||
402 | 34 | if (uri.has_prefix ("abp:subscribe?location=")) { | ||
403 | 35 | /* abp://subscripe?location=http://example.com&title=foo */ | ||
404 | 36 | string[] parts = uri.substring (23, -1).split ("&", 2); | ||
405 | 37 | sub_uri = parts[0]; | ||
406 | 38 | } | ||
407 | 39 | } | ||
408 | 40 | |||
409 | 41 | string decoded_uri = Soup.URI.decode (sub_uri); | ||
410 | 42 | return decoded_uri; | ||
411 | 43 | } | ||
412 | 44 | return null; | ||
413 | 45 | } | ||
414 | 46 | |||
415 | 19 | public class Extension : Midori.Extension { | 47 | public class Extension : Midori.Extension { |
418 | 20 | Config config; | 48 | internal Config config; |
419 | 21 | HashTable<string, Directive?> cache; | 49 | internal Subscription custom; |
420 | 50 | internal HashTable<string, Directive?> cache; | ||
421 | 51 | internal StatusIcon status_icon; | ||
422 | 52 | internal SubscriptionManager manager; | ||
423 | 53 | internal State state; | ||
424 | 54 | internal bool debug_element; | ||
425 | 22 | 55 | ||
426 | 23 | #if HAVE_WEBKIT2 | 56 | #if HAVE_WEBKIT2 |
427 | 24 | public Extension (WebKit.WebExtension web_extension) { | 57 | public Extension (WebKit.WebExtension web_extension) { |
428 | @@ -44,99 +77,7 @@ | |||
429 | 44 | } | 77 | } |
430 | 45 | 78 | ||
431 | 46 | void extension_preferences () { | 79 | void extension_preferences () { |
525 | 47 | open_dialog (null); | 80 | manager.add_subscription (null); |
433 | 48 | } | ||
434 | 49 | |||
435 | 50 | void open_dialog (string? uri) { | ||
436 | 51 | var dialog = new Gtk.Dialog.with_buttons (_("Configure Advertisement filters"), | ||
437 | 52 | null, | ||
438 | 53 | #if !HAVE_GTK3 | ||
439 | 54 | Gtk.DialogFlags.NO_SEPARATOR | | ||
440 | 55 | #endif | ||
441 | 56 | Gtk.DialogFlags.DESTROY_WITH_PARENT, | ||
442 | 57 | Gtk.STOCK_HELP, Gtk.ResponseType.HELP, | ||
443 | 58 | Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE); | ||
444 | 59 | #if HAVE_GTK3 | ||
445 | 60 | dialog.get_widget_for_response (Gtk.ResponseType.HELP).get_style_context ().add_class ("help_button"); | ||
446 | 61 | #endif | ||
447 | 62 | dialog.set_icon_name (Gtk.STOCK_PROPERTIES); | ||
448 | 63 | dialog.set_response_sensitive (Gtk.ResponseType.HELP, false); | ||
449 | 64 | |||
450 | 65 | var hbox = new Gtk.HBox (false, 0); | ||
451 | 66 | (dialog.get_content_area () as Gtk.Box).pack_start (hbox, true, true, 12); | ||
452 | 67 | var vbox = new Gtk.VBox (false, 0); | ||
453 | 68 | hbox.pack_start (vbox, true, true, 4); | ||
454 | 69 | var button = new Gtk.Label (null); | ||
455 | 70 | string description = """ | ||
456 | 71 | Type the address of a preconfigured filter list in the text entry | ||
457 | 72 | and click "Add" to add it to the list. | ||
458 | 73 | You can find more lists at %s %s. | ||
459 | 74 | """.printf ( | ||
460 | 75 | "<a href=\"http://adblockplus.org/en/subscriptions\">adblockplus.org/en/subscriptions</a>", | ||
461 | 76 | "<a href=\"http://easylist.adblockplus.org/\">easylist.adblockplus.org</a>"); | ||
462 | 77 | button.activate_link.connect ((uri)=>{ | ||
463 | 78 | var browser = Midori.Browser.get_for_widget (button); | ||
464 | 79 | var view = browser.add_uri (uri); | ||
465 | 80 | browser.tab = view; | ||
466 | 81 | return true; | ||
467 | 82 | }); | ||
468 | 83 | button.set_markup (description); | ||
469 | 84 | button.set_line_wrap (true); | ||
470 | 85 | vbox.pack_start (button, false, false, 4); | ||
471 | 86 | |||
472 | 87 | var entry = new Gtk.Entry (); | ||
473 | 88 | if (uri != null) | ||
474 | 89 | entry.set_text (uri); | ||
475 | 90 | vbox.pack_start (entry, false, false, 4); | ||
476 | 91 | |||
477 | 92 | var liststore = new Gtk.ListStore (1, typeof (Subscription)); | ||
478 | 93 | var treeview = new Gtk.TreeView.with_model (liststore); | ||
479 | 94 | treeview.set_headers_visible (false); | ||
480 | 95 | var column = new Gtk.TreeViewColumn (); | ||
481 | 96 | var renderer_toggle = new Gtk.CellRendererToggle (); | ||
482 | 97 | column.pack_start (renderer_toggle, false); | ||
483 | 98 | column.set_cell_data_func (renderer_toggle, (column, renderer, model, iter) => { | ||
484 | 99 | Subscription sub; | ||
485 | 100 | liststore.get (iter, 0, out sub); | ||
486 | 101 | renderer.set ("active", sub.active, | ||
487 | 102 | "sensitive", !sub.uri.has_suffix ("custom.list")); | ||
488 | 103 | }); | ||
489 | 104 | renderer_toggle.toggled.connect ((path) => { | ||
490 | 105 | Gtk.TreeIter iter; | ||
491 | 106 | if (liststore.get_iter_from_string (out iter, path)) { | ||
492 | 107 | Subscription sub; | ||
493 | 108 | liststore.get (iter, 0, out sub); | ||
494 | 109 | sub.active = !sub.active; | ||
495 | 110 | } | ||
496 | 111 | }); | ||
497 | 112 | treeview.append_column (column); | ||
498 | 113 | |||
499 | 114 | column = new Gtk.TreeViewColumn (); | ||
500 | 115 | var renderer_text = new Gtk.CellRendererText (); | ||
501 | 116 | column.pack_start (renderer_text, false); | ||
502 | 117 | renderer_text.set ("editable", true); | ||
503 | 118 | // TODO: renderer_text.edited.connect | ||
504 | 119 | column.set_cell_data_func (renderer_text, (column, renderer, model, iter) => { | ||
505 | 120 | Subscription sub; | ||
506 | 121 | liststore.get (iter, 0, out sub); | ||
507 | 122 | renderer.set ("text", sub.uri); | ||
508 | 123 | }); | ||
509 | 124 | treeview.append_column (column); | ||
510 | 125 | |||
511 | 126 | var scrolled = new Gtk.ScrolledWindow (null, null); | ||
512 | 127 | scrolled.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); | ||
513 | 128 | scrolled.add (treeview); | ||
514 | 129 | vbox.pack_start (scrolled); | ||
515 | 130 | |||
516 | 131 | foreach (Subscription sub in config) | ||
517 | 132 | liststore.insert_with_values (null, 0, 0, sub); | ||
518 | 133 | // TODO: row-inserted row-changed row-deleted | ||
519 | 134 | // TODO vbox with add/ edit/ remove/ down/ up | ||
520 | 135 | |||
521 | 136 | dialog.get_content_area ().show_all (); | ||
522 | 137 | |||
523 | 138 | dialog.response.connect ((response)=>{ dialog.destroy (); }); | ||
524 | 139 | dialog.show (); | ||
526 | 140 | } | 81 | } |
527 | 141 | 82 | ||
528 | 142 | void extension_activated (Midori.App app) { | 83 | void extension_activated (Midori.App app) { |
529 | @@ -150,14 +91,24 @@ | |||
530 | 150 | foreach (var tab in browser.get_tabs ()) | 91 | foreach (var tab in browser.get_tabs ()) |
531 | 151 | tab_added (tab); | 92 | tab_added (tab); |
532 | 152 | browser.add_tab.connect (tab_added); | 93 | browser.add_tab.connect (tab_added); |
533 | 94 | |||
534 | 95 | var toggle_button = new StatusIcon.IconButton (); | ||
535 | 96 | toggle_button.set_status (config.enabled ? "enabled" : "disabled"); | ||
536 | 97 | browser.statusbar.pack_start (toggle_button, false, false, 3); | ||
537 | 98 | toggle_button.show (); | ||
538 | 99 | toggle_button.clicked.connect (status_icon.icon_clicked); | ||
539 | 100 | status_icon.toggle_buttons.append (toggle_button); | ||
540 | 153 | } | 101 | } |
541 | 154 | 102 | ||
542 | 103 | |||
543 | 155 | void tab_added (Midori.View view) { | 104 | void tab_added (Midori.View view) { |
544 | 156 | view.web_view.resource_request_starting.connect (resource_requested); | 105 | view.web_view.resource_request_starting.connect (resource_requested); |
545 | 157 | view.web_view.navigation_policy_decision_requested.connect (navigation_requested); | 106 | view.web_view.navigation_policy_decision_requested.connect (navigation_requested); |
546 | 158 | view.notify["load-status"].connect ((pspec) => { | 107 | view.notify["load-status"].connect ((pspec) => { |
549 | 159 | if (view.load_status == Midori.LoadStatus.FINISHED) | 108 | if (config.enabled) { |
550 | 160 | inject_css (view, view.uri); | 109 | if (view.load_status == Midori.LoadStatus.FINISHED) |
551 | 110 | inject_css (view, view.uri); | ||
552 | 111 | } | ||
553 | 161 | }); | 112 | }); |
554 | 162 | view.context_menu.connect (context_menu); | 113 | view.context_menu.connect (context_menu); |
555 | 163 | } | 114 | } |
556 | @@ -174,54 +125,31 @@ | |||
557 | 174 | return; | 125 | return; |
558 | 175 | var action = new Gtk.Action ("BlockElement", label, null, null); | 126 | var action = new Gtk.Action ("BlockElement", label, null, null); |
559 | 176 | action.activate.connect ((action) => { | 127 | action.activate.connect ((action) => { |
561 | 177 | edit_rule_dialog (uri); | 128 | CustomRulesEditor custom_rules_editor = new CustomRulesEditor (custom); |
562 | 129 | custom_rules_editor.set_uri (uri); | ||
563 | 130 | custom_rules_editor.show(); | ||
564 | 178 | }); | 131 | }); |
565 | 179 | menu.add (action); | 132 | menu.add (action); |
566 | 180 | } | 133 | } |
567 | 181 | 134 | ||
603 | 182 | void edit_rule_dialog (string uri) { | 135 | Adblock.State adblock_get_state (Adblock.Directive directive) |
604 | 183 | var dialog = new Gtk.Dialog.with_buttons (_("Edit rule"), | 136 | { |
605 | 184 | null, | 137 | if (directive == Directive.BLOCK) |
606 | 185 | #if !HAVE_GTK3 | 138 | return State.BLOCKED; |
607 | 186 | Gtk.DialogFlags.NO_SEPARATOR | | 139 | if (config.enabled) |
608 | 187 | #endif | 140 | return State.ENABLED; |
609 | 188 | Gtk.DialogFlags.DESTROY_WITH_PARENT, | 141 | else |
610 | 189 | Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, | 142 | return State.DISABLED; |
576 | 190 | Gtk.STOCK_ADD, Gtk.ResponseType.ACCEPT); | ||
577 | 191 | dialog.set_icon_name (Gtk.STOCK_ADD); | ||
578 | 192 | dialog.resizable = false; | ||
579 | 193 | |||
580 | 194 | var hbox = new Gtk.HBox (false, 8); | ||
581 | 195 | var sizegroup = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); | ||
582 | 196 | hbox.border_width = 5; | ||
583 | 197 | var label = new Gtk.Label.with_mnemonic (_("_Rule:")); | ||
584 | 198 | sizegroup.add_widget (label); | ||
585 | 199 | hbox.pack_start (label, false, false, 0); | ||
586 | 200 | (dialog.get_content_area () as Gtk.Box).pack_start (hbox, false, true, 0); | ||
587 | 201 | |||
588 | 202 | var entry = new Gtk.Entry (); | ||
589 | 203 | sizegroup.add_widget (entry); | ||
590 | 204 | entry.activates_default = true; | ||
591 | 205 | entry.set_text (uri); | ||
592 | 206 | hbox.pack_start (entry, true, true, 0); | ||
593 | 207 | |||
594 | 208 | dialog.get_content_area ().show_all (); | ||
595 | 209 | |||
596 | 210 | dialog.set_default_response (Gtk.ResponseType.ACCEPT); | ||
597 | 211 | if (dialog.run () != Gtk.ResponseType.ACCEPT) | ||
598 | 212 | return; | ||
599 | 213 | |||
600 | 214 | string new_rule = entry.get_text (); | ||
601 | 215 | dialog.destroy (); | ||
602 | 216 | config.add_custom_rule (new_rule); | ||
611 | 217 | } | 143 | } |
612 | 218 | 144 | ||
613 | 219 | |||
614 | 220 | void resource_requested (WebKit.WebView web_view, WebKit.WebFrame frame, | 145 | void resource_requested (WebKit.WebView web_view, WebKit.WebFrame frame, |
615 | 221 | WebKit.WebResource resource, WebKit.NetworkRequest request, WebKit.NetworkResponse? response) { | 146 | WebKit.WebResource resource, WebKit.NetworkRequest request, WebKit.NetworkResponse? response) { |
616 | 222 | 147 | ||
618 | 223 | if (request_handled (web_view.uri, request.uri)) | 148 | if (request_handled (web_view.uri, request.uri)) { |
619 | 224 | request.set_uri ("about:blank"); | 149 | request.set_uri ("about:blank"); |
620 | 150 | state = adblock_get_state (get_directive_for_uri (web_view.uri)); | ||
621 | 151 | status_icon.set_state (state); | ||
622 | 152 | } | ||
623 | 225 | } | 153 | } |
624 | 226 | 154 | ||
625 | 227 | bool navigation_requested (WebKit.WebFrame frame, WebKit.NetworkRequest request, | 155 | bool navigation_requested (WebKit.WebFrame frame, WebKit.NetworkRequest request, |
626 | @@ -229,39 +157,28 @@ | |||
627 | 229 | 157 | ||
628 | 230 | string uri = request.uri; | 158 | string uri = request.uri; |
629 | 231 | if (uri.has_prefix ("abp:")) { | 159 | if (uri.has_prefix ("abp:")) { |
638 | 232 | uri = uri.replace ("abp://", "abp:"); | 160 | decision.ignore (); |
639 | 233 | if (uri.has_prefix ("abp:subscribe?location=")) { | 161 | string parsed_uri = parse_subscription_uri (uri); |
640 | 234 | /* abp://subscripe?location=http://example.com&title=foo */ | 162 | manager.add_subscription (parsed_uri); |
641 | 235 | string[] parts = uri.substring (23, -1).split ("&", 2); | 163 | return true; |
634 | 236 | decision.ignore (); | ||
635 | 237 | open_dialog (parts[0]); | ||
636 | 238 | return true; | ||
637 | 239 | } | ||
642 | 240 | } | 164 | } |
643 | 165 | state = adblock_get_state (get_directive_for_uri (request.uri)); | ||
644 | 166 | status_icon.set_state (state); | ||
645 | 241 | return false; | 167 | return false; |
646 | 242 | } | 168 | } |
647 | 243 | 169 | ||
664 | 244 | void inject_css (Midori.View view, string page_uri) { | 170 | string? get_hider_css_for_blocked_resources () { |
649 | 245 | /* Don't block ads on internal pages */ | ||
650 | 246 | if (!Midori.URI.is_http (page_uri)) | ||
651 | 247 | return; | ||
652 | 248 | string domain = Midori.URI.parse_hostname (page_uri, null); | ||
653 | 249 | string[] subdomains = domain.split ("."); | ||
654 | 250 | if (subdomains == null) | ||
655 | 251 | return; | ||
656 | 252 | int cnt = subdomains.length - 1; | ||
657 | 253 | var subdomain = new StringBuilder (subdomains[cnt]); | ||
658 | 254 | subdomain.prepend_c ('.'); | ||
659 | 255 | cnt--; | ||
660 | 256 | var code = new StringBuilder (); | ||
661 | 257 | bool debug_element = "adblock:element" in (Environment.get_variable ("MIDORI_DEBUG") ?? ""); | ||
662 | 258 | string hider_css; | ||
663 | 259 | |||
665 | 260 | /* Hide elements that were blocked, otherwise we will get "broken image" icon */ | 171 | /* Hide elements that were blocked, otherwise we will get "broken image" icon */ |
666 | 172 | var code = new StringBuilder (); | ||
667 | 261 | cache.foreach ((key, val) => { | 173 | cache.foreach ((key, val) => { |
668 | 262 | if (val == Adblock.Directive.BLOCK) | 174 | if (val == Adblock.Directive.BLOCK) |
669 | 263 | code.append ("img[src*=\"%s\"] , iframe[src*=\"%s\"] , ".printf (key, key)); | 175 | code.append ("img[src*=\"%s\"] , iframe[src*=\"%s\"] , ".printf (key, key)); |
670 | 264 | }); | 176 | }); |
671 | 177 | |||
672 | 178 | if (code.str == "") | ||
673 | 179 | return null; | ||
674 | 180 | |||
675 | 181 | string hider_css; | ||
676 | 265 | if (debug_element) | 182 | if (debug_element) |
677 | 266 | hider_css = " { background-color: red; border: 4px solid green; }"; | 183 | hider_css = " { background-color: red; border: 4px solid green; }"; |
678 | 267 | else | 184 | else |
679 | @@ -271,55 +188,96 @@ | |||
680 | 271 | code.append (hider_css); | 188 | code.append (hider_css); |
681 | 272 | if (debug_element) | 189 | if (debug_element) |
682 | 273 | stdout.printf ("hider css: %s\n", code.str); | 190 | stdout.printf ("hider css: %s\n", code.str); |
684 | 274 | view.inject_stylesheet (code.str); | 191 | return code.str; |
685 | 192 | } | ||
686 | 275 | 193 | ||
689 | 276 | code.erase (); | 194 | string[]? get_domains_for_uri (string uri) { |
690 | 277 | int blockscnt = 0; | 195 | if (uri == null) |
691 | 196 | return null; | ||
692 | 197 | string[]? domains = null; | ||
693 | 198 | string domain = Midori.URI.parse_hostname (uri, null); | ||
694 | 199 | string[] subdomains = domain.split ("."); | ||
695 | 200 | if (subdomains == null) | ||
696 | 201 | return null; | ||
697 | 202 | int cnt = subdomains.length - 1; | ||
698 | 203 | var subdomain = new StringBuilder (subdomains[cnt]); | ||
699 | 204 | subdomain.prepend_c ('.'); | ||
700 | 205 | cnt--; | ||
701 | 278 | while (cnt >= 0) { | 206 | while (cnt >= 0) { |
702 | 279 | subdomain.prepend (subdomains[cnt]); | 207 | subdomain.prepend (subdomains[cnt]); |
709 | 280 | string? style = null; | 208 | domains += subdomain.str; |
710 | 281 | foreach (Subscription sub in config) { | 209 | subdomain.prepend_c ('.'); |
711 | 282 | foreach (var feature in sub) { | 210 | cnt--; |
712 | 283 | if (feature is Adblock.Element) { | 211 | } |
713 | 284 | style = (feature as Adblock.Element).lookup (subdomain.str); | 212 | return domains; |
714 | 285 | break; | 213 | } |
715 | 214 | |||
716 | 215 | string? get_hider_css_rules_for_uri (string page_uri) { | ||
717 | 216 | if (page_uri == null) | ||
718 | 217 | return null; | ||
719 | 218 | string[]? domains = get_domains_for_uri (page_uri); | ||
720 | 219 | if (domains == null) | ||
721 | 220 | return null; | ||
722 | 221 | var code = new StringBuilder (); | ||
723 | 222 | int blockscnt = 0; | ||
724 | 223 | string? style = null; | ||
725 | 224 | foreach (Subscription sub in config) { | ||
726 | 225 | foreach (var feature in sub) { | ||
727 | 226 | if (feature is Adblock.Element) { | ||
728 | 227 | foreach (var subdomain in domains) { | ||
729 | 228 | style = (feature as Adblock.Element).lookup (subdomain); | ||
730 | 229 | if (style != null) { | ||
731 | 230 | code.append (style); | ||
732 | 231 | code.append_c (','); | ||
733 | 232 | blockscnt++; | ||
734 | 233 | } | ||
735 | 286 | } | 234 | } |
736 | 287 | } | 235 | } |
737 | 288 | } | 236 | } |
738 | 289 | if (style != null) { | ||
739 | 290 | code.append (style); | ||
740 | 291 | code.append_c (','); | ||
741 | 292 | blockscnt++; | ||
742 | 293 | } | ||
743 | 294 | subdomain.prepend_c ('.'); | ||
744 | 295 | cnt--; | ||
745 | 296 | } | 237 | } |
746 | 238 | |||
747 | 297 | if (blockscnt == 0) | 239 | if (blockscnt == 0) |
749 | 298 | return; | 240 | return null; |
750 | 299 | code.truncate (code.len - 1); | 241 | code.truncate (code.len - 1); |
751 | 300 | 242 | ||
752 | 243 | string hider_css; | ||
753 | 301 | if (debug_element) | 244 | if (debug_element) |
754 | 302 | hider_css = " { background-color: red !important; border: 4px solid green !important; }"; | 245 | hider_css = " { background-color: red !important; border: 4px solid green !important; }"; |
755 | 303 | else | 246 | else |
756 | 304 | hider_css = " { display: none !important }"; | 247 | hider_css = " { display: none !important }"; |
757 | 305 | 248 | ||
758 | 306 | code.append (hider_css); | 249 | code.append (hider_css); |
759 | 307 | view.inject_stylesheet (code.str); | ||
760 | 308 | if (debug_element) | 250 | if (debug_element) |
761 | 309 | stdout.printf ("css: %s\n", code.str); | 251 | stdout.printf ("css: %s\n", code.str); |
762 | 252 | |||
763 | 253 | return code.str; | ||
764 | 254 | } | ||
765 | 255 | |||
766 | 256 | void inject_css (Midori.View view, string page_uri) { | ||
767 | 257 | /* Don't block ads on internal pages */ | ||
768 | 258 | if (!Midori.URI.is_http (page_uri)) | ||
769 | 259 | return; | ||
770 | 260 | |||
771 | 261 | if ("adblock:element" in (Environment.get_variable ("MIDORI_DEBUG") ?? "")) | ||
772 | 262 | debug_element = true; | ||
773 | 263 | else | ||
774 | 264 | debug_element = status_icon.debug_element_toggled; | ||
775 | 265 | |||
776 | 266 | string? blocked_css = get_hider_css_for_blocked_resources (); | ||
777 | 267 | if (blocked_css != null) | ||
778 | 268 | view.inject_stylesheet (blocked_css); | ||
779 | 269 | |||
780 | 270 | string? style = get_hider_css_rules_for_uri (page_uri); | ||
781 | 271 | if (style != null) | ||
782 | 272 | view.inject_stylesheet (style); | ||
783 | 310 | } | 273 | } |
784 | 311 | #endif | 274 | #endif |
785 | 312 | 275 | ||
786 | 313 | internal void init () { | 276 | internal void init () { |
787 | 314 | debug ("Adblock2"); | ||
788 | 315 | |||
789 | 316 | string config_dir = Midori.Paths.get_extension_config_dir ("adblock"); | ||
790 | 317 | config = new Config (config_dir); | ||
791 | 318 | reload_rules (); | ||
792 | 319 | } | ||
793 | 320 | |||
794 | 321 | void reload_rules () { | ||
795 | 322 | cache = new HashTable<string, Directive?> (str_hash, str_equal); | 277 | cache = new HashTable<string, Directive?> (str_hash, str_equal); |
796 | 278 | load_config (); | ||
797 | 279 | status_icon = new StatusIcon (config); | ||
798 | 280 | manager = new SubscriptionManager (config); | ||
799 | 323 | foreach (Subscription sub in config) { | 281 | foreach (Subscription sub in config) { |
800 | 324 | try { | 282 | try { |
801 | 325 | sub.parse (); | 283 | sub.parse (); |
802 | @@ -327,24 +285,61 @@ | |||
803 | 327 | warning ("Error parsing %s: %s", sub.uri, error.message); | 285 | warning ("Error parsing %s: %s", sub.uri, error.message); |
804 | 328 | } | 286 | } |
805 | 329 | } | 287 | } |
816 | 330 | } | 288 | config.notify["size"].connect (subscriptions_added_removed); |
817 | 331 | 289 | manager.description_label.activate_link.connect (open_link); | |
818 | 332 | bool request_handled (string page_uri, string request_uri) { | 290 | } |
819 | 333 | /* Always allow the main page */ | 291 | |
820 | 334 | if (request_uri == page_uri) | 292 | bool open_link (string uri) { |
821 | 335 | return false; | 293 | var browser = get_app ().browser; |
822 | 336 | 294 | var view = browser.add_uri (uri); | |
823 | 337 | /* Skip adblock on internal pages */ | 295 | browser.tab = view; |
824 | 338 | if (Midori.URI.is_blank (page_uri)) | 296 | return true; |
825 | 339 | return false; | 297 | } |
826 | 298 | |||
827 | 299 | void subscriptions_added_removed (ParamSpec pspec) { | ||
828 | 300 | cache.remove_all (); | ||
829 | 301 | } | ||
830 | 302 | |||
831 | 303 | void load_config () { | ||
832 | 304 | string config_dir = Midori.Paths.get_extension_config_dir ("adblock"); | ||
833 | 305 | string presets = Midori.Paths.get_extension_preset_filename ("adblock", "config"); | ||
834 | 306 | string filename = Path.build_filename (config_dir, "config"); | ||
835 | 307 | config = new Config (filename, presets); | ||
836 | 308 | string custom_list = GLib.Path.build_filename (config_dir, "custom.list"); | ||
837 | 309 | try { | ||
838 | 310 | custom = new Subscription (Filename.to_uri (custom_list, null)); | ||
839 | 311 | custom.mutable = false; | ||
840 | 312 | custom.title = _("Custom"); | ||
841 | 313 | config.add (custom); | ||
842 | 314 | } catch (Error error) { | ||
843 | 315 | custom = null; | ||
844 | 316 | warning ("Failed to add custom list %s: %s", custom_list, error.message); | ||
845 | 317 | } | ||
846 | 318 | } | ||
847 | 319 | |||
848 | 320 | public Adblock.Directive get_directive_for_uri (string request_uri, string? page_uri = null) { | ||
849 | 321 | if (!config.enabled) | ||
850 | 322 | return Directive.ALLOW; | ||
851 | 323 | |||
852 | 324 | if (page_uri != null) { | ||
853 | 325 | /* Always allow the main page */ | ||
854 | 326 | if (request_uri == page_uri) | ||
855 | 327 | return Directive.ALLOW; | ||
856 | 328 | |||
857 | 329 | /* Skip adblock on internal pages */ | ||
858 | 330 | if (Midori.URI.is_blank (page_uri)) | ||
859 | 331 | return Directive.ALLOW; | ||
860 | 332 | } | ||
861 | 340 | 333 | ||
862 | 341 | /* Skip adblock on favicons and non http schemes */ | 334 | /* Skip adblock on favicons and non http schemes */ |
863 | 342 | if (!Midori.URI.is_http (request_uri) || request_uri.has_suffix ("favicon.ico")) | 335 | if (!Midori.URI.is_http (request_uri) || request_uri.has_suffix ("favicon.ico")) |
865 | 343 | return false; | 336 | return Directive.ALLOW; |
866 | 344 | 337 | ||
867 | 345 | Directive? directive = cache.lookup (request_uri); | 338 | Directive? directive = cache.lookup (request_uri); |
868 | 346 | if (directive == null) { | 339 | if (directive == null) { |
869 | 347 | foreach (Subscription sub in config) { | 340 | foreach (Subscription sub in config) { |
870 | 341 | if (page_uri == null) | ||
871 | 342 | page_uri = request_uri; | ||
872 | 348 | directive = sub.get_directive (request_uri, page_uri); | 343 | directive = sub.get_directive (request_uri, page_uri); |
873 | 349 | if (directive != null) | 344 | if (directive != null) |
874 | 350 | break; | 345 | break; |
875 | @@ -352,8 +347,14 @@ | |||
876 | 352 | if (directive == null) | 347 | if (directive == null) |
877 | 353 | directive = Directive.ALLOW; | 348 | directive = Directive.ALLOW; |
878 | 354 | cache.insert (request_uri, directive); | 349 | cache.insert (request_uri, directive); |
879 | 350 | if (directive == Directive.BLOCK) | ||
880 | 351 | cache.insert (page_uri, directive); | ||
881 | 355 | } | 352 | } |
883 | 356 | return directive == Directive.BLOCK; | 353 | return directive; |
884 | 354 | } | ||
885 | 355 | |||
886 | 356 | internal bool request_handled (string page_uri, string request_uri) { | ||
887 | 357 | return get_directive_for_uri (request_uri, page_uri) == Directive.BLOCK; | ||
888 | 357 | } | 358 | } |
889 | 358 | } | 359 | } |
890 | 359 | 360 | ||
891 | @@ -411,6 +412,179 @@ | |||
892 | 411 | #endif | 412 | #endif |
893 | 412 | 413 | ||
894 | 413 | #if !HAVE_WEBKIT2 | 414 | #if !HAVE_WEBKIT2 |
895 | 415 | static string? tmp_folder = null; | ||
896 | 416 | string get_test_file (string contents) { | ||
897 | 417 | if (tmp_folder == null) | ||
898 | 418 | tmp_folder = Midori.Paths.make_tmp_dir ("adblockXXXXXX"); | ||
899 | 419 | string checksum = Checksum.compute_for_string (ChecksumType.MD5, contents); | ||
900 | 420 | string file = Path.build_path (Path.DIR_SEPARATOR_S, tmp_folder, checksum); | ||
901 | 421 | try { | ||
902 | 422 | FileUtils.set_contents (file, contents, -1); | ||
903 | 423 | } catch (Error file_error) { | ||
904 | 424 | GLib.error (file_error.message); | ||
905 | 425 | } | ||
906 | 426 | return file; | ||
907 | 427 | } | ||
908 | 428 | |||
909 | 429 | struct TestCaseConfig { | ||
910 | 430 | public string content; | ||
911 | 431 | public uint size; | ||
912 | 432 | public bool enabled; | ||
913 | 433 | } | ||
914 | 434 | |||
915 | 435 | const TestCaseConfig[] configs = { | ||
916 | 436 | { "", 0, true }, | ||
917 | 437 | { "[settings]", 0, true }, | ||
918 | 438 | { "[settings]\nfilters=foo;", 1, true }, | ||
919 | 439 | { "[settings]\nfilters=foo;\ndisabled=true", 1, false } | ||
920 | 440 | }; | ||
921 | 441 | |||
922 | 442 | void test_adblock_config () { | ||
923 | 443 | assert (new Adblock.Config (null, null).size == 0); | ||
924 | 444 | |||
925 | 445 | foreach (var conf in configs) { | ||
926 | 446 | var config = new Adblock.Config (get_test_file (conf.content), null); | ||
927 | 447 | if (config.size != conf.size) | ||
928 | 448 | error ("Wrong size %s rather than %s:\n%s", | ||
929 | 449 | config.size.to_string (), conf.size.to_string (), conf.content); | ||
930 | 450 | if (config.enabled != conf.enabled) | ||
931 | 451 | error ("Wrongly got enabled=%s rather than %s:\n%s", | ||
932 | 452 | config.enabled.to_string (), conf.enabled.to_string (), conf.content); | ||
933 | 453 | } | ||
934 | 454 | } | ||
935 | 455 | |||
936 | 456 | struct TestCaseSub { | ||
937 | 457 | public string uri; | ||
938 | 458 | public bool active; | ||
939 | 459 | } | ||
940 | 460 | |||
941 | 461 | const TestCaseSub[] subs = { | ||
942 | 462 | { "http://foo.com", true }, | ||
943 | 463 | { "http://bar.com", false }, | ||
944 | 464 | { "https://spam.com", true }, | ||
945 | 465 | { "https://eggs.com", false }, | ||
946 | 466 | { "file:///bla", true }, | ||
947 | 467 | { "file:///blub", false } | ||
948 | 468 | }; | ||
949 | 469 | |||
950 | 470 | void test_adblock_subs () { | ||
951 | 471 | var config = new Adblock.Config (get_test_file (""" | ||
952 | 472 | [settings] | ||
953 | 473 | filters=http://foo.com;http-//bar.com;https://spam.com;http-://eggs.com;file:///bla;file-///blub;http://foo.com; | ||
954 | 474 | """), null); | ||
955 | 475 | |||
956 | 476 | assert (config.enabled); | ||
957 | 477 | foreach (var sub in subs) { | ||
958 | 478 | bool found = false; | ||
959 | 479 | foreach (var subscription in config) { | ||
960 | 480 | if (subscription.uri == sub.uri) { | ||
961 | 481 | assert (subscription.active == sub.active); | ||
962 | 482 | found = true; | ||
963 | 483 | } | ||
964 | 484 | } | ||
965 | 485 | if (!found) | ||
966 | 486 | error ("%s not found", sub.uri); | ||
967 | 487 | } | ||
968 | 488 | |||
969 | 489 | /* 6 unique URLs, 1 duplicate */ | ||
970 | 490 | assert (config.size == 6); | ||
971 | 491 | /* Duplicates aren't added again either */ | ||
972 | 492 | assert (!config.add (new Adblock.Subscription ("https://spam.com"))); | ||
973 | 493 | |||
974 | 494 | /* Saving the config and loading it should give back identical results */ | ||
975 | 495 | config.save (); | ||
976 | 496 | var copy = new Adblock.Config (config.path, null); | ||
977 | 497 | assert (copy.size == config.size); | ||
978 | 498 | assert (copy.enabled == config.enabled); | ||
979 | 499 | for (int i = 0; i < config.size; i++) { | ||
980 | 500 | assert (copy[i].uri == config[i].uri); | ||
981 | 501 | assert (copy[i].active == config[i].active); | ||
982 | 502 | } | ||
983 | 503 | /* Enabled status should be saved and loaded */ | ||
984 | 504 | config.enabled = false; | ||
985 | 505 | copy = new Adblock.Config (config.path, null); | ||
986 | 506 | assert (copy.enabled == config.enabled); | ||
987 | 507 | /* Flipping individual active values should be retained after saving */ | ||
988 | 508 | foreach (var sub in config) | ||
989 | 509 | sub.active = !sub.active; | ||
990 | 510 | copy = new Adblock.Config (config.path, null); | ||
991 | 511 | for (uint i = 0; i < config.size; i++) { | ||
992 | 512 | if (config[i].active != copy[i].active) { | ||
993 | 513 | string contents; | ||
994 | 514 | try { | ||
995 | 515 | FileUtils.get_contents (config.path, out contents, null); | ||
996 | 516 | } catch (Error file_error) { | ||
997 | 517 | error (file_error.message); | ||
998 | 518 | } | ||
999 | 519 | error ("%s is %s but should be %s:\n%s", | ||
1000 | 520 | copy[i].uri, copy[i].active ? "active" : "disabled", config[i].active ? "active" : "disabled", contents); | ||
1001 | 521 | } | ||
1002 | 522 | } | ||
1003 | 523 | |||
1004 | 524 | /* Adding and removing works, changes size */ | ||
1005 | 525 | var s = new Adblock.Subscription ("http://en.de"); | ||
1006 | 526 | assert (config.add (s)); | ||
1007 | 527 | assert (config.size == 7); | ||
1008 | 528 | config.remove (s); | ||
1009 | 529 | assert (config.size == 6); | ||
1010 | 530 | /* If it was removed before we should be able to add it again */ | ||
1011 | 531 | assert (config.add (s)); | ||
1012 | 532 | assert (config.size == 7); | ||
1013 | 533 | } | ||
1014 | 534 | |||
1015 | 535 | void test_adblock_init () { | ||
1016 | 536 | /* No config */ | ||
1017 | 537 | var extension = new Adblock.Extension (); | ||
1018 | 538 | extension.init (); | ||
1019 | 539 | assert (extension.config.enabled); | ||
1020 | 540 | /* Defaults plus custom */ | ||
1021 | 541 | if (extension.config.size != 3) | ||
1022 | 542 | error ("Expected 3 initial subs, got %s".printf ( | ||
1023 | 543 | extension.config.size.to_string ())); | ||
1024 | 544 | assert (extension.cache.size () == 0); | ||
1025 | 545 | |||
1026 | 546 | /* Add new subscription */ | ||
1027 | 547 | string path = Midori.Paths.get_res_filename ("adblock.list"); | ||
1028 | 548 | string uri; | ||
1029 | 549 | try { | ||
1030 | 550 | uri = Filename.to_uri (path, null); | ||
1031 | 551 | } catch (Error error) { | ||
1032 | 552 | GLib.error (error.message); | ||
1033 | 553 | } | ||
1034 | 554 | var sub = new Adblock.Subscription (uri); | ||
1035 | 555 | extension.config.add (sub); | ||
1036 | 556 | assert (extension.cache.size () == 0); | ||
1037 | 557 | assert (extension.config.size == 4); | ||
1038 | 558 | try { | ||
1039 | 559 | sub.parse (); | ||
1040 | 560 | } catch (GLib.Error error) { | ||
1041 | 561 | GLib.error (error.message); | ||
1042 | 562 | } | ||
1043 | 563 | /* The page itself never hits */ | ||
1044 | 564 | assert (!extension.request_handled ("https://ads.bogus.name/blub", "https://ads.bogus.name/blub")); | ||
1045 | 565 | /* Favicons don't either */ | ||
1046 | 566 | assert (!extension.request_handled ("https://foo.com", "https://ads.bogus.name/blub/favicon.ico")); | ||
1047 | 567 | assert (extension.cache.size () == 0); | ||
1048 | 568 | /* Some sanity checks to be sure there's no earlier problem */ | ||
1049 | 569 | assert (sub.title == "Exercise"); | ||
1050 | 570 | assert (sub.get_directive ("https://ads.bogus.name/blub", "") == Adblock.Directive.BLOCK); | ||
1051 | 571 | /* A rule hit should add to the cache */ | ||
1052 | 572 | assert (extension.request_handled ("https://foo.com", "https://ads.bogus.name/blub")); | ||
1053 | 573 | assert (extension.cache.size () > 0); | ||
1054 | 574 | /* Disabled means no request should be handled */ | ||
1055 | 575 | extension.config.enabled = false; | ||
1056 | 576 | assert (!extension.request_handled ("https://foo.com", "https://ads.bogus.name/blub")); | ||
1057 | 577 | /* Removing a subscription should clear the cache */ | ||
1058 | 578 | extension.config.remove (sub); | ||
1059 | 579 | assert (extension.cache.size () == 0); | ||
1060 | 580 | assert (extension.config.size == 3); | ||
1061 | 581 | /* Now let's add a custom rule */ | ||
1062 | 582 | extension.config.enabled = true; | ||
1063 | 583 | extension.custom.add_rule ("*.png"); | ||
1064 | 584 | assert (!extension.request_handled ("https://foo.com", "http://alpha.beta.com/images/yota.png")); | ||
1065 | 585 | assert (extension.cache.size () > 0); | ||
1066 | 586 | } | ||
1067 | 587 | |||
1068 | 414 | struct TestCaseLine { | 588 | struct TestCaseLine { |
1069 | 415 | public string line; | 589 | public string line; |
1070 | 416 | public string fixed; | 590 | public string fixed; |
1071 | @@ -499,19 +673,27 @@ | |||
1072 | 499 | } | 673 | } |
1073 | 500 | } | 674 | } |
1074 | 501 | 675 | ||
1075 | 676 | string pretty_date (DateTime? date) { | ||
1076 | 677 | if (date == null) | ||
1077 | 678 | return "N/A"; | ||
1078 | 679 | return date.to_string (); | ||
1079 | 680 | } | ||
1080 | 681 | |||
1081 | 502 | struct TestUpdateExample { | 682 | struct TestUpdateExample { |
1082 | 503 | public string content; | 683 | public string content; |
1083 | 504 | public bool result; | 684 | public bool result; |
1084 | 685 | public bool valid; | ||
1085 | 505 | } | 686 | } |
1086 | 506 | 687 | ||
1087 | 507 | const TestUpdateExample[] examples = { | 688 | const TestUpdateExample[] examples = { |
1095 | 508 | { "[Adblock Plus 1.1]\n! Last modified: 05 Sep 2010 11:00 UTC\n! This list expires after 48 hours\n", true }, | 689 | { "[Adblock Plus 1.1]\n! Last modified: 05 Sep 2010 11:00 UTC\n! This list expires after 48 hours\n", true, true }, |
1096 | 509 | { "[Adblock Plus 1.1]\n! Last modified: 05.09.2010 11:00 UTC\n! Expires: 2 days (update frequency)\n", true }, | 690 | { "[Adblock Plus 1.1]\n! Last modified: 05.09.2010 11:00 UTC\n! Expires: 2 days (update frequency)\n", true, true }, |
1097 | 510 | { "[Adblock Plus 1.1]\n! Updated: 05 Nov 2024 11:00 UTC\n! Expires: 5 days (update frequency)\n", false }, | 691 | { "[Adblock Plus 1.1]\n! Updated: 05 Nov 2024 11:00 UTC\n! Expires: 5 days (update frequency)\n", false, true }, |
1098 | 511 | { "[Adblock]\n! dutchblock v3\n! This list expires after 14 days\n|http://b*.mookie1.com/\n", false }, | 692 | { "[Adblock]\n! dutchblock v3\n! This list expires after 14 days\n|http://b*.mookie1.com/\n", false, true }, |
1099 | 512 | { "[Adblock Plus 2.0]\n! Last modification time (GMT): 2012.11.05 13:33\n! Expires: 5 days (update frequency)\n", true }, | 693 | { "[Adblock Plus 2.0]\n! Last modification time (GMT): 2012.11.05 13:33\n! Expires: 5 days (update frequency)\n", true, true }, |
1100 | 513 | { "[Adblock Plus 2.0]\n! Last modification time (GMT): 2012.11.05 13:33\n", true }, | 694 | { "[Adblock Plus 2.0]\n! Last modification time (GMT): 2012.11.05 13:33\n", true, true }, |
1101 | 514 | { "[Adblock]\n ! dummy, i dont have any dates\n", false } | 695 | { "[Adblock]\n ! dummy, i dont have any dates\n", false, true }, |
1102 | 696 | { "\n", false, false } | ||
1103 | 515 | }; | 697 | }; |
1104 | 516 | 698 | ||
1105 | 517 | void test_subscription_update () { | 699 | void test_subscription_update () { |
1106 | @@ -531,23 +713,52 @@ | |||
1107 | 531 | foreach (var example in examples) { | 713 | foreach (var example in examples) { |
1108 | 532 | try { | 714 | try { |
1109 | 533 | file.replace_contents (example.content.data, null, false, FileCreateFlags.NONE, null); | 715 | file.replace_contents (example.content.data, null, false, FileCreateFlags.NONE, null); |
1112 | 534 | updater.last_mod_meta = null; | 716 | sub.clear (); |
1111 | 535 | updater.expires_meta = null; | ||
1113 | 536 | sub.parse (); | 717 | sub.parse (); |
1114 | 537 | } catch (Error error) { | 718 | } catch (Error error) { |
1115 | 538 | GLib.error (error.message); | 719 | GLib.error (error.message); |
1116 | 539 | } | 720 | } |
1121 | 540 | if (example.result == true) | 721 | if (example.valid != sub.valid) |
1122 | 541 | assert (updater.needs_updating()); | 722 | error ("Subscription expected to be %svalid but %svalid:\n%s", |
1123 | 542 | else | 723 | example.valid ? "" : "in", sub.valid ? "" : "in", example.content); |
1124 | 543 | assert (!updater.needs_updating()); | 724 | if (example.result != updater.needs_update) |
1125 | 725 | error ("Update%s expected for:\n%s\nLast Updated: %s\nExpires: %s", | ||
1126 | 726 | example.result ? "" : " not", example.content, | ||
1127 | 727 | pretty_date (updater.last_updated), pretty_date (updater.expires)); | ||
1128 | 728 | } | ||
1129 | 729 | } | ||
1130 | 730 | |||
1131 | 731 | struct TestSubUri { | ||
1132 | 732 | public string? src_uri; | ||
1133 | 733 | public string? dst_uri; | ||
1134 | 734 | } | ||
1135 | 735 | |||
1136 | 736 | const TestSubUri[] suburis = | ||
1137 | 737 | { | ||
1138 | 738 | { null, null }, | ||
1139 | 739 | { "not-a-link", null }, | ||
1140 | 740 | { "http://some.uri", "http://some.uri" }, | ||
1141 | 741 | { "abp:subscribe?location=https%3A%2F%2Feasylist-downloads.adblockplus.org%2Fabpindo%2Beasylist.txt&title=ABPindo%2BEasyList", "https://easylist-downloads.adblockplus.org/abpindo+easylist.txt" } | ||
1142 | 742 | }; | ||
1143 | 743 | |||
1144 | 744 | void test_subscription_uri_parsing () { | ||
1145 | 745 | string? parsed_uri; | ||
1146 | 746 | foreach (var example in suburis) { | ||
1147 | 747 | parsed_uri = Adblock.parse_subscription_uri (example.src_uri); | ||
1148 | 748 | if (parsed_uri != example.dst_uri) | ||
1149 | 749 | error ("Subscription expected to be %svalid but %svalid:\n%s", | ||
1150 | 750 | example.dst_uri, parsed_uri, example.src_uri); | ||
1151 | 544 | } | 751 | } |
1152 | 545 | } | 752 | } |
1153 | 546 | 753 | ||
1154 | 547 | public void extension_test () { | 754 | public void extension_test () { |
1155 | 755 | Test.add_func ("/extensions/adblock2/config", test_adblock_config); | ||
1156 | 756 | Test.add_func ("/extensions/adblock2/subs", test_adblock_subs); | ||
1157 | 757 | Test.add_func ("/extensions/adblock2/init", test_adblock_init); | ||
1158 | 548 | Test.add_func ("/extensions/adblock2/parse", test_adblock_fixup_regexp); | 758 | Test.add_func ("/extensions/adblock2/parse", test_adblock_fixup_regexp); |
1159 | 549 | Test.add_func ("/extensions/adblock2/pattern", test_adblock_pattern); | 759 | Test.add_func ("/extensions/adblock2/pattern", test_adblock_pattern); |
1160 | 550 | Test.add_func ("/extensions/adblock2/update", test_subscription_update); | 760 | Test.add_func ("/extensions/adblock2/update", test_subscription_update); |
1161 | 761 | Test.add_func ("/extensions/adblock2/subsparse", test_subscription_uri_parsing); | ||
1162 | 551 | } | 762 | } |
1163 | 552 | #endif | 763 | #endif |
1164 | 553 | 764 | ||
1165 | 554 | 765 | ||
1166 | === modified file 'extensions/adblock/subscriptions.vala' | |||
1167 | --- extensions/adblock/subscriptions.vala 2014-02-20 18:27:01 +0000 | |||
1168 | +++ extensions/adblock/subscriptions.vala 2014-03-10 10:27:25 +0000 | |||
1169 | @@ -15,6 +15,9 @@ | |||
1170 | 15 | public virtual bool header (string key, string value) { | 15 | public virtual bool header (string key, string value) { |
1171 | 16 | return false; | 16 | return false; |
1172 | 17 | } | 17 | } |
1173 | 18 | public virtual bool parsed (File file) { | ||
1174 | 19 | return true; | ||
1175 | 20 | } | ||
1176 | 18 | public virtual Directive? match (string request_uri, string page_uri) throws Error { | 21 | public virtual Directive? match (string request_uri, string page_uri) throws Error { |
1177 | 19 | return null; | 22 | return null; |
1178 | 20 | } | 23 | } |
1179 | @@ -24,8 +27,12 @@ | |||
1180 | 24 | 27 | ||
1181 | 25 | public class Subscription : GLib.Object { | 28 | public class Subscription : GLib.Object { |
1182 | 26 | public string? path; | 29 | public string? path; |
1183 | 30 | bool debug_parse; | ||
1184 | 27 | public string uri { get; set; default = null; } | 31 | public string uri { get; set; default = null; } |
1185 | 32 | public string title { get; set; default = null; } | ||
1186 | 28 | public bool active { get; set; default = true; } | 33 | public bool active { get; set; default = true; } |
1187 | 34 | public bool mutable { get; set; default = true; } | ||
1188 | 35 | public bool valid { get; private set; default = true; } | ||
1189 | 29 | List<Feature> features; | 36 | List<Feature> features; |
1190 | 30 | public Pattern pattern; | 37 | public Pattern pattern; |
1191 | 31 | public Keys keys; | 38 | public Keys keys; |
1192 | @@ -35,6 +42,8 @@ | |||
1193 | 35 | WebKit.Download? download; | 42 | WebKit.Download? download; |
1194 | 36 | 43 | ||
1195 | 37 | public Subscription (string uri) { | 44 | public Subscription (string uri) { |
1196 | 45 | debug_parse = "adblock:parse" in (Environment.get_variable ("MIDORI_DEBUG") ?? ""); | ||
1197 | 46 | |||
1198 | 38 | this.uri = uri; | 47 | this.uri = uri; |
1199 | 39 | 48 | ||
1200 | 40 | this.optslist = new Options (); | 49 | this.optslist = new Options (); |
1201 | @@ -172,7 +181,8 @@ | |||
1202 | 172 | return; | 181 | return; |
1203 | 173 | 182 | ||
1204 | 174 | string format_patt = fixup_regex (prefix, patt); | 183 | string format_patt = fixup_regex (prefix, patt); |
1206 | 175 | debug ("got: %s opts %s", format_patt, opts); | 184 | if (debug_parse) |
1207 | 185 | stdout.printf ("got: %s opts %s\n", format_patt, opts); | ||
1208 | 176 | compile_regexp (format_patt, opts); | 186 | compile_regexp (format_patt, opts); |
1209 | 177 | /* return format_patt */ | 187 | /* return format_patt */ |
1210 | 178 | } | 188 | } |
1211 | @@ -186,7 +196,8 @@ | |||
1212 | 186 | if (Regex.match_simple ("^/.*[\\^\\$\\*].*/$", patt, | 196 | if (Regex.match_simple ("^/.*[\\^\\$\\*].*/$", patt, |
1213 | 187 | RegexCompileFlags.UNGREEDY, RegexMatchFlags.NOTEMPTY) | 197 | RegexCompileFlags.UNGREEDY, RegexMatchFlags.NOTEMPTY) |
1214 | 188 | || opts != null && opts.contains ("whitelist")) { | 198 | || opts != null && opts.contains ("whitelist")) { |
1216 | 189 | debug ("patt: %s", patt); | 199 | if (debug_parse) |
1217 | 200 | stdout.printf ("patt: %s\n", patt); | ||
1218 | 190 | if (opts.contains ("whitelist")) | 201 | if (opts.contains ("whitelist")) |
1219 | 191 | this.whitelist.insert (patt, regex); | 202 | this.whitelist.insert (patt, regex); |
1220 | 192 | else | 203 | else |
1221 | @@ -233,12 +244,15 @@ | |||
1222 | 233 | string value = ""; | 244 | string value = ""; |
1223 | 234 | if (header.contains (":")) { | 245 | if (header.contains (":")) { |
1224 | 235 | string[] parts = header.split (":", 2); | 246 | string[] parts = header.split (":", 2); |
1226 | 236 | if (parts[0] != null) { | 247 | if (parts[0] != null && parts[0] != "" |
1227 | 248 | && parts[1] != null && parts[1] != "") { | ||
1228 | 237 | key = parts[0].substring (2, -1); | 249 | key = parts[0].substring (2, -1); |
1229 | 238 | value = parts[1].substring (1, -1); | 250 | value = parts[1].substring (1, -1); |
1230 | 239 | } | 251 | } |
1231 | 240 | } | 252 | } |
1232 | 241 | debug ("Header '%s' says '%s'", key, value); | 253 | debug ("Header '%s' says '%s'", key, value); |
1233 | 254 | if (key == "Title") | ||
1234 | 255 | title = value; | ||
1235 | 242 | foreach (var feature in features) { | 256 | foreach (var feature in features) { |
1236 | 243 | if (feature.header (key, value)) | 257 | if (feature.header (key, value)) |
1237 | 244 | break; | 258 | break; |
1238 | @@ -283,18 +297,25 @@ | |||
1239 | 283 | #if HAVE_WEBKIT2 | 297 | #if HAVE_WEBKIT2 |
1240 | 284 | /* TODO */ | 298 | /* TODO */ |
1241 | 285 | #else | 299 | #else |
1244 | 286 | if (download != null) | 300 | /* Don't bother trying to download local files */ |
1245 | 287 | return; | 301 | if (!uri.has_prefix ("file://")) { |
1246 | 302 | if (download != null) | ||
1247 | 303 | return; | ||
1248 | 288 | 304 | ||
1254 | 289 | download = new WebKit.Download (new WebKit.NetworkRequest (uri)); | 305 | string destination_uri = Filename.to_uri (path, null); |
1255 | 290 | download.destination_uri = Filename.to_uri (path, null); | 306 | debug ("Fetching %s to %s now", uri, destination_uri); |
1256 | 291 | download.notify["status"].connect (download_status); | 307 | download = new WebKit.Download (new WebKit.NetworkRequest (uri)); |
1257 | 292 | debug ("Fetching %s to %s now", uri, download.destination_uri); | 308 | if (!Midori.Download.has_enough_space (download, destination_uri, true)) |
1258 | 293 | download.start (); | 309 | throw new FileError.EXIST ("Can't download to \"%s\"", path); |
1259 | 310 | download.destination_uri = destination_uri; | ||
1260 | 311 | download.notify["status"].connect (download_status); | ||
1261 | 312 | download.start (); | ||
1262 | 294 | #endif | 313 | #endif |
1263 | 314 | } | ||
1264 | 295 | return; | 315 | return; |
1265 | 296 | } | 316 | } |
1266 | 297 | 317 | ||
1267 | 318 | valid = false; | ||
1268 | 298 | string? line; | 319 | string? line; |
1269 | 299 | while ((line = stream.read_line (null)) != null) { | 320 | while ((line = stream.read_line (null)) != null) { |
1270 | 300 | if (line == null) | 321 | if (line == null) |
1271 | @@ -306,6 +327,13 @@ | |||
1272 | 306 | parse_header (chomped); | 327 | parse_header (chomped); |
1273 | 307 | else | 328 | else |
1274 | 308 | parse_line (chomped); | 329 | parse_line (chomped); |
1275 | 330 | /* The file isn't completely empty */ | ||
1276 | 331 | valid = true; | ||
1277 | 332 | } | ||
1278 | 333 | |||
1279 | 334 | foreach (var feature in features) { | ||
1280 | 335 | if (!feature.parsed (filter_file)) | ||
1281 | 336 | valid = false; | ||
1282 | 309 | } | 337 | } |
1283 | 310 | } | 338 | } |
1284 | 311 | 339 | ||
1285 | @@ -324,5 +352,15 @@ | |||
1286 | 324 | } | 352 | } |
1287 | 325 | return null; | 353 | return null; |
1288 | 326 | } | 354 | } |
1289 | 355 | |||
1290 | 356 | public void add_rule (string rule) { | ||
1291 | 357 | try { | ||
1292 | 358 | var file = File.new_for_uri (uri); | ||
1293 | 359 | file.append_to (FileCreateFlags.NONE).write (("%s\n".printf (rule)).data); | ||
1294 | 360 | parse (); | ||
1295 | 361 | } catch (Error error) { | ||
1296 | 362 | warning ("Failed to add custom rule: %s", error.message); | ||
1297 | 363 | } | ||
1298 | 364 | } | ||
1299 | 327 | } | 365 | } |
1300 | 328 | } | 366 | } |
1301 | 329 | 367 | ||
1302 | === modified file 'extensions/adblock/updater.vala' | |||
1303 | --- extensions/adblock/updater.vala 2014-02-20 00:14:15 +0000 | |||
1304 | +++ extensions/adblock/updater.vala 2014-03-10 10:27:25 +0000 | |||
1305 | @@ -12,15 +12,23 @@ | |||
1306 | 12 | 12 | ||
1307 | 13 | namespace Adblock { | 13 | namespace Adblock { |
1308 | 14 | public class Updater : Feature { | 14 | public class Updater : Feature { |
1314 | 15 | public string expires_meta { get; set; default = null; } | 15 | string expires_meta; |
1315 | 16 | public string last_mod_meta { get; set; default = null; } | 16 | string last_mod_meta; |
1316 | 17 | public int64 update_tstamp { get; set; default = 0; } | 17 | public DateTime last_updated { get; set; } |
1317 | 18 | public int64 last_mod_tstamp { get; set; default = 0; } | 18 | public DateTime expires { get; set; } |
1318 | 19 | public int64 last_check_tstamp { get; set; default = 0; } | 19 | public bool needs_update { get; set; } |
1319 | 20 | 20 | ||
1320 | 21 | public Updater () { | 21 | public Updater () { |
1321 | 22 | } | 22 | } |
1322 | 23 | 23 | ||
1323 | 24 | public override void clear () { | ||
1324 | 25 | expires_meta = null; | ||
1325 | 26 | last_mod_meta = null; | ||
1326 | 27 | last_updated = null; | ||
1327 | 28 | expires = null; | ||
1328 | 29 | needs_update = false; | ||
1329 | 30 | } | ||
1330 | 31 | |||
1331 | 24 | public override bool header (string key, string value) { | 32 | public override bool header (string key, string value) { |
1332 | 25 | if (key.has_prefix ("Last mod") || key == "Updated") { | 33 | if (key.has_prefix ("Last mod") || key == "Updated") { |
1333 | 26 | last_mod_meta = value; | 34 | last_mod_meta = value; |
1334 | @@ -37,6 +45,12 @@ | |||
1335 | 37 | return false; | 45 | return false; |
1336 | 38 | } | 46 | } |
1337 | 39 | 47 | ||
1338 | 48 | public override bool parsed (File file) { | ||
1339 | 49 | process_dates (file); | ||
1340 | 50 | /* It's not an error to have no update headers, we go for defaults */ | ||
1341 | 51 | return true; | ||
1342 | 52 | } | ||
1343 | 53 | |||
1344 | 40 | int get_month_from_string (string? month) { | 54 | int get_month_from_string (string? month) { |
1345 | 41 | if (month == null) | 55 | if (month == null) |
1346 | 42 | return 0; | 56 | return 0; |
1347 | @@ -50,19 +64,17 @@ | |||
1348 | 50 | return 0; | 64 | return 0; |
1349 | 51 | } | 65 | } |
1350 | 52 | 66 | ||
1352 | 53 | public bool needs_updating () { | 67 | void process_dates (File file) { |
1353 | 54 | DateTime now = new DateTime.now_local (); | 68 | DateTime now = new DateTime.now_local (); |
1358 | 55 | DateTime expire_date = null; | 69 | last_updated = null; |
1359 | 56 | DateTime last_mod_date = null; | 70 | expires = null; |
1356 | 57 | string? last_mod = last_mod_meta; | ||
1357 | 58 | string? expires = expires_meta; | ||
1360 | 59 | 71 | ||
1361 | 60 | /* We have "last modification" metadata */ | 72 | /* We have "last modification" metadata */ |
1363 | 61 | if (last_mod != null) { | 73 | if (last_mod_meta != null) { |
1364 | 62 | int h = 0, min = 0, d, m, y; | 74 | int h = 0, min = 0, d, m, y; |
1365 | 63 | /* Date in a form of: 20.08.2012 12:34 */ | 75 | /* Date in a form of: 20.08.2012 12:34 */ |
1368 | 64 | if (last_mod.contains (".") || last_mod.contains("-")) { | 76 | if (last_mod_meta.contains (".") || last_mod_meta.contains("-")) { |
1369 | 65 | string[] parts = last_mod.split (" ", 2); | 77 | string[] parts = last_mod_meta.split (" ", 2); |
1370 | 66 | string[] date_parts; | 78 | string[] date_parts; |
1371 | 67 | string split_char = " "; | 79 | string split_char = " "; |
1372 | 68 | 80 | ||
1373 | @@ -89,7 +101,7 @@ | |||
1374 | 89 | d = int.parse(date_parts[2]); | 101 | d = int.parse(date_parts[2]); |
1375 | 90 | } | 102 | } |
1376 | 91 | } else { /* Date in a form of: 20 Mar 2012 12:34 */ | 103 | } else { /* Date in a form of: 20 Mar 2012 12:34 */ |
1378 | 92 | string[] parts = last_mod.split (" ", 4); | 104 | string[] parts = last_mod_meta.split (" ", 4); |
1379 | 93 | /* contains time part ? */ | 105 | /* contains time part ? */ |
1380 | 94 | if (parts[3] != null && parts[3].contains (":")) { | 106 | if (parts[3] != null && parts[3].contains (":")) { |
1381 | 95 | string[] time_parts = parts[3].split (":", 2); | 107 | string[] time_parts = parts[3].split (":", 2); |
1382 | @@ -107,33 +119,37 @@ | |||
1383 | 107 | } | 119 | } |
1384 | 108 | } | 120 | } |
1385 | 109 | 121 | ||
1387 | 110 | last_mod_date = new DateTime.local (y, m, d, h, min, 0.0); | 122 | last_updated = new DateTime.local (y, m, d, h, min, 0.0); |
1388 | 123 | } else { | ||
1389 | 124 | /* FIXME: use file modification date if there's no update header | ||
1390 | 125 | try { | ||
1391 | 126 | string modified = FileAttribute.TIME_MODIFIED; | ||
1392 | 127 | var info = file.query_filesystem_info (modified); | ||
1393 | 128 | last_updated = new DateTime.from_timeval_local (info.get_modification_time ()); | ||
1394 | 129 | } catch (Error error) { | ||
1395 | 130 | last_updated = now; | ||
1396 | 131 | } | ||
1397 | 132 | */ | ||
1398 | 133 | last_updated = now; | ||
1399 | 111 | } | 134 | } |
1400 | 112 | 135 | ||
1401 | 113 | if (last_mod_date == null) | ||
1402 | 114 | last_mod_date = now; | ||
1403 | 115 | |||
1404 | 116 | /* We have "expires" metadata */ | 136 | /* We have "expires" metadata */ |
1412 | 117 | if (expires != null) { | 137 | if (expires_meta != null) { |
1413 | 118 | if (expires.contains ("days")) { | 138 | if (expires_meta.contains ("days")) { |
1414 | 119 | string[] parts = expires.split (" "); | 139 | string[] parts = expires_meta.split (" "); |
1415 | 120 | expire_date = last_mod_date.add_days (int.parse (parts[0])); | 140 | expires = last_updated.add_days (int.parse (parts[0])); |
1416 | 121 | } else if (expires.contains ("hours")) { | 141 | } else if (expires_meta.contains ("hours")) { |
1417 | 122 | string[] parts = expires.split (" "); | 142 | string[] parts = expires_meta.split (" "); |
1418 | 123 | expire_date = last_mod_date.add_hours (int.parse (parts[0])); | 143 | expires = last_updated.add_hours (int.parse (parts[0])); |
1419 | 124 | } | 144 | } |
1420 | 125 | } else { | 145 | } else { |
1421 | 126 | /* No expire metadata found, assume x days */ | 146 | /* No expire metadata found, assume x days */ |
1422 | 127 | int days_to_expire = 7; | 147 | int days_to_expire = 7; |
1424 | 128 | expire_date = last_mod_date.add_days (days_to_expire); | 148 | expires = last_updated.add_days (days_to_expire); |
1425 | 129 | } | 149 | } |
1426 | 130 | 150 | ||
1427 | 131 | last_mod_tstamp = last_mod_date.to_unix (); | ||
1428 | 132 | last_check_tstamp = now.to_unix (); | ||
1429 | 133 | update_tstamp = expire_date.to_unix (); | ||
1430 | 134 | |||
1431 | 135 | /* Check if we are past expire date */ | 151 | /* Check if we are past expire date */ |
1433 | 136 | return now.compare (expire_date) == 1; | 152 | needs_update = now.compare (expires) == 1; |
1434 | 137 | } | 153 | } |
1435 | 138 | } | 154 | } |
1436 | 139 | } | 155 | } |
1437 | 140 | 156 | ||
1438 | === added file 'extensions/adblock/widgets.vala' | |||
1439 | --- extensions/adblock/widgets.vala 1970-01-01 00:00:00 +0000 | |||
1440 | +++ extensions/adblock/widgets.vala 2014-03-10 10:27:25 +0000 | |||
1441 | @@ -0,0 +1,310 @@ | |||
1442 | 1 | /* | ||
1443 | 2 | Copyright (C) 2009-2014 Christian Dywan <christian@twotoasts.de> | ||
1444 | 3 | Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com> | ||
1445 | 4 | |||
1446 | 5 | This library is free software; you can redistribute it and/or | ||
1447 | 6 | modify it under the terms of the GNU Lesser General Public | ||
1448 | 7 | License as published by the Free Software Foundation; either | ||
1449 | 8 | version 2.1 of the License, or (at your option) any later version. | ||
1450 | 9 | |||
1451 | 10 | See the file COPYING for the full license text. | ||
1452 | 11 | */ | ||
1453 | 12 | |||
1454 | 13 | namespace Adblock { | ||
1455 | 14 | |||
1456 | 15 | |||
1457 | 16 | public class StatusIcon { | ||
1458 | 17 | Config config; | ||
1459 | 18 | State state; | ||
1460 | 19 | public bool debug_element_toggled; | ||
1461 | 20 | public List<IconButton> toggle_buttons; | ||
1462 | 21 | |||
1463 | 22 | public StatusIcon (Adblock.Config config) { | ||
1464 | 23 | this.config = config; | ||
1465 | 24 | this.debug_element_toggled = false; | ||
1466 | 25 | } | ||
1467 | 26 | |||
1468 | 27 | public void set_state (Adblock.State state) { | ||
1469 | 28 | this.state = state; | ||
1470 | 29 | update_buttons (); | ||
1471 | 30 | } | ||
1472 | 31 | |||
1473 | 32 | public class IconButton : Gtk.Button { | ||
1474 | 33 | Gtk.Image icon; | ||
1475 | 34 | |||
1476 | 35 | public IconButton () { | ||
1477 | 36 | icon = new Gtk.Image (); | ||
1478 | 37 | add (icon); | ||
1479 | 38 | icon.show (); | ||
1480 | 39 | } | ||
1481 | 40 | |||
1482 | 41 | public void set_status (string status) { | ||
1483 | 42 | string filename = Midori.Paths.get_res_filename ("adblock/%s.svg".printf (status)); | ||
1484 | 43 | icon.set_from_file (filename); | ||
1485 | 44 | } | ||
1486 | 45 | } | ||
1487 | 46 | |||
1488 | 47 | public void update_buttons () { | ||
1489 | 48 | string state = ""; | ||
1490 | 49 | foreach (var toggle_button in toggle_buttons) { | ||
1491 | 50 | if (this.state == State.BLOCKED) { | ||
1492 | 51 | toggle_button.set_status ("blocked"); | ||
1493 | 52 | state = _("Blocking"); | ||
1494 | 53 | } | ||
1495 | 54 | if (this.state == State.ENABLED) { | ||
1496 | 55 | toggle_button.set_status ("enabled"); | ||
1497 | 56 | state = _("Enabled"); | ||
1498 | 57 | } | ||
1499 | 58 | if (this.state == State.DISABLED) { | ||
1500 | 59 | toggle_button.set_status ("disabled"); | ||
1501 | 60 | state = _("Disabled"); | ||
1502 | 61 | } | ||
1503 | 62 | toggle_button.set_tooltip_text (_("Adblock state: %s").printf (state)); | ||
1504 | 63 | } | ||
1505 | 64 | } | ||
1506 | 65 | |||
1507 | 66 | public void icon_clicked (Gtk.Button toggle_button) { | ||
1508 | 67 | var menu = new Gtk.Menu (); | ||
1509 | 68 | var checkitem = new Gtk.CheckMenuItem.with_label (_("Disabled")); | ||
1510 | 69 | checkitem.set_active (!config.enabled); | ||
1511 | 70 | checkitem.toggled.connect (() => { | ||
1512 | 71 | config.enabled = !checkitem.active; | ||
1513 | 72 | set_state (config.enabled ? Adblock.State.ENABLED : Adblock.State.DISABLED); | ||
1514 | 73 | }); | ||
1515 | 74 | menu.append (checkitem); | ||
1516 | 75 | |||
1517 | 76 | var hideritem = new Gtk.CheckMenuItem.with_label (_("Display hidden elements")); | ||
1518 | 77 | hideritem.set_active (debug_element_toggled); | ||
1519 | 78 | hideritem.toggled.connect (() => { | ||
1520 | 79 | this.debug_element_toggled = hideritem.active; | ||
1521 | 80 | }); | ||
1522 | 81 | menu.append (hideritem); | ||
1523 | 82 | |||
1524 | 83 | var menuitem = new Gtk.ImageMenuItem.with_label (_("Preferences")); | ||
1525 | 84 | var image = new Gtk.Image.from_stock (Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU); | ||
1526 | 85 | menuitem.always_show_image = true; | ||
1527 | 86 | menuitem.set_image (image); | ||
1528 | 87 | menuitem.activate.connect (() => { | ||
1529 | 88 | SubscriptionManager manager = new SubscriptionManager (config); | ||
1530 | 89 | manager.add_subscription (null); | ||
1531 | 90 | }); | ||
1532 | 91 | menu.append (menuitem); | ||
1533 | 92 | |||
1534 | 93 | menu.show_all (); | ||
1535 | 94 | Katze.widget_popup (toggle_button, menu, null, Katze.MenuPos.CURSOR); | ||
1536 | 95 | } | ||
1537 | 96 | } | ||
1538 | 97 | |||
1539 | 98 | public class SubscriptionManager { | ||
1540 | 99 | Gtk.TreeView treeview; | ||
1541 | 100 | Gtk.ListStore liststore; | ||
1542 | 101 | Adblock.Config config; | ||
1543 | 102 | public Gtk.Label description_label; | ||
1544 | 103 | string description; | ||
1545 | 104 | |||
1546 | 105 | public SubscriptionManager (Config config) { | ||
1547 | 106 | this.config = config; | ||
1548 | 107 | this.liststore = new Gtk.ListStore (1, typeof (Subscription)); | ||
1549 | 108 | this.description_label = new Gtk.Label (null); | ||
1550 | 109 | this.description = _("Type the address of a preconfigured filter list in the text entry and hit Enter.\n"); | ||
1551 | 110 | this.description += _("You can find more lists by visiting following sites:\n %s, %s\n".printf ( | ||
1552 | 111 | "<a href=\"http://adblockplus.org/en/subscriptions\">adblockplus.org/en/subscriptions</a>", | ||
1553 | 112 | "<a href=\"http://easylist.adblockplus.org/\">easylist.adblockplus.org</a>" | ||
1554 | 113 | )); | ||
1555 | 114 | } | ||
1556 | 115 | |||
1557 | 116 | public void add_subscription (string? uri) { | ||
1558 | 117 | var dialog = new Gtk.Dialog.with_buttons (_("Configure Advertisement filters"), | ||
1559 | 118 | null, | ||
1560 | 119 | #if !HAVE_GTK3 | ||
1561 | 120 | Gtk.DialogFlags.NO_SEPARATOR | | ||
1562 | 121 | #endif | ||
1563 | 122 | Gtk.DialogFlags.DESTROY_WITH_PARENT, | ||
1564 | 123 | Gtk.STOCK_HELP, Gtk.ResponseType.HELP, | ||
1565 | 124 | Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE); | ||
1566 | 125 | #if HAVE_GTK3 | ||
1567 | 126 | dialog.get_widget_for_response (Gtk.ResponseType.HELP).get_style_context ().add_class ("help_button"); | ||
1568 | 127 | #endif | ||
1569 | 128 | dialog.set_icon_name (Gtk.STOCK_PROPERTIES); | ||
1570 | 129 | dialog.set_response_sensitive (Gtk.ResponseType.HELP, false); | ||
1571 | 130 | |||
1572 | 131 | var hbox = new Gtk.HBox (false, 0); | ||
1573 | 132 | (dialog.get_content_area () as Gtk.Box).pack_start (hbox, true, true, 12); | ||
1574 | 133 | var vbox = new Gtk.VBox (false, 0); | ||
1575 | 134 | hbox.pack_start (vbox, true, true, 4); | ||
1576 | 135 | this.description_label.set_markup (this.description); | ||
1577 | 136 | this.description_label.set_line_wrap (true); | ||
1578 | 137 | vbox.pack_start (this.description_label, false, false, 4); | ||
1579 | 138 | |||
1580 | 139 | var entry = new Gtk.Entry (); | ||
1581 | 140 | if (uri != null) | ||
1582 | 141 | entry.set_text (uri); | ||
1583 | 142 | vbox.pack_start (entry, false, false, 4); | ||
1584 | 143 | |||
1585 | 144 | liststore = new Gtk.ListStore (1, typeof (Subscription)); | ||
1586 | 145 | treeview = new Gtk.TreeView.with_model (liststore); | ||
1587 | 146 | treeview.set_headers_visible (false); | ||
1588 | 147 | var column = new Gtk.TreeViewColumn (); | ||
1589 | 148 | var renderer_toggle = new Gtk.CellRendererToggle (); | ||
1590 | 149 | column.pack_start (renderer_toggle, false); | ||
1591 | 150 | column.set_cell_data_func (renderer_toggle, (column, renderer, model, iter) => { | ||
1592 | 151 | Subscription sub; | ||
1593 | 152 | liststore.get (iter, 0, out sub); | ||
1594 | 153 | renderer.set ("active", sub.active, | ||
1595 | 154 | "sensitive", sub.mutable); | ||
1596 | 155 | }); | ||
1597 | 156 | renderer_toggle.toggled.connect ((path) => { | ||
1598 | 157 | Gtk.TreeIter iter; | ||
1599 | 158 | if (liststore.get_iter_from_string (out iter, path)) { | ||
1600 | 159 | Subscription sub; | ||
1601 | 160 | liststore.get (iter, 0, out sub); | ||
1602 | 161 | sub.active = !sub.active; | ||
1603 | 162 | } | ||
1604 | 163 | }); | ||
1605 | 164 | treeview.append_column (column); | ||
1606 | 165 | |||
1607 | 166 | column = new Gtk.TreeViewColumn (); | ||
1608 | 167 | var renderer_text = new Gtk.CellRendererText (); | ||
1609 | 168 | column.pack_start (renderer_text, false); | ||
1610 | 169 | renderer_text.set ("editable", true); | ||
1611 | 170 | // TODO: renderer_text.edited.connect | ||
1612 | 171 | column.set_cell_data_func (renderer_text, (column, renderer, model, iter) => { | ||
1613 | 172 | Subscription sub; | ||
1614 | 173 | liststore.get (iter, 0, out sub); | ||
1615 | 174 | string status = ""; | ||
1616 | 175 | foreach (var feature in sub) { | ||
1617 | 176 | if (feature is Adblock.Updater) { | ||
1618 | 177 | var updater = feature as Adblock.Updater; | ||
1619 | 178 | if (updater.last_updated != null) | ||
1620 | 179 | status = updater.last_updated.format (_("Last update: %x %X")); | ||
1621 | 180 | } | ||
1622 | 181 | } | ||
1623 | 182 | if (!sub.valid) | ||
1624 | 183 | status = _("File incomplete - broken download?"); | ||
1625 | 184 | renderer.set ("markup", (Markup.printf_escaped ("<b>%s</b>\n%s", | ||
1626 | 185 | sub.title ?? sub.uri, status))); | ||
1627 | 186 | }); | ||
1628 | 187 | treeview.append_column (column); | ||
1629 | 188 | |||
1630 | 189 | column = new Gtk.TreeViewColumn (); | ||
1631 | 190 | Gtk.CellRendererPixbuf renderer_button = new Gtk.CellRendererPixbuf (); | ||
1632 | 191 | column.pack_start (renderer_button, false); | ||
1633 | 192 | column.set_cell_data_func (renderer_button, on_render_button); | ||
1634 | 193 | treeview.append_column (column); | ||
1635 | 194 | |||
1636 | 195 | var scrolled = new Gtk.ScrolledWindow (null, null); | ||
1637 | 196 | scrolled.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); | ||
1638 | 197 | scrolled.add (treeview); | ||
1639 | 198 | vbox.pack_start (scrolled); | ||
1640 | 199 | |||
1641 | 200 | foreach (Subscription sub in config) | ||
1642 | 201 | liststore.insert_with_values (null, 0, 0, sub); | ||
1643 | 202 | treeview.button_release_event.connect (button_released); | ||
1644 | 203 | |||
1645 | 204 | entry.activate.connect (() => { | ||
1646 | 205 | string? parsed_uri = Adblock.parse_subscription_uri (entry.text); | ||
1647 | 206 | if (parsed_uri != null) { | ||
1648 | 207 | var sub = new Subscription (parsed_uri); | ||
1649 | 208 | if (config.add (sub)) { | ||
1650 | 209 | liststore.insert_with_values (null, 0, 0, sub); | ||
1651 | 210 | try { | ||
1652 | 211 | sub.parse (); | ||
1653 | 212 | } catch (GLib.Error error) { | ||
1654 | 213 | warning ("Error parsing %s: %s", sub.uri, error.message); | ||
1655 | 214 | } | ||
1656 | 215 | } | ||
1657 | 216 | } | ||
1658 | 217 | entry.text = ""; | ||
1659 | 218 | }); | ||
1660 | 219 | |||
1661 | 220 | dialog.get_content_area ().show_all (); | ||
1662 | 221 | |||
1663 | 222 | dialog.response.connect ((response)=>{ dialog.destroy (); }); | ||
1664 | 223 | dialog.show (); | ||
1665 | 224 | } | ||
1666 | 225 | |||
1667 | 226 | void on_render_button (Gtk.CellLayout column, Gtk.CellRenderer renderer, | ||
1668 | 227 | Gtk.TreeModel model, Gtk.TreeIter iter) { | ||
1669 | 228 | |||
1670 | 229 | Subscription sub; | ||
1671 | 230 | liststore.get (iter, 0, out sub); | ||
1672 | 231 | |||
1673 | 232 | renderer.set ("stock-id", sub.mutable ? Gtk.STOCK_DELETE : null, | ||
1674 | 233 | "stock-size", Gtk.IconSize.MENU); | ||
1675 | 234 | } | ||
1676 | 235 | |||
1677 | 236 | public bool button_released (Gdk.EventButton event) { | ||
1678 | 237 | Gtk.TreePath? path; | ||
1679 | 238 | Gtk.TreeViewColumn column; | ||
1680 | 239 | if (treeview.get_path_at_pos ((int)event.x, (int)event.y, out path, out column, null, null)) { | ||
1681 | 240 | if (path != null) { | ||
1682 | 241 | if (column == treeview.get_column (2)) { | ||
1683 | 242 | Gtk.TreeIter iter; | ||
1684 | 243 | if (liststore.get_iter (out iter, path)) { | ||
1685 | 244 | Subscription sub; | ||
1686 | 245 | liststore.get (iter, 0, out sub); | ||
1687 | 246 | if (sub.mutable) { | ||
1688 | 247 | config.remove (sub); | ||
1689 | 248 | liststore.remove (iter); | ||
1690 | 249 | return true; | ||
1691 | 250 | } | ||
1692 | 251 | } | ||
1693 | 252 | } | ||
1694 | 253 | } | ||
1695 | 254 | } | ||
1696 | 255 | return false; | ||
1697 | 256 | } | ||
1698 | 257 | } | ||
1699 | 258 | |||
1700 | 259 | class CustomRulesEditor { | ||
1701 | 260 | Gtk.Dialog dialog; | ||
1702 | 261 | Subscription custom; | ||
1703 | 262 | public string? rule { get; set; } | ||
1704 | 263 | |||
1705 | 264 | public CustomRulesEditor (Subscription custom) { | ||
1706 | 265 | this.custom = custom; | ||
1707 | 266 | } | ||
1708 | 267 | |||
1709 | 268 | public void set_uri (string uri) { | ||
1710 | 269 | this.rule = uri; | ||
1711 | 270 | } | ||
1712 | 271 | |||
1713 | 272 | public void show () { | ||
1714 | 273 | this.dialog = new Gtk.Dialog.with_buttons (_("Edit rule"), | ||
1715 | 274 | null, | ||
1716 | 275 | #if !HAVE_GTK3 | ||
1717 | 276 | Gtk.DialogFlags.NO_SEPARATOR | | ||
1718 | 277 | #endif | ||
1719 | 278 | Gtk.DialogFlags.DESTROY_WITH_PARENT, | ||
1720 | 279 | Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, | ||
1721 | 280 | Gtk.STOCK_ADD, Gtk.ResponseType.ACCEPT); | ||
1722 | 281 | dialog.set_icon_name (Gtk.STOCK_ADD); | ||
1723 | 282 | dialog.resizable = false; | ||
1724 | 283 | |||
1725 | 284 | var hbox = new Gtk.HBox (false, 8); | ||
1726 | 285 | var sizegroup = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); | ||
1727 | 286 | hbox.border_width = 5; | ||
1728 | 287 | var label = new Gtk.Label.with_mnemonic (_("_Rule:")); | ||
1729 | 288 | sizegroup.add_widget (label); | ||
1730 | 289 | hbox.pack_start (label, false, false, 0); | ||
1731 | 290 | (dialog.get_content_area () as Gtk.Box).pack_start (hbox, false, true, 0); | ||
1732 | 291 | |||
1733 | 292 | var entry = new Gtk.Entry (); | ||
1734 | 293 | sizegroup.add_widget (entry); | ||
1735 | 294 | entry.activates_default = true; | ||
1736 | 295 | entry.set_text (this.rule); | ||
1737 | 296 | hbox.pack_start (entry, true, true, 0); | ||
1738 | 297 | |||
1739 | 298 | dialog.get_content_area ().show_all (); | ||
1740 | 299 | |||
1741 | 300 | dialog.set_default_response (Gtk.ResponseType.ACCEPT); | ||
1742 | 301 | if (dialog.run () != Gtk.ResponseType.ACCEPT) | ||
1743 | 302 | return; | ||
1744 | 303 | |||
1745 | 304 | this.rule = entry.get_text (); | ||
1746 | 305 | this.dialog.destroy (); | ||
1747 | 306 | custom.add_rule (this.rule); | ||
1748 | 307 | } | ||
1749 | 308 | } | ||
1750 | 309 | |||
1751 | 310 | } | ||
1752 | 0 | 311 | ||
1753 | === modified file 'katze/midori-paths.vala' | |||
1754 | --- katze/midori-paths.vala 2014-02-20 18:27:01 +0000 | |||
1755 | +++ katze/midori-paths.vala 2014-03-10 10:27:25 +0000 | |||
1756 | @@ -366,17 +366,24 @@ | |||
1757 | 366 | if (Posix.access (path, Posix.F_OK) == 0) | 366 | if (Posix.access (path, Posix.F_OK) == 0) |
1758 | 367 | return path; | 367 | return path; |
1759 | 368 | 368 | ||
1760 | 369 | return build_folder ("data", null, filename) ?? | ||
1761 | 370 | Path.build_filename (MDATADIR, PACKAGE_NAME, "res", filename); | ||
1762 | 371 | #endif | ||
1763 | 372 | } | ||
1764 | 373 | |||
1765 | 374 | string? build_folder (string folder, string? middle, string filename) { | ||
1766 | 369 | /* Fallback to build folder */ | 375 | /* Fallback to build folder */ |
1767 | 370 | File? parent = File.new_for_path (exec_path); | 376 | File? parent = File.new_for_path (exec_path); |
1768 | 371 | while (parent != null) { | 377 | while (parent != null) { |
1770 | 372 | var data = parent.get_child ("data"); | 378 | var data = parent.get_child (folder); |
1771 | 379 | if (middle != null) | ||
1772 | 380 | data = data.get_child (middle); | ||
1773 | 373 | var child = data.get_child (filename); | 381 | var child = data.get_child (filename); |
1774 | 374 | if (child.query_exists ()) | 382 | if (child.query_exists ()) |
1775 | 375 | return child.get_path (); | 383 | return child.get_path (); |
1776 | 376 | parent = parent.get_parent (); | 384 | parent = parent.get_parent (); |
1777 | 377 | } | 385 | } |
1780 | 378 | return Path.build_filename (MDATADIR, PACKAGE_NAME, "res", filename); | 386 | return null; |
1779 | 379 | #endif | ||
1781 | 380 | } | 387 | } |
1782 | 381 | 388 | ||
1783 | 382 | /* returns the path to a file containing read-only data installed with the application | 389 | /* returns the path to a file containing read-only data installed with the application |
1784 | @@ -416,7 +423,8 @@ | |||
1785 | 416 | return path; | 423 | return path; |
1786 | 417 | } | 424 | } |
1787 | 418 | 425 | ||
1789 | 419 | return Path.build_filename (SYSCONFDIR, "xdg", PACKAGE_NAME, folder ?? "", filename); | 426 | return build_folder ("config", folder, filename) ?? |
1790 | 427 | Path.build_filename (SYSCONFDIR, "xdg", PACKAGE_NAME, folder ?? "", filename); | ||
1791 | 420 | #endif | 428 | #endif |
1792 | 421 | } | 429 | } |
1793 | 422 | 430 | ||
1794 | 423 | 431 | ||
1795 | === modified file 'midori/midori-app.c' | |||
1796 | --- midori/midori-app.c 2014-02-24 22:16:00 +0000 | |||
1797 | +++ midori/midori-app.c 2014-03-10 10:27:25 +0000 | |||
1798 | @@ -1257,7 +1257,7 @@ | |||
1799 | 1257 | midori_debug (const gchar* token) | 1257 | midori_debug (const gchar* token) |
1800 | 1258 | { | 1258 | { |
1801 | 1259 | static const gchar* debug_token = NULL; | 1259 | static const gchar* debug_token = NULL; |
1803 | 1260 | const gchar* debug_tokens = "adblock:match adblock:time adblock:element startup headers body referer cookies paths hsts unarmed bookmarks mouse app "; | 1260 | const gchar* debug_tokens = "adblock:match adblock:parse adblock:time adblock:element startup headers body referer cookies paths hsts unarmed bookmarks mouse app "; |
1804 | 1261 | if (debug_token == NULL) | 1261 | if (debug_token == NULL) |
1805 | 1262 | { | 1262 | { |
1806 | 1263 | gchar* found_token; | 1263 | gchar* found_token; |
1807 | 1264 | 1264 | ||
1808 | === modified file 'midori/midori-browser.c' | |||
1809 | --- midori/midori-browser.c 2014-03-03 21:28:53 +0000 | |||
1810 | +++ midori/midori-browser.c 2014-03-10 10:27:25 +0000 | |||
1811 | @@ -1237,7 +1237,7 @@ | |||
1812 | 1237 | 1237 | ||
1813 | 1238 | { | 1238 | { |
1814 | 1239 | #ifndef HAVE_WEBKIT2 | 1239 | #ifndef HAVE_WEBKIT2 |
1816 | 1240 | if (!midori_download_has_enough_space (download, uri)) | 1240 | if (!midori_download_has_enough_space (download, uri, FALSE)) |
1817 | 1241 | return FALSE; | 1241 | return FALSE; |
1818 | 1242 | webkit_download_set_destination_uri (download, uri); | 1242 | webkit_download_set_destination_uri (download, uri); |
1819 | 1243 | g_signal_emit (browser, signals[ADD_DOWNLOAD], 0, download); | 1243 | g_signal_emit (browser, signals[ADD_DOWNLOAD], 0, download); |
1820 | 1244 | 1244 | ||
1821 | === modified file 'midori/midori-download.vala' | |||
1822 | --- midori/midori-download.vala 2014-03-05 07:17:45 +0000 | |||
1823 | +++ midori/midori-download.vala 2014-03-10 10:27:25 +0000 | |||
1824 | @@ -348,7 +348,7 @@ | |||
1825 | 348 | * Returns whether it seems possible to save @download to the path specified by | 348 | * Returns whether it seems possible to save @download to the path specified by |
1826 | 349 | * @destination_uri, considering space on disk and permissions | 349 | * @destination_uri, considering space on disk and permissions |
1827 | 350 | */ | 350 | */ |
1829 | 351 | public static bool has_enough_space (WebKit.Download download, string destination_uri) { | 351 | public static bool has_enough_space (WebKit.Download download, string destination_uri, bool quiet=false) { |
1830 | 352 | #if !HAVE_WEBKIT2 | 352 | #if !HAVE_WEBKIT2 |
1831 | 353 | var folder = File.new_for_uri (destination_uri).get_parent (); | 353 | var folder = File.new_for_uri (destination_uri).get_parent (); |
1832 | 354 | bool can_write; | 354 | bool can_write; |
1833 | @@ -380,7 +380,8 @@ | |||
1834 | 380 | } | 380 | } |
1835 | 381 | else | 381 | else |
1836 | 382 | assert_not_reached (); | 382 | assert_not_reached (); |
1838 | 383 | Sokoke.message_dialog (Gtk.MessageType.ERROR, message, detailed_message, false); | 383 | if (!quiet) |
1839 | 384 | Sokoke.message_dialog (Gtk.MessageType.ERROR, message, detailed_message, false); | ||
1840 | 384 | return false; | 385 | return false; |
1841 | 385 | } | 386 | } |
1842 | 386 | #endif | 387 | #endif |
1843 | 387 | 388 | ||
1844 | === modified file 'po/POTFILES.in' | |||
1845 | --- po/POTFILES.in 2014-03-02 23:15:34 +0000 | |||
1846 | +++ po/POTFILES.in 2014-03-10 10:27:25 +0000 | |||
1847 | @@ -102,4 +102,5 @@ | |||
1848 | 102 | extensions/adblock/config.vala | 102 | extensions/adblock/config.vala |
1849 | 103 | extensions/adblock/updater.vala | 103 | extensions/adblock/updater.vala |
1850 | 104 | extensions/adblock/element.vala | 104 | extensions/adblock/element.vala |
1851 | 105 | extensions/adblock/widgets.vala | ||
1852 | 105 | extensions/domain-keys.vala | 106 | extensions/domain-keys.vala |