Merge lp:~mardy/webbrowser-app/multi-account-no-ui into lp:webbrowser-app

Proposed by Alberto Mardegan
Status: Needs review
Proposed branch: lp:~mardy/webbrowser-app/multi-account-no-ui
Merge into: lp:webbrowser-app
Diff against target: 1344 lines (+809/-244)
16 files modified
src/app/webcontainer/AccountChooserDialog.qml (+129/-0)
src/app/webcontainer/AccountItem.qml (+4/-6)
src/app/webcontainer/AccountsLoginPage.qml (+54/-137)
src/app/webcontainer/AccountsModel.qml (+0/-51)
src/app/webcontainer/AccountsPage.qml (+173/-10)
src/app/webcontainer/CMakeLists.txt (+1/-1)
src/app/webcontainer/LoggingInSheet.qml (+39/-0)
src/app/webcontainer/LogoutDetector.qml (+78/-0)
src/app/webcontainer/LogoutErrorSheet.qml (+64/-0)
src/app/webcontainer/SplashScreen.qml (+105/-0)
src/app/webcontainer/WebApp.qml (+2/-0)
src/app/webcontainer/cookie-store.cpp (+1/-0)
src/app/webcontainer/logout-detector.js (+41/-0)
src/app/webcontainer/webapp-container.cpp (+24/-0)
src/app/webcontainer/webapp-container.h (+3/-0)
src/app/webcontainer/webapp-container.qml (+91/-39)
To merge this branch: bzr merge lp:~mardy/webbrowser-app/multi-account-no-ui
Reviewer Review Type Date Requested Status
system-apps-ci-bot continuous-integration Needs Fixing
PS Jenkins bot continuous-integration Needs Fixing
Ubuntu Phablet Team Pending
Review via email: mp+255946@code.launchpad.net

Commit message

Detection of logout events

Description of the change

Detection of logout events

This can be tested with Twitter: its .desktop file needs to be modified so that the Exec line becomes (remove any newlines!):

Exec=webapp-container --enable-back-forward --store-session-cookies
--name=Twitter --icon=./twitter.png --accountProvider='twitter' --logoutSelectors='input[type="password"]' --logoutUrlPattern=https://mobile.twitter.com/api/destroy --webappUrlPatterns=https?://mobile.twitter.com/* https://mobile.twitter.com/session/new %u

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

Remove multi-account leftovers

975. By Alberto Mardegan

From trunk

[ Alexandre Abreu ]
* remove qtwebkit deps (LP: #1362640) (LP: #1362640)
[ CI Train Bot ]
* New rebuild forced.
[ Justin McPherson ]
* Command line options for media-hub use through Oxide.
[ Olivier Tilloy ]
* Update translation template.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
976. By Alberto Mardegan

Add missing import

977. By Alberto Mardegan

Remove count of login attempts

We cannot count it reliably anyway.

978. By Alberto Mardegan

Reset the webview on logout detected

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) wrote :
review: Approve (continuous-integration)
979. By Alberto Mardegan

UI changes

980. By Alberto Mardegan

Fixes

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
981. By Alberto Mardegan

UI updates

982. By Alberto Mardegan

alignment

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

Unmerged revisions

982. By Alberto Mardegan

alignment

981. By Alberto Mardegan

UI updates

980. By Alberto Mardegan

Fixes

979. By Alberto Mardegan

UI changes

978. By Alberto Mardegan

Reset the webview on logout detected

977. By Alberto Mardegan

Remove count of login attempts

We cannot count it reliably anyway.

976. By Alberto Mardegan

Add missing import

975. By Alberto Mardegan

From trunk

[ Alexandre Abreu ]
* remove qtwebkit deps (LP: #1362640) (LP: #1362640)
[ CI Train Bot ]
* New rebuild forced.
[ Justin McPherson ]
* Command line options for media-hub use through Oxide.
[ Olivier Tilloy ]
* Update translation template.

974. By Alberto Mardegan

Remove multi-account leftovers

973. By Alberto Mardegan

Automatic re-login

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'src/app/webcontainer/AccountChooserDialog.qml'
--- src/app/webcontainer/AccountChooserDialog.qml 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/AccountChooserDialog.qml 2015-04-16 14:53:15 +0000
@@ -0,0 +1,129 @@
1/*
2 * Copyright 2013-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 Qt.labs.settings 1.0
21import Ubuntu.Components 1.1
22import Ubuntu.Components.ListItems 1.0 as ListItem
23import Ubuntu.Components.Popups 1.0
24import Ubuntu.OnlineAccounts 0.1
25import Ubuntu.OnlineAccounts.Client 0.1
26
27Dialog {
28 id: root
29
30 property string providerId: ""
31 property string applicationId: ""
32 property bool accountMandatory: true
33 property var accountsModel: null
34
35 signal accountSelected(int accountId)
36 signal cancel()
37
38 property var __selectedAccount: settings.selectedAccount
39
40 Settings {
41 id: settings
42 property int selectedAccount
43 }
44
45 Setup {
46 id: setup
47 applicationId: root.applicationId
48 providerId: root.providerId
49 onFinished: {
50 if ("accountId" in reply) {
51 root.chooseAccount(reply.accountId)
52 } else {
53 root.cancel()
54 }
55 }
56 }
57
58 Repeater {
59 model: accountsModel
60 AccountItem {
61 providerName: model.providerName
62 accountName: model.displayName
63 selected: model.accountId === root.__selectedAccount
64 onClicked: root.__selectedAccount = model.accountId
65 }
66 }
67
68 ListItem.Standard {
69 id: addAccountButton
70 text: i18n.tr("Add account")
71 iconName: "add"
72 selected: root.__selectedAccount === -1
73 onClicked: root.__selectedAccount = -1
74 }
75
76 ListItem.Standard {
77 id: skipButton
78 visible: !root.accountMandatory
79 text: i18n.tr("Don't use an account")
80 selected: root.__selectedAccount === -2
81 onClicked: root.__selectedAccount = -2
82 }
83
84 Item {
85 anchors.left: parent.left
86 anchors.right: parent.right
87 anchors.margins: units.gu(1)
88 height: childrenRect.height + units.gu(1)
89
90 Button {
91 id: cancelButton
92 anchors.left: parent.left
93 width: parent.width / 2 - units.gu(1)
94 text: i18n.tr("Cancel")
95 onClicked: root.cancel()
96 }
97
98 Button {
99 anchors.right: parent.right
100 width: cancelButton.width
101 text: i18n.tr("OK")
102 onClicked: root.onConfirmed()
103 }
104 }
105
106 function chooseAccount(accountId) {
107 for (var i = 0; i < accountsModel.count; i++) {
108 if (accountsModel.get(i, "accountId") === accountId) {
109 settings.selectedAccount = accountId
110 root.accountSelected(accountId)
111 return
112 }
113 }
114
115 // The selected account was not found
116 settings.selectedAccount = -1
117 root.cancel()
118 }
119
120 function onConfirmed() {
121 if (__selectedAccount === -2) {
122 root.selectedAccount(0)
123 } else if (__selectedAccount === -1) {
124 setup.exec()
125 } else {
126 chooseAccount(__selectedAccount)
127 }
128 }
129}
0130
=== renamed file 'src/app/webcontainer/AccountItemView.qml' => 'src/app/webcontainer/AccountItem.qml'
--- src/app/webcontainer/AccountItemView.qml 2014-07-29 21:51:07 +0000
+++ src/app/webcontainer/AccountItem.qml 2015-04-16 14:53:15 +0000
@@ -20,14 +20,12 @@
20import Ubuntu.Components 1.120import Ubuntu.Components 1.1
21import Ubuntu.Components.ListItems 1.0 as ListItem21import Ubuntu.Components.ListItems 1.0 as ListItem
2222
23ListItem.Standard {23ListItem.Subtitled {
24 id: root24 id: root
2525
26 property string providerName
26 property string accountName27 property string accountName
2728
28 text: accountName29 text: providerName
2930 subText: accountName
30 iconSource: Qt.resolvedUrl("/usr/share/icons/ubuntu-mobile/actions/scalable/contact.svg")
31}31}
32
33
3432
=== modified file 'src/app/webcontainer/AccountsLoginPage.qml'
--- src/app/webcontainer/AccountsLoginPage.qml 2014-10-06 12:52:34 +0000
+++ src/app/webcontainer/AccountsLoginPage.qml 2015-04-16 14:53:15 +0000
@@ -17,18 +17,19 @@
17 */17 */
1818
19import QtQuick 2.019import QtQuick 2.0
20import Qt.labs.settings 1.0
20import Ubuntu.Components 1.121import Ubuntu.Components 1.1
21import Ubuntu.Components.ListItems 1.0 as ListItem22import Ubuntu.Components.ListItems 1.0 as ListItem
22import Ubuntu.OnlineAccounts 0.123import Ubuntu.OnlineAccounts 0.1
2324import Ubuntu.OnlineAccounts.Client 0.1
2425
25Item {26Item {
26 id: root27 id: root
2728
28 property string accountProvider: ""29 property var accountsModel
29 property string applicationName: ""
3030
31 signal done(variant credentialsId)31 signal accountSelected(int accountId)
32 signal done(bool successful)
3233
33 Timer {34 Timer {
34 id: checkTimer35 id: checkTimer
@@ -38,14 +39,21 @@
38 interval: 10039 interval: 100
39 }40 }
4041
41 AccountsModel {42 Settings {
42 id: accountsModel43 id: settings
43 accountProvider: root.accountProvider44 property int selectedAccount: -1
44 applicationName: root.applicationName45 }
45 onCountChanged: checkAccounts()46
47 Setup {
48 id: setup
49 applicationId: accountsModel.applicationId
50 providerId: accountsModel.provider
46 onFinished: {51 onFinished: {
47 if (count === 0) {52 if ("accountId" in reply) {
48 Qt.quit();53 settings.selectedAccount = reply.accountId
54 root.accountSelected(reply.accountId)
55 } else {
56 Qt.quit()
49 }57 }
50 }58 }
51 }59 }
@@ -64,137 +72,46 @@
64 checkTimer.stop()72 checkTimer.stop()
65 console.log("Accounts: " + accountsModel.count)73 console.log("Accounts: " + accountsModel.count)
66 if (accountsModel.count === 0) {74 if (accountsModel.count === 0) {
67 accountsModel.createNewAccount()75 setup.exec();
68 } else {76 } else if (settings.selectedAccount > 0) {
69 doLogin(accountsModel.model.get(0, "accountServiceHandle"))77 // check that the account exists
70 }78 for (var i = 0; i < accountsModel.count; i++) {
7179 if (accountsModel.get(i, "accountId") === settings.selectedAccount) {
72 // Note: Disable the account selection for now until we have a clearer view of80 break;
73 // the design and behavior related to the feature. Keep the code for reference.81 }
74 /*82 }
75 if (accountsModel.count === 1) {83 if (i >= accountsModel.count) {
76 doLogin(accountsModel.model.get(0, "accountServiceHandle"))84 // The selected account was not found, pick the first account
77 } else {85 settings.selectedAccount = accountsModel.get(0, "accountId")
78 accountsViewLoader.sourceComponent = accountsSelectionViewComponent86 }
79 }87 }
80 */88
81 }89 root.accountSelected(settings.selectedAccount)
8290 }
83 Component {91
84 id: accountsAdditionToolbarViewComponent92 function login(account, forceCookieRefresh) {
85 Item {93 console.log("Preparing for login, forced = " + forceCookieRefresh)
86 id: addAccountView
87
88 Label {
89 id: label
90 anchors.centerIn: parent
91 text: i18n.tr("No local account found for ") + root.accountProvider + "."
92 }
93
94 Label {
95 id: skipLabel
96 text: i18n.tr("Skip account creation step")
97 color: UbuntuColors.orange
98 fontSize: "small"
99
100 anchors.top: label.bottom
101 anchors.horizontalCenter: parent.horizontalCenter
102
103 Icon {
104 anchors.left: parent.right
105 anchors.verticalCenter: parent.verticalCenter
106 height: units.dp(12)
107 width: units.dp(12)
108 name: "chevron"
109 color: UbuntuColors.orange
110 }
111
112 MouseArea {
113 anchors.fill: parent
114 anchors.margins: -units.gu(5)
115 onClicked: root.done(null)
116 }
117 }
118
119 Panel {
120 id: panel
121 anchors {
122 right: parent.right
123 left: parent.left
124 bottom: parent.bottom
125 }
126
127 locked: true
128
129 height: units.gu(8)
130
131 Rectangle {
132 color: Theme.palette.normal.overlay
133 anchors.fill: parent
134 Item {
135 height: units.gu(8)
136 width: units.gu(8)
137
138 anchors {
139 right: parent.right
140 bottom: parent.bottom
141 }
142
143 ToolbarButton {
144 action: Action {
145 text: i18n.tr("Add account")
146 iconSource: Qt.resolvedUrl("/usr/share/icons/ubuntu-mobile/actions/scalable/add.svg")
147 onTriggered: {
148 accountsModel.createNewAccount();
149 }
150 }
151 }
152
153 signal clicked()
154 onClicked: {
155 accountsModel.createNewAccount();
156 }
157 }
158 }
159
160 Component.onCompleted: panel.open()
161 }
162
163 }
164 }
165
166 Component {
167 id: accountsSelectionViewComponent
168 AccountsView {
169 id: accountsView
170
171 model: accountsModel.model
172
173 onAccountSelected: doLogin(accountServiceHandle)
174 }
175 }
176
177 function doLogin(accountHandle) {
178 var account = accountComponent.createObject(root, {objectHandle: accountHandle});
17994
180 function authenticatedCallback() {95 function authenticatedCallback() {
181 account.authenticated.disconnect(authenticatedCallback);96 console.log("Authenticated!")
182 done(account.authData.credentialsId);97 account.authenticated.disconnect(authenticatedCallback)
98 root.done(true)
183 }99 }
184 account.authenticated.connect(authenticatedCallback);100 account.authenticated.connect(authenticatedCallback)
185101
186 function errorCallback() {102 function errorCallback() {
187 account.authenticationError.disconnect(errorCallback);103 console.log("Authentication error!")
188 done(null);104 account.authenticationError.disconnect(errorCallback)
189 }105 root.done(false)
190 account.authenticationError.connect(errorCallback);106 }
191107 account.authenticationError.connect(errorCallback)
192 account.authenticate(null);108
193 }109 var params = {}
194110 if (forceCookieRefresh) {
195 Component {111 params["UiPolicy"] = 1 // RequestPasswordPolicy
196 id: accountComponent112 }
197 AccountService { }113
114 account.authenticate(params)
198 }115 }
199}116}
200117
201118
=== removed file 'src/app/webcontainer/AccountsModel.qml'
--- src/app/webcontainer/AccountsModel.qml 2014-10-02 07:30:06 +0000
+++ src/app/webcontainer/AccountsModel.qml 1970-01-01 00:00:00 +0000
@@ -1,51 +0,0 @@
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 Ubuntu.OnlineAccounts 0.1
21import Ubuntu.OnlineAccounts.Client 0.1
22
23Item {
24 id: root
25 property string accountProvider: ""
26 property string applicationName: ""
27 property alias count: accountsModel.count
28
29 signal finished
30
31 function createNewAccount() {
32 setup.exec();
33 }
34
35 readonly property alias model: accountsModel
36
37 AccountServiceModel {
38 id: accountsModel
39 includeDisabled: false
40 serviceType: "webapps"
41 applicationId: root.applicationName
42 provider: root.accountProvider
43 }
44
45 Setup {
46 id: setup
47 applicationId: root.applicationName
48 providerId: root.accountProvider
49 onFinished: root.finished()
50 }
51}
520
=== modified file 'src/app/webcontainer/AccountsPage.qml'
--- src/app/webcontainer/AccountsPage.qml 2014-10-02 18:03:46 +0000
+++ src/app/webcontainer/AccountsPage.qml 2015-04-16 14:53:15 +0000
@@ -18,15 +18,33 @@
1818
19import QtQuick 2.019import QtQuick 2.0
20import Ubuntu.Components 1.120import Ubuntu.Components 1.1
21import Ubuntu.Components.Popups 1.0
22import Ubuntu.OnlineAccounts 0.1
21import webcontainer.private 0.123import webcontainer.private 0.1
2224
23Page {25Page {
24 id: accountsPage26 id: root
2527
26 property alias accountProvider: accountsLogin.accountProvider28 property string providerId: ""
27 property alias applicationName: accountsLogin.applicationName29 property string applicationId: ""
2830 property string webappName: ""
29 signal done(bool successful, var credentialsId)31 property url webappIcon
32 property int credentialsId: -1
33 property alias webview: detector.webview
34 property alias logoutUrlPattern: detector.logoutUrlPattern
35 property alias logoutSelectors: detector.logoutSelectors
36
37 signal accountSelected(var credentialsId)
38 signal done(bool successful)
39
40 property string __applicationName: webappName
41 property url __applicationIcon: webappIcon
42 property string __providerName: providerId
43 property var __account: null
44 property var __loggedOutAccounts: []
45 property var __accountsModel: accountsModel
46 property bool __loggingIn: false
47 property bool __ignoreLogout: false
3048
31 visible: true49 visible: true
32 anchors.fill: parent50 anchors.fill: parent
@@ -35,11 +53,156 @@
35 id: accountsLogin53 id: accountsLogin
3654
37 anchors.fill: parent55 anchors.fill: parent
56 accountsModel: root.__accountsModel
3857
58 onAccountSelected: {
59 if (accountId < 0) {
60 showErrorSheet()
61 } else {
62 root.__setupAccount(accountId)
63 }
64 }
39 onDone: {65 onDone: {
40 if (!accountsPage.visible)66 __loggingIn = false
41 return67 if (successful && __account) {
42 accountsPage.done(credentialsId != null, credentialsId)68 root.credentialsId = root.__account.authData.credentialsId
43 }69 }
70 root.done(successful)
71 }
72 }
73
74 LogoutErrorSheet {
75 id: errorSheet
76
77 visible: false
78
79 onAccountLoginClicked: {
80 root.credentialsId = -1
81 __loggedOutAccounts.push(__account.accountId)
82 root.login()
83 }
84
85 onManualLoginClicked: {
86 root.__ignoreLogout = true
87 root.visible = false
88 visible = false
89 }
90 }
91
92 LoggingInSheet {
93 visible: root.__loggingIn
94 }
95
96 Component {
97 id: accountChooserComponent
98 AccountChooserDialog {
99 id: accountChooser
100 providerId: root.providerId
101 applicationId: root.applicationId
102 accountsModel: root.__accountsModel
103 onCancel: PopupUtils.close(accountChooser)
104 onAccountSelected: {
105 PopupUtils.close(accountChooser)
106 root.__setupAccount(accountId)
107 }
108 }
109 }
110
111 LogoutDetector {
112 id: detector
113 onLogoutDetected: {
114 console.log("Logout detected")
115 if (!__ignoreLogout) {
116 root.visible = true
117 root.showErrorSheet()
118 }
119 }
120 }
121
122 ApplicationModel {
123 id: applicationModel
124 service: root.applicationId
125 }
126
127 ProviderModel {
128 id: providerModel
129 applicationId: root.applicationId
130 }
131
132 AccountServiceModel {
133 id: accountsModel
134 provider: root.providerId
135 applicationId: root.applicationId
136 }
137
138 Component {
139 id: accountComponent
140 AccountService { }
141 }
142
143 function __setupApplicationData() {
144 for (var i = 0; i < applicationModel.count; i++) {
145 if (applicationModel.get(i, "applicationId") === root.applicationId) {
146 var name = applicationModel.get(i, "displayName")
147 if (name) root.__applicationName = name
148 var icon = applicationModel.get(i, "iconName")
149 if (icon) root.__applicationIcon = icon
150 break
151 }
152 }
153 }
154
155 function __setupProviderData() {
156 for (var i = 0; i < providerModel.count; i++) {
157 if (providerModel.get(i, "providerId") === root.providerId) {
158 root.__providerName = providerModel.get(i, "displayName")
159 break
160 }
161 }
162 }
163
164 Component.onCompleted: {
165 __setupApplicationData()
166 __setupProviderData()
167 }
168
169 function __setupAccount(accountId) {
170 console.log("Setup account " + accountId)
171 if (__account && accountId === __account.accountId) {
172 console.log("Same as current account")
173 return
174 }
175 __account = null
176 for (var i = 0; i < accountsModel.count; i++) {
177 if (accountsModel.get(i, "accountId") === accountId) {
178 var accountHandle = accountsModel.get(i, "accountServiceHandle")
179 __account = accountComponent.createObject(root, {
180 objectHandle: accountHandle
181 })
182 break;
183 }
184 }
185 credentialsId = __account ? __account.authData.credentialsId : 0
186 console.log("Credentials ID: " + credentialsId)
187 }
188
189 function login() {
190 console.log("Logging in to " + __account)
191 __loggingIn = true
192 var forceCookieRefresh = false
193 var index = __loggedOutAccounts.indexOf(__account.accountId)
194 if (index >= 0) {
195 forceCookieRefresh = true
196 __loggedOutAccounts.splice(index, 1)
197 }
198 accountsLogin.login(__account, forceCookieRefresh)
199 }
200
201 function showErrorSheet() {
202 errorSheet.visible = true
203 }
204
205 function chooseAccount() {
206 PopupUtils.open(accountChooserComponent)
44 }207 }
45}208}
46209
=== modified file 'src/app/webcontainer/CMakeLists.txt'
--- src/app/webcontainer/CMakeLists.txt 2015-01-26 14:53:18 +0000
+++ src/app/webcontainer/CMakeLists.txt 2015-04-16 14:53:15 +0000
@@ -30,7 +30,7 @@
30install(TARGETS ${WEBAPP_CONTAINER}30install(TARGETS ${WEBAPP_CONTAINER}
31 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})31 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
3232
33file(GLOB QML_FILES *.qml)33file(GLOB QML_FILES *.qml *.js)
34install(FILES ${QML_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer)34install(FILES ${QML_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer)
35install(DIRECTORY actions DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer35install(DIRECTORY actions DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer
36 FILES_MATCHING PATTERN *.qml)36 FILES_MATCHING PATTERN *.qml)
3737
=== added file 'src/app/webcontainer/LoggingInSheet.qml'
--- src/app/webcontainer/LoggingInSheet.qml 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/LoggingInSheet.qml 2015-04-16 14:53:15 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright 2015 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 1.1
21
22Rectangle {
23 anchors.fill: parent
24
25 ActivityIndicator {
26 id: spinner
27 anchors.centerIn: parent
28 running: true
29 }
30
31 Label {
32 anchors.left: parent.left
33 anchors.right: parent.right
34 anchors.top: spinner.bottom
35 anchors.margins: units.gu(3)
36 text: i18n.tr("Automatic login with Ubuntu in progress…").arg(url)
37 wrapMode: Text.Wrap
38 }
39}
040
=== added file 'src/app/webcontainer/LogoutDetector.qml'
--- src/app/webcontainer/LogoutDetector.qml 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/LogoutDetector.qml 2015-04-16 14:53:15 +0000
@@ -0,0 +1,78 @@
1/*
2 * Copyright 2015 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 com.canonical.Oxide 1.0
21
22QtObject {
23 id: root
24
25 property var webview: null
26 property string logoutUrlPattern: ""
27 property string logoutSelectors: ""
28
29 signal logoutDetected()
30
31 property var __scriptMessageHandlerComponent: Component {
32 ScriptMessageHandler {
33 msgId: "domChanged"
34 contexts: ["oxide://logoutDetector/"]
35 callback: function(msg, frame) {
36 console.log('Got a DOM changed message: ' + msg.args)
37 var request = webview.rootFrame.sendMessage(
38 "oxide://logoutDetector/",
39 "evaluateSelectors",
40 { selectors: root.logoutSelectors }
41 )
42
43 // NOTE: does not handle error
44 request.onreply = function(response) {
45 console.log('Selector result: ' + response.result)
46 if (response.result) {
47 root.logoutDetected()
48 }
49 }
50 }
51 }
52 }
53
54 property var __connections: Connections {
55 target: webview
56 onLoadEvent: {
57 console.log("Load event: " + event.url)
58 if (logoutUrlPattern.length !== 0 && event.url.toString().match(logoutUrlPattern)) {
59 root.logoutDetected()
60 }
61 }
62 }
63
64 property var __userScript: UserScript {
65 context: "oxide://logoutDetector/"
66 url: Qt.resolvedUrl("logout-detector.js")
67 incognitoEnabled: true
68 matchAllFrames: true
69 }
70
71 onWebviewChanged: {
72 if (!webview) return
73 console.log("Webview changed, adding script")
74 var handler = __scriptMessageHandlerComponent.createObject(null, {})
75 webview.addMessageHandler(handler)
76 webview.context.addUserScript(__userScript)
77 }
78}
079
=== added file 'src/app/webcontainer/LogoutErrorSheet.qml'
--- src/app/webcontainer/LogoutErrorSheet.qml 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/LogoutErrorSheet.qml 2015-04-16 14:53:15 +0000
@@ -0,0 +1,64 @@
1/*
2 * Copyright 2015 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 1.1
21
22Rectangle {
23 signal accountLoginClicked()
24 signal manualLoginClicked()
25
26 anchors.fill: parent
27
28 Column {
29 anchors.fill: parent
30 anchors.margins: units.gu(4)
31
32 spacing: units.gu(3)
33
34 Label {
35 width: parent.width
36 fontSize: "x-large"
37 text: i18n.tr("Logged out")
38 }
39
40 Label {
41 width: parent.width
42 text: i18n.tr("It appears that you have been logged out.").arg(url)
43 wrapMode: Text.Wrap
44 }
45
46 Label {
47 width: parent.width
48 text: i18n.tr("Press the <b>Login</b> button to automatically login via Ubuntu, or <b>Continue</b> to go back to the website.")
49 wrapMode: Text.Wrap
50 }
51
52 Button {
53 anchors.horizontalCenter: parent.horizontalCenter
54 text: i18n.tr("Login with Ubuntu")
55 onClicked: accountLoginClicked()
56 }
57
58 Button {
59 anchors.horizontalCenter: parent.horizontalCenter
60 text: i18n.tr("Continue anyway")
61 onClicked: manualLoginClicked()
62 }
63 }
64}
065
=== added file 'src/app/webcontainer/SplashScreen.qml'
--- src/app/webcontainer/SplashScreen.qml 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/SplashScreen.qml 2015-04-16 14:53:15 +0000
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2013-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 1.1
21import Ubuntu.OnlineAccounts 0.1
22
23Item {
24 id: root
25
26 property string providerName
27 property string applicationName
28 property alias iconSource: icon.source
29 property bool accountMandatory: true
30
31 signal chooseAccount()
32 signal skip()
33
34 anchors.fill: parent
35
36 Column {
37 anchors {
38 left: parent.left
39 right: parent.right
40 verticalCenter: parent.verticalCenter
41 }
42 spacing: units.gu(2)
43
44 Icon {
45 id: icon
46 anchors.horizontalCenter: parent.horizontalCenter
47 width: units.gu(10)
48 height: width
49 }
50
51 Label {
52 anchors.horizontalCenter: parent.horizontalCenter
53 fontSize: "x-large"
54 text: root.applicationName
55 }
56
57 Label {
58 anchors.left: parent.left
59 anchors.right: parent.right
60 horizontalAlignment: Text.AlignHCenter
61 wrapMode: Text.WordWrap
62 text: i18n.tr("<b>%1</b> needs to access your %2 online account.").arg(root.applicationName).arg(root.providerName)
63 visible: root.accountMandatory
64 }
65
66 Label {
67 anchors.left: parent.left
68 anchors.right: parent.right
69 horizontalAlignment: Text.AlignHCenter
70 wrapMode: Text.WordWrap
71 text: i18n.tr("<b>%1</b> would like to access your %2 online account.").arg(root.applicationName).arg(root.providerName)
72 visible: !root.accountMandatory
73 }
74
75 Label {
76 anchors.left: parent.left
77 anchors.right: parent.right
78 horizontalAlignment: Text.AlignHCenter
79 wrapMode: Text.WordWrap
80 text: i18n.tr("Choose an account now, or skip this step and choose an online account later.")
81 visible: !root.accountMandatory
82 }
83
84 Item {
85 anchors.left: parent.left
86 anchors.right: parent.right
87 anchors.margins: units.gu(1)
88 height: units.gu(6)
89
90 Button {
91 anchors.left: parent.left
92 width: parent.width / 2 - units.gu(1)
93 text: root.accountMandatory ? i18n.tr("Close the app") : i18n.tr("Skip")
94 onClicked: root.accountMandatory ? Qt.quit() : root.skip()
95 }
96
97 Button {
98 anchors.right: parent.right
99 width: parent.width / 2 - units.gu(1)
100 text: i18n.tr("Choose account")
101 onClicked: root.chooseAccount()
102 }
103 }
104 }
105}
0106
=== modified file 'src/app/webcontainer/WebApp.qml'
--- src/app/webcontainer/WebApp.qml 2015-04-08 13:20:57 +0000
+++ src/app/webcontainer/WebApp.qml 2015-04-16 14:53:15 +0000
@@ -46,6 +46,8 @@
46 property bool chromeVisible: false46 property bool chromeVisible: false
47 readonly property bool chromeless: !chromeVisible && !backForwardButtonsVisible47 readonly property bool chromeless: !chromeVisible && !backForwardButtonsVisible
4848
49 signal chooseAccount()
50
49 actions: [51 actions: [
50 Actions.Back {52 Actions.Back {
51 enabled: webapp.backForwardButtonsVisible && webview.currentWebview && webview.currentWebview.canGoBack53 enabled: webapp.backForwardButtonsVisible && webview.currentWebview && webview.currentWebview.canGoBack
5254
=== modified file 'src/app/webcontainer/cookie-store.cpp'
--- src/app/webcontainer/cookie-store.cpp 2014-10-08 14:16:14 +0000
+++ src/app/webcontainer/cookie-store.cpp 2015-04-16 14:53:15 +0000
@@ -51,6 +51,7 @@
51 QObject(parent)51 QObject(parent)
52{52{
53 qRegisterMetaType<QNetworkCookie>();53 qRegisterMetaType<QNetworkCookie>();
54 qRegisterMetaType<QList<QNetworkCookie> >("QList<QNetworkCookie>");
54 qRegisterMetaType<Cookies>("Cookies");55 qRegisterMetaType<Cookies>("Cookies");
55}56}
5657
5758
=== added file 'src/app/webcontainer/logout-detector.js'
--- src/app/webcontainer/logout-detector.js 1970-01-01 00:00:00 +0000
+++ src/app/webcontainer/logout-detector.js 2015-04-16 14:53:15 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2015 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
19oxide.sendMessage('domChanged', 'Some message');
20
21var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
22
23var observer = new MutationObserver(function(mutations) {
24 var addnodes = []
25 mutations.forEach(function(mutation) {
26 for (var i in mutation.addedNodes) {
27 addnodes.push(mutation.addedNodes[i].className)
28 }
29 });
30
31 oxide.sendMessage('domChanged', JSON.stringify(addnodes))
32});
33observer.observe(document.body, {childList: true, subtree: true });
34
35
36oxide.addMessageHandler("evaluateSelectors", function(msg) {
37 var selectors = msg.args.selectors;
38 console.log("Evaluating selectors: " + selectors);
39 var match = document.querySelector(selectors);
40 msg.reply({result: (match !== null)});
41});
042
=== modified file 'src/app/webcontainer/webapp-container.cpp'
--- src/app/webcontainer/webapp-container.cpp 2015-04-10 13:33:19 +0000
+++ src/app/webcontainer/webapp-container.cpp 2015-04-16 14:53:15 +0000
@@ -116,9 +116,17 @@
116 }116 }
117117
118 m_window->setProperty("webappName", m_webappName);118 m_window->setProperty("webappName", m_webappName);
119 QFileInfo iconInfo(m_webappIcon);
120 QUrl iconUrl;
121 if (iconInfo.isReadable()) {
122 iconUrl = QUrl::fromLocalFile(iconInfo.absoluteFilePath());
123 }
124 m_window->setProperty("webappIcon", iconUrl);
119 m_window->setProperty("backForwardButtonsVisible", m_backForwardButtonsVisible);125 m_window->setProperty("backForwardButtonsVisible", m_backForwardButtonsVisible);
120 m_window->setProperty("chromeVisible", m_addressBarVisible);126 m_window->setProperty("chromeVisible", m_addressBarVisible);
121 m_window->setProperty("accountProvider", m_accountProvider);127 m_window->setProperty("accountProvider", m_accountProvider);
128 m_window->setProperty("logoutUrlPattern", m_logoutUrlPattern);
129 m_window->setProperty("logoutSelectors", m_logoutSelectors);
122130
123 m_window->setProperty("webappUrlPatterns", m_webappUrlPatterns);131 m_window->setProperty("webappUrlPatterns", m_webappUrlPatterns);
124 QQmlContext* context = m_engine->rootContext();132 QQmlContext* context = m_engine->rootContext();
@@ -251,9 +259,13 @@
251 " [--app-id=APP_ID]"259 " [--app-id=APP_ID]"
252 " [--homepage=URL]"260 " [--homepage=URL]"
253 " [--webapp=name]"261 " [--webapp=name]"
262 " [--name=NAME]"
263 " [--icon=PATH]"
254 " [--webappModelSearchPath=PATH]"264 " [--webappModelSearchPath=PATH]"
255 " [--webappUrlPatterns=URL_PATTERNS]"265 " [--webappUrlPatterns=URL_PATTERNS]"
256 " [--accountProvider=PROVIDER_NAME]"266 " [--accountProvider=PROVIDER_NAME]"
267 " [--logoutUrlPattern=URL_PATTERN]"
268 " [--logoutSelectors=selector1,selector2,...]"
257 " [--enable-back-forward]"269 " [--enable-back-forward]"
258 " [--enable-addressbar]"270 " [--enable-addressbar]"
259 " [--store-session-cookies]"271 " [--store-session-cookies]"
@@ -268,9 +280,13 @@
268 out << " --app-id=APP_ID run the application with a specific APP_ID" << endl;280 out << " --app-id=APP_ID run the application with a specific APP_ID" << endl;
269 out << " --homepage=URL override any URL passed as an argument" << endl;281 out << " --homepage=URL override any URL passed as an argument" << endl;
270 out << " --webapp=name try to match the webapp by name with an installed integration script" << endl;282 out << " --webapp=name try to match the webapp by name with an installed integration script" << endl;
283 out << " --name=NAME display name of the webapp, shown in the splash screen" << endl;
284 out << " --icon=PATH Icon to be shown in the splash screen. PATH can be an absolute or path relative to CWD" << endl;
271 out << " --webappModelSearchPath=PATH alter the search path for installed webapps and set it to PATH. PATH can be an absolute or path relative to CWD" << endl;285 out << " --webappModelSearchPath=PATH alter the search path for installed webapps and set it to PATH. PATH can be an absolute or path relative to CWD" << endl;
272 out << " --webappUrlPatterns=URL_PATTERNS list of comma-separated url patterns (wildcard based) that the webapp is allowed to navigate to" << endl;286 out << " --webappUrlPatterns=URL_PATTERNS list of comma-separated url patterns (wildcard based) that the webapp is allowed to navigate to" << endl;
273 out << " --accountProvider=PROVIDER_NAME Online account provider for the application if the application is to reuse a local account." << endl;287 out << " --accountProvider=PROVIDER_NAME Online account provider for the application if the application is to reuse a local account." << endl;
288 out << " --logoutUrlPattern=PATTERN Regexp pattern for detecting logout URLs." << endl;
289 out << " --logoutSelectors=SELECTORS Comma separated list of CSS selectors to detect the logout situation." << endl;
274 out << " --store-session-cookies store session cookies on disk" << endl;290 out << " --store-session-cookies store session cookies on disk" << endl;
275 out << " --enable-media-hub-audio enable media-hub for audio playback" << endl;291 out << " --enable-media-hub-audio enable media-hub for audio playback" << endl;
276 out << " --user-agent-string=USER_AGENT overrides the default User Agent with the provided one." << endl;292 out << " --user-agent-string=USER_AGENT overrides the default User Agent with the provided one." << endl;
@@ -298,6 +314,10 @@
298 // TODO: validate that it is fine in all cases (country dependent, etc…).314 // TODO: validate that it is fine in all cases (country dependent, etc…).
299 QString name = argument.split("--webapp=")[1];315 QString name = argument.split("--webapp=")[1];
300 m_webappName = QByteArray::fromBase64(name.toUtf8()).trimmed();316 m_webappName = QByteArray::fromBase64(name.toUtf8()).trimmed();
317 } else if (argument.startsWith("--name=")) {
318 m_webappName = argument.split("--name=")[1];
319 } else if (argument.startsWith("--icon=")) {
320 m_webappIcon = argument.split("--icon=")[1];
301 } else if (argument.startsWith("--webappUrlPatterns=")) {321 } else if (argument.startsWith("--webappUrlPatterns=")) {
302 QString tail = argument.split("--webappUrlPatterns=")[1];322 QString tail = argument.split("--webappUrlPatterns=")[1];
303 if (!tail.isEmpty()) {323 if (!tail.isEmpty()) {
@@ -306,6 +326,10 @@
306 }326 }
307 } else if (argument.startsWith("--accountProvider=")) {327 } else if (argument.startsWith("--accountProvider=")) {
308 m_accountProvider = argument.split("--accountProvider=")[1];328 m_accountProvider = argument.split("--accountProvider=")[1];
329 } else if (argument.startsWith("--logoutUrlPattern=")) {
330 m_logoutUrlPattern = argument.split("--logoutUrlPattern=")[1];
331 } else if (argument.startsWith("--logoutSelectors=")) {
332 m_logoutSelectors = argument.split("--logoutSelectors=")[1];
309 } else if (argument == "--clear-cookies") {333 } else if (argument == "--clear-cookies") {
310 qWarning() << argument << " is an unsupported option: it can be removed without notice..." << endl;334 qWarning() << argument << " is an unsupported option: it can be removed without notice..." << endl;
311 clearCookiesHack(m_accountProvider);335 clearCookiesHack(m_accountProvider);
312336
=== modified file 'src/app/webcontainer/webapp-container.h'
--- src/app/webcontainer/webapp-container.h 2015-04-10 13:33:19 +0000
+++ src/app/webcontainer/webapp-container.h 2015-04-16 14:53:15 +0000
@@ -58,9 +58,12 @@
5858
59private:59private:
60 QString m_webappName;60 QString m_webappName;
61 QString m_webappIcon;
61 QString m_webappModelSearchPath;62 QString m_webappModelSearchPath;
62 QStringList m_webappUrlPatterns;63 QStringList m_webappUrlPatterns;
63 QString m_accountProvider;64 QString m_accountProvider;
65 QString m_logoutUrlPattern;
66 QString m_logoutSelectors;
64 bool m_storeSessionCookies;67 bool m_storeSessionCookies;
65 bool m_backForwardButtonsVisible;68 bool m_backForwardButtonsVisible;
66 bool m_addressBarVisible;69 bool m_addressBarVisible;
6770
=== modified file 'src/app/webcontainer/webapp-container.qml'
--- src/app/webcontainer/webapp-container.qml 2015-04-07 14:30:52 +0000
+++ src/app/webcontainer/webapp-container.qml 2015-04-16 14:53:15 +0000
@@ -34,10 +34,13 @@
3434
35 property var intentFilterHandler35 property var intentFilterHandler
36 property string url: ""36 property string url: ""
37 property string webappIcon: ""
37 property string webappName: ""38 property string webappName: ""
38 property string webappModelSearchPath: ""39 property string webappModelSearchPath: ""
39 property var webappUrlPatterns40 property var webappUrlPatterns
40 property string accountProvider: ""41 property string accountProvider: ""
42 property string logoutUrlPattern: ""
43 property string logoutSelectors: ""
41 property string popupRedirectionUrlPrefixPattern: ""44 property string popupRedirectionUrlPrefixPattern: ""
42 property url webviewOverrideFile: ""45 property url webviewOverrideFile: ""
43 property var __webappCookieStore: null46 property var __webappCookieStore: null
@@ -50,6 +53,10 @@
5053
51 title: getWindowTitle()54 title: getWindowTitle()
5255
56 onCurrentWebviewChanged: if (accountsPageComponentLoader.item) {
57 accountsPageComponentLoader.item.webview = currentWebview
58 }
59
53 // Used for testing60 // Used for testing
54 signal intentUriHandleResult(string uri)61 signal intentUriHandleResult(string uri)
5562
@@ -102,6 +109,8 @@
102 root.title = getWindowTitle();109 root.title = getWindowTitle();
103 }110 }
104 }111 }
112
113 onChooseAccount: accountsPageComponentLoader.item.chooseAccount()
105 }114 }
106 }115 }
107116
@@ -158,13 +167,15 @@
158 Loader {167 Loader {
159 id: accountsPageComponentLoader168 id: accountsPageComponentLoader
160 anchors.fill: parent169 anchors.fill: parent
170 z: -1 // This is needed to have the dialogs shown; see above comment about bug 1398046
161 onStatusChanged: {171 onStatusChanged: {
162 if (status == Loader.Error) {172 if (status == Loader.Error) {
163 // Happens on the desktop, if Ubuntu.OnlineAccounts.Client173 // Happens on the desktop, if Ubuntu.OnlineAccounts.Client
164 // can't be imported174 // can't be imported
165 loadWebAppView()175 loadWebAppView(true)
166 } else if (status == Loader.Ready) {176 } else if (status == Loader.Ready) {
167 item.visible = true177 item.visible = true
178 initializeForAccount(item.credentialsId)
168 }179 }
169 }180 }
170 }181 }
@@ -175,48 +186,82 @@
175 }186 }
176 if (!result) {187 if (!result) {
177 console.log("Cookies were not moved")188 console.log("Cookies were not moved")
189 } else {
190 console.log("cookies moved")
178 }191 }
179 webappViewLoader.item.url = root.url192 webappViewLoader.item.url = root.url
180 }193 }
181194
182 function moveCookies(credentialsId) {195 function moveCookies(credentialsId) {
196 console.log("moving cookies for id " + credentialsId)
197 var storeComponent = localCookieStoreDbPath.length !== 0 ?
198 localCookieStoreComponent : onlineAccountStoreComponent
199
200 var instance = storeComponent.createObject(root, { "accountId": credentialsId })
201 __webappCookieStore.moved.connect(onCookiesMoved)
202 __webappCookieStore.moveFrom(instance)
203 }
204
205 function doLogin() {
183 if (!__webappCookieStore) {206 if (!__webappCookieStore) {
184 var context = webappViewLoader.item.currentWebview.context207 var context = webappViewLoader.item.currentWebview.context
185 __webappCookieStore = oxideCookieStoreComponent.createObject(this, {208 __webappCookieStore = oxideCookieStoreComponent.createObject(webappViewLoader.item, {
186 "oxideStoreBackend": context.cookieManager,209 "oxideStoreBackend": context.cookieManager,
187 "dbPath": context.dataPath + "/cookies.sqlite"210 "dbPath": context.dataPath + "/cookies.sqlite"
188 })211 })
189 }212 }
190213
191 var storeComponent = localCookieStoreDbPath.length !== 0 ?214 accountsPageComponentLoader.item.login()
192 localCookieStoreComponent : onlineAccountStoreComponent215 }
193216
194 var instance = storeComponent.createObject(root, { "accountId": credentialsId })217 function initializeForAccount(credentialsId) {
195 __webappCookieStore.moved.connect(onCookiesMoved)218 console.log("Account selected, creds: " + credentialsId)
196 __webappCookieStore.moveFrom(instance)219 if (credentialsId < 0) {
220 webappViewLoader.sourceComponent = null
221 __webappCookieStore = null
222 webappViewLoader.credentialsId = credentialsId
223 return
224 }
225
226 if (credentialsId > 0) {
227 if (credentialsId == webappViewLoader.credentialsId) {
228 doLogin()
229 return
230 }
231
232 webappViewLoader.sourceComponent = null
233 __webappCookieStore = null
234 webappViewLoader.loaded.connect(function onLoaded() {
235 if (webappViewLoader.status == Loader.Ready) {
236 webappViewLoader.loaded.disconnect(onLoaded)
237 doLogin()
238 }
239 });
240 webappViewLoader.credentialsId = credentialsId
241 // If we need to preserve session cookies, make sure that the
242 // mode is "restored" and not "persistent", or the cookies
243 // transferred from OA would be lost.
244 // We check if the webContextSessionCookieMode is defined and, if so,
245 // we override it in the webapp loader.
246 if (typeof webContextSessionCookieMode === "string") {
247 webappViewLoader.webContextSessionCookieMode = "restored"
248 }
249 }
250
251 loadWebAppView(credentialsId == 0)
197 }252 }
198253
199 Connections {254 Connections {
200 target: accountsPageComponentLoader.item255 target: accountsPageComponentLoader.item
256 onCredentialsIdChanged: initializeForAccount(accountsPageComponentLoader.item.credentialsId)
257 onVisibleChanged: webappViewLoader.item.visible = !accountsPageComponentLoader.item.visible
201 onDone: {258 onDone: {
259 console.log("Authentication done, successful = " + successful)
202 if (successful) {260 if (successful) {
203 webappViewLoader.loaded.connect(function () {261 moveCookies(webappViewLoader.credentialsId)
204 if (webappViewLoader.status == Loader.Ready) {262 } else {
205 moveCookies(webappViewLoader.credentialsId)263 loadWebAppView(true)
206 }
207 });
208 webappViewLoader.credentialsId = credentialsId
209 // If we need to preserve session cookies, make sure that the
210 // mode is "restored" and not "persistent", or the cookies
211 // transferred from OA would be lost.
212 // We check if the webContextSessionCookieMode is defined and, if so,
213 // we override it in the webapp loader.
214 if (typeof webContextSessionCookieMode === "string") {
215 webappViewLoader.webContextSessionCookieMode = "restored"
216 }
217 }264 }
218
219 loadWebAppView()
220 }265 }
221 }266 }
222267
@@ -241,7 +286,7 @@
241 if (accountProvider.length !== 0) {286 if (accountProvider.length !== 0) {
242 loadLoginView();287 loadLoginView();
243 } else {288 } else {
244 loadWebAppView();289 loadWebAppView(true);
245 }290 }
246 }291 }
247292
@@ -252,27 +297,34 @@
252297
253 function loadLoginView() {298 function loadLoginView() {
254 accountsPageComponentLoader.setSource("AccountsPage.qml", {299 accountsPageComponentLoader.setSource("AccountsPage.qml", {
255 "accountProvider": accountProvider,300 "providerId": accountProvider,
256 "applicationName": unversionedAppId,301 "applicationId": unversionedAppId,
302 "webappName": getWebappName(),
303 "webappIcon": webappIcon,
304 "logoutUrlPattern": logoutUrlPattern,
305 "logoutSelectors": logoutSelectors,
257 })306 })
258 }307 }
259308
260 function loadWebAppView() {309 function loadWebAppView(startBrowsing) {
261 if (accountsPageComponentLoader.item)310 if (accountsPageComponentLoader.item)
262 accountsPageComponentLoader.item.visible = false311 accountsPageComponentLoader.item.visible = false
263312
264 webappViewLoader.loaded.connect(function () {313 if (startBrowsing) {
265 if (webappViewLoader.status === Loader.Ready) {314 webappViewLoader.loaded.connect(function onLoaded() {
266 // As we use StateSaver to restore the URL, we need to check first if315 if (webappViewLoader.status === Loader.Ready) {
267 // it has not been set previously before setting the URL to the default property 316 webappViewLoader.loaded.disconnect(onLoaded)
268 // homepage.317 // As we use StateSaver to restore the URL, we need to check first if
269 var webView = webappViewLoader.item.currentWebview318 // it has not been set previously before setting the URL to the default property
270 var current_url = webView.url.toString();319 // homepage.
271 if (!current_url || current_url.length === 0) {320 var webView = webappViewLoader.item.currentWebview
272 webView.url = root.url321 var current_url = webView.url.toString();
322 if (!current_url || current_url.length === 0) {
323 webView.url = root.url
324 }
273 }325 }
274 }326 });
275 });327 }
276 webappViewLoader.sourceComponent = webappViewComponent328 webappViewLoader.sourceComponent = webappViewComponent
277 }329 }
278330

Subscribers

People subscribed via source and target branches

to status/vote changes: