Merge lp:~abreu-alexandre/webbrowser-app/support-oxide-and-qtwebkit into lp:~osomon/webbrowser-app/with-oxide

Proposed by Alexandre Abreu on 2014-03-26
Status: Merged
Merged at revision: 492
Proposed branch: lp:~abreu-alexandre/webbrowser-app/support-oxide-and-qtwebkit
Merge into: lp:~osomon/webbrowser-app/with-oxide
Diff against target: 664 lines (+392/-103)
10 files modified
debian/control (+1/-0)
src/app/browserapplication.cpp (+1/-1)
src/app/browserapplication.h (+1/-1)
src/app/webbrowser/webbrowser-app.cpp (+3/-0)
src/app/webcontainer/WebApp.qml (+18/-101)
src/app/webcontainer/WebViewImplWebkit.qml (+159/-0)
src/app/webcontainer/WebappContainerWebview.qml (+151/-0)
src/app/webcontainer/webapp-container.cpp (+56/-0)
src/app/webcontainer/webapp-container.h (+1/-0)
src/app/webcontainer/webapp-container.qml (+1/-0)
To merge this branch: bzr merge lp:~abreu-alexandre/webbrowser-app/support-oxide-and-qtwebkit
Reviewer Review Type Date Requested Status
Olivier Tilloy 2014-03-26 Needs Fixing on 2014-03-28
Review via email: mp+212850@code.launchpad.net

Commit message

Make the webapp-container adaptable to the runtime context (oxide or not) and instanciate the proper web backend. To account for the multiple potential frameworks (13.10, and soon 14.04) and avoid 1. user having their webapps not working anymore, 2. asking user to update their click package, a bit of runtime behavior has been added (ack'd by Jamie Strandboge) to validate the presence of oxide,

Description of the change

Make the webapp-container adaptable to the runtime context (oxide or not) and instanciate the proper web backend. To account for the multiple potential frameworks (13.10, and soon 14.04) and avoid 1. user having their webapps not working anymore, 2. asking user to update their click package, a bit of runtime behavior has been added (ack'd by Jamie Strandboge) to validate the presence of oxide,

To post a comment you must log in.
488. By Alexandre Abreu on 2014-03-26

merge trunk

489. By Alexandre Abreu on 2014-03-26

fixes

490. By Alexandre Abreu on 2014-03-26

Add build deps

Olivier Tilloy (osomon) wrote :

A couple of general remarks before I dive in the code more seriously:

 - could you please get rid of the ComponentCreation parameter, thus making the instantiation of the component always a 2-step process? I don’t think we’re gaining anything from having two separate code paths there. See https://code.launchpad.net/~mardy/webbrowser-app/add-onlineaccount-support-for-container2/+merge/211701 where Alberto did that

 - the runtime dep on libqt5webkit5-qmlwebkitplugin should be added to webapp-container, not webbrowser-app

 - detecting the architecture would probably be more reliable by testing the definition of Q_PROCESSOR_X86_32, Q_PROCESSOR_X86_64, and Q_PROCESSOR_ARM (include <QtCore/QtGlobal> to make use of them)

 - out of curiosity, wouldn’t using the QFile API work to test whether we can access the oxide-renderer binary?

review: Needs Fixing
491. By Alexandre Abreu on 2014-03-27

fixes

Olivier Tilloy (osomon) wrote :

At line 33 of the diff, an extra blank line was added, can it be reverted?

Olivier Tilloy (osomon) wrote :

563 +#include <unistd.h>

Is this include statement really needed?

Olivier Tilloy (osomon) wrote :

In WebappContainer::withOxide(), what about adding recognition for a "--oxide" flag to force the use of oxide, for testing purposes (that would be handy for me on my development workstation where I don’t have oxide installed system-wide - I use a locally compiled version) ?

Olivier Tilloy (osomon) wrote :

632 + // to update its app or change somehting in the Exec args.

typo: s/somehting/something/

Olivier Tilloy (osomon) wrote :

In WebappContainer::withOxide(), can you make the comment extra explicit by explaining that this works under confinement because version 1.1 of the ubuntu apparmor policy allows access to this file, whereas version 1.0 knows only of QtWebKit.

I just want to make sure when I read this code again in 6 months from now I’ll understand right away why we wrote it and how it works.

492. By Alexandre Abreu on 2014-03-27

fixes

Alexandre Abreu (abreu-alexandre) wrote :

> At line 33 of the diff, an extra blank line was added, can it be reverted?
done

Alexandre Abreu (abreu-alexandre) wrote :

> In WebappContainer::withOxide(), can you make the comment extra explicit by
> explaining that this works under confinement because version 1.1 of the ubuntu
> apparmor policy allows access to this file, whereas version 1.0 knows only of
> QtWebKit.
>
> I just want to make sure when I read this code again in 6 months from now I’ll
> understand right away why we wrote it and how it works.

done

Alexandre Abreu (abreu-alexandre) wrote :

> 632 + // to update its app or change somehting in the Exec args.
>
> typo: s/somehting/something/

done

Alexandre Abreu (abreu-alexandre) wrote :

> 563 +#include <unistd.h>
>
> Is this include statement really needed?

done

Olivier Tilloy (osomon) wrote :

This doesn’t work here on my device: I’ve installed packages built from this branch (which pulled in oxide), and running a webapp that has version 1.0 of the policy fails, I’m seeing this in the log:

    Using Oxide as the web engine backend

and then:

    LaunchProcess: failed to execvp:
    /usr/lib/arm-linux-gnueabihf/oxide-qt/chrome-sandbox

QFile::exists() is probably not good enough to check access rights.
I have tried the following:

    return QFile(oxideHintLocation).open(QIODevice::ReadOnly);

which is closer to your original solution, but I’m still getting the same issue. Could it be that version 1.0 of the policy doesn’t prevent from reading this file? Can you check with Jamie?

review: Needs Fixing
Jamie Strandboge (jdstrand) wrote :

So, 1.0 of the policy doesn't block the access. I'll update the apparmor-easyprof-ubuntu policy to make sure it does.

493. By Alexandre Abreu on 2014-03-28

simplify oxide detection

Olivier Tilloy (osomon) wrote :

currentArchitecturePathName() should probably be marked static.

Olivier Tilloy (osomon) wrote :

441 + id: webview

this id seems to be unused

Olivier Tilloy (osomon) wrote :

457 + toolbar: panel.panel

This doesn’t look correct. Shouldn’t it be:

    toolbar: containerWebview.toolbar

494. By Alexandre Abreu on 2014-03-28

Fixes

Olivier Tilloy (osomon) wrote :

287 + experimental.preferences.developerExtrasEnabled: developerExtrasEnabled

"developerExtrasEnabled" is not defined in this context (this might actually work because it is defined in a parent context, but it breaks encapsulation, thus making the code hard to read and to maintain).
Can you make it a property of the WebViewImplWebkit and ensure it’s set from the caller?

495. By Alexandre Abreu on 2014-03-28

Fixes

496. By Alexandre Abreu on 2014-03-28

Fixes

Olivier Tilloy (osomon) wrote :

In src/app/webcontainer/WebApp.qml:

    property alias developerExtrasEnabled: webview.developerExtrasEnabled

I don’t think this will work, because WebApp is an instance of BrowserView which already defines a top-level "developerExtrasEnabled" property.

497. By Alexandre Abreu on 2014-03-28

Fix developer extra enabled

Alexandre Abreu (abreu-alexandre) wrote :

> In src/app/webcontainer/WebApp.qml:
>
> property alias developerExtrasEnabled: webview.developerExtrasEnabled
>
> I don’t think this will work, because WebApp is an instance of BrowserView
> which already defines a top-level "developerExtrasEnabled" property.

right, done

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2014-03-18 15:18:34 +0000
+++ debian/control 2014-03-28 16:05:34 +0000
@@ -51,6 +51,7 @@
51Depends: ${misc:Depends},51Depends: ${misc:Depends},
52 ${shlibs:Depends},52 ${shlibs:Depends},
53 unity-webapps-qml,53 unity-webapps-qml,
54 libqt5webkit5-qmlwebkitplugin,
54 webbrowser-app (= ${binary:Version}),55 webbrowser-app (= ${binary:Version}),
55Description: Ubuntu web applications container56Description: Ubuntu web applications container
56 A lightweight webapps container tailored for Ubuntu, based on the Webkit57 A lightweight webapps container tailored for Ubuntu, based on the Webkit
5758
=== modified file 'src/app/browserapplication.cpp'
--- src/app/browserapplication.cpp 2014-03-17 22:16:59 +0000
+++ src/app/browserapplication.cpp 2014-03-28 16:05:34 +0000
@@ -140,7 +140,7 @@
140 m_webbrowserWindowProxy = new WebBrowserWindow();140 m_webbrowserWindowProxy = new WebBrowserWindow();
141 context->setContextProperty("webbrowserWindowProxy", m_webbrowserWindowProxy);141 context->setContextProperty("webbrowserWindowProxy", m_webbrowserWindowProxy);
142142
143 QObject* browser = m_component->create();143 QObject* browser = m_component->beginCreate(context);
144 m_window = qobject_cast<QQuickWindow*>(browser);144 m_window = qobject_cast<QQuickWindow*>(browser);
145 m_webbrowserWindowProxy->setWindow(m_window);145 m_webbrowserWindowProxy->setWindow(m_window);
146146
147147
=== modified file 'src/app/browserapplication.h'
--- src/app/browserapplication.h 2014-03-17 22:16:59 +0000
+++ src/app/browserapplication.h 2014-03-28 16:05:34 +0000
@@ -49,11 +49,11 @@
49 QStringList m_arguments;49 QStringList m_arguments;
50 QQmlEngine* m_engine;50 QQmlEngine* m_engine;
51 QQuickWindow* m_window;51 QQuickWindow* m_window;
52 QQmlComponent* m_component;
5253
53private:54private:
54 QString appId() const;55 QString appId() const;
5556
56 QQmlComponent* m_component;
57 WebBrowserWindow *m_webbrowserWindowProxy;57 WebBrowserWindow *m_webbrowserWindowProxy;
58};58};
5959
6060
=== modified file 'src/app/webbrowser/webbrowser-app.cpp'
--- src/app/webbrowser/webbrowser-app.cpp 2014-03-13 09:04:26 +0000
+++ src/app/webbrowser/webbrowser-app.cpp 2014-03-28 16:05:34 +0000
@@ -89,6 +89,9 @@
89 Q_FOREACH(const QUrl& url, urls) {89 Q_FOREACH(const QUrl& url, urls) {
90 QMetaObject::invokeMethod(browser, "newTab", Q_ARG(QVariant, url), Q_ARG(QVariant, true));90 QMetaObject::invokeMethod(browser, "newTab", Q_ARG(QVariant, url), Q_ARG(QVariant, true));
91 }91 }
92
93 m_component->completeCreate();
94
92 return true;95 return true;
93 } else {96 } else {
94 return false;97 return false;
9598
=== modified file 'src/app/webcontainer/WebApp.qml'
--- src/app/webcontainer/WebApp.qml 2014-03-26 13:29:24 +0000
+++ src/app/webcontainer/WebApp.qml 2014-03-28 16:05:34 +0000
@@ -27,20 +27,23 @@
27BrowserView {27BrowserView {
28 id: webapp28 id: webapp
2929
30 currentWebview: webview30 currentWebview: webview.currentWebview
3131
32 property alias url: webview.url32 property alias url: webview.url
33 property string webappName: ""33
34 property string webappModelSearchPath: ""34 property string webappModelSearchPath: ""
35 property var webappUrlPatterns: null35
36 property alias oxide: webview.withOxide
37 property alias webappName: webview.webappName
38 property alias webappUrlPatterns: webview.webappUrlPatterns
3639
37 actions: [40 actions: [
38 Actions.Back {41 Actions.Back {
39 enabled: backForwardButtonsVisible && currentWebview.canGoBack42 enabled: backForwardButtonsVisible && webview.currentWebview && webview.currentWebview.canGoBack
40 onTriggered: webview.goBack()43 onTriggered: webview.goBack()
41 },44 },
42 Actions.Forward {45 Actions.Forward {
43 enabled: backForwardButtonsVisible && currentWebview.canGoForward46 enabled: backForwardButtonsVisible && webview.currentWebview && webview.currentWebview.canGoForward
44 onTriggered: webview.goForward()47 onTriggered: webview.goForward()
45 },48 },
46 Actions.Reload {49 Actions.Reload {
@@ -56,10 +59,8 @@
56 // The UITK is trying too hard to be clever about the header and toolbar.59 // The UITK is trying too hard to be clever about the header and toolbar.
57 flickable: null60 flickable: null
5861
59 WebViewImpl {62 WebappContainerWebview {
60 id: webview63 id: webview
61
62 currentWebview: webview
63 toolbar: panel.panel64 toolbar: panel.panel
6465
65 anchors {66 anchors {
@@ -68,97 +69,17 @@
68 top: parent.top69 top: parent.top
69 }70 }
70 height: parent.height - osk.height71 height: parent.height - osk.height
7172 developerExtrasEnabled: webapp.developerExtrasEnabled
72 contextualActions: ActionList {
73 Actions.CopyLink {
74 enabled: webview.contextualData.href.toString()
75 onTriggered: Clipboard.push([webview.contextualData.href])
76 }
77 Actions.CopyImage {
78 enabled: webview.contextualData.img.toString()
79 onTriggered: Clipboard.push([webview.contextualData.img])
80 }
81 }
82
83 function haveValidUrlPatterns() {
84 return webappUrlPatterns && webappUrlPatterns.length !== 0
85 }
86
87 /*function navigationRequestedDelegate(request) {
88 if (!request.isMainFrame) {
89 request.action = WebView.AcceptRequest
90 return
91 }
92
93 // Pass-through if we are not running as a named webapp (--webapp='Gmail')
94 // or if we dont have a list of url patterns specified to filter the
95 // browsing actions
96 if ( ! haveValidUrlPatterns() && ! isRunningAsANamedWebapp()) {
97 request.action = WebView.AcceptRequest
98 return
99 }
100
101 var action = WebView.IgnoreRequest
102 var url = request.url.toString()
103
104 // The list of url patterns defined by the webapp takes precedence over command line
105 if (isRunningAsANamedWebapp()) {
106 if (unityWebapps.model.exists(unityWebapps.name) &&
107 unityWebapps.model.doesUrlMatchesWebapp(unityWebapps.name, url)) {
108 request.action = WebView.AcceptRequest
109 return;
110 }
111 }
112
113 // We still take the possible additional patterns specified in the command line
114 // (the in the case of finer grained ones specifically for the container and not
115 // as an 'install source' for the webapp).
116 if (webappUrlPatterns && webappUrlPatterns.length !== 0) {
117 for (var i = 0; i < webappUrlPatterns.length; ++i) {
118 var pattern = webappUrlPatterns[i]
119 if (url.match(pattern)) {
120 action = WebView.AcceptRequest
121 break
122 }
123 }
124 }
125
126 request.action = action
127 if (action === WebView.IgnoreRequest) {
128 console.debug('Opening: ' + url + ' in the browser window.')
129 Qt.openUrlExternally(url)
130 }
131 }*/
132
133 onNewTabRequested: Qt.openUrlExternally(url)
134
135 preferences.localStorageEnabled: true
136
137 // Small shim needed when running as a webapp to wire-up connections
138 // with the webview (message received, etc…).
139 // This is being called (and expected) internally by the webapps
140 // component as a way to bind to a webview lookalike without
141 // reaching out directly to its internals (see it as an interface).
142 function getUnityWebappsProxies() {
143 var eventHandlers = {
144 onAppRaised: function () {
145 if (webbrowserWindow) {
146 try {
147 webbrowserWindow.raise();
148 } catch (e) {
149 console.debug('Error while raising: ' + e);
150 }
151 }
152 }
153 };
154 return UnityWebAppsUtils.makeProxiesForWebViewBindee(webview, eventHandlers)
155 }
156 }73 }
15774
158 ErrorSheet {75 ErrorSheet {
159 anchors.fill: webview76 anchors.fill: webview
160 visible: webview.lastLoadFailed77 visible: {
161 url: webview.url78 if (webview.lastLoadFailed !== undefined)
79 return webview.lastLoadFailed
80 return webview.currentWebview && webview.currentWebview.lastLoadFailed
81 }
82 url: webview.currentWebview.url
162 onRefreshClicked: webview.reload()83 onRefreshClicked: webview.reload()
163 }84 }
164 }85 }
@@ -166,7 +87,7 @@
166 PanelLoader {87 PanelLoader {
167 id: panel88 id: panel
16889
169 currentWebview: webview90 currentWebview: webview.currentWebview
170 chromeless: webapp.chromeless91 chromeless: webapp.chromeless
17192
172 backForwardButtonsVisible: webapp.backForwardButtonsVisible93 backForwardButtonsVisible: webapp.backForwardButtonsVisible
@@ -183,12 +104,8 @@
183 UnityWebApps.UnityWebApps {104 UnityWebApps.UnityWebApps {
184 id: unityWebapps105 id: unityWebapps
185 name: webappName106 name: webappName
186 bindee: currentWebview107 bindee: webview.currentWebview
187 actionsContext: actionManager.globalContext108 actionsContext: actionManager.globalContext
188 model: UnityWebApps.UnityWebappsAppModel { searchPath: webappModelSearchPath }109 model: UnityWebApps.UnityWebappsAppModel { searchPath: webappModelSearchPath }
189 }110 }
190
191 function isRunningAsANamedWebapp() {
192 return webappName && typeof(webappName) === 'string' && webappName.length != 0
193 }
194}111}
195112
=== added file 'src/app/webcontainer/WebViewImplWebkit.qml'
--- src/app/webcontainer/WebViewImplWebkit.qml 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/WebViewImplWebkit.qml 2014-03-28 16:05:34 +0000
@@ -0,0 +1,159 @@
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 QtWebKit 3.1
21import QtWebKit.experimental 1.0
22import Ubuntu.Components 0.1
23import Ubuntu.Components.Extras.Browser 0.1
24import Ubuntu.UnityWebApps 0.1 as UnityWebApps
25import Ubuntu.Components.Popups 0.1
26import "../actions" as Actions
27import ".."
28
29UbuntuWebView {
30 id: webview
31
32 property bool developerExtrasEnabled: false
33 property var currentWebview: webview
34 property var toolbar: null
35 property string webappName: ""
36 property var webappUrlPatterns: null
37
38 experimental.certificateVerificationDialog: CertificateVerificationDialog {}
39 experimental.authenticationDialog: AuthenticationDialog {}
40 experimental.proxyAuthenticationDialog: ProxyAuthenticationDialog {}
41 experimental.alertDialog: AlertDialog {}
42 experimental.confirmDialog: ConfirmDialog {}
43 experimental.promptDialog: PromptDialog {}
44
45 selectionActions: ActionList {
46 Actions.Copy {
47 onTriggered: selection.copy()
48 }
49 }
50
51 property bool lastLoadFailed: false
52 onLoadingChanged: {
53 lastLoadFailed = (loadRequest.status === WebView.LoadFailedStatus)
54 }
55
56 experimental.preferences.developerExtrasEnabled: developerExtrasEnabled
57
58 experimental.onPermissionRequested: {
59 if (permission.type === PermissionRequest.Geolocation) {
60 if (webview.toolbar) {
61 webview.toolbar.close()
62 }
63 var text = i18n.tr("This page wants to know your device’s location.")
64 PopupUtils.open(Qt.resolvedUrl("PermissionRequest.qml"),
65 webview.currentWebview,
66 {"permission": permission, "text": text})
67 }
68 // TODO: handle other types of permission requests
69 // TODO: we might want to store the answer to avoid requesting
70 // the permission everytime the user visits this site.
71 }
72
73 contextualActions: ActionList {
74 Actions.CopyLink {
75 enabled: webview.contextualData.href.toString()
76 onTriggered: Clipboard.push([webview.contextualData.href])
77 }
78 Actions.CopyImage {
79 enabled: webview.contextualData.img.toString()
80 onTriggered: Clipboard.push([webview.contextualData.img])
81 }
82 }
83
84 function isRunningAsANamedWebapp() {
85 return webview.webappName && typeof(webview.webappName) === 'string' && webview.webappName.length != 0
86 }
87
88 function haveValidUrlPatterns() {
89 return webappUrlPatterns && webappUrlPatterns.length !== 0
90 }
91
92 function navigationRequestedDelegate(request) {
93 if (!request.isMainFrame) {
94 request.action = WebView.AcceptRequest
95 return
96 }
97
98 // Pass-through if we are not running as a named webapp (--webapp='Gmail')
99 // or if we dont have a list of url patterns specified to filter the
100 // browsing actions
101 if ( ! haveValidUrlPatterns() && ! isRunningAsANamedWebapp()) {
102 request.action = WebView.AcceptRequest
103 return
104 }
105
106 var action = WebView.IgnoreRequest
107 var url = request.url.toString()
108
109 // The list of url patterns defined by the webapp takes precedence over command line
110 if (isRunningAsANamedWebapp()) {
111 if (unityWebapps.model.exists(unityWebapps.name) &&
112 unityWebapps.model.doesUrlMatchesWebapp(unityWebapps.name, url)) {
113 request.action = WebView.AcceptRequest
114 return;
115 }
116 }
117
118 // We still take the possible additional patterns specified in the command line
119 // (the in the case of finer grained ones specifically for the container and not
120 // as an 'install source' for the webapp).
121 if (webappUrlPatterns && webappUrlPatterns.length !== 0) {
122 for (var i = 0; i < webappUrlPatterns.length; ++i) {
123 var pattern = webappUrlPatterns[i]
124 if (url.match(pattern)) {
125 action = WebView.AcceptRequest
126 break
127 }
128 }
129 }
130
131 request.action = action
132 if (action === WebView.IgnoreRequest) {
133 console.debug('Opening: ' + url + ' in the browser window.')
134 Qt.openUrlExternally(url)
135 }
136 }
137
138 onNewTabRequested: Qt.openUrlExternally(url)
139
140 // Small shim needed when running as a webapp to wire-up connections
141 // with the webview (message received, etc…).
142 // This is being called (and expected) internally by the webapps
143 // component as a way to bind to a webview lookalike without
144 // reaching out directly to its internals (see it as an interface).
145 function getUnityWebappsProxies() {
146 var eventHandlers = {
147 onAppRaised: function () {
148 if (webbrowserWindow) {
149 try {
150 webbrowserWindow.raise();
151 } catch (e) {
152 console.debug('Error while raising: ' + e);
153 }
154 }
155 }
156 };
157 return UnityWebAppsUtils.makeProxiesForQtWebViewBindee(webview, eventHandlers)
158 }
159}
0160
=== added file 'src/app/webcontainer/WebappContainerWebview.qml'
--- src/app/webcontainer/WebappContainerWebview.qml 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/WebappContainerWebview.qml 2014-03-28 16:05:34 +0000
@@ -0,0 +1,151 @@
1/*
2 * Copyright 2014 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 Ubuntu.Components 0.1
21import Ubuntu.Unity.Action 1.0 as UnityActions
22import Ubuntu.UnityWebApps 0.1 as UnityWebApps
23import "../actions" as Actions
24import ".."
25
26Item {
27 id: containerWebview
28
29 property string url: ""
30 property bool withOxide: false
31 property bool developerExtrasEnabled: false
32 property string webappName: ""
33 property var currentWebview: webappContainerWebViewLoader.item
34 property var toolbar: null
35 property var webappUrlPatterns: null
36
37 Loader {
38 id: webappContainerWebViewLoader
39 anchors.fill: parent
40 sourceComponent: withOxide ? webappContainerWebViewOxide : webappContainerWebViewWebkit
41 }
42
43 Component {
44 id: webappContainerWebViewWebkit
45
46 WebViewImplWebkit {
47 toolbar: containerWebview.toolbar
48 url: containerWebview.url
49 webappName: containerWebview.webappName
50 webappUrlPatterns: containerWebview.webappUrlPatterns
51 developerExtrasEnabled: containerWebview.developerExtrasEnabled
52 }
53 }
54
55 Component {
56 id: webappContainerWebViewOxide
57
58 WebViewImpl {
59 id: webview
60
61 url: containerWebview.url
62 currentWebview: webview
63 toolbar: containerWebview.toolbar
64
65 contextualActions: ActionList {
66 Actions.CopyLink {
67 enabled: webview.contextualData.href.toString()
68 onTriggered: Clipboard.push([webview.contextualData.href])
69 }
70 Actions.CopyImage {
71 enabled: webview.contextualData.img.toString()
72 onTriggered: Clipboard.push([webview.contextualData.img])
73 }
74 }
75
76 function haveValidUrlPatterns() {
77 return webappUrlPatterns && webappUrlPatterns.length !== 0
78 }
79
80 /*function navigationRequestedDelegate(request) {
81 if (!request.isMainFrame) {
82 request.action = WebView.AcceptRequest
83 return
84 }
85
86 // Pass-through if we are not running as a named webapp (--webapp='Gmail')
87 // or if we dont have a list of url patterns specified to filter the
88 // browsing actions
89 if ( ! haveValidUrlPatterns() && ! isRunningAsANamedWebapp()) {
90 request.action = WebView.AcceptRequest
91 return
92 }
93
94 var action = WebView.IgnoreRequest
95 var url = request.url.toString()
96
97 // The list of url patterns defined by the webapp takes precedence over command line
98 if (isRunningAsANamedWebapp()) {
99 if (unityWebapps.model.exists(unityWebapps.name) &&
100 unityWebapps.model.doesUrlMatchesWebapp(unityWebapps.name, url)) {
101 request.action = WebView.AcceptRequest
102 return;
103 }
104 }
105
106 // We still take the possible additional patterns specified in the command line
107 // (the in the case of finer grained ones specifically for the container and not
108 // as an 'install source' for the webapp).
109 if (webappUrlPatterns && webappUrlPatterns.length !== 0) {
110 for (var i = 0; i < webappUrlPatterns.length; ++i) {
111 var pattern = webappUrlPatterns[i]
112 if (url.match(pattern)) {
113 action = WebView.AcceptRequest
114 break
115 }
116 }
117 }
118
119 request.action = action
120 if (action === WebView.IgnoreRequest) {
121 console.debug('Opening: ' + url + ' in the browser window.')
122 Qt.openUrlExternally(url)
123 }
124 }*/
125
126 onNewTabRequested: Qt.openUrlExternally(url)
127
128 preferences.localStorageEnabled: true
129
130 // Small shim needed when running as a webapp to wire-up connections
131 // with the webview (message received, etc…).
132 // This is being called (and expected) internally by the webapps
133 // component as a way to bind to a webview lookalike without
134 // reaching out directly to its internals (see it as an interface).
135 function getUnityWebappsProxies() {
136 var eventHandlers = {
137 onAppRaised: function () {
138 if (webbrowserWindow) {
139 try {
140 webbrowserWindow.raise();
141 } catch (e) {
142 console.debug('Error while raising: ' + e);
143 }
144 }
145 }
146 };
147 return UnityWebAppsUtils.makeProxiesForWebViewBindee(webview, eventHandlers)
148 }
149 }
150 }
151}
0152
=== modified file 'src/app/webcontainer/webapp-container.cpp'
--- src/app/webcontainer/webapp-container.cpp 2014-03-20 18:17:12 +0000
+++ src/app/webcontainer/webapp-container.cpp 2014-03-28 16:05:34 +0000
@@ -24,10 +24,32 @@
24// Qt24// Qt
25#include <QtCore/QCoreApplication>25#include <QtCore/QCoreApplication>
26#include <QtCore/QDebug>26#include <QtCore/QDebug>
27#include <QtCore/QFile>
27#include <QtCore/QFileInfo>28#include <QtCore/QFileInfo>
29#include <QtCore/QtGlobal>
28#include <QtCore/QRegularExpression>30#include <QtCore/QRegularExpression>
29#include <QtCore/QTextStream>31#include <QtCore/QTextStream>
30#include <QtQuick/QQuickWindow>32#include <QtQuick/QQuickWindow>
33#include <QtQml/QQmlComponent>
34
35
36namespace
37{
38
39QString currentArchitecturePathName()
40{
41#if defined(Q_PROCESSOR_X86_32)
42 return QLatin1String("i386-linux-gnu");
43#elif defined(Q_PROCESSOR_X86_64)
44 return QLatin1String("x86_64-linux-gnu");
45#elif defined(Q_PROCESSOR_ARM)
46 return QLatin1String("arm-linux-gnueabihf");
47#else
48#error Unable to determine target architecture
49#endif
50}
51
52}
3153
32WebappContainer::WebappContainer(int& argc, char** argv)54WebappContainer::WebappContainer(int& argc, char** argv)
33 : BrowserApplication(argc, argv)55 : BrowserApplication(argc, argv)
@@ -50,7 +72,13 @@
50 m_window->setProperty("webappName", name);72 m_window->setProperty("webappName", name);
51 m_window->setProperty("backForwardButtonsVisible", m_arguments.contains("--enable-back-forward"));73 m_window->setProperty("backForwardButtonsVisible", m_arguments.contains("--enable-back-forward"));
52 m_window->setProperty("addressBarVisible", m_arguments.contains("--enable-addressbar"));74 m_window->setProperty("addressBarVisible", m_arguments.contains("--enable-addressbar"));
75
76 bool oxide = withOxide();
77 qDebug() << "Using" << (oxide ? "Oxide" : "QtWebkit") << "as the web engine backend";
78 m_window->setProperty("oxide", oxide);
79
53 m_window->setProperty("webappUrlPatterns", webappUrlPatterns());80 m_window->setProperty("webappUrlPatterns", webappUrlPatterns());
81
54 // When a webapp is being launched by name, the URL is pulled from its 'homepage'.82 // When a webapp is being launched by name, the URL is pulled from its 'homepage'.
55 if (name.isEmpty()) {83 if (name.isEmpty()) {
56 QList<QUrl> urls = this->urls();84 QList<QUrl> urls = this->urls();
@@ -58,6 +86,9 @@
58 m_window->setProperty("url", urls.first());86 m_window->setProperty("url", urls.first());
59 }87 }
60 }88 }
89
90 m_component->completeCreate();
91
61 return true;92 return true;
62 } else {93 } else {
63 return false;94 return false;
@@ -84,6 +115,31 @@
84 out << " --enable-addressbar enable the display of the address bar" << endl;115 out << " --enable-addressbar enable the display of the address bar" << endl;
85}116}
86117
118bool WebappContainer::withOxide() const
119{
120 Q_FOREACH(const QString& argument, m_arguments) {
121 if (argument == "--webkit") {
122 // force webkit
123 return false;
124 }
125 if (argument == "--oxide") {
126 // force oxide
127 return true;
128 }
129 }
130
131 // Use a runtime hint to transparently know if oxide
132 // can be used as a backend without the user/dev having
133 // to update its app or change something in the Exec args.
134 // Version 1.1 of ubuntu apparmor policy allows this file to
135 // be accessed whereas v1.0 only knows about qtwebkit.
136 QString oxideHintLocation =
137 QString("/usr/lib/%1/oxide-qt/oxide-renderer")
138 .arg(currentArchitecturePathName());
139
140 return QFile(oxideHintLocation).open(QIODevice::ReadOnly);
141}
142
87QString WebappContainer::webappModelSearchPath() const143QString WebappContainer::webappModelSearchPath() const
88{144{
89 Q_FOREACH(const QString& argument, m_arguments) {145 Q_FOREACH(const QString& argument, m_arguments) {
90146
=== modified file 'src/app/webcontainer/webapp-container.h'
--- src/app/webcontainer/webapp-container.h 2014-03-14 14:51:22 +0000
+++ src/app/webcontainer/webapp-container.h 2014-03-28 16:05:34 +0000
@@ -39,6 +39,7 @@
39 QString webappModelSearchPath() const;39 QString webappModelSearchPath() const;
40 QString webappName() const;40 QString webappName() const;
41 QStringList webappUrlPatterns() const;41 QStringList webappUrlPatterns() const;
42 bool withOxide() const;
42};43};
4344
44#endif // __WEBAPP_CONTAINER_H__45#endif // __WEBAPP_CONTAINER_H__
4546
=== modified file 'src/app/webcontainer/webapp-container.qml'
--- src/app/webcontainer/webapp-container.qml 2014-03-17 10:16:11 +0000
+++ src/app/webcontainer/webapp-container.qml 2014-03-28 16:05:34 +0000
@@ -30,6 +30,7 @@
30 property alias webappName: browser.webappName30 property alias webappName: browser.webappName
31 property alias webappModelSearchPath: browser.webappModelSearchPath31 property alias webappModelSearchPath: browser.webappModelSearchPath
32 property alias webappUrlPatterns: browser.webappUrlPatterns32 property alias webappUrlPatterns: browser.webappUrlPatterns
33 property alias oxide: browser.oxide
3334
34 contentOrientation: browser.screenOrientation35 contentOrientation: browser.screenOrientation
3536

Subscribers

People subscribed via source and target branches