Merge lp:~osomon/webbrowser-app/ua-override into lp:webbrowser-app

Proposed by Olivier Tilloy
Status: Merged
Approved by: Olivier Tilloy
Approved revision: 293
Merged at revision: 283
Proposed branch: lp:~osomon/webbrowser-app/ua-override
Merge into: lp:webbrowser-app
Diff against target: 347 lines (+263/-27)
5 files modified
src/Ubuntu/Components/Extras/Browser/UbuntuWebView.qml (+7/-26)
src/Ubuntu/Components/Extras/Browser/UserAgent.qml (+80/-0)
src/Ubuntu/Components/Extras/Browser/ua-overrides.js (+96/-0)
tests/unittests/qml/CMakeLists.txt (+9/-1)
tests/unittests/qml/tst_UserAgent.qml (+71/-0)
To merge this branch: bzr merge lp:~osomon/webbrowser-app/ua-override
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Günter Schwann (community) Approve
Review via email: mp+180592@code.launchpad.net

Commit message

Initial implementation of a user-agent string override mechanism,
largely inspired by B2G’s implementation.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Günter Schwann (schwann) wrote :

83 +import Ubuntu.Components 0.1
Seem not to be used

Just because I like small functions, I'd move the functionality of getting the domain from a url into it's own function (UserAgent.qml). Easier to read, easier to test, easier to (maybe) reuse.

Revision history for this message
Olivier Tilloy (osomon) wrote :

> 83 +import Ubuntu.Components 0.1
> Seem not to be used

It is required, because I’m using units.gu(…).

> Just because I like small functions, I'd move the functionality of getting the
> domain from a url into it's own function (UserAgent.qml). Easier to read,
> easier to test, easier to (maybe) reuse.

Good idea, will do.

Revision history for this message
Günter Schwann (schwann) wrote :

looks good

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Ubuntu/Components/Extras/Browser/UbuntuWebView.qml'
2--- src/Ubuntu/Components/Extras/Browser/UbuntuWebView.qml 2013-07-18 21:26:13 +0000
3+++ src/Ubuntu/Components/Extras/Browser/UbuntuWebView.qml 2013-08-19 08:47:57 +0000
4@@ -17,7 +17,6 @@
5 */
6
7 import QtQuick 2.0
8-import QtQuick.Window 2.0
9 import QtWebKit 3.0
10 import QtWebKit.experimental 1.0
11 import Ubuntu.Components 0.1
12@@ -29,18 +28,6 @@
13
14 signal newTabRequested(url url)
15
16- QtObject {
17- // clumsy way of defining an enum in QML
18- id: formFactor
19- readonly property int desktop: 0
20- readonly property int phone: 1
21- readonly property int tablet: 2
22- }
23- // FIXME: this is a quick hack that will become increasingly unreliable
24- // as we support more devices, so we need a better solution for this
25- // FIXME: only handling phone and tablet for now
26- property int formFactor: (Screen.width >= units.gu(60)) ? formFactor.tablet : formFactor.phone
27-
28 property real devicePixelRatio: 1.0
29 onDevicePixelRatioChanged: {
30 // Do not make this patch to QtWebKit a hard requirement.
31@@ -54,19 +41,13 @@
32
33 property real scale: experimental.test.contentsScale * experimental.test.devicePixelRatio
34
35- experimental.userAgent: {
36- // FIXME: using iOS 5.0’s iPhone/iPad user-agent strings
37- // (source: http://stackoverflow.com/questions/7825873/what-is-the-ios-5-0-user-agent-string),
38- // this should be changed to a more neutral user-agent in the
39- // future as we don’t want websites to recommend installing
40- // their iPhone/iPad apps.
41- if (_webview.formFactor === formFactor.phone) {
42- return "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"
43- } else if (_webview.formFactor === formFactor.tablet) {
44- return "Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"
45- } else {
46- return ""
47- }
48+ UserAgent {
49+ id: userAgent
50+ }
51+ experimental.userAgent: userAgent.defaultUA
52+ onNavigationRequested: {
53+ _webview.experimental.userAgent = userAgent.getUAString(request.url)
54+ request.action = WebView.AcceptRequest
55 }
56
57 experimental.preferences.navigatorQtObjectEnabled: true
58
59=== added file 'src/Ubuntu/Components/Extras/Browser/UserAgent.qml'
60--- src/Ubuntu/Components/Extras/Browser/UserAgent.qml 1970-01-01 00:00:00 +0000
61+++ src/Ubuntu/Components/Extras/Browser/UserAgent.qml 2013-08-19 08:47:57 +0000
62@@ -0,0 +1,80 @@
63+/*
64+ * Copyright 2013 Canonical Ltd.
65+ *
66+ * This file is part of webbrowser-app.
67+ *
68+ * webbrowser-app is free software; you can redistribute it and/or modify
69+ * it under the terms of the GNU General Public License as published by
70+ * the Free Software Foundation; version 3.
71+ *
72+ * webbrowser-app is distributed in the hope that it will be useful,
73+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
74+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75+ * GNU General Public License for more details.
76+ *
77+ * You should have received a copy of the GNU General Public License
78+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
79+ */
80+
81+import QtQuick 2.0
82+import QtQuick.Window 2.0
83+import Ubuntu.Components 0.1
84+import "ua-overrides.js" as Overrides
85+
86+/*
87+ * Useful documentation:
88+ * http://en.wikipedia.org/wiki/User_agent#Format
89+ * https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference
90+ * https://wiki.mozilla.org/B2G/User_Agent
91+ * https://github.com/mozilla-b2g/gaia/blob/master/build/ua-override-prefs.js
92+ * https://developers.google.com/chrome/mobile/docs/user-agent
93+ */
94+
95+// This is an Item, not a QtObject, because it needs information about the Screen.
96+Item {
97+ // %1: form factor (Mobile, Tablet, Desktop)
98+ // %2: WebKit version
99+ readonly property string _template: "Mozilla/5.0 (Ubuntu; %1) WebKit/%2"
100+
101+ // See Source/WebCore/Configurations/Version.xcconfig in QtWebKit’s source tree
102+ // TODO: determine this value at runtime
103+ readonly property string _webkitVersion: "537.21"
104+
105+ // FIXME: this is a quick hack that will become increasingly unreliable
106+ // as we support more devices, so we need a better solution for this
107+ // FIXME: only handling phone and tablet for now, need to handle desktop too
108+ readonly property string _formFactor: (Screen.width >= units.gu(60)) ? "Tablet" : "Mobile"
109+
110+ property string defaultUA: _template.arg(_formFactor).arg(_webkitVersion)
111+
112+ property var overrides: Overrides.overrides
113+
114+ function getDomain(url) {
115+ var domain = url.toString()
116+ var indexOfScheme = domain.indexOf("://")
117+ if (indexOfScheme !== -1) {
118+ domain = domain.slice(indexOfScheme + 3)
119+ }
120+ var indexOfPath = domain.indexOf("/")
121+ if (indexOfPath !== -1) {
122+ domain = domain.slice(0, indexOfPath)
123+ }
124+ return domain
125+ }
126+
127+ function getUAString(url) {
128+ var ua = defaultUA
129+ var domain = getDomain(url)
130+ for (var override in overrides) {
131+ if (domain.indexOf(override, domain.length - override.length) !== -1) {
132+ var form = overrides[override]
133+ if (typeof form == "string") {
134+ return form
135+ } else if (typeof form == "object") {
136+ return ua.replace(form[0], form[1])
137+ }
138+ }
139+ }
140+ return ua
141+ }
142+}
143
144=== added file 'src/Ubuntu/Components/Extras/Browser/ua-overrides.js'
145--- src/Ubuntu/Components/Extras/Browser/ua-overrides.js 1970-01-01 00:00:00 +0000
146+++ src/Ubuntu/Components/Extras/Browser/ua-overrides.js 2013-08-19 08:47:57 +0000
147@@ -0,0 +1,96 @@
148+/*
149+ * Copyright 2013 Canonical Ltd.
150+ *
151+ * This file is part of webbrowser-app.
152+ *
153+ * webbrowser-app is free software; you can redistribute it and/or modify
154+ * it under the terms of the GNU General Public License as published by
155+ * the Free Software Foundation; version 3.
156+ *
157+ * webbrowser-app is distributed in the hope that it will be useful,
158+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
159+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
160+ * GNU General Public License for more details.
161+ *
162+ * You should have received a copy of the GNU General Public License
163+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
164+ */
165+
166+.pragma library
167+
168+// B2G’s list of overrides: https://github.com/mozilla-b2g/gaia/blob/master/build/ua-override-prefs.js
169+
170+// List of user agent string overrides in the form of an object.
171+// Each key is a domain name for which the default user agent string doesn’t
172+// work well enough. Values can either be a string (full override) or an array
173+// containing two values that are passed to the String.replace method (the
174+// first value may be either a string or a regular expression, the second value
175+// must be a string).
176+
177+// Examples of valid entries:
178+// "example.org": "full override"
179+// "example.com": ["Ubuntu", "Ubuntu Edge"]
180+// "google.com": [/mobi/i, "b"]
181+
182+// The original list was initially built from the top 100 entries
183+// at http://www.alexa.com/topsites (2013-08-16), using Chrome on
184+// Android as a reference.
185+
186+var overrides = {
187+ "google.com": ["Mobile", "Android; Mobile"],
188+ "youtube.com": ["Mobile", "Android; Mobile"],
189+ "yahoo.com": ["Mobile", "Android; Mobile"],
190+ "baidu.com": ["Mobile", "Android; Mobile"],
191+ "qq.com": [/WebKit\/[.0-9]*/, "Apple$& Mobile"],
192+ "amazon.com": ["Mobile", "Android; Mobile"],
193+ "linkedin.com": ["Mobile", "Android; Mobile"],
194+ "blogspot.com": ["Mobile", "Android; Mobile"],
195+ "taobao.com": ["Mobile", "Android; Mobile"],
196+ "google.co.in": ["Mobile", "Android; Mobile"],
197+ "bing.com": ["Mobile", "Android; Mobile"],
198+ "yahoo.co.jp": ["Ubuntu", "Linux; Android 4; Galaxy Build/"],
199+ "yandex.ru": ["Mobile", "Android; Mobile"],
200+ "sina.com.cn": ["Mobile", "Android; Mobile"],
201+ "ebay.com": ["Mobile", "Android; Mobile"],
202+ "google.de": ["Mobile", "Android; Mobile"],
203+ "tumblr.com": ["Mobile", "Android; Mobile"],
204+ "google.co.uk": ["Mobile", "Android; Mobile"],
205+ "msn.com": ["Mobile", "Android; Mobile"],
206+ "google.fr": ["Mobile", "Android; Mobile"],
207+ "mail.ru": ["Ubuntu", "Linux; Android 4; Galaxy Build/"],
208+ "google.com.br": ["Mobile", "Android; Mobile"],
209+ "google.co.jp": ["Mobile", "Android; Mobile"],
210+ "hao123.com": ["Mobile", "Android; Mobile"],
211+ "ask.com": ["Mobile", "Android; Mobile"],
212+ "google.com.hk": ["Mobile", "Android; Mobile"],
213+ "google.ru": ["Mobile", "Android; Mobile"],
214+ "blogger.com": ["Mobile", "Android; Mobile"],
215+ "imdb.com": ["Mobile", "Android; Mobile"],
216+ "google.it": ["Mobile", "Android; Mobile"],
217+ "google.es": ["Mobile", "Android; Mobile"],
218+ "amazon.co.jp": ["Mobile", "Android; Mobile"],
219+ "tmall.com": ["Mobile", "Android; Mobile"],
220+ "fc2.com": ["Mobile", "Android; Mobile"],
221+ "google.com.mx": ["Mobile", "Android; Mobile"],
222+ "google.ca": ["Mobile", "Android; Mobile"],
223+ "soso.com": ["Mobile", "Android; Mobile"],
224+ "delta-search.com": ["Mobile", "Android; Mobile"],
225+ "odnoklassniki.ru": ["Mobile", "Android; Mobile"],
226+ "alibaba.com": ["Mobile", "Android; Mobile"],
227+ "flickr.com": ["Mobile", "Android; Mobile"],
228+ "amazon.de": ["Mobile", "Android; Mobile"],
229+ "blogspot.in": ["Mobile", "Android; Mobile"],
230+ "ifeng.com": ["Mobile", "Android; Mobile"],
231+ "360.cn": ["Mobile", "Android; Mobile"],
232+ "google.com.tr": ["Mobile", "Android; Mobile"],
233+ "google.com.au": ["Mobile", "Android; Mobile"],
234+ "youku.com": ["Mobile", "Android; Mobile"],
235+ "ebay.de": ["Mobile", "Android; Mobile"],
236+ "uol.com.br": ["Mobile", "Android; Mobile"],
237+ "aol.com": ["Mobile", "Android; Mobile"],
238+ "google.pl": ["Mobile", "Android; Mobile"],
239+ "alipay.com": ["Mobile", "Android; Mobile"],
240+ "dailymotion.com": ["Mobile", "Android; Mobile Safari"],
241+ "amazon.co.uk": ["Mobile", "Android; Mobile"],
242+ "ebay.co.uk": ["Mobile", "Android; Mobile"],
243+};
244
245=== modified file 'tests/unittests/qml/CMakeLists.txt'
246--- tests/unittests/qml/CMakeLists.txt 2013-07-19 14:11:08 +0000
247+++ tests/unittests/qml/CMakeLists.txt 2013-08-19 08:47:57 +0000
248@@ -5,14 +5,22 @@
249 set_tests_properties(${TEST} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
250
251 # copy qml files under test to build dir
252+set(out_qml_files)
253 file(GLOB qmlFiles RELATIVE ${webbrowser-app_SOURCE_DIR} ${webbrowser-app_SOURCE_DIR}/*.qml)
254-set(out_qml_files)
255 foreach(qmlFile ${qmlFiles})
256 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile}
257 DEPENDS ${webbrowser-app_SOURCE_DIR}/${qmlFile}
258 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${webbrowser-app_SOURCE_DIR}/${qmlFile} ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile})
259 list(APPEND out_qml_files undertest/${qmlFile})
260 endforeach(qmlFile)
261+file(GLOB qmlFiles RELATIVE ${webbrowser-plugin_SOURCE_DIR} ${webbrowser-plugin_SOURCE_DIR}/*.qml
262+ ${webbrowser-plugin_SOURCE_DIR} ${webbrowser-plugin_SOURCE_DIR}/*.js)
263+foreach(qmlFile ${qmlFiles})
264+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile}
265+ DEPENDS ${webbrowser-plugin_SOURCE_DIR}/${qmlFile}
266+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${webbrowser-plugin_SOURCE_DIR}/${qmlFile} ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile})
267+ list(APPEND out_qml_files undertest/${qmlFile})
268+endforeach(qmlFile)
269 add_custom_target(copy_qml_files_under_test_to_build_dir DEPENDS ${out_qml_files})
270 add_dependencies(${TEST} copy_qml_files_under_test_to_build_dir)
271
272
273=== added file 'tests/unittests/qml/tst_UserAgent.qml'
274--- tests/unittests/qml/tst_UserAgent.qml 1970-01-01 00:00:00 +0000
275+++ tests/unittests/qml/tst_UserAgent.qml 2013-08-19 08:47:57 +0000
276@@ -0,0 +1,71 @@
277+/*
278+ * Copyright 2013 Canonical Ltd.
279+ *
280+ * This file is part of webbrowser-app.
281+ *
282+ * webbrowser-app is free software; you can redistribute it and/or modify
283+ * it under the terms of the GNU General Public License as published by
284+ * the Free Software Foundation; version 3.
285+ *
286+ * webbrowser-app is distributed in the hope that it will be useful,
287+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
288+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
289+ * GNU General Public License for more details.
290+ *
291+ * You should have received a copy of the GNU General Public License
292+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
293+ */
294+
295+import QtQuick 2.0
296+import QtTest 1.0
297+import "undertest"
298+
299+TestCase {
300+ name: "UserAgent"
301+
302+ function test_get_domain() {
303+ compare(userAgent.getDomain("http://ubuntu.com"), "ubuntu.com")
304+ compare(userAgent.getDomain("http://www.ubuntu.com"), "www.ubuntu.com")
305+ compare(userAgent.getDomain("http://ubuntu.com/"), "ubuntu.com")
306+ compare(userAgent.getDomain("http://www.ubuntu.com/"), "www.ubuntu.com")
307+ compare(userAgent.getDomain("ubuntu.com"), "ubuntu.com")
308+ compare(userAgent.getDomain("ubuntu.com/"), "ubuntu.com")
309+ compare(userAgent.getDomain("ubuntu.com/phone"), "ubuntu.com")
310+ compare(userAgent.getDomain("http://ubuntu.com/phone"), "ubuntu.com")
311+ compare(userAgent.getDomain("www.ubuntu.com/phone"), "www.ubuntu.com")
312+ compare(userAgent.getDomain("http://ubuntu.com/phone/index.html"), "ubuntu.com")
313+ compare(userAgent.getDomain("ubuntu.com/phone/index.html"), "ubuntu.com")
314+ compare(userAgent.getDomain("www.ubuntu.com/phone/index.html"), "www.ubuntu.com")
315+ compare(userAgent.getDomain("http://ubuntu.com/phone/index.html?foo=bar&baz=bleh"), "ubuntu.com")
316+ }
317+
318+ function test_ua_unmodified() {
319+ compare(userAgent.getUAString("http://ubuntu.com"), userAgent.defaultUA)
320+ }
321+
322+ function test_ua_full_override() {
323+ compare(userAgent.getUAString("http://example.org"), "full override")
324+ }
325+
326+ function test_ua_string_replace() {
327+ compare(userAgent.getUAString("http://example.com/test"),
328+ "Mozilla/5.0 (Ubuntu Edge; Mobile) WebKit/537.21")
329+ }
330+
331+ function test_ua_regexp_replace() {
332+ compare(userAgent.getUAString("http://www.google.com/"),
333+ "Mozilla/5.0 (Ubuntu; ble) WebKit/537.21")
334+ }
335+
336+ UserAgent {
337+ id: userAgent
338+
339+ defaultUA: "Mozilla/5.0 (Ubuntu; Mobile) WebKit/537.21"
340+
341+ overrides: {
342+ "example.org": "full override",
343+ "example.com": ["Ubuntu", "Ubuntu Edge"],
344+ "google.com": [/mobi/i, "b"],
345+ }
346+ }
347+}

Subscribers

People subscribed via source and target branches

to status/vote changes: