Merge lp:~jderose/userwebkit/links into lp:userwebkit

Proposed by Jason Gerard DeRose
Status: Merged
Merged at revision: 22
Proposed branch: lp:~jderose/userwebkit/links
Merge into: lp:userwebkit
Diff against target: 223 lines (+139/-5)
4 files modified
debian/control (+3/-3)
test_userwebkit.py (+91/-0)
ui/index.html (+3/-0)
userwebkit.py (+42/-2)
To merge this branch: bzr merge lp:~jderose/userwebkit/links
Reviewer Review Type Date Requested Status
Novacut Dev Pending
Review via email: mp+86652@code.launchpad.net

Description of the change

Adds CouchView._on_nav_policy_decision() and its test.

Also adds new CouchView 'open' signal, used to open external links in the user's default browser.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2011-10-01 01:05:20 +0000
3+++ debian/control 2011-12-22 05:11:23 +0000
4@@ -3,7 +3,7 @@
5 Priority: optional
6 Maintainer: Jason Gerard DeRose <jderose@novacut.com>
7 Build-Depends: debhelper (>= 8.9), python3 (>= 3.2),
8- python3-microfiber (>= 11.10),
9+ python3-microfiber (>= 11.12),
10 python3-gobject,
11 gir1.2-gtk-3.0,
12 gir1.2-webkit-3.0,
13@@ -15,8 +15,8 @@
14 Package: python3-userwebkit
15 Architecture: all
16 Depends: ${misc:Depends}, python3 (>= 3.2),
17- python3-microfiber (>= 11.10),
18- dc3 (>= 11.10),
19+ python3-microfiber (>= 11.12),
20+ dc3 (>= 11.12),
21 python3-gobject,
22 gir1.2-gtk-3.0,
23 gir1.2-webkit-3.0,
24
25=== modified file 'test_userwebkit.py'
26--- test_userwebkit.py 2011-09-26 10:25:21 +0000
27+++ test_userwebkit.py 2011-12-22 05:11:23 +0000
28@@ -63,6 +63,31 @@
29 }
30
31
32+class DummyCallback:
33+ def __init__(self):
34+ self._calls = []
35+
36+ def __call__(self, *args):
37+ self._calls.append(args)
38+
39+
40+class DummyRequest:
41+ def __init__(self, uri):
42+ self.__uri = uri
43+
44+ def get_uri(self):
45+ return self.__uri
46+
47+
48+class DummyPolicy:
49+ def __init__(self):
50+ self._called = False
51+
52+ def ignore(self):
53+ assert self._called is False
54+ self._called = True
55+
56+
57 class TestCouchView(TestCase):
58 def test_init(self):
59 view = userwebkit.CouchView()
60@@ -115,3 +140,69 @@
61 self.assertIsNone(view._env)
62 self.assertIsNone(view._on_request(None, None, None, None, None))
63
64+ def test_on_nav_policy_decision(self):
65+ callback = DummyCallback()
66+ view = userwebkit.CouchView()
67+ view.connect('open', callback)
68+
69+ # Make sure on_request() immediately returns when env is None:
70+ self.assertIsNone(
71+ view._on_nav_policy_decision(None, None, None, None, None)
72+ )
73+ self.assertEqual(callback._calls, [])
74+
75+ # When URI netloc and scheme matches env, should return False
76+ env = random_env()
77+ view.set_env(env)
78+ request = DummyRequest(env['url'] + 'foo')
79+ self.assertIs(
80+ view._on_nav_policy_decision(None, None, request, None, None),
81+ False
82+ )
83+ self.assertEqual(callback._calls, [])
84+
85+ # For external http, https URI, should fire 'open' signal, call
86+ # policy.ignore(), and return True
87+ request = DummyRequest('http://www.ubuntu.com/')
88+ policy = DummyPolicy()
89+ self.assertIs(
90+ view._on_nav_policy_decision(None, None, request, None, policy),
91+ True
92+ )
93+ self.assertIs(policy._called, True)
94+ self.assertEqual(callback._calls,
95+ [
96+ (view, 'http://www.ubuntu.com/'),
97+ ]
98+ )
99+
100+ request = DummyRequest('https://launchpad.net/novacut')
101+ policy = DummyPolicy()
102+ self.assertIs(
103+ view._on_nav_policy_decision(None, None, request, None, policy),
104+ True
105+ )
106+ self.assertIs(policy._called, True)
107+ self.assertEqual(callback._calls,
108+ [
109+ (view, 'http://www.ubuntu.com/'),
110+ (view, 'https://launchpad.net/novacut'),
111+ ]
112+ )
113+
114+ # For other non-internal URI, should just call policy.ignore() and
115+ # return True... should not fire 'open'
116+ request = DummyRequest('ftp://example.com/')
117+ policy = DummyPolicy()
118+ self.assertIs(
119+ view._on_nav_policy_decision(None, None, request, None, policy),
120+ True
121+ )
122+ self.assertIs(policy._called, True)
123+ self.assertEqual(callback._calls,
124+ [
125+ (view, 'http://www.ubuntu.com/'),
126+ (view, 'https://launchpad.net/novacut'),
127+ ]
128+ )
129+
130
131=== modified file 'ui/index.html'
132--- ui/index.html 2011-11-24 20:42:28 +0000
133+++ ui/index.html 2011-12-22 05:11:23 +0000
134@@ -54,5 +54,8 @@
135 <p id="hello"></p>
136 <p>Right click and <strong>Inspect Element</strong></p>
137 <button id="button">Start</button>
138+<p>
139+<a href="http://novacut.com/">A test link</a>
140+</p>
141 </body>
142 </html>
143
144=== modified file 'userwebkit.py'
145--- userwebkit.py 2011-12-18 14:41:37 +0000
146+++ userwebkit.py 2011-12-22 05:11:23 +0000
147@@ -74,12 +74,18 @@
148 'title_data': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
149 [TYPE_PYOBJECT]
150 ),
151+ 'open': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
152+ [TYPE_PYOBJECT]
153+ ),
154 }
155
156 def __init__(self, env=None):
157 super().__init__()
158 self.connect('resource-request-starting', self._on_request)
159 self.connect('notify::title', self._on_notify_title)
160+ self.connect('navigation-policy-decision-requested',
161+ self._on_nav_policy_decision
162+ )
163 self.set_env(env)
164
165 def set_env(self, env):
166@@ -116,6 +122,35 @@
167 for (key, value) in h.items():
168 request.props.message.props.request_headers.append(key, value)
169
170+ def _on_nav_policy_decision(self, view, frame, request, nav, policy):
171+ """
172+ Handle user trying to Navigate away from current page.
173+
174+ Note that this will be called before `CouchView._on_resource_request()`.
175+
176+ The *policy* arg is a ``WebPolicyDecision`` instance. To handle the
177+ decision, call one of:
178+
179+ * ``WebPolicyDecision.ignore()``
180+ * ``WebPolicyDecision.use()``
181+ * ``WebPolicyDecision.download()``
182+
183+ And then return ``True``.
184+
185+ Otherwise, return ``False`` or ``None`` to have the WebKit default
186+ behavior apply.
187+ """
188+ if self._env is None:
189+ return
190+ uri = request.get_uri()
191+ u = urlparse(uri)
192+ if u.netloc == self._u.netloc and u.scheme in ('http', 'https'):
193+ return False
194+ if u.scheme in ('http', 'https'):
195+ self.emit('open', uri)
196+ policy.ignore()
197+ return True
198+
199 def _on_notify_title(self, view, notify):
200 title = view.get_property('title')
201 if title is None:
202@@ -233,6 +268,7 @@
203 Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC
204 )
205 self.view = CouchView()
206+ self.view.connect('open', self.on_open)
207 self.scroll.add(self.view)
208 self.view.get_settings().set_property('enable-developer-extras', True)
209 inspector = self.view.get_inspector()
210@@ -293,8 +329,12 @@
211
212 def on_reload(self, button):
213 self.view.reload_bypass_cache()
214-
215+
216 def on_futon(self, button):
217 self.view.load_uri(self.server._full_url('/_utils/'))
218-
219+
220+ def on_open(self, view, uri):
221+ import subprocess
222+ subprocess.check_call(['/usr/bin/xdg-open', uri])
223+
224

Subscribers

People subscribed via source and target branches