Merge lp:~abreu-alexandre/webbrowser-app/theme-color-meta-detection into lp:webbrowser-app

Proposed by Alexandre Abreu
Status: Merged
Approved by: Alberto Mardegan
Approved revision: no longer in the source branch.
Merged at revision: 1320
Proposed branch: lp:~abreu-alexandre/webbrowser-app/theme-color-meta-detection
Merge into: lp:webbrowser-app
Diff against target: 322 lines (+211/-2)
8 files modified
src/app/ChromeBase.qml (+2/-0)
src/app/webcontainer/CMakeLists.txt (+1/-1)
src/app/webcontainer/WebApp.qml (+5/-0)
src/app/webcontainer/WebViewImplOxide.qml (+43/-1)
src/app/webcontainer/WebappContainerWebview.qml (+8/-0)
src/app/webcontainer/webapp-specific-page-metadata-collector.js (+56/-0)
tests/autopilot/webapp_container/tests/fake_servers.py (+47/-0)
tests/autopilot/webapp_container/tests/test_page_meta_collector.py (+49/-0)
To merge this branch: bzr merge lp:~abreu-alexandre/webbrowser-app/theme-color-meta-detection
Reviewer Review Type Date Requested Status
Alberto Mardegan (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+279120@code.launchpad.net

Commit message

Handle theme_color page metainformation.

Description of the change

Handle theme_color page meta information as described here:

https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android?hl=en

Test Case
---------

1. Go to a website that supports the theme_color meta info, e.g.

http://browsernative.com/theme-color-meta-tag-chrome-android-lollipop-546/

2. MAke sure that the background color of the navigation ui is updated,

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alberto Mardegan (mardy) wrote :

Since the tests are there, the description needs an update.

The code is good, I just wonder if we should implement some tricks on the text colour, to ensure that it's always visible against the background.

review: Approve
1295. By CI Train Bot Account

Resync trunk.

1296. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

1297. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

1298. By Zsombor Egri

Fix local Toolbar collision with UITK 1.3 Toolbar.
Approved by: Olivier Tilloy, Zoltan Balogh

1299. By Olivier Tilloy

Work around what appears to be a regression in the UITK by specifying a non-null delay when swiping a list item to delete it in unit tests. Fixes: #1526940
Approved by: Michael Sheldon

1300. By CI Train Bot Account

Releasing 0.23+16.04.20151218-0ubuntu1

1301. By Michael Sheldon

Add support for handling downloads internally within the browser. Fixes: #1354391
Approved by: Olivier Tilloy

1302. By CI Train Bot Account

Releasing 0.23+16.04.20151221-0ubuntu1

1303. By Olivier Tilloy

Update translation template.

1304. By Olivier Tilloy

Recognize openoffice and MS-office file formats as documents, now that the document viewer app knows how to render them. Fixes: #1523452
Approved by: Michael Sheldon, PS Jenkins bot

1305. By Olivier Tilloy

Do not allow interacting with tabs and the chrome while the settings page is shown. Fixes: #1524353
Approved by: PS Jenkins bot, Ugo Riboni

1306. By Olivier Tilloy

Use the screen size (diagonal in millimeters) to determine which default UA string and which UA overrides to use.
An empirical threshold of 19cm is being used, it is subject to further adjustments. Fixes: #1504084
Approved by: PS Jenkins bot

1307. By Olivier Tilloy

Add keyboard shorcuts for 'next' (Ctrl+G) and 'previous' (Ctrl+Shift+G) while in find-in-page mode. Fixes: #1522152
Approved by: PS Jenkins bot, Ugo Riboni

1308. By Olivier Tilloy

Fix the tab preview sometimes covering the tab chrome, in the tabs view.
Offset tab previews by 1px to cover the semi-transparent horizontal line at the bottom of the tab chrome asset. Fixes: #1520624
Approved by: PS Jenkins bot, Ugo Riboni

1309. By Olivier Tilloy

Fix some obvious issues in PreviewManager. Fixes: #1519019
Approved by: PS Jenkins bot, Ugo Riboni

1310. By Olivier Tilloy

Fix a crash when clearing the navigation history while the new tab view is open. Fixes: #1525937
Approved by: Ugo Riboni

1311. By Olivier Tilloy

Fix deleting multiple domains from the history view.
Add unit tests for the HistoryView component. Fixes: #1527144

1312. By CI Train Bot Account

Releasing 0.23+16.04.20151222.1-0ubuntu1

1313. By CI Train Bot Account

Resync trunk.

1314. By Launchpad Translations on behalf of phablet-team

Launchpad automatic translations update.

1315. By Alexandre Abreu

Make the webapp-container click hook more flexible. Instead of being able to delete cache & resource folders as the click is being uninstalled, one can also act on them as the click is being upgraded & installed. Fixes: #1522562
Approved by: PS Jenkins bot, Alberto Mardegan

1316. By Alexandre Abreu

Handle empty url pattern in configuration file and invalid url pattern being specified. Fixes: #1522585
Approved by: PS Jenkins bot, Alberto Mardegan

1317. By Alexandre Abreu

Handle application crashes or OOM interventions & save opened overlays Fixes: #1508969
Approved by: PS Jenkins bot, Alberto Mardegan

1318. By Alexandre Abreu

Limited handling of custom context menu for the container
Approved by: Alberto Mardegan

1319. By CI Train Bot Account

Releasing 0.23+16.04.20160106.4-0ubuntu1

1320. By Alexandre Abreu

Handle theme-color metadata

1321. By Alexandre Abreu

Add forgottten js file install

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/app/ChromeBase.qml'
2--- src/app/ChromeBase.qml 2015-08-10 15:22:00 +0000
3+++ src/app/ChromeBase.qml 2016-01-08 19:32:31 +0000
4@@ -23,6 +23,8 @@
5 StyledItem {
6 id: chrome
7
8+ objectName: "chromeBase"
9+
10 property var webview
11 property alias backgroundColor: backgroundRect.color
12
13
14=== modified file 'src/app/webcontainer/CMakeLists.txt'
15--- src/app/webcontainer/CMakeLists.txt 2015-09-29 19:31:47 +0000
16+++ src/app/webcontainer/CMakeLists.txt 2016-01-08 19:32:31 +0000
17@@ -40,7 +40,7 @@
18 install(TARGETS ${WEBAPP_CONTAINER}
19 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
20
21-file(GLOB QML_FILES *.qml)
22+file(GLOB QML_FILES *.qml *.js)
23 install(FILES ${QML_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer)
24 install(DIRECTORY actions DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer
25 FILES_MATCHING PATTERN *.qml)
26
27=== modified file 'src/app/webcontainer/WebApp.qml'
28--- src/app/webcontainer/WebApp.qml 2016-01-06 19:43:23 +0000
29+++ src/app/webcontainer/WebApp.qml 2016-01-08 19:32:31 +0000
30@@ -140,6 +140,11 @@
31 height: parent.height - osk.height
32 developerExtrasEnabled: webapp.developerExtrasEnabled
33
34+ onThemeColorMetaInformationDetected: {
35+ if (!webapp.chromeless && chromeLoader.item) {
36+ chromeLoader.item.backgroundColor = theme_color
37+ }
38+ }
39 onSamlRequestUrlPatternReceived: {
40 addGeneratedUrlPattern(urlPattern)
41 }
42
43=== modified file 'src/app/webcontainer/WebViewImplOxide.qml'
44--- src/app/webcontainer/WebViewImplOxide.qml 2016-01-06 19:43:23 +0000
45+++ src/app/webcontainer/WebViewImplOxide.qml 2016-01-08 19:32:31 +0000
46@@ -46,6 +46,7 @@
47 property bool blockOpenExternalUrls: false
48
49 signal samlRequestUrlPatternReceived(string urlPattern)
50+ signal themeColorMetaInformationDetected(string theme_color)
51
52 // Those signals are used for testing purposes to externally
53 // track down the various internal logic & steps of a popup lifecycle.
54@@ -69,7 +70,25 @@
55 context: WebContext {
56 dataPath: webview.dataPath
57 userAgent: localUserAgentOverride ? localUserAgentOverride : defaultUserAgent
58+
59+ userScripts: [
60+ Oxide.UserScript {
61+ context: "oxide://webapp-specific-page-metadata-collector/"
62+ url: Qt.resolvedUrl("webapp-specific-page-metadata-collector.js")
63+ incognitoEnabled: false
64+ matchAllFrames: false
65+ }
66+ ]
67 }
68+ messageHandlers: [
69+ Oxide.ScriptMessageHandler {
70+ msgId: "webapp-specific-page-metadata-detected"
71+ contexts: ["oxide://webapp-specific-page-metadata-collector/"]
72+ callback: function(msg, frame) {
73+ handlePageMetadata(msg.args)
74+ }
75+ }
76+ ]
77
78 preferences.allowFileAccessFromFileUrls: runningLocalApplication
79 preferences.allowUniversalAccessFromFileUrls: runningLocalApplication
80@@ -319,6 +338,30 @@
81 }
82 }
83
84+ function handlePageMetadata(metadata) {
85+ if (metadata.type === 'manifest') {
86+ var request = new XMLHttpRequest();
87+ request.onreadystatechange = function() {
88+ if (request.readyState === XMLHttpRequest.DONE) {
89+ try {
90+ var manifest = JSON.parse(request.responseText);
91+ if (manifest['theme_color']
92+ && manifest['theme_color'].length !== 0) {
93+ themeColorMetaInformationDetected(manifest['theme_color'])
94+ }
95+ } catch(e) {}
96+ }
97+ }
98+ request.open("GET", metadata.manifest);
99+ request.send();
100+ } else if (metadata.type === 'theme-color') {
101+ if (metadata['theme_color']
102+ && metadata['theme_color'].length !== 0) {
103+ themeColorMetaInformationDetected(metadata['theme_color'])
104+ }
105+ }
106+ }
107+
108 onShowDownloadDialog: {
109 if (downloadDialogLoader.status === Loader.Ready) {
110 var downloadDialog = PopupUtils.open(downloadDialogLoader.item, webview, {"contentType" : contentType,
111@@ -341,5 +384,4 @@
112 source: "ContentPickerDialog.qml"
113 asynchronous: true
114 }
115-
116 }
117
118=== modified file 'src/app/webcontainer/WebappContainerWebview.qml'
119--- src/app/webcontainer/WebappContainerWebview.qml 2016-01-06 19:43:23 +0000
120+++ src/app/webcontainer/WebappContainerWebview.qml 2016-01-08 19:32:31 +0000
121@@ -42,6 +42,7 @@
122 property bool wide: false
123
124 signal samlRequestUrlPatternReceived(string urlPattern)
125+ signal themeColorMetaInformationDetected(string theme_color)
126
127 onWideChanged: if (webappContainerWebViewLoader.item) webappContainerWebViewLoader.item.wide = wide
128
129@@ -70,6 +71,13 @@
130 }
131 }
132
133+ Connections {
134+ target: webappContainerWebViewLoader.item
135+ onThemeColorMetaInformationDetected: {
136+ themeColorMetaInformationDetected(theme_color)
137+ }
138+ }
139+
140 Loader {
141 id: webappContainerWebViewLoader
142 objectName: "containerWebviewLoader"
143
144=== added file 'src/app/webcontainer/webapp-specific-page-metadata-collector.js'
145--- src/app/webcontainer/webapp-specific-page-metadata-collector.js 1970-01-01 00:00:00 +0000
146+++ src/app/webcontainer/webapp-specific-page-metadata-collector.js 2016-01-08 19:32:31 +0000
147@@ -0,0 +1,56 @@
148+/*
149+ * Copyright 2015 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+(function() {
167+ function detectThemeColorMetaInformation() {
168+ var theme_color_meta =
169+ document.head.querySelector('meta[name="theme-color"]');
170+ if (theme_color_meta) {
171+ oxide.sendMessage(
172+ 'webapp-specific-page-metadata-detected', {
173+ type: 'theme-color',
174+ baseurl: document.location.href,
175+ theme_color: theme_color_meta.getAttribute('content')
176+ });
177+ return true;
178+ }
179+ return false;
180+ }
181+ function detectManifestMetaInformation() {
182+ var manifest = document.head.querySelector('link[rel="manifest"]');
183+
184+ if (manifest && manifest.getAttribute('href')) {
185+ oxide.sendMessage(
186+ 'webapp-specific-page-metadata-detected', {
187+ type: 'manifest',
188+ baseurl: document.location.href,
189+ manifest: manifest.href
190+ });
191+ return true;
192+ }
193+
194+ return false;
195+ }
196+
197+ var detectors = [detectThemeColorMetaInformation, detectManifestMetaInformation]
198+ for (var i in detectors) {
199+ if (detectors[i]()) {
200+ break;
201+ }
202+ }
203+})();
204
205=== modified file 'tests/autopilot/webapp_container/tests/fake_servers.py'
206--- tests/autopilot/webapp_container/tests/fake_servers.py 2015-12-17 13:56:54 +0000
207+++ tests/autopilot/webapp_container/tests/fake_servers.py 2016-01-08 19:32:31 +0000
208@@ -117,6 +117,39 @@
209 </html>
210 """.format(loopcount)
211
212+ def manifest_json_content(self):
213+ return """
214+{
215+ "name": "Theme Color",
216+ "short_name": "Theme Color",
217+ "icons": [],
218+ "theme_color": "#FF0000"
219+} """
220+
221+ def theme_color_content(self, color, with_manifest=False):
222+ color_content = ''
223+ if color:
224+ color_content = """
225+<meta name=\"theme-color\" content=\"{}\"></meta>
226+""".format(color)
227+ manifest_content = ''
228+ if with_manifest:
229+ manifest_content = "<link rel=\"manifest\" href=\"manifest.json\">"
230+
231+ return """
232+<html>
233+<head>
234+{}
235+{}
236+<title>theme-color</title>
237+<script>
238+</script>
239+</head>
240+<body>
241+</body>
242+</html>
243+ """.format(color_content, manifest_content)
244+
245 def open_close_content(self):
246 return """
247 <html>
248@@ -187,6 +220,20 @@
249 elif self.path == '/open-close-content':
250 self.send_response(200)
251 self.serve_content(self.open_close_content())
252+ elif self.path == '/theme-color/manifest.json':
253+ self.send_response(200)
254+ self.serve_content(self.manifest_json_content())
255+ elif self.path.startswith('/theme-color/'):
256+ args = self.path[len('/theme-color/'):]
257+ self.send_response(200)
258+ color = ''
259+ if args.startswith('?color='):
260+ color = args[len('?color='):]
261+ with_manifest = False
262+ if args.startswith('?manifest='):
263+ with_manifest = True
264+ self.send_response(200)
265+ self.serve_content(self.theme_color_content(color, with_manifest))
266 elif self.path.startswith('/saml/'):
267 args = self.path[len('/saml/'):]
268 loopCount = 0
269
270=== added file 'tests/autopilot/webapp_container/tests/test_page_meta_collector.py'
271--- tests/autopilot/webapp_container/tests/test_page_meta_collector.py 1970-01-01 00:00:00 +0000
272+++ tests/autopilot/webapp_container/tests/test_page_meta_collector.py 2016-01-08 19:32:31 +0000
273@@ -0,0 +1,49 @@
274+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
275+# Copyright 2015 Canonical
276+#
277+# This program is free software: you can redistribute it and/or modify it
278+# under the terms of the GNU General Public License version 3, as published
279+# by the Free Software Foundation.
280+#
281+# This program is distributed in the hope that it will be useful,
282+# but WITHOUT ANY WARRANTY; without even the implied warranty of
283+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
284+# GNU General Public License for more details.
285+#
286+# You should have received a copy of the GNU General Public License
287+# along with this program. If not, see <http://www.gnu.org/licenses/>.
288+
289+from webapp_container.tests import WebappContainerTestCaseWithLocalContentBase
290+
291+from testtools.matchers import Equals
292+from autopilot.matchers import Eventually
293+
294+
295+class TestPageMetaCollector(WebappContainerTestCaseWithLocalContentBase):
296+ def test_update_theme_color(self):
297+ args = ['--enable-addressbar']
298+ self.launch_webcontainer_app_with_local_http_server(
299+ args,
300+ '/theme-color/?color=red')
301+ self.get_webcontainer_window().visible.wait_for(True)
302+
303+ chrome_base = self.app.wait_select_single(
304+ objectName="chromeBase")
305+
306+ self.assertThat(
307+ lambda: str(chrome_base.backgroundColor),
308+ Eventually(Equals("Color(255, 0, 0, 255)")))
309+
310+ def test_update_theme_color_with_manifest(self):
311+ args = ['--enable-addressbar']
312+ self.launch_webcontainer_app_with_local_http_server(
313+ args,
314+ '/theme-color/?manifest=true')
315+ self.get_webcontainer_window().visible.wait_for(True)
316+
317+ chrome_base = self.app.wait_select_single(
318+ objectName="chromeBase")
319+
320+ self.assertThat(
321+ lambda: str(chrome_base.backgroundColor),
322+ Eventually(Equals("Color(255, 0, 0, 255)")))

Subscribers

People subscribed via source and target branches

to status/vote changes: