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
=== modified file 'src/Ubuntu/Components/Extras/Browser/UbuntuWebView.qml'
--- src/Ubuntu/Components/Extras/Browser/UbuntuWebView.qml 2013-07-18 21:26:13 +0000
+++ src/Ubuntu/Components/Extras/Browser/UbuntuWebView.qml 2013-08-19 08:47:57 +0000
@@ -17,7 +17,6 @@
17 */17 */
1818
19import QtQuick 2.019import QtQuick 2.0
20import QtQuick.Window 2.0
21import QtWebKit 3.020import QtWebKit 3.0
22import QtWebKit.experimental 1.021import QtWebKit.experimental 1.0
23import Ubuntu.Components 0.122import Ubuntu.Components 0.1
@@ -29,18 +28,6 @@
2928
30 signal newTabRequested(url url)29 signal newTabRequested(url url)
3130
32 QtObject {
33 // clumsy way of defining an enum in QML
34 id: formFactor
35 readonly property int desktop: 0
36 readonly property int phone: 1
37 readonly property int tablet: 2
38 }
39 // FIXME: this is a quick hack that will become increasingly unreliable
40 // as we support more devices, so we need a better solution for this
41 // FIXME: only handling phone and tablet for now
42 property int formFactor: (Screen.width >= units.gu(60)) ? formFactor.tablet : formFactor.phone
43
44 property real devicePixelRatio: 1.031 property real devicePixelRatio: 1.0
45 onDevicePixelRatioChanged: {32 onDevicePixelRatioChanged: {
46 // Do not make this patch to QtWebKit a hard requirement.33 // Do not make this patch to QtWebKit a hard requirement.
@@ -54,19 +41,13 @@
5441
55 property real scale: experimental.test.contentsScale * experimental.test.devicePixelRatio42 property real scale: experimental.test.contentsScale * experimental.test.devicePixelRatio
5643
57 experimental.userAgent: {44 UserAgent {
58 // FIXME: using iOS 5.0’s iPhone/iPad user-agent strings45 id: userAgent
59 // (source: http://stackoverflow.com/questions/7825873/what-is-the-ios-5-0-user-agent-string),46 }
60 // this should be changed to a more neutral user-agent in the47 experimental.userAgent: userAgent.defaultUA
61 // future as we don’t want websites to recommend installing48 onNavigationRequested: {
62 // their iPhone/iPad apps.49 _webview.experimental.userAgent = userAgent.getUAString(request.url)
63 if (_webview.formFactor === formFactor.phone) {50 request.action = WebView.AcceptRequest
64 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"
65 } else if (_webview.formFactor === formFactor.tablet) {
66 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"
67 } else {
68 return ""
69 }
70 }51 }
7152
72 experimental.preferences.navigatorQtObjectEnabled: true53 experimental.preferences.navigatorQtObjectEnabled: true
7354
=== added file 'src/Ubuntu/Components/Extras/Browser/UserAgent.qml'
--- src/Ubuntu/Components/Extras/Browser/UserAgent.qml 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/Extras/Browser/UserAgent.qml 2013-08-19 08:47:57 +0000
@@ -0,0 +1,80 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.0
20import QtQuick.Window 2.0
21import Ubuntu.Components 0.1
22import "ua-overrides.js" as Overrides
23
24/*
25 * Useful documentation:
26 * http://en.wikipedia.org/wiki/User_agent#Format
27 * https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference
28 * https://wiki.mozilla.org/B2G/User_Agent
29 * https://github.com/mozilla-b2g/gaia/blob/master/build/ua-override-prefs.js
30 * https://developers.google.com/chrome/mobile/docs/user-agent
31 */
32
33// This is an Item, not a QtObject, because it needs information about the Screen.
34Item {
35 // %1: form factor (Mobile, Tablet, Desktop)
36 // %2: WebKit version
37 readonly property string _template: "Mozilla/5.0 (Ubuntu; %1) WebKit/%2"
38
39 // See Source/WebCore/Configurations/Version.xcconfig in QtWebKit’s source tree
40 // TODO: determine this value at runtime
41 readonly property string _webkitVersion: "537.21"
42
43 // FIXME: this is a quick hack that will become increasingly unreliable
44 // as we support more devices, so we need a better solution for this
45 // FIXME: only handling phone and tablet for now, need to handle desktop too
46 readonly property string _formFactor: (Screen.width >= units.gu(60)) ? "Tablet" : "Mobile"
47
48 property string defaultUA: _template.arg(_formFactor).arg(_webkitVersion)
49
50 property var overrides: Overrides.overrides
51
52 function getDomain(url) {
53 var domain = url.toString()
54 var indexOfScheme = domain.indexOf("://")
55 if (indexOfScheme !== -1) {
56 domain = domain.slice(indexOfScheme + 3)
57 }
58 var indexOfPath = domain.indexOf("/")
59 if (indexOfPath !== -1) {
60 domain = domain.slice(0, indexOfPath)
61 }
62 return domain
63 }
64
65 function getUAString(url) {
66 var ua = defaultUA
67 var domain = getDomain(url)
68 for (var override in overrides) {
69 if (domain.indexOf(override, domain.length - override.length) !== -1) {
70 var form = overrides[override]
71 if (typeof form == "string") {
72 return form
73 } else if (typeof form == "object") {
74 return ua.replace(form[0], form[1])
75 }
76 }
77 }
78 return ua
79 }
80}
081
=== added file 'src/Ubuntu/Components/Extras/Browser/ua-overrides.js'
--- src/Ubuntu/Components/Extras/Browser/ua-overrides.js 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/Extras/Browser/ua-overrides.js 2013-08-19 08:47:57 +0000
@@ -0,0 +1,96 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19.pragma library
20
21// B2G’s list of overrides: https://github.com/mozilla-b2g/gaia/blob/master/build/ua-override-prefs.js
22
23// List of user agent string overrides in the form of an object.
24// Each key is a domain name for which the default user agent string doesn’t
25// work well enough. Values can either be a string (full override) or an array
26// containing two values that are passed to the String.replace method (the
27// first value may be either a string or a regular expression, the second value
28// must be a string).
29
30// Examples of valid entries:
31// "example.org": "full override"
32// "example.com": ["Ubuntu", "Ubuntu Edge"]
33// "google.com": [/mobi/i, "b"]
34
35// The original list was initially built from the top 100 entries
36// at http://www.alexa.com/topsites (2013-08-16), using Chrome on
37// Android as a reference.
38
39var overrides = {
40 "google.com": ["Mobile", "Android; Mobile"],
41 "youtube.com": ["Mobile", "Android; Mobile"],
42 "yahoo.com": ["Mobile", "Android; Mobile"],
43 "baidu.com": ["Mobile", "Android; Mobile"],
44 "qq.com": [/WebKit\/[.0-9]*/, "Apple$& Mobile"],
45 "amazon.com": ["Mobile", "Android; Mobile"],
46 "linkedin.com": ["Mobile", "Android; Mobile"],
47 "blogspot.com": ["Mobile", "Android; Mobile"],
48 "taobao.com": ["Mobile", "Android; Mobile"],
49 "google.co.in": ["Mobile", "Android; Mobile"],
50 "bing.com": ["Mobile", "Android; Mobile"],
51 "yahoo.co.jp": ["Ubuntu", "Linux; Android 4; Galaxy Build/"],
52 "yandex.ru": ["Mobile", "Android; Mobile"],
53 "sina.com.cn": ["Mobile", "Android; Mobile"],
54 "ebay.com": ["Mobile", "Android; Mobile"],
55 "google.de": ["Mobile", "Android; Mobile"],
56 "tumblr.com": ["Mobile", "Android; Mobile"],
57 "google.co.uk": ["Mobile", "Android; Mobile"],
58 "msn.com": ["Mobile", "Android; Mobile"],
59 "google.fr": ["Mobile", "Android; Mobile"],
60 "mail.ru": ["Ubuntu", "Linux; Android 4; Galaxy Build/"],
61 "google.com.br": ["Mobile", "Android; Mobile"],
62 "google.co.jp": ["Mobile", "Android; Mobile"],
63 "hao123.com": ["Mobile", "Android; Mobile"],
64 "ask.com": ["Mobile", "Android; Mobile"],
65 "google.com.hk": ["Mobile", "Android; Mobile"],
66 "google.ru": ["Mobile", "Android; Mobile"],
67 "blogger.com": ["Mobile", "Android; Mobile"],
68 "imdb.com": ["Mobile", "Android; Mobile"],
69 "google.it": ["Mobile", "Android; Mobile"],
70 "google.es": ["Mobile", "Android; Mobile"],
71 "amazon.co.jp": ["Mobile", "Android; Mobile"],
72 "tmall.com": ["Mobile", "Android; Mobile"],
73 "fc2.com": ["Mobile", "Android; Mobile"],
74 "google.com.mx": ["Mobile", "Android; Mobile"],
75 "google.ca": ["Mobile", "Android; Mobile"],
76 "soso.com": ["Mobile", "Android; Mobile"],
77 "delta-search.com": ["Mobile", "Android; Mobile"],
78 "odnoklassniki.ru": ["Mobile", "Android; Mobile"],
79 "alibaba.com": ["Mobile", "Android; Mobile"],
80 "flickr.com": ["Mobile", "Android; Mobile"],
81 "amazon.de": ["Mobile", "Android; Mobile"],
82 "blogspot.in": ["Mobile", "Android; Mobile"],
83 "ifeng.com": ["Mobile", "Android; Mobile"],
84 "360.cn": ["Mobile", "Android; Mobile"],
85 "google.com.tr": ["Mobile", "Android; Mobile"],
86 "google.com.au": ["Mobile", "Android; Mobile"],
87 "youku.com": ["Mobile", "Android; Mobile"],
88 "ebay.de": ["Mobile", "Android; Mobile"],
89 "uol.com.br": ["Mobile", "Android; Mobile"],
90 "aol.com": ["Mobile", "Android; Mobile"],
91 "google.pl": ["Mobile", "Android; Mobile"],
92 "alipay.com": ["Mobile", "Android; Mobile"],
93 "dailymotion.com": ["Mobile", "Android; Mobile Safari"],
94 "amazon.co.uk": ["Mobile", "Android; Mobile"],
95 "ebay.co.uk": ["Mobile", "Android; Mobile"],
96};
097
=== modified file 'tests/unittests/qml/CMakeLists.txt'
--- tests/unittests/qml/CMakeLists.txt 2013-07-19 14:11:08 +0000
+++ tests/unittests/qml/CMakeLists.txt 2013-08-19 08:47:57 +0000
@@ -5,14 +5,22 @@
5set_tests_properties(${TEST} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")5set_tests_properties(${TEST} PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
66
7# copy qml files under test to build dir7# copy qml files under test to build dir
8set(out_qml_files)
8file(GLOB qmlFiles RELATIVE ${webbrowser-app_SOURCE_DIR} ${webbrowser-app_SOURCE_DIR}/*.qml)9file(GLOB qmlFiles RELATIVE ${webbrowser-app_SOURCE_DIR} ${webbrowser-app_SOURCE_DIR}/*.qml)
9set(out_qml_files)
10foreach(qmlFile ${qmlFiles})10foreach(qmlFile ${qmlFiles})
11 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile}11 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile}
12 DEPENDS ${webbrowser-app_SOURCE_DIR}/${qmlFile}12 DEPENDS ${webbrowser-app_SOURCE_DIR}/${qmlFile}
13 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${webbrowser-app_SOURCE_DIR}/${qmlFile} ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile})13 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${webbrowser-app_SOURCE_DIR}/${qmlFile} ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile})
14 list(APPEND out_qml_files undertest/${qmlFile})14 list(APPEND out_qml_files undertest/${qmlFile})
15endforeach(qmlFile)15endforeach(qmlFile)
16file(GLOB qmlFiles RELATIVE ${webbrowser-plugin_SOURCE_DIR} ${webbrowser-plugin_SOURCE_DIR}/*.qml
17 ${webbrowser-plugin_SOURCE_DIR} ${webbrowser-plugin_SOURCE_DIR}/*.js)
18foreach(qmlFile ${qmlFiles})
19 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile}
20 DEPENDS ${webbrowser-plugin_SOURCE_DIR}/${qmlFile}
21 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${webbrowser-plugin_SOURCE_DIR}/${qmlFile} ${CMAKE_CURRENT_BINARY_DIR}/undertest/${qmlFile})
22 list(APPEND out_qml_files undertest/${qmlFile})
23endforeach(qmlFile)
16add_custom_target(copy_qml_files_under_test_to_build_dir DEPENDS ${out_qml_files})24add_custom_target(copy_qml_files_under_test_to_build_dir DEPENDS ${out_qml_files})
17add_dependencies(${TEST} copy_qml_files_under_test_to_build_dir)25add_dependencies(${TEST} copy_qml_files_under_test_to_build_dir)
1826
1927
=== added file 'tests/unittests/qml/tst_UserAgent.qml'
--- tests/unittests/qml/tst_UserAgent.qml 1970-01-01 00:00:00 +0000
+++ tests/unittests/qml/tst_UserAgent.qml 2013-08-19 08:47:57 +0000
@@ -0,0 +1,71 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.0
20import QtTest 1.0
21import "undertest"
22
23TestCase {
24 name: "UserAgent"
25
26 function test_get_domain() {
27 compare(userAgent.getDomain("http://ubuntu.com"), "ubuntu.com")
28 compare(userAgent.getDomain("http://www.ubuntu.com"), "www.ubuntu.com")
29 compare(userAgent.getDomain("http://ubuntu.com/"), "ubuntu.com")
30 compare(userAgent.getDomain("http://www.ubuntu.com/"), "www.ubuntu.com")
31 compare(userAgent.getDomain("ubuntu.com"), "ubuntu.com")
32 compare(userAgent.getDomain("ubuntu.com/"), "ubuntu.com")
33 compare(userAgent.getDomain("ubuntu.com/phone"), "ubuntu.com")
34 compare(userAgent.getDomain("http://ubuntu.com/phone"), "ubuntu.com")
35 compare(userAgent.getDomain("www.ubuntu.com/phone"), "www.ubuntu.com")
36 compare(userAgent.getDomain("http://ubuntu.com/phone/index.html"), "ubuntu.com")
37 compare(userAgent.getDomain("ubuntu.com/phone/index.html"), "ubuntu.com")
38 compare(userAgent.getDomain("www.ubuntu.com/phone/index.html"), "www.ubuntu.com")
39 compare(userAgent.getDomain("http://ubuntu.com/phone/index.html?foo=bar&baz=bleh"), "ubuntu.com")
40 }
41
42 function test_ua_unmodified() {
43 compare(userAgent.getUAString("http://ubuntu.com"), userAgent.defaultUA)
44 }
45
46 function test_ua_full_override() {
47 compare(userAgent.getUAString("http://example.org"), "full override")
48 }
49
50 function test_ua_string_replace() {
51 compare(userAgent.getUAString("http://example.com/test"),
52 "Mozilla/5.0 (Ubuntu Edge; Mobile) WebKit/537.21")
53 }
54
55 function test_ua_regexp_replace() {
56 compare(userAgent.getUAString("http://www.google.com/"),
57 "Mozilla/5.0 (Ubuntu; ble) WebKit/537.21")
58 }
59
60 UserAgent {
61 id: userAgent
62
63 defaultUA: "Mozilla/5.0 (Ubuntu; Mobile) WebKit/537.21"
64
65 overrides: {
66 "example.org": "full override",
67 "example.com": ["Ubuntu", "Ubuntu Edge"],
68 "google.com": [/mobi/i, "b"],
69 }
70 }
71}

Subscribers

People subscribed via source and target branches

to status/vote changes: